/// <summary>Initializes a new instance of <see cref="Package"/>.</summary> /// <param name="store">The ISlkStore to use.</param> /// <param name="file">The package file in SharePoint.</param> /// <param name="location">The location of the file.</param> public Package(ISlkStore store, SPFile file, SharePointFileLocation location) { this.store = store; this.file = file; Location = location; try { reader = store.CreatePackageReader(file, location); Initialize(); } catch (CacheException ex) { throw new SafeToDisplayException(ex.Message); } catch (InvalidPackageException ex) { string extension = System.IO.Path.GetExtension(file.Name).ToUpperInvariant(); switch (extension) { case ".ZIP": case ".LRM": throw new SafeToDisplayException(culture.Format(culture.Resources.PackageNotValid, ex.Message)); default: IsNonELearning = true; break; } } }
string AssignmentSiteUrl(string webUrl) { string urlFormat = "{0}{1}AssignmentProperties.aspx?Location={2}{3}{4}"; string orgIndex = null; string titleValue = null; SharePointFileLocation location = null; string title = null; if (NoFileAssignment) { title = Request.QueryString["title"];; location = Package.NoPackageLocation; } else { location = package.Location; if (NonELearning == false) { orgIndex = String.Format(CultureInfo.InvariantCulture, "&OrgIndex={0}", OrganizationIndex); } } if (string.IsNullOrEmpty(title) == false) { titleValue = "&Title=" + title; } return(String.Format(CultureInfo.InvariantCulture, urlFormat, webUrl, Constants.SlkUrlPath, location.ToString(), orgIndex, titleValue)); }
/// <summary> /// Send the non-elearning content to the response. Non-elearning content is any content other than /// scorm or lrm content. It is an error to call this method when the current learner assignment is elearning content. /// In some cases, this method will end the response. /// </summary> private void SendNonElearningContent() { // Get the cached learner assignment properties LearnerAssignmentProperties la = GetLearnerAssignment(); SharePointFileLocation spFileLocation; if (!SharePointFileLocation.TryParse(la.Assignment.Location, out spFileLocation)) { // location was not valid RegisterError(SlkFrameset.FRM_DocumentNotFoundTitleHtml, SlkFrameset.FRM_DocumentNotFound, false); return; } // Find the location of the document in the Sharepoint Document Library and go there string documentUrl = GetNonElearningDocumentUrl(spFileLocation); // Special case handling for HTML files: // * Launch directly from the document library, not from the Cache // * Add the LearnerAssignmentId to the Query portion of the URL so that we pass the learning context down to the content // This enables us to have more advanced behavior (CMI Tracking, scoring, completion status) for "Non-ELearning" documents. // It is a first step towards a more comprehensive strategy for adding educational workflow to all types of documents. if (documentUrl.EndsWith("html", StringComparison.OrdinalIgnoreCase) || documentUrl.EndsWith("htm", StringComparison.OrdinalIgnoreCase)) { string redirectUrl = String.Format("{0}?{1}={2}", documentUrl, FramesetQueryParameter.LearnerAssignmentId, LearnerAssignmentGuidId.ToString()); Response.Clear(); Response.Redirect(redirectUrl, true); // ends response } string framesetPath = GetFramesetPath(); Response.Clear(); using (CachedSharePointFile cachedFile = new CachedSharePointFile(SlkStore.SharePointCacheSettings, spFileLocation, true)) { // If the current request URL does not include the file name of the file, then this request is the first frameset rendering. // That means this will redirect to a URL that does include the filename of the file. This redirection allows the browser to // properly handle the content. if (String.IsNullOrEmpty(framesetPath)) { string redirectUrl = GetNonElearningFrameUrl(cachedFile.FileName); cachedFile.Dispose(); Response.Redirect(redirectUrl, true); // ends response } // This is the first actual access of the file. If it doesn't exist, the exception will be caught by the Page_load method. SetMimeType(cachedFile.FileName); // If this file is using IIS Compability mode, then we get the stream from the cached file and write it to the // response, otherwise, use TransmitFile. if (UseCompatibilityMode(cachedFile.FileName)) { WriteIisCompatibilityModeToResponse(cachedFile.GetFileStream()); } else { cachedFile.TransmitFile(Response); } } }
void CheckPlayAssignment() { string play = Request.QueryString[FramesetQueryParameter.PlayAssignment]; if (play == "true") { AssignmentObjectsFromQueryString objects = new AssignmentObjectsFromQueryString(); objects.LoadObjects(SPWeb); SharePointFileLocation fileLocation = Package.CreateFileLocation(SPWeb, objects.File); AssignmentProperties assignment = AssignmentProperties.LoadSelfAssignmentForLocation(fileLocation, SlkStore); if (assignment != null) { LearnerAssignmentGuidId = assignment.Results[0].LearnerAssignmentGuidId; learnerAssignmentGuidIdHasBeenSet = true; } else { // Create the self assignment so Frameset can load int organizationIndex = 0; // Assume only one organization LearnerAssignmentGuidId = AssignmentProperties.CreateSelfAssignment(SlkStore, SPWeb, fileLocation, organizationIndex); learnerAssignmentGuidIdHasBeenSet = true; } } }
/// <summary>Copies the original file to the student's drop box.</summary> /// <returns>The url of the file.</returns> public AssignmentFile CopyFileToDropBox() { AssignmentFile assignmentFile = null; SPSecurity.RunWithElevatedPrivileges(delegate() { SharePointFileLocation fileLocation; if (!SharePointFileLocation.TryParse(assignmentProperties.Location, out fileLocation)) { throw new SafeToDisplayException(SlkFrameset.FRM_DocumentNotFound); } using (SPSite sourceSite = new SPSite(fileLocation.SiteId)) { using (SPWeb sourceWeb = sourceSite.OpenWeb(fileLocation.WebId)) { SPFile file = sourceWeb.GetFile(fileLocation.FileId); if (file.Exists == false) { string message = string.Format(CultureInfo.CurrentUICulture, culture.Resources.AssignmentFileDoesNotExist, fileLocation.FileId, assignmentProperties.Title); store.LogError(message); throw new SafeToDisplayException(message); } if (MustCopyFileToDropBox(file.Name)) { try { assignmentFile = SaveFile(file); } catch (SPException) { // Retry in case a temporary error try { assignmentFile = SaveFile(file); } catch (SPException e) { string message = string.Format(CultureInfo.CurrentUICulture, culture.Resources.DropBoxFailedToCopyFile, file.Name, assignmentProperties.Title, e.Message); store.LogError(message); string safeMessage = string.Format(CultureInfo.CurrentUICulture, culture.Resources.DropBoxFailedToCopyFile, file.Name, assignmentProperties.Title, string.Empty); throw new SafeToDisplayException(safeMessage); } } } } } }); return assignmentFile; }
/// <summary>Creates a self assingment.</summary> /// <returns>The ID of the learner assignment.</returns> public static Guid CreateSelfAssignment(SlkStore store, SPWeb web, SharePointFileLocation location, Nullable <int> organizationIndex) { AssignmentProperties properties = CreateNewAssignmentObject(store, web, SlkRole.Learner); properties.SetLocation(location, organizationIndex); // Have to allow unsafe updates or self assignment fails bool allowUnsafeUpdates = web.AllowUnsafeUpdates; web.AllowUnsafeUpdates = true; try { properties.Save(web, SlkRole.Learner); } finally { web.AllowUnsafeUpdates = allowUnsafeUpdates; } return(properties.Learners[0].AssignmentUserGuidId); }
/// <summary> /// Given a SharePoint File, find the URL location of the File /// </summary> /// <returns>The url in Ascii format</returns> protected string GetNonElearningDocumentUrl(SharePointFileLocation spFileLocation) { string documentUrl = null; SPSecurity.RunWithElevatedPrivileges(delegate() { // If the site does not exist, this throws FileNotFound using (SPSite spSite = new SPSite(spFileLocation.SiteId, SPContext.Current.Site.Zone)) { // If the web does not exist, this throws FileNotFound using (SPWeb spWeb = spSite.OpenWeb(spFileLocation.WebId)) { SPFile spFile = spWeb.GetFile(spFileLocation.FileId); documentUrl = UrlCombine(spSite.Url, HttpUtility.UrlPathEncode(spFile.ServerRelativeUrl)); } } }); return(documentUrl); }
/// <summary> /// accesses the document library at the path provided, /// loops through the learning packages /// located the library and reads the package Id from package manifest /// </summary> /// <param name="siteURL">web site url</param> /// <param name="documentLibraryName">document library name</param> /// <returns></returns> public Hashtable GetAllLearningResources(string siteURL, string documentLibraryName) { Hashtable resources = new Hashtable(); SharePointV3 sharepoint = new SharePointV3(); SPWeb documentLibWeb = sharepoint.OpenWeb(siteURL); SPDocumentLibrary docLibrary = sharepoint.GetDocumentLibrary(documentLibraryName, documentLibWeb); Microsoft.SharePointLearningKit.SlkStore store = SlkStore.GetStore(documentLibWeb); foreach (SPListItem item in docLibrary.Items) { //if this list item is a file if (item.File != null) { SharePointFileLocation fileLocation = new SharePointFileLocation(documentLibWeb, item.UniqueId, item.File.UIVersion); string location = fileLocation.ToString(); try { PackageInformation info = store.GetPackageInformation(location); XPathNavigator manifestNavigator = info.ManifestReader.CreateNavigator(); Guid packageIdentifier = ManifestParser.ParseIndexXml(manifestNavigator); if (packageIdentifier == Guid.Empty) { packageIdentifier = ManifestParser.ParseImsManifestXml(manifestNavigator); } if (packageIdentifier != Guid.Empty) { resources.Add(packageIdentifier.ToString(), location); } } catch { //not a valid learning package, do nothing } } } return(resources); }
public static void RunProgram(string classWebUrl) { Stack <IDisposable> disposer = new Stack <IDisposable>(); try { // "log in" to SLK as the current user, and set <memberships> to information about // the instructors and learners in the class Web site (i.e. the SPWeb with URL // <classWebUrl>) SPSite spSite = new SPSite(classWebUrl); disposer.Push(spSite); SPWeb spWeb = spSite.OpenWeb(); disposer.Push(spWeb); SlkStore slkStore = SlkStore.GetStore(spWeb); SlkMemberships memberships = slkStore.GetMemberships(spWeb, null, null); // make sure there's at least one instructor and one learner on the class Web; these // roles are defined by the "SLK Instructor" and "SLK Learner" permissions (as defined // in the SharePoint Learning Kit configuration page in SharePoint Central // Administration) if (memberships.Instructors.Count == 0) { throw new Exception("Class Web must have at least one instructor"); } if (memberships.Learners.Count == 0) { throw new Exception("Class Web must have at least one learner"); } // arbitrarily choose the first instructor in the class as the user who will create // the assignments SlkUser primaryInstructor = memberships.Instructors[0]; // set <classWeb> to the SPWeb of the SharePoint Web site that the new assignment will // be associated with; "log into" this Web site as the instructor retrieved above SPSite classSite = new SPSite(classWebUrl, primaryInstructor.SPUser.UserToken); disposer.Push(classSite); SPWeb classWeb = classSite.OpenWeb(); disposer.Push(classWeb); // set <slkStore> to the SharePoint Learning Kit store associated with the SPSite of // <classWeb> slkStore = SlkStore.GetStore(classWeb); // set <packageLocations> to the SharePointPackageStore-format location strings // corresponding to each element of <PackageUrls>; "log into" these Web sites as the // instructor retrieved above string[] packageLocations = new string[PackageUrls.Length]; for (int packageIndex = 0; packageIndex < packageLocations.Length; packageIndex++) { // set <packageWeb> to the SPWeb of the SharePoint Web site containing the package // or document to assign string packageUrl = PackageUrls[packageIndex]; SPSite packageSite = new SPSite(packageUrl, primaryInstructor.SPUser.UserToken); disposer.Push(packageSite); SPWeb packageWeb = packageSite.OpenWeb(); disposer.Push(packageWeb); // set <spFile> to the SPFile of the package or document to assign SPFile spFile = packageWeb.GetFile(packageUrl); // set the current element of <packageLocation> to the SharePointPackageStore // format location string that uniquely identifies the current version of the // <spFile> packageLocations[packageIndex] = new SharePointFileLocation( packageWeb, spFile.UniqueId, spFile.UIVersion).ToString(); } // create a random number generator s_random = new Random(RandomNumberSeed); // set <maxNumberOfLearners> to the number of learners in the class int maxNumberOfLearners = memberships.Learners.Count; // set <learners> to an array of learners of this class; for each assignment, we'll // shuffle this array and choose a subset to be learners on the assignment SlkUser[] learners = new SlkUser[memberships.Learners.Count]; memberships.Learners.CopyTo(learners, 0); // display table header Console.WriteLine("Assign. No. of Due Not"); Console.WriteLine("ID Learners Date Started Active Completed Final"); Console.WriteLine("----------------------------------------------------------"); // create assignments as specified by the constants at the top of this source file for (int assignmentIndex = 0; assignmentIndex < NumberOfAssignments; assignmentIndex++) { // set <fraction> to be proportional to <assignmentIndex>, between 0.0 and 1.0 double fraction = (double)assignmentIndex / NumberOfAssignments; // randomly choose an e-learning package or non-e-learning document to be assigned string packageLocation = packageLocations[s_random.Next(0, PackageUrls.Length)]; // get some information about the package/document; set <isNonELearning> to true if // if it's a non-e-learning document; NOTE: this is oversimplified code -- proper // production code should handle error conditions more carefully SPFile spFile = SlkUtilities.GetSPFileFromPackageLocation(packageLocation); bool isNonELearning; SharePointFileLocation spFileLocation; SharePointFileLocation.TryParse(packageLocation, out spFileLocation); using (SharePointPackageReader spPackageReader = new SharePointPackageReader(slkStore.SharePointCacheSettings, spFileLocation)) { isNonELearning = PackageValidator.Validate(spPackageReader).HasErrors; } // set <assignmentProperties> to the default assignment properties for the package // or document being assigned; some of these properties will be overridden below LearningStoreXml packageWarnings; int?organizationIndex = (isNonELearning ? (int?)null : 0); AssignmentProperties assignmentProperties = slkStore.GetNewAssignmentDefaultProperties( classWeb, packageLocation, organizationIndex, SlkRole.Instructor, out packageWarnings); // randomly generate a title for the assignment assignmentProperties.Title = CreateRandomTitle(); // set the due date of the assignment based on <fraction>, // <OldestAssignmentDaysAgo>, and <NewestAssignmentDaysFromNow> assignmentProperties.DueDate = DateTime.Now.AddDays( (OldestAssignmentDaysAgo + NewestAssignmentDaysFromNow) * fraction - OldestAssignmentDaysAgo); // set the start date of the assignment to be a day earlier than the earliest // due date assignmentProperties.StartDate = DateTime.Today.AddDays( -OldestAssignmentDaysAgo - 1); // randomly set Points Possible if ((assignmentProperties.PointsPossible == null) && (s_random.NextDouble() > FractionOfBlankPointsPossible)) { const int divideBy = 4; const int maxValue = 100; assignmentProperties.PointsPossible = (float)Math.Round( s_random.NextDouble() * divideBy * maxValue) / maxValue; } // make all instructors of this class (i.e. all SharePoint users that have the SLK // Instructor permission) be instructors on this assignment assignmentProperties.Instructors.Clear(); foreach (SlkUser slkUser in memberships.Instructors) { assignmentProperties.Instructors.Add(slkUser); } // shuffle <learners> for (int learnerIndex = 0; learnerIndex < learners.Length; learnerIndex++) { int otherLearnerIndex = s_random.Next(0, learners.Length); SlkUser temp = learners[learnerIndex]; learners[learnerIndex] = learners[otherLearnerIndex]; learners[otherLearnerIndex] = temp; } // randomly choose a number of learners for this assignment int numberOfLearners = s_random.Next( Math.Min(maxNumberOfLearners, MinLearnersPerAssignment), maxNumberOfLearners + 1); // copy the first <numberOfLearners> learners to <assignmentProperties> assignmentProperties.Learners.Clear(); for (int learnerIndex = 0; learnerIndex < numberOfLearners; learnerIndex++) { assignmentProperties.Learners.Add(learners[learnerIndex]); } // create the assignment AssignmentItemIdentifier assignmentId = slkStore.CreateAssignment(classWeb, packageLocation, organizationIndex, SlkRole.Instructor, assignmentProperties); // set <gradingPropertiesList> to information about the learner assignments of the // new assignment; in particular, we need the learner assignment IDs AssignmentProperties basicAssignmentProperties; ReadOnlyCollection <GradingProperties> gradingPropertiesList = slkStore.GetGradingProperties(assignmentId, out basicAssignmentProperties); // adjust the status of each learner assignment of this assignment according to // the rules specified in constants at the top of this source file int[] newStatusCount = new int[(int)LearnerAssignmentState.Final + 1]; for (int learnerIndex = 0; learnerIndex < gradingPropertiesList.Count; learnerIndex++) { // set <gradingProperties> to information about this learner assignment GradingProperties gradingProperties = gradingPropertiesList[learnerIndex]; // set <newStatus> to the new status of the assignment, applying the rules // specified in constants at the top of this source file if (fraction > 1 - FractionOfAssignmentsNotStarted) { gradingProperties.Status = LearnerAssignmentState.NotStarted; } else if (fraction < FractionOfAssignmentsAllFinal) { gradingProperties.Status = LearnerAssignmentState.Final; } else { gradingProperties.Status = (LearnerAssignmentState) s_random.Next(0, (int)LearnerAssignmentState.Final + 1); } // if we're transitioning learner assignment to Final state, optionally // assign a final points value if ((gradingProperties.Status == LearnerAssignmentState.Final) && (assignmentProperties.PointsPossible != null)) { if (s_random.NextDouble() < FractionOfOverriddenFinalPoints) { const int divideBy = 4; gradingProperties.FinalPoints = (float)Math.Round( s_random.NextDouble() * divideBy * assignmentProperties.PointsPossible.Value) / divideBy; } } // update statistics newStatusCount[(int)gradingProperties.Status]++; } // save changes to the assignment string warnings = slkStore.SetGradingProperties(assignmentId, gradingPropertiesList); Debug.Assert(warnings == null, warnings); // display feedback Console.WriteLine("{0,-8}{1,-10}{2,-10:d}{3,-8}{4,-7}{5,-10}{6,-6}", assignmentId.GetKey(), assignmentProperties.Learners.Count, assignmentProperties.DueDate, newStatusCount[0], newStatusCount[1], newStatusCount[2], newStatusCount[3]); } } finally { // dispose of objects used by this method while (disposer.Count > 0) { disposer.Pop().Dispose(); } } }
/// <summary>Sets the location of the package.</summary> /// <remarks>Security checks:Fails if the user doesn't have access to the package/file</remarks> /// <param name="location">The MLC SharePoint location string that refers to the e-learning /// package or non-e-learning document to assign. Use /// <c>SharePointPackageStore.GetLocation</c> to construct this string.</param> /// <param name="organizationIndex">The zero-based index of the organization within the /// e-learning content to assign; this is the value that's used as an index to /// <c>ManifestReader.Organizations</c>. If the content being assigned is a non-e-learning /// document, use <c>null</c> for <paramref name="organizationIndex"/>.</param> /// <param name="title">Any title that has been passed in.</param> public void SetLocation(SharePointFileLocation location, Nullable <int> organizationIndex, string title) { if (location == null) { throw new ArgumentNullException("location"); } if (location.ToString() == Package.NoPackageLocation.ToString()) { MakeNoPackageAssignment(title); return; } // Access the properties of the file to verify that the user has access to the file SPFile file = location.LoadFile(); System.Collections.Hashtable fileProperties = file.Properties; // set <rootActivityId> to the ID of the organization, or null if a non-e-learning document is being assigned if (organizationIndex != null) { using (Package package = new Package(Store, file, location)) { package.Register(); RootActivityId = package.FindRootActivity(organizationIndex.Value); bool existingTitle = (string.IsNullOrEmpty(Title) == false); if (existingTitle == false) { Title = package.Title; } if (string.IsNullOrEmpty(Description)) { Description = package.Description; } // validate <organizationIndex> if ((organizationIndex.Value < 0) || (organizationIndex.Value >= package.Organizations.Count)) { throw new SafeToDisplayException(SlkCulture.GetResources().InvalidOrganizationIndex); } PackageFormat = package.PackageFormat; // set <organizationNodeReader> to refer to the organization OrganizationNodeReader organizationNodeReader = package.Organizations[organizationIndex.Value]; // if there is more than one organization, append the organization title, if any if (existingTitle == false && package.Organizations.Count > 1) { if (!String.IsNullOrEmpty(organizationNodeReader.Title)) { SlkCulture culture = new SlkCulture(); Title = culture.Format(culture.Resources.SlkPackageAndOrganizationTitle, Title, organizationNodeReader.Title); } } // set <pointsPossible> to the points-possible value stored in the manifest, or null if none switch (PackageFormat) { case Microsoft.LearningComponents.PackageFormat.Lrm: PointsPossible = organizationNodeReader.PointsPossible; break; case Microsoft.LearningComponents.PackageFormat.V1p3: PointsPossible = 100; break; default: PointsPossible = null; break; } } } else // Non-elearning content { RootActivityId = null; Location = location.ToString(); if (string.IsNullOrEmpty(Title)) { Title = file.Title; if (String.IsNullOrEmpty(Title)) { Title = System.IO.Path.GetFileNameWithoutExtension(file.Name); } } if (string.IsNullOrEmpty(Description)) { Description = string.Empty; } if (PointsPossible == null) { PointsPossible = null; // "Points Possible" defaults to null for non-e-learning content PackageWarnings = null; // no package warnings PackageFormat = null; // non-e-learning package } } }
/// <summary>Sets the location of the package.</summary> /// <remarks>Security checks:Fails if the user doesn't have access to the package/file</remarks> /// <param name="location">The MLC SharePoint location string that refers to the e-learning /// package or non-e-learning document to assign. Use /// <c>SharePointPackageStore.GetLocation</c> to construct this string.</param> /// <param name="organizationIndex">The zero-based index of the organization within the /// e-learning content to assign; this is the value that's used as an index to /// <c>ManifestReader.Organizations</c>. If the content being assigned is a non-e-learning /// document, use <c>null</c> for <paramref name="organizationIndex"/>.</param> public void SetLocation(SharePointFileLocation location, Nullable <int> organizationIndex) { SetLocation(location, organizationIndex, null); }
/// <summary>Loads a self assignment for a particular location if one exists.</summary> /// <param name="location">The location of the assignment.</param> /// <param name="store">The <see cref="ISlkStore"/> to use.</param> /// <returns>An <see cref="AssignmentProperties"/>.</returns> public static AssignmentProperties LoadSelfAssignmentForLocation(SharePointFileLocation location, ISlkStore store) { return(store.LoadSelfAssignmentForLocation(location)); }
/// <summary> /// Creates a SharePoint Learning Kit assignment. /// </summary> /// /// <param name="packageUrl">The URL of the e-learning package or non-e-learning document /// to assign. This file must be located within a SharePoint document library.</param> /// /// <param name="organizationIndex">If <paramref name="packageUrl"/> refers to an e-learning /// package (e.g. a SCORM .zip file), <paramref name="organizationIndex"/> should be /// the zero-based index of the organization to assign. (Use 0 to assign the first /// organization.) If <paramref name="packageUrl"/> is a non-e-learning document, /// <paramref name="organizationIndex"/> should be <c>null</c>.</param> /// /// <param name="assignmentWebUrl">The URL of the SharePoint Web site that the new assignment /// will be associated with.</param> /// /// <param name="title"></param> /// /// <param name="instructorLoginName">The SharePoint login name of the instructor of the /// assignment. If the instructor account is a local machine account, the caller can /// specify @".\account-name". This user must have read access to the file specified by /// <paramref name="packageUrl"/>, and must have the "SLK Instructor" permission on the /// SharePoint Web site specified by <paramref name="assignmentWebUrl"/>.</param> /// /// <param name="learnerLoginNames">The SharePoint login names of the learners of the /// assignment. If a learner account is a local machine account, the caller can /// specify @".\account-name". Learners need not have access to the file specified by /// <paramref name="packageUrl"/>, but they must have the "SLK Learner" permission on the /// SharePoint Web site specified by <paramref name="assignmentWebUrl"/>.</param> /// /// <returns> /// The <c>AssignmentItemIdentifier</c> of the newly-created SharePoint Learning Kit /// assignment. /// </returns> /// static AssignmentItemIdentifier CreateAssignment(string packageUrl, int?organizationIndex, string assignmentWebUrl, string title, string instructorLoginName, params string[] learnerLoginNames) { Stack <IDisposable> disposer = new Stack <IDisposable>(); try { // set <instructorToken> to the SPUserToken of the instructor SPUser instructor; SPUserToken instructorToken; SPSite anonymousSite = new SPSite(packageUrl); disposer.Push(anonymousSite); if (instructorLoginName.StartsWith(@".\")) { instructorLoginName = anonymousSite.HostName + instructorLoginName.Substring(1); } disposer.Push(anonymousSite.RootWeb); instructor = anonymousSite.RootWeb.AllUsers[instructorLoginName]; instructorToken = instructor.UserToken; // set <packageWeb> to the SPWeb of the SharePoint Web site containing the package // or document to assign SPSite packageSite = new SPSite(packageUrl, instructorToken); disposer.Push(packageSite); SPWeb packageWeb = packageSite.OpenWeb(); disposer.Push(packageWeb); // set <spFile> to the SPFile of the package or document to assign SPFile spFile = packageWeb.GetFile(packageUrl); // set <packageLocation> to the SharePointPackageStore-format location string that // uniquely identifies the current version of the <spFile> string packageLocation = new SharePointFileLocation(packageWeb, spFile.UniqueId, spFile.UIVersion).ToString(); // set <assignmentWeb> to the SPWeb of the SharePoint Web site that the new assignment // will be associated with SPSite assignmentSite = new SPSite(assignmentWebUrl, instructorToken); disposer.Push(assignmentSite); SPWeb assignmentWeb = assignmentSite.OpenWeb(); disposer.Push(assignmentWeb); // set <slkStore> to the SharePoint Learning Kit store associated with the SPSite of // <assignmentWeb> SlkStore slkStore = SlkStore.GetStore(assignmentWeb); // set <assignmentProperties> to the default assignment properties for the package or // document being assigned; some of these properties will be overridden below LearningStoreXml packageWarnings; AssignmentProperties assignmentProperties = slkStore.GetNewAssignmentDefaultProperties( assignmentWeb, packageLocation, organizationIndex, SlkRole.Instructor, out packageWarnings); // set the assignment title assignmentProperties.Title = title; // set <allLearners> to a dictionary that maps SharePoint user login names to SlkUser // objects, for all users that have the "SLK Learner" permission on <assignmentWeb> SlkMemberships memberships = slkStore.GetMemberships(assignmentWeb, null, null); Dictionary <string, SlkUser> allLearners = new Dictionary <string, SlkUser>( StringComparer.OrdinalIgnoreCase); foreach (SlkUser learner in memberships.Learners) { allLearners.Add(learner.SPUser.LoginName, learner); } // set the learners of the assignment to be <learnerLoginNames> assignmentProperties.Learners.Clear(); foreach (string rawLearnerLoginName in learnerLoginNames) { string learnerLoginName; if (rawLearnerLoginName.StartsWith(@".\")) { learnerLoginName = anonymousSite.HostName + rawLearnerLoginName.Substring(1); } else { learnerLoginName = rawLearnerLoginName; } SlkUser slkUser; if (allLearners.TryGetValue(learnerLoginName, out slkUser)) { assignmentProperties.Learners.Add(slkUser); } else { throw new Exception(String.Format("Not a learner: {0}", learnerLoginName)); } } // create the assignment AssignmentItemIdentifier assignmentId = slkStore.CreateAssignment(assignmentWeb, packageLocation, organizationIndex, SlkRole.Instructor, assignmentProperties); // return the ID of the new assignment return(assignmentId); } finally { // dispose of objects used by this method while (disposer.Count > 0) { disposer.Pop().Dispose(); } } }
/// Returns true if the correct version of the file exists in SharePoint. /// NOTE: This method checks file availability using elevated privileges. Be /// cautious when using this information in messages displayed to the user. private static bool FileExistsInSharePoint(string location) { SharePointFileLocation spFileLocation; bool fileExists = true; // assume it exists if (SharePointFileLocation.TryParse(location, out spFileLocation)) { SPSecurity.RunWithElevatedPrivileges(delegate() { // If the site does not exist, this throws FileNotFound using (SPSite spSite = new SPSite(spFileLocation.SiteId, SPContext.Current.Site.Zone)) { // If the web does not exist, this throws FileNotFound using (SPWeb spWeb = spSite.OpenWeb(spFileLocation.WebId)) { SPFile spFile = spWeb.GetFile(spFileLocation.FileId); if (!spFile.Exists) { fileExists = false; return; } // The file exists. Now check if the right version exists. DateTime lastModified; if ((spFile.Versions.Count == 0) || spFile.UIVersion == spFileLocation.VersionId) { // The requested version is the currect one if (spFile.UIVersion != spFileLocation.VersionId) { fileExists = false; return; } // It exists: check its timestamp lastModified = spFile.TimeLastModified; } else { // The specified version isn't the current one SPFileVersion spFileVersion = spFile.Versions.GetVersionFromID(spFileLocation.VersionId); if (spFileVersion == null) { fileExists = false; return; } // There is no 'last modified' of a version, so use the time the version was created. lastModified = spFileVersion.Created; } // If the timestamps are not the same, the file has been modified, so return false if (lastModified.CompareTo(spFileLocation.Timestamp) != 0) { fileExists = false; return; } } } }); } return(fileExists); }