/// <summary> /// Gets the attempt id of the requested attempt. If the page is provided a learner assignment id and /// the attempt associated with the assignment doesn't exist, then one is created. If the user does not have /// access to the attempt, or the requested view of the attempt, or there is no /// attempt (such as non-elearning content) then false is returned. /// </summary> /// <param name="showErrorPage"></param> /// <param name="attemptId"></param> /// <returns></returns> public override bool TryGetAttemptId(bool showErrorPage, out AttemptItemIdentifier attemptId) { // Initialize out parameter attemptId = null; if (learnerAssignmentGuidIdHasBeenSet == false) { Guid learnerAssignmentGuidId; if (!TryProcessLearnerAssignmentIdParameter(showErrorPage, out learnerAssignmentGuidId)) { // In this case, if the parameter was not valid (eg, it's not a number), the error is already registered. // So just return. return(false); } LearnerAssignmentGuidId = learnerAssignmentGuidId; } // Put this operation in a transaction because if the attempt has not been started, we'll start the attempt // and update the assignment. Both should succeed or both should fail. LearnerAssignmentProperties la; TransactionOptions options = new TransactionOptions(); options.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead; using (LearningStoreTransactionScope scope = new LearningStoreTransactionScope(options)) { // Must force a read of assignment data so that it's read in the same transaction that it might be updated. la = GetLearnerAssignment(true); SessionView view; if (!TryGetSessionView(true, out view)) { return(false); } if (la.Assignment.IsELearning) { // This is e-learning content m_isELearning = true; // Accessing LearnerAssignment (above) would have checked the database and retrieve any information available about // the assignment, including its attempt id, if it exists. If the LearnerAssignment information is valid // but there's no attempt, the AttemptId property will be null if (la.AttemptId == null) { // Only create the attempt if this is a request for Execute view if (view == SessionView.Execute) { if (!FileExistsInSharePoint(la.Assignment.Location)) { if (showErrorPage) { RegisterError(SlkFrameset.FRM_PackageNotFoundTitle, SlkFrameset.FRM_PackageNotFound, false); } return(false); } SlkStore.StartAttemptOnLearnerAssignment(LearnerAssignmentGuidId); // Force a reset of internal data regarding the current learner assignment la = GetLearnerAssignment(true); } else { // This is an error condition, since in other cases, the attempt must already exist. // Use private method to get the right error message. if (!ProcessViewRequest(la.Status, view)) { return(false); } } } else { // Attempt is already created. Verify the user has access to it and that the package exists. if (!ProcessViewRequest(la.Status, view)) { return(false); } if (!FileExistsInSharePoint(la.Assignment.Location)) { if (showErrorPage) { RegisterError(SlkFrameset.FRM_PackageNotFoundTitle, SlkFrameset.FRM_PackageNotFound, false); } return(false); } } // Attempt exists, set the out parameter attemptId = la.AttemptId; } else { // Is not e-learning assignment m_isELearning = false; // Verify that the learner can see the assignment. if (view == SessionView.Execute) { if (!FileExistsInSharePoint(la.Assignment.Location)) { if (showErrorPage) { RegisterError(SlkFrameset.FRM_PackageNotFoundTitle, SlkFrameset.FRM_PackageNotFound, false); } return(false); } // Mark the assignment as started if (la.Status != LearnerAssignmentState.Active) { la.Start(); } } else { // Verify this is a view they have access to given the state of the assignment. No need to check // return value, as non-elearning content always returns false from this method. if (!ProcessViewRequest(la.Status, view)) { return(false); } if (!FileExistsInSharePoint(la.Assignment.Location)) { if (showErrorPage) { RegisterError(SlkFrameset.FRM_PackageNotFoundTitle, SlkFrameset.FRM_PackageNotFound, false); } return(false); } } } scope.Complete(); } return(attemptId != null); }