Best JavaScript code snippet using root
assign.js
Source:assign.js
1// (C) Copyright 2015 Martin Dougiamas2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14angular.module('mm.addons.mod_assign')15/**16 * Assignments service.17 *18 * @module mm.addons.mod_assign19 * @ngdoc controller20 * @name $mmaModAssign21 */22.factory('$mmaModAssign', function($mmSite, $q, $mmUser, $mmSitesManager, mmaModAssignComponent, $mmFilepool, $mmComments,23 $mmaModAssignSubmissionDelegate, mmaModAssignSubmissionStatusNew, mmaModAssignSubmissionStatusSubmitted, $mmText) {24 var self = {};25 /**26 * Get cache key for assignment data WS calls.27 *28 * @param {Number} courseId Course ID.29 * @return {String} Cache key.30 */31 function getAssignmentCacheKey(courseId) {32 return 'mmaModAssign:assignment:' + courseId;33 }34 /**35 * Get cache key for assignment user mappings data WS calls.36 *37 * @param {Number} assignmentId Assignment ID.38 * @return {String} Cache key.39 */40 function getAssignmentUserMappingsCacheKey(assignmentId) {41 return 'mmaModAssign:usermappings:' + assignmentId;42 }43 /**44 * Get cache key for assignment submissions data WS calls.45 *46 * @param {Number} assignId Assignment id.47 * @return {String} Cache key.48 */49 function getSubmissionsCacheKey(assignId) {50 return 'mmaModAssign:submissions:' + assignId;51 }52 /**53 * Get cache key for assignment list participants data WS calls.54 *55 * @param {Number} assignId Assignment id.56 * @param {Number} groupId Group id.57 * @return {String} Cache key.58 */59 function listParticipantsCacheKey(assignId, groupId) {60 return listParticipantsPrefixCacheKey(assignId) + ':' + groupId;61 }62 /**63 * Get prefix cache key for assignment list participants data WS calls.64 *65 * @param {Number} assignId Assignment id.66 * @return {String} Cache key.67 */68 function listParticipantsPrefixCacheKey(assignId) {69 return 'mmaModAssign:participants:' + assignId;70 }71 /**72 * Get cache key for get submission status data WS calls.73 *74 * @param {Number} assignId Assignment instance id.75 * @param {Number} [userId] User id (empty for current user).76 * @param {Number} [isBlind] If blind marking is enabled or not.77 * @return {String} Cache key.78 */79 function getSubmissionStatusCacheKey(assignId, userId, isBlind) {80 if (!userId) {81 isBlind = 0;82 userId = $mmSite.getUserId();83 }84 isBlind = isBlind ? 1 : 0;85 return getSubmissionsCacheKey(assignId) + ':' + userId + ':' + isBlind;86 }87 /**88 * Get an assignment.89 *90 * @module mm.addons.mod_assign91 * @ngdoc method92 * @name $mmaModAssign#getAssignment93 * @param {Number} courseId Course ID the assignment belongs to.94 * @param {Number} cmid Assignment module ID.95 * @param {String} [siteId] Site ID. If not defined, current site.96 * @return {Promise} Promise resolved with the assignment.97 */98 self.getAssignment = function(courseId, cmid, siteId) {99 siteId = siteId || $mmSite.getId();100 return $mmSitesManager.getSite(siteId).then(function(site) {101 var params = {102 "courseids": [courseId]103 },104 preSets = {105 cacheKey: getAssignmentCacheKey(courseId)106 };107 return site.read('mod_assign_get_assignments', params, preSets).then(function(response) {108 if (response.courses && response.courses.length) {109 var assignments = response.courses[0].assignments;110 for (var i = 0; i < assignments.length; i++) {111 if (assignments[i].cmid == cmid) {112 return assignments[i];113 }114 }115 }116 return $q.reject();117 });118 });119 };120 /**121 * Get an assignment user mapping for blind marking.122 *123 * @module mm.addons.mod_assign124 * @ngdoc method125 * @name $mmaModAssign#getAssignmentUserMappings126 * @param {Number} assignmentId Assignment Id.127 * @param {Number} userId User Id to be blinded.128 * @param {String} [siteId] Site ID. If not defined, current site.129 * @return {Promise} Promise resolved with the user blind id.130 */131 self.getAssignmentUserMappings = function(assignmentId, userId, siteId) {132 siteId = siteId || $mmSite.getId();133 return $mmSitesManager.getSite(siteId).then(function(site) {134 var params = {135 "assignmentids": [assignmentId]136 },137 preSets = {138 cacheKey: getAssignmentUserMappingsCacheKey(assignmentId)139 };140 return site.read('mod_assign_get_user_mappings', params, preSets).then(function(response) {141 if (userId && userId > 0 && response.assignments && response.assignments.length) {142 var assignment = response.assignments[0];143 if (assignment.assignmentid == assignmentId) {144 var mappings = assignment.mappings;145 for (var i = 0; i < mappings.length; i++) {146 if (mappings[i].userid == userId) {147 return mappings[i].id;148 }149 }150 }151 }152 return $q.reject();153 });154 });155 };156 /**157 * Get the submission object from an attempt.158 *159 * @module mm.addons.mod_assign160 * @ngdoc method161 * @name $mmaModAssign#getSubmissionObjectFromAttempt162 * @param {Object} assign Assign.163 * @param {Object} attempt Attempt.164 * @return {Object} Submission object.165 */166 self.getSubmissionObjectFromAttempt = function(assign, attempt) {167 return assign.teamsubmission ? attempt.teamsubmission : attempt.submission;168 };169 /**170 * Get attachments of a submission Submission.171 *172 * @module mm.addons.mod_assign173 * @ngdoc method174 * @name $mmaModAssign#getSubmissionPluginAttachments175 * @param {Object} submissionPlugin Submission Plugin.176 * @return {Object[]} Submission Pluginattachments.177 */178 self.getSubmissionPluginAttachments = function(submissionPlugin) {179 var files = [];180 if (submissionPlugin.fileareas) {181 angular.forEach(submissionPlugin.fileareas, function(filearea) {182 angular.forEach(filearea.files, function(file) {183 var filename = file.filepath[0] == '/' ? file.filepath.substr(1) : file.filepath;184 files.push({185 'filename' : filename,186 'fileurl': file.fileurl187 });188 });189 });190 }191 return files;192 };193 /**194 * Get text of a submission plugin.195 *196 * @module mm.addons.mod_assign197 * @ngdoc method198 * @name $mmaModAssign#getSubmissionText199 * @param {Object} submissionPlugin Submission Plugin.200 * @param {Boolean} [keepUrls] True if it should keep original URLs, false if they should be replaced.201 * @return {String} Submission text.202 */203 self.getSubmissionPluginText = function(submissionPlugin, keepUrls) {204 var text = '';205 if (submissionPlugin.editorfields) {206 angular.forEach(submissionPlugin.editorfields, function(field) {207 text += field.text;208 });209 if (!keepUrls && submissionPlugin.fileareas && submissionPlugin.fileareas[0]) {210 text = $mmText.replacePluginfileUrls(text, submissionPlugin.fileareas[0].files);211 }212 }213 return text;214 };215 /**216 * Get an assignment submissions.217 *218 * @module mm.addons.mod_assign219 * @ngdoc method220 * @name $mmaModAssign#getSubmissions221 * @param {Number} assignId Assignment id.222 * @param {String} [siteId] Site ID. If not defined, current site.223 * @return {Promise} Promise resolved with:224 * - canviewsubmissions: True if user can view submissions, false otherwise.225 * - submissions: Array of submissions.226 */227 self.getSubmissions = function(assignId, siteId) {228 siteId = siteId || $mmSite.getId();229 return $mmSitesManager.getSite(siteId).then(function(site) {230 var params = {231 "assignmentids": [assignId]232 },233 preSets = {234 cacheKey: getSubmissionsCacheKey(assignId)235 };236 return site.read('mod_assign_get_submissions', params, preSets).then(function(response) {237 // Check if we can view submissions, with enough permissions.238 if (response.warnings.length > 0 && response.warnings[0].warningcode == 1) {239 return {canviewsubmissions: false};240 }241 if (response.assignments && response.assignments.length) {242 return {243 canviewsubmissions: true,244 submissions: response.assignments[0].submissions245 };246 }247 return $q.reject();248 });249 });250 };251 /**252 * Get user data for submissions since they only have userid.253 *254 * @module mm.addons.mod_assign255 * @ngdoc method256 * @name $mmaModAssign#getSubmissionsUserData257 * @param {Object[]} submissions Submissions to get the data for.258 * @param {Number} courseId ID of the course the submissions belong to.259 * @param {Number} assignId ID of the assignment the submissions belong to.260 * @param {Boolean} blind The user data need to be blinded.261 * @param {Object[]} [participants] List of participants in the assignment.262 * @return {Promise} Promise always resolved. Resolve param is the formatted submissions.263 */264 self.getSubmissionsUserData = function(submissions, courseId, assignId, blind, participants) {265 var promises = [],266 subs = [];267 angular.forEach(submissions, function(submission) {268 var participant = false;269 if (submission.userid > 0) {270 submission.submitid = submission.userid;271 if (!blind && participants) {272 for (var x in participants) {273 if (participants[x].id == submission.userid) {274 participant = participants[x];275 delete participants[x];276 break;277 }278 }279 if (participant) {280 submission.userfullname = participant.fullname;281 submission.userprofileimageurl = participant.profileimageurl;282 subs.push(submission);283 }284 } else {285 if (!blind) {286 promises.push($mmUser.getProfile(submission.userid, courseId, true).then(function(user) {287 submission.userfullname = user.fullname;288 submission.userprofileimageurl = user.profileimageurl;289 subs.push(submission);290 }).catch(function() {291 // Error getting profile, resolve promise without adding any extra data.292 }));293 } else {294 // Users not blinded! (Moodle < 3.1.1, 3.2)295 delete submission.userid;296 promises.push(self.getAssignmentUserMappings(assignId, submission.submitid).then(function(blindId) {297 submission.blindid = blindId;298 }).catch(function() {299 // Error mapping user, fail silently (Moodle < 2.6)300 }));301 // Add it always.302 subs.push(submission);303 }304 }305 } else if (submission.blindid > 0) {306 for (var x in participants) {307 if (participants[x].id == submission.blindid) {308 participant = participants[x];309 delete participants[x];310 break;311 }312 }313 submission.submitid = submission.blindid;314 subs.push(submission);315 }316 });317 if (participants) {318 angular.forEach(participants, function(participant) {319 var submission = {320 submitid: participant.id321 };322 if (!blind) {323 submission.userid = participant.id;324 submission.userfullname = participant.fullname;325 submission.userprofileimageurl = participant.profileimageurl;326 } else {327 submission.blindid = participant.id;328 }329 submission.status = participant.submitted ? mmaModAssignSubmissionStatusSubmitted : mmaModAssignSubmissionStatusNew;330 subs.push(submission);331 });332 }333 return $q.all(promises).then(function() {334 return subs;335 });336 };337 /**338 * Given a list of plugins, returns the plugin names that aren't supported for editing.339 *340 * @module mm.addons.mod_quiz341 * @ngdoc method342 * @name $mmaModAssign#getUnsupportedEditPlugins343 * @param {Object[]} plugins Plugins to check.344 * @return {Promise} Promise resolved with unsupported plugin names.345 */346 self.getUnsupportedEditPlugins = function(plugins) {347 var notSupported = [],348 promises = [];349 angular.forEach(plugins, function(plugin) {350 promises.push($q.when($mmaModAssignSubmissionDelegate.isPluginSupportedForEdit(plugin.type)).then(function(enabled) {351 if (!enabled) {352 notSupported.push(plugin.name);353 }354 }));355 });356 return $q.all(promises).then(function() {357 return notSupported;358 });359 };360 /**361 * List the participants for a single assignment, with some summary info about their submissions.362 *363 * @module mm.addons.mod_assign364 * @ngdoc method365 * @name $mmaModAssign#listParticipants366 * @param {Number} assignId Assignment id.367 * @param {Number} groupId Group id.368 * @param {String} [siteId] Site ID. If not defined, current site.369 * @return {Promise} Promise resolved with the list of participants and summary of submissions.370 */371 self.listParticipants = function(assignId, groupId, siteId) {372 siteId = siteId || $mmSite.getId();373 return $mmSitesManager.getSite(siteId).then(function(site) {374 if (!site.wsAvailable('mod_assign_list_participants')) {375 // Silently fail if is not available. (needs Moodle version >= 3.2)376 return $q.reject();377 }378 groupId = 0;379 var params = {380 "assignid": assignId,381 "groupid": groupId,382 "filter": "",383 },384 preSets = {385 cacheKey: listParticipantsCacheKey(assignId, groupId)386 };387 return site.read('mod_assign_list_participants', params, preSets);388 });389 };390 /**391 * Get information about an assignment submission status for a given user.392 *393 * @module mm.addons.mod_assign394 * @ngdoc method395 * @name $mmaModAssign#getSubmissionStatus396 * @param {Number} assignId Assignment instance id.397 * @param {Number} [userId] User id (empty for current user).398 * @param {Number} [isBlind] If blind marking is enabled or not.399 * @param {Number} [filter=true] True to filter WS response, false otherwise.400 * @param {Boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down).401 * @param {Number} [siteId] Site id (empty for current site).402 * @return {Promise} Promise always resolved with the user submission status.403 */404 self.getSubmissionStatus = function(assignId, userId, isBlind, filter, ignoreCache, siteId) {405 siteId = siteId || $mmSite.getId();406 if (typeof filter == 'undefined') {407 filter = true;408 }409 return $mmSitesManager.getSite(siteId).then(function(site) {410 if (!site.wsAvailable('mod_assign_get_submission_status')) {411 // Silently fail if is not available. (needs Moodle version >= 3.1)412 return $q.reject();413 }414 userId = userId || 0;415 var params = {416 assignid: assignId,417 userid: userId418 },419 preSets = {420 cacheKey: getSubmissionStatusCacheKey(assignId, userId, isBlind),421 getCacheUsingCacheKey: true, // We use the cache key to take isBlind into account.422 filter: filter423 };424 if (ignoreCache) {425 preSets.getFromCache = 0;426 preSets.emergencyCache = 0;427 }428 return site.read('mod_assign_get_submission_status', params, preSets).then(function(response) {429 return response;430 });431 });432 };433 /**434 * Invalidates assignment data WS calls.435 *436 * @module mm.addons.mod_assign437 * @ngdoc method438 * @name $mmaModAssign#invalidateAssignmentData439 * @param {Number} courseId Course ID.440 * @param {Number} [siteId] Site id (empty for current site).441 * @return {Promise} Promise resolved when the data is invalidated.442 */443 self.invalidateAssignmentData = function(courseId, siteId) {444 siteId = siteId || $mmSite.getId();445 return $mmSitesManager.getSite(siteId).then(function(site) {446 return site.invalidateWsCacheForKey(getAssignmentCacheKey(courseId));447 });448 };449 /**450 * Invalidates assignment user mappings data WS calls.451 *452 * @module mm.addons.mod_assign453 * @ngdoc method454 * @name $mmaModAssign#invalidateAssignmentUserMappingsData455 * @param {Number} assignmentId Assignment ID.456 * @param {Number} [siteId] Site id (empty for current site).457 * @return {Promise} Promise resolved when the data is invalidated.458 */459 self.invalidateAssignmentUserMappingsData = function(assignmentId, siteId) {460 siteId = siteId || $mmSite.getId();461 return $mmSitesManager.getSite(siteId).then(function(site) {462 return site.invalidateWsCacheForKey(getAssignmentUserMappingsCacheKey(assignmentId));463 });464 };465 /**466 * Invalidates assignment submissions data WS calls.467 *468 * @module mm.addons.mod_assign469 * @ngdoc method470 * @name $mmaModAssign#invalidateSubmissionData471 * @param {Number} assignId Assignment instance id.472 * @param {Number} [siteId] Site id (empty for current site).473 * @return {Promise} Promise resolved when the data is invalidated.474 */475 self.invalidateSubmissionData = function(assignId, siteId) {476 siteId = siteId || $mmSite.getId();477 return $mmSitesManager.getSite(siteId).then(function(site) {478 return site.invalidateWsCacheForKey(getSubmissionsCacheKey(assignId));479 });480 };481 /**482 * Invalidates All submission status data.483 *484 * @module mm.addons.mod_assign485 * @ngdoc method486 * @name $mmaModAssign#invalidateAllSubmissionData487 * @param {Number} assignId Assignment instance id.488 * @param {Number} [siteId] Site id (empty for current site).489 * @return {Promise} Promise resolved when the data is invalidated.490 */491 self.invalidateAllSubmissionData = function(assignId, siteId) {492 siteId = siteId || $mmSite.getId();493 return $mmSitesManager.getSite(siteId).then(function(site) {494 return site.invalidateWsCacheForKeyStartingWith(getSubmissionsCacheKey(assignId));495 });496 };497 /**498 * Invalidates submission status data.499 *500 * @module mm.addons.mod_assign501 * @ngdoc method502 * @name $mmaModAssign#invalidateSubmissionStatusData503 * @param {Number} assignId Assignment instance id.504 * @param {Number} [userId] User id (empty for current user).505 * @param {Number} [isBlind] If blind marking is enabled or not.506 * @param {Number} [siteId] Site id (empty for current site).507 * @return {Promise} Promise resolved when the data is invalidated.508 */509 self.invalidateSubmissionStatusData = function(assignId, userId, isBlind, siteId) {510 siteId = siteId || $mmSite.getId();511 return $mmSitesManager.getSite(siteId).then(function(site) {512 return site.invalidateWsCacheForKey(getSubmissionStatusCacheKey(assignId, userId, isBlind));513 });514 };515 /**516 * Invalidates assignment participants data.517 *518 * @module mm.addons.mod_assign519 * @ngdoc method520 * @name $mmaModAssign#invalidateListParticipantsData521 * @param {Number} assignId Assignment instance id.522 * @param {Number} [siteId] Site id (empty for current site).523 * @return {Promise} Promise resolved when the data is invalidated.524 */525 self.invalidateListParticipantsData = function(assignId, siteId) {526 siteId = siteId || $mmSite.getId();527 return $mmSitesManager.getSite(siteId).then(function(site) {528 return site.invalidateWsCacheForKeyStartingWith(listParticipantsPrefixCacheKey(assignId));529 });530 };531 /**532 * Invalidate the prefetched content.533 *534 * @module mm.addons.mod_assign535 * @ngdoc method536 * @name $mmaModAssign#invalidateContent537 * @param {Object} moduleId The module ID.538 * @param {Number} courseId Course ID.539 * @param {String} [siteId] Site ID. If not defined, current site.540 * @return {Promise}541 */542 self.invalidateContent = function(moduleId, courseId, siteId) {543 var promises = [];544 siteId = siteId || $mmSite.getId();545 promises.push(self.getAssignment(courseId, moduleId, siteId).then(function(assign) {546 var ps = [];547 // Do not invalidate assignment data before getting assignment info, we need it!548 ps.push(self.invalidateAssignmentData(courseId, siteId));549 ps.push(self.invalidateAllSubmissionData(assign.id, siteId));550 ps.push(self.invalidateAssignmentUserMappingsData(assign.id, siteId));551 ps.push(self.invalidateListParticipantsData(assign.id, siteId));552 ps.push($mmComments.invalidateCommentsByInstance('module', assign.id, siteId));553 return $q.all(ps);554 }));555 promises.push($mmFilepool.invalidateFilesByComponent(siteId, mmaModAssignComponent, moduleId));556 return $q.all(promises);557 };558 /**559 * Check if assignments plugin is enabled in a certain site.560 *561 * @module mm.addons.mod_assign562 * @ngdoc method563 * @name $mmaModAssign#isPluginEnabled564 * @param {String} [siteId] Site ID. If not defined, current site.565 * @return {Promise} Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise.566 */567 self.isPluginEnabled = function(siteId) {568 siteId = siteId || $mmSite.getId();569 return $mmSitesManager.getSite(siteId).then(function(site) {570 return site.wsAvailable('mod_assign_get_assignments') && site.wsAvailable('mod_assign_get_submissions');571 });572 };573 /**574 * Check if assignments plugin prefetch is enabled in a certain site.575 *576 * @module mm.addons.mod_assign577 * @ngdoc method578 * @name $mmaModAssign#isPrefetchEnabled579 * @return {Boolean} if plugin prefetch is enabled.580 */581 self.isPrefetchEnabled = function() {582 return $mmSite.wsAvailable('mod_assign_get_assignments') && $mmSite.wsAvailable('mod_assign_get_submissions') &&583 $mmSite.wsAvailable('mod_assign_get_submission_status');584 };585 /**586 * Check if save and submit assignments is enabled in site.587 *588 * @module mm.addons.mod_assign589 * @ngdoc method590 * @name $mmaModAssign#isSaveAndSubmitSupported591 * @param {String} [siteId] Site ID. If not defined, current site.592 * @return {Promise} Promise resolved with true if enabled, false otherwise.593 */594 self.isSaveAndSubmitSupported = function(siteId) {595 siteId = siteId || $mmSite.getId();596 return $mmSitesManager.getSite(siteId).then(function(site) {597 // Even if save & submit WS were introduced in 2.6, we'll also check get_submission_status WS598 // to make sure we have all the WS to provide the whole submit experience.599 return site.wsAvailable('mod_assign_get_submission_status') && site.wsAvailable('mod_assign_save_submission') &&600 site.wsAvailable('mod_assign_submit_for_grading');601 }).catch(function() {602 return false;603 });604 };605 /**606 * Report an assignment submission as being viewed.607 *608 * @module mm.addons.mod_assign609 * @ngdoc method610 * @name $mmaModAssign#logSubmissionView611 * @param {Number} assignId Assignment ID.612 * @param {String} [siteId] Site ID. If not defined, current site.613 * @return {Promise} Promise resolved when the WS call is successful.614 */615 self.logSubmissionView = function(assignId, siteId) {616 if (assignId) {617 siteId = siteId || $mmSite.getId();618 return $mmSitesManager.getSite(siteId).then(function(site) {619 var params = {620 assignid: assignId621 };622 return site.write('mod_assign_view_submission_status', params);623 });624 }625 return $q.reject();626 };627 /**628 * Report an assignment grading table is being viewed.629 *630 * @module mm.addons.mod_assign631 * @ngdoc method632 * @name $mmaModAssign#logGradingView633 * @param {Number} assignId Assignment ID.634 * @param {String} [siteId] Site ID. If not defined, current site.635 * @return {Promise} Promise resolved when the WS call is successful.636 */637 self.logGradingView = function(assignId, siteId) {638 if (assignId) {639 siteId = siteId || $mmSite.getId();640 return $mmSitesManager.getSite(siteId).then(function(site) {641 var params = {642 assignid: assignId643 };644 return site.write('mod_assign_view_grading_table', params);645 });646 }647 return $q.reject();648 };649 /**650 * Returns the badge class for a given status name651 *652 * @module mm.addons.mod_assign653 * @ngdoc method654 * @name $mmaModAssign#getSubmissionStatusClass655 * @param {Number} status Status name656 * @return {String} The badge class name.657 */658 self.getSubmissionStatusClass = function(status) {659 switch (status) {660 case 'submitted':661 return 'badge-balanced';662 case 'draft':663 return 'badge-positive';664 case 'new':665 case 'noattempt':666 case 'noonlinesubmissions':667 case 'nosubmission':668 return 'badge-assertive';669 }670 return "";671 };672 /**673 * Save current user submission for a certain assignment.674 *675 * @module mm.addons.mod_assign676 * @ngdoc method677 * @name $mmaModAssign#saveSubmission678 * @param {Number} assignmentId Assign ID.679 * @param {Object} pluginData Data to save.680 * @return {Promise} Promise resolved when saved, rejected otherwise.681 */682 self.saveSubmission = function(assignmentId, pluginData) {683 var params = {684 assignmentid: assignmentId,685 plugindata: pluginData686 };687 return $mmSite.write('mod_assign_save_submission', params).then(function(warnings) {688 if (warnings && warnings.length) {689 // The WebService returned warnings, reject.690 return $q.reject(warnings[0].item);691 }692 });693 };694 /**695 * Submit the current user assignment for grading.696 *697 * @module mm.addons.mod_assign698 * @ngdoc method699 * @name $mmaModAssign#submitForGrading700 * @param {Number} assignmentId Assign ID.701 * @param {Boolean} acceptStatement True if submission statement is accepted, false otherwise.702 * @return {Promise} Promise resolved when submitted, rejected otherwise.703 */704 self.submitForGrading = function(assignmentId, acceptStatement) {705 var params = {706 assignmentid: assignmentId,707 acceptsubmissionstatement: acceptStatement ? 1 : 0708 };709 return $mmSite.write('mod_assign_submit_for_grading', params).then(function(warnings) {710 if (warnings && warnings.length) {711 // The WebService returned warnings, reject.712 return $q.reject(warnings[0].message);713 }714 });715 };716 return self;...
submission.js
Source:submission.js
1// (C) Copyright 2015 Martin Dougiamas2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14angular.module('mm.addons.mod_assign')15/**16 * Directive to render an submission.17 *18 * @module mm.addons.mod_assign19 * @ngdoc directive20 * @name mmaModAssignSubmission21 * @description22 * Directive to render submission.23 */24.directive('mmaModAssignSubmission', function($mmaModAssign, $translate, $mmUser, mmaModAssignAttemptReopenMethodNone, $q, $mmSite,25 mmaModAssignUnlimitedAttempts, mmaModAssignGradingStatusGraded, mmaModAssignGradingStatusNotGraded, mmUserProfileState,26 mmaModMarkingWorkflowStateReleased, mmaModAssignSubmissionStatusNew, mmaModAssignSubmissionStatusSubmitted, $mmUtil,27 mmaModAssignSubmissionInvalidatedEvent, $mmGroups, $state, $mmaModAssignHelper, mmaModAssignSubmissionStatusReopened,28 $mmEvents, mmaModAssignSubmittedForGradingEvent, $mmFileUploaderHelper, $mmApp, $mmText) {29 // Directive controller.30 function controller() {31 var self = this;32 self.load = function(scope, moduleId, courseId, submitId, blindId) {33 var isBlind = !!blindId;34 if (!submitId) {35 submitId = $mmSite.getUserId();36 isBlind = false;37 }38 return $mmaModAssign.getAssignment(courseId, moduleId).then(function(assign) {39 var time = parseInt(Date.now() / 1000),40 submissionStatementMissing = assign.requiresubmissionstatement &&41 typeof assign.submissionstatement == 'undefined';42 scope.assign = assign;43 if (assign.allowsubmissionsfromdate && assign.allowsubmissionsfromdate >= time) {44 scope.fromDate = moment(assign.allowsubmissionsfromdate * 1000)45 .format($translate.instant('mm.core.dfmediumdate'));46 }47 scope.currentAttempt = 0;48 scope.unlimitedAttempts = mmaModAssignUnlimitedAttempts;49 return $mmaModAssign.getSubmissionStatus(assign.id, submitId, isBlind).then(function(response) {50 var promises = [];51 scope.submissionStatusAvailable = true;52 scope.lastAttempt = response.lastattempt;53 scope.previousAttempts = response.previousattempts;54 scope.membersToSubmit = [];55 if (response.lastattempt) {56 var blindMarking = scope.isGrading && response.lastattempt.blindmarking && !assign.revealidentities;57 scope.canSubmit = !scope.isGrading && response.lastattempt.cansubmit;58 scope.canEdit = !scope.isGrading && response.lastattempt.canedit;59 // Get submission statement if needed.60 if (assign.requiresubmissionstatement && assign.submissiondrafts && submitId == $mmSite.getUserId()) {61 scope.submissionStatement = assign.submissionstatement;62 scope.submitModel.submissionStatement = false;63 } else {64 scope.submissionStatement = false;65 scope.submitModel.submissionStatement = true; // No submission statement, so it's accepted.66 }67 // Show error instead of edit/submit button if submission statement should be shown68 // but we couldn't retrieve it from server (Moodle 3.1 or previous).69 scope.showErrorStatementEdit = submissionStatementMissing && !assign.submissiondrafts &&70 submitId == $mmSite.getUserId();71 scope.showErrorStatementSubmit = submissionStatementMissing && assign.submissiondrafts;72 scope.userSubmission = $mmaModAssign.getSubmissionObjectFromAttempt(assign, response.lastattempt);73 if (assign.attemptreopenmethod != mmaModAssignAttemptReopenMethodNone) {74 if (scope.userSubmission) {75 scope.currentAttempt = scope.userSubmission.attemptnumber + 1;76 }77 }78 if (!assign.teamsubmission) {79 if (scope.userSubmission && scope.userSubmission.status != mmaModAssignSubmissionStatusNew) {80 scope.statusTranslated = $translate.instant('mma.mod_assign.submissionstatus_' +81 scope.userSubmission.status);82 scope.statusClass = $mmaModAssign.getSubmissionStatusClass(scope.userSubmission.status);83 } else {84 if (!response.lastattempt.submissionsenabled) {85 scope.statusTranslated = $translate.instant('mma.mod_assign.noonlinesubmissions');86 scope.statusClass = $mmaModAssign.getSubmissionStatusClass('noonlinesubmissions');87 } else {88 scope.statusTranslated = $translate.instant('mma.mod_assign.noattempt');89 scope.statusClass = $mmaModAssign.getSubmissionStatusClass('noattempt');90 }91 }92 } else {93 if (response.lastattempt.submissiongroup) {94 promises.push($mmGroups.getActivityAllowedGroups(assign.cmid).then(function(groups) {95 angular.forEach(groups, function(group) {96 if (group.id == response.lastattempt.submissiongroup) {97 scope.lastAttempt.submissiongroupname = group.name;98 }99 });100 }));101 }102 if (!response.lastattempt.submissiongroup && assign.preventsubmissionnotingroup) {103 scope.statusTranslated = $translate.instant('mma.mod_assign.nosubmission');104 scope.statusClass = $mmaModAssign.getSubmissionStatusClass('nosubmission');105 } else if (scope.userSubmission && scope.userSubmission.status != mmaModAssignSubmissionStatusNew) {106 scope.userStateName = mmUserProfileState;107 angular.forEach(response.lastattempt.submissiongroupmemberswhoneedtosubmit, function(member) {108 if (blindMarking) {109 // Users not blinded! (Moodle < 3.1.1, 3.2)110 promises.push($mmaModAssign.getAssignmentUserMappings(assign.id, member).then(function(blindId) {111 scope.membersToSubmit.push(blindId);112 }).catch(function() {113 // Fail silently (Moodle < 2.6)114 }));115 } else {116 promises.push($mmUser.getProfile(member, courseId).then(function(profile) {117 scope.membersToSubmit.push(profile);118 }));119 }120 });121 angular.forEach(response.lastattempt.submissiongroupmemberswhoneedtosubmitblind, function(member) {122 scope.membersToSubmit.push(member);123 });124 scope.statusTranslated = $translate.instant('mma.mod_assign.submissionstatus_' +125 scope.userSubmission.status);126 scope.statusClass = $mmaModAssign.getSubmissionStatusClass(scope.userSubmission.status);127 } else {128 if (!response.lastattempt.submissionsenabled) {129 scope.statusTranslated = $translate.instant('mma.mod_assign.noonlinesubmissions');130 scope.statusClass = $mmaModAssign.getSubmissionStatusClass('noonlinesubmissions');131 } else {132 scope.statusTranslated = $translate.instant('mma.mod_assign.nosubmission');133 scope.statusClass = $mmaModAssign.getSubmissionStatusClass('nosubmission');134 }135 }136 }137 if (response.lastattempt.gradingstatus == mmaModAssignGradingStatusGraded ||138 response.lastattempt.gradingstatus == mmaModAssignGradingStatusNotGraded) {139 scope.gradingStatus = $translate.instant('mma.mod_assign.'+response.lastattempt.gradingstatus);140 } else {141 scope.gradingStatus = $translate.instant('mma.mod_assign.markingworkflowstate' +142 response.lastattempt.gradingstatus);143 }144 if (response.lastattempt.gradingstatus == mmaModAssignGradingStatusGraded ||145 response.lastattempt.gradingstatus == mmaModMarkingWorkflowStateReleased) {146 scope.gradingClass = 'submissiongraded';147 } else {148 scope.gradingClass = 'submissionnotgraded';149 }150 if (scope.userSubmission) {151 if (!assign.teamsubmission || response.lastattempt.submissiongroup != false ||152 !assign.preventsubmissionnotingroup) {153 scope.submissionPlugins = scope.userSubmission.plugins;154 }155 }156 }157 if (assign.duedate > 0) {158 var duedate = response.lastattempt && response.lastattempt.extensionduedate ?159 response.lastattempt.extensionduedate: assign.duedate,160 time = parseInt(Date.now() / 1000);161 timeRemaining = duedate - time;162 if (timeRemaining <= 0) {163 if (!scope.userSubmission || scope.userSubmission.status != mmaModAssignSubmissionStatusSubmitted) {164 if ((response.lastattempt && response.lastattempt.submissionsenabled) ||165 (response.gradingsummary && response.gradingsummary.submissionsenabled)) {166 scope.timeRemaining = $translate.instant('mma.mod_assign.overdue',167 {'$a': $mmUtil.formatDuration(-timeRemaining, 3) });168 scope.timeRemainingClass = 'overdue';169 } else {170 scope.timeRemaining = $translate.instant('mma.mod_assign.duedatereached');171 }172 } else {173 if (scope.userSubmission.timemodified > duedate) {174 scope.timeRemaining = $translate.instant('mma.mod_assign.submittedlate',175 {'$a': $mmUtil.formatDuration(-timeRemaining, 3) });176 scope.timeRemainingClass = 'latesubmission';177 } else {178 scope.timeRemaining = $translate.instant('mma.mod_assign.submittedearly',179 {'$a': $mmUtil.formatDuration(-timeRemaining, 3) });180 scope.timeRemainingClass = 'earlysubmission';181 }182 }183 } else {184 scope.timeRemaining = $mmUtil.formatDuration(timeRemaining, 3);185 }186 }187 // Feedback info.188 if (response.feedback) {189 scope.feedback = response.feedback;190 if (response.feedback.grade && response.feedback.grade.grader) {191 $mmUser.getProfile(response.feedback.grade.grader, courseId).then(function(profile) {192 scope.grader = profile;193 });194 }195 if (response.feedback.gradefordisplay) {196 var position = response.feedback.gradefordisplay.indexOf('class="advancedgrade"');197 if (position > -1) {198 scope.feedback.advancedgrade = true;199 }200 }201 }202 // Check if there's any unsupported plugin for editing.203 var plugins;204 if (scope.userSubmission) {205 plugins = scope.userSubmission.plugins;206 } else {207 // Submission not created yet, we have to use assign configs to detect the plugins used.208 plugins = [];209 angular.forEach(assign.configs, function(config) {210 if (config.subtype == 'assignsubmission') {211 if (config.name == 'enabled' && parseInt(config.value, 10) === 1) {212 plugins.push({213 type: config.plugin,214 name: config.plugin215 });216 }217 }218 });219 }220 promises.push($mmaModAssign.getUnsupportedEditPlugins(plugins).then(function(list) {221 scope.unsupportedEditPlugins = list;222 }));223 return $q.all(promises);224 }).catch(function(error) {225 if (typeof error != "undefined") {226 if (error == 'error/nopermission') {227 $mmUtil.showModal('mm.core.notice', 'mma.mod_assign.errorshowinginformation');228 return $q.when();229 }230 return $q.reject(error);231 }232 // Fallback. Legacy code ahead.233 if (assign.duedate > 0) {234 var time = parseInt(Date.now() / 1000);235 if (assign.duedate - time <= 0) {236 scope.timeRemaining = $translate.instant('mma.mod_assign.duedatereached');237 } else {238 scope.timeRemaining = $mmUtil.formatDuration(assign.duedate - time, 3);239 }240 }241 return $mmaModAssign.getSubmissions(assign.id).then(function(data) {242 scope.canSubmit = !data.canviewsubmissions;243 if (data.submissions) {244 scope.userSubmission = false;245 angular.forEach(data.submissions, function(submission) {246 if (submission.userid == submitId) {247 scope.userSubmission = submission;248 scope.statusTranslated = $translate.instant('mma.mod_assign.submissionstatus_' +249 submission.status);250 scope.statusClass = $mmaModAssign.getSubmissionStatusClass(submission.status);251 scope.currentAttempt = submission.attemptnumber + 1;252 scope.submissionPlugins = submission.plugins;253 }254 });255 }256 });257 });258 }).catch(function(message) {259 if (message) {260 $mmUtil.showErrorModal(message);261 } else {262 $mmUtil.showErrorModal('Error getting assigment data.');263 }264 return $q.reject();265 }).finally(function() {266 scope.loaded = true;267 });268 };269 }270 return {271 scope: {272 courseid: '@',273 moduleid: '@',274 submitid: '@?',275 blindid: '@?',276 scrollHandle: '@?'277 },278 restrict: 'E',279 controller: controller,280 templateUrl: 'addons/mod/assign/templates/submission.html',281 link: function(scope, element, attributes, controller) {282 var moduleId = parseInt(attributes.moduleid, 10),283 courseId = parseInt(attributes.courseid, 10),284 submitId = parseInt(attributes.submitid, 10),285 blindId = parseInt(attributes.blindid, 10);286 scope.isGrading = !!submitId;287 scope.statusNew = mmaModAssignSubmissionStatusNew;288 scope.statusReopened = mmaModAssignSubmissionStatusReopened;289 scope.loaded = false;290 scope.submitModel = {};291 var obsLoaded = scope.$on(mmaModAssignSubmissionInvalidatedEvent, function() {292 controller.load(scope, moduleId, courseId, submitId, blindId);293 });294 // Check if submit through app is supported.295 $mmaModAssign.isSaveAndSubmitSupported().then(function(enabled) {296 scope.submitSupported = enabled;297 });298 scope.$on('$destroy', obsLoaded);299 controller.load(scope, moduleId, courseId, submitId, blindId);300 // Add or edit submission.301 scope.goToEdit = function() {302 $state.go('site.mod_assign-submission-edit', {303 moduleid: moduleId,304 courseid: courseId,305 userid: submitId,306 blindid: blindId307 });308 };309 // Copy previous attempt and then go to edit.310 scope.copyPrevious = function() {311 if (!$mmApp.isOnline()) {312 $mmUtil.showErrorModal('mm.core.networkerrormsg', true);313 return;314 }315 if (!scope.previousAttempts || !scope.previousAttempts.length) {316 // Cannot access previous attempts, just go to edit.317 scope.goToEdit();318 return;319 }320 var modal = $mmUtil.showModalLoading(),321 previousAttempt = scope.previousAttempts[scope.previousAttempts.length - 1],322 previousSubmission = $mmaModAssign.getSubmissionObjectFromAttempt(scope.assign, previousAttempt);323 $mmaModAssignHelper.getSubmissionSizeForCopy(scope.assign, previousSubmission).catch(function() {324 // Error calculating size, return -1.325 return -1;326 }).then(function(size) {327 modal.dismiss();328 // Confirm action.329 return $mmFileUploaderHelper.confirmUploadFile(size, true);330 }).then(function() {331 // User confirmed, copy the attempt.332 modal = $mmUtil.showModalLoading('mm.core.sending', true);333 $mmaModAssignHelper.copyPreviousAttempt(scope.assign, previousSubmission).then(function() {334 // Now go to edit.335 scope.goToEdit();336 // Invalidate and refresh data to update this view.337 invalidateAndRefresh();338 if (!scope.assign.submissiondrafts) {339 // No drafts allowed, so it was submitted. Trigger event.340 $mmEvents.trigger(mmaModAssignSubmittedForGradingEvent, {341 assignmentId: scope.assign.id,342 submissionId: scope.userSubmission.id,343 userId: $mmSite.getUserId(),344 siteId: $mmSite.getId()345 });346 }347 }).catch(function(err) {348 alert(err);349 }).finally(function() {350 modal.dismiss();351 });352 });353 };354 // Context Menu Description action.355 scope.showAdvancedGrade = function() {356 if (scope.feedback.advancedgrade) {357 $mmText.expandText($translate.instant('mma.grades.grade'), scope.feedback.gradefordisplay);358 }359 };360 // Submit for grading.361 scope.submit = function(acceptStatement) {362 // Ask for confirmation. @todo plugin precheck_submission363 $mmUtil.showConfirm($translate('mma.mod_assign.confirmsubmission')).then(function() {364 var modal = $mmUtil.showModalLoading('mm.core.sending', true);365 $mmaModAssign.submitForGrading(scope.assign.id, acceptStatement).then(function() {366 // Invalidate and refresh data.367 invalidateAndRefresh();368 // Submitted, trigger event.369 $mmEvents.trigger(mmaModAssignSubmittedForGradingEvent, {370 assignmentId: scope.assign.id,371 submissionId: scope.userSubmission.id,372 userId: $mmSite.getUserId(),373 siteId: $mmSite.getId()374 });375 }).catch(function(error) {376 $mmUtil.showErrorModal(error);377 }).finally(function() {378 modal.dismiss();379 });380 });381 };382 // Invalidate and refresh data.383 function invalidateAndRefresh() {384 scope.loaded = false;385 var promises = [$mmaModAssign.invalidateAssignmentData(courseId)];386 if (scope.assign) {387 promises.push($mmaModAssign.invalidateAllSubmissionData(scope.assign.id));388 promises.push($mmaModAssign.invalidateAssignmentUserMappingsData(scope.assign.id));389 }390 $q.all(promises).finally(function() {391 controller.load(scope, moduleId, courseId, submitId, blindId);392 });393 }394 }395 };...
prefetch_handler.js
Source:prefetch_handler.js
1// (C) Copyright 2015 Martin Dougiamas2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14angular.module('mm.addons.mod_assign')15/**16 * Mod assign prefetch handler.17 *18 * @module mm.addons.mod_assign19 * @ngdoc service20 * @name $mmaModAssignPrefetchHandler21 */22.factory('$mmaModAssignPrefetchHandler', function($mmaModAssign, mmaModAssignComponent, $mmSite, $mmFilepool, $q, $mmCourseHelper,23 $mmCourse, $mmGroups, $mmUser, $mmaModAssignSubmissionDelegate, $mmaModAssignFeedbackDelegate, mmCoreDownloading,24 mmCoreDownloaded) {25 var self = {},26 downloadPromises = {}; // Store download promises to prevent duplicate requests.27 self.component = mmaModAssignComponent;28 /**29 * Get the download size of a module.30 *31 * @module mm.addons.mod_assign32 * @ngdoc method33 * @name $mmaModAssignPrefetchHandler#getDownloadSize34 * @param {Object} module Module to get the size.35 * @param {Number} courseId Course ID the module belongs to.36 * @param {String} [siteId] Site ID. If not defined, current site.37 * @return {Promise} Size.38 */39 self.getDownloadSize = function(module, courseId, siteId) {40 siteId = siteId || $mmSite.getId();41 return self.getFiles(module, courseId, siteId).then(function(files) {42 var size = 0;43 angular.forEach(files, function(file) {44 if (file.filesize) {45 size = size + file.filesize;46 }47 });48 // Avoid failing.49 if (size == 0) {50 return 1;51 }52 return size;53 });54 };55 /**56 * Get the list of downloadable files.57 *58 * @module mm.addons.mod_assign59 * @ngdoc method60 * @name $mmaModAssignPrefetchHandler#getFiles61 * @param {Object} module Module to get the files.62 * @param {Number} courseId Course ID the module belongs to.63 * @param {String} [siteId] Site ID. If not defined, current site.64 * @return {Promise} List of files.65 */66 self.getFiles = function(module, courseId, siteId) {67 siteId = siteId || $mmSite.getId();68 return $mmaModAssign.getAssignment(courseId, module.id, siteId).then(function(assign) {69 var files = assign.introattachments || [];70 return $mmaModAssign.getSubmissions(assign.id, siteId).then(function(data) {71 var blindMarking = assign.blindmarking && !assign.revealidentities;72 if (data.canviewsubmissions) {73 // Teacher, get all submissions.74 return $mmaModAssign.getSubmissionsUserData(data.submissions, courseId, assign.id, blindMarking)75 .then(function(submissions) {76 var promises = [];77 // Get Submission status with all files78 angular.forEach(submissions, function(submission) {79 promises.push(getSubmissionFiles(assign, submission.submitid, !!submission.blindid,80 submission.plugins, siteId).then(function(submissionFiles) {81 files = files.concat(submissionFiles);82 }));83 });84 return $q.all(promises).then(function() {85 return files;86 });87 });88 } else {89 // Student, get only his/her submissions.90 var userId = $mmSite.getUserId();91 return getSubmissionFiles(assign, userId, blindMarking, [], siteId).then(function(submissionFiles) {92 files = files.concat(submissionFiles);93 return files;94 });95 }96 });97 }).catch(function() {98 // Assign not found, return empty list.99 return [];100 });101 };102 /**103 * Get submission files.104 *105 * @param {Object} assign Assign.106 * @param {Number} submitId User ID of the submission to get.107 * @param {Boolean} blindMarking True if blind marking, false otherwise.108 * @param {Object[]} plugins Submission plugins. Only used for legacy code.109 * @param {String} [siteId] Site ID. If not defined, current site.110 * @return {Promise} Promise resolved with array of files.111 */112 function getSubmissionFiles(assign, submitId, blindMarking, plugins, siteId) {113 return $mmaModAssign.getSubmissionStatus(assign.id, submitId, blindMarking, true, false, siteId).then(function(response) {114 var promises = [];115 if (response.lastattempt) {116 var userSubmission = $mmaModAssign.getSubmissionObjectFromAttempt(assign, response.lastattempt);117 if (userSubmission) {118 // Add submission plugin files.119 angular.forEach(userSubmission.plugins, function(plugin) {120 promises.push($mmaModAssignSubmissionDelegate.getPluginFiles(assign, userSubmission, plugin, siteId));121 });122 }123 }124 if (response.feedback) {125 // Add feedback plugin files.126 angular.forEach(response.feedback.plugins, function(plugin) {127 promises.push($mmaModAssignFeedbackDelegate.getPluginFiles(assign, response, plugin, siteId));128 });129 }130 return $q.all(promises);131 }).catch(function(error) {132 var promises = [];133 if (typeof error != "undefined") {134 return [];135 }136 // Fallback. Legacy code ahead. Only add user submission files.137 angular.forEach(plugins, function(plugin) {138 promises.push($mmaModAssign.getSubmissionPluginAttachments(plugin));139 });140 return $q.all(promises);141 }).then(function(filePromises) {142 var files = [];143 angular.forEach(filePromises, function(filePromise) {144 files = files.concat(filePromise);145 });146 return files;147 });148 }149 /**150 * Get timemodified of a Assign.151 *152 * @module mm.addons.mod_assign153 * @ngdoc method154 * @name $mmaModAssignPrefetchHandler#getTimemodified155 * @param {Object} module Module to get the timemodified.156 * @param {Number} courseId Course ID the module belongs to.157 * @param {String} [siteId] Site ID. If not defined, current site.158 * @return {Promise} Timemodified.159 */160 self.getTimemodified = function(module, courseId, siteId) {161 var lastModified = 0;162 return $mmaModAssign.getAssignment(courseId, module.id, siteId).then(function(assign) {163 lastModified = assign.timemodified;164 return $mmaModAssign.getSubmissions(assign.id, siteId).then(function(data) {165 var blindMarking = assign.blindmarking && !assign.revealidentities,166 promise;167 if (data.canviewsubmissions) {168 // Teacher, get all submissions.169 promise = $mmaModAssign.getSubmissionsUserData(data.submissions, courseId, assign.id, blindMarking)170 .then(function(submissions) {171 var promises = [];172 // Get Submission status with all files173 angular.forEach(submissions, function(submission) {174 promises.push(getSubmissionTimemodified(assign, submission.submitid,175 !!submission.blindid, submission.timemodified, siteId));176 });177 return $q.all(promises).then(function(lastmodifiedTimes) {178 // Get the maximum value in the array.179 return Math.max.apply(null, lastmodifiedTimes);180 });181 });182 } else {183 // Student, get only his/her submissions.184 promise = getSubmissionTimemodified(assign, $mmSite.getUserId(), blindMarking, undefined, siteId);185 }186 return promise.then(function(submissionTimemodified) {187 lastModified = Math.max(lastModified, submissionTimemodified);188 return self.getFiles(module, courseId, siteId).then(function(files) {189 var lastModifiedFiles = $mmFilepool.getTimemodifiedFromFileList(files);190 // Get the maximum value in the array.191 return Math.max(lastModified, lastModifiedFiles);192 });193 });194 });195 }).catch(function() {196 return lastModified;197 });198 };199 /**200 * Get submission timemodified.201 *202 * @param {Object} assign Assign.203 * @param {Number} submitId User ID of the submission to get.204 * @param {Boolean} blindMarking True if blind marking, false otherwise.205 * @param {Number} [timemodified] Submission timemodified, undefined if unknown.206 * @param {String} [siteId] Site ID. If not defined, current site.207 * @return {Promise} Promise resolved with array of files.208 */209 function getSubmissionTimemodified(assign, submitId, blindMarking, timemodified, siteId) {210 return $mmaModAssign.getSubmissionStatus(assign.id, submitId, blindMarking, true, false, siteId)211 .then(function(response) {212 var lastModified = 0;213 if (response.lastattempt) {214 var userSubmission = $mmaModAssign.getSubmissionObjectFromAttempt(assign, response.lastattempt);215 if (userSubmission && lastModified < userSubmission.timemodified) {216 lastModified = userSubmission.timemodified;217 }218 }219 if (response.feedback && lastModified < response.feedback.gradeddate) {220 lastModified = response.feedback.gradeddate;221 }222 return lastModified;223 }).catch(function(error) {224 if (typeof error != 'undefined'Â || !timemodified) {225 return 0;226 }227 return timemodified;228 });229 }230 /**231 * Whether or not the module is enabled for the site.232 *233 * @module mm.addons.mod_assign234 * @ngdoc method235 * @name $mmaModAssignPrefetchHandler#isEnabled236 * @return {Boolean}237 */238 self.isEnabled = function() {239 return $mmaModAssign.isPluginEnabled();240 };241 /**242 * Check if an assign is downloadable.243 *244 * @module mm.addons.mod_assign245 * @ngdoc method246 * @name $mmaModAssignPrefetchHandler#isDownloadable247 * @param {Object} module Module to check.248 * @param {Number} courseId Course ID the module belongs to.249 * @return {Promise} Promise resolved with true if downloadable, resolved with false otherwise.250 */251 self.isDownloadable = function(module, courseId) {252 return $mmaModAssign.isPrefetchEnabled();253 };254 /**255 * Invalidates WS calls needed to determine module status.256 *257 * @module mm.addons.mod_assign258 * @ngdoc method259 * @name $mmaModAssignPrefetchHandler#invalidateModule260 * @param {Object} module Module to invalidate.261 * @param {Number} courseId Course ID the module belongs to.262 * @return {Promise} Promise resolved when done.263 */264 self.invalidateModule = function(module, courseId) {265 return $mmaModAssign.invalidateContent(module.id, courseId);266 };267 /**268 * Prefetch the module.269 *270 * @module mm.addons.mod_assign271 * @ngdoc method272 * @name $mmaModAssignPrefetchHandler#prefetch273 * @param {Object} module The module object returned by WS.274 * @param {Number} courseId Course ID the module belongs to.275 * @param {Boolean} single True if we're downloading a single module, false if we're downloading a whole section.276 * @return {Promise} Promise resolved when all files have been downloaded. Data returned is not reliable.277 */278 self.prefetch = function(module, courseId, single) {279 var siteId = $mmSite.getId(),280 userId = $mmSite.getUserId(),281 prefetchPromise,282 deleted = false,283 revision,284 timemod,285 component = mmaModAssignComponent;286 if (downloadPromises[siteId] && downloadPromises[siteId][module.id]) {287 // There's already a download ongoing for this package, return the promise.288 return downloadPromises[siteId][module.id];289 } else if (!downloadPromises[siteId]) {290 downloadPromises[siteId] = {};291 }292 // Mark package as downloading.293 prefetchPromise = $mmFilepool.storePackageStatus(siteId, component, module.id, mmCoreDownloading).then(function() {294 var promises = [];295 promises.push($mmCourse.getModuleBasicInfo(module.id, siteId));296 // Get Assignment to retrieve all its submissions.297 promises.push($mmaModAssign.getAssignment(courseId, module.id, siteId).then(function(assign) {298 var subPromises = [],299 blindMarking = assign.blindmarking && !assign.revealidentities;300 if (blindMarking) {301 subPromises.push($mmaModAssign.getAssignmentUserMappings(assign.id, false, siteId).catch(function() {302 // Fail silently (Moodle < 2.6)303 }));304 }305 subPromises.push(prefetchSubmissions(assign, courseId, siteId, userId));306 subPromises.push($mmCourseHelper.getModuleCourseIdByInstance(assign.id, 'assign', siteId));307 // Get related submissions files and fetch them.308 subPromises.push(self.getFiles(module, courseId, siteId).then(function(files) {309 var filePromises = [];310 revision = $mmFilepool.getRevisionFromFileList(files);311 angular.forEach(files, function(file) {312 var url = file.fileurl;313 filePromises.push($mmFilepool.addToQueueByUrl(siteId, url, component, module.id, file.timemodified));314 });315 return $q.all(filePromises);316 }));317 return $q.all(subPromises);318 }));319 // Get timemodified.320 promises.push(self.getTimemodified(module, courseId, siteId).then(function(timemodified) {321 timemod = timemodified;322 }));323 return $q.all(promises);324 }).then(function() {325 // Prefetch finished, mark as downloaded.326 return $mmFilepool.storePackageStatus(siteId, component, module.id, mmCoreDownloaded, revision, timemod);327 }).catch(function(error) {328 // Error prefetching, go back to previous status and reject the promise.329 return $mmFilepool.setPackagePreviousStatus(siteId, component, module.id).then(function() {330 return $q.reject(error);331 });332 }).finally(function() {333 deleted = true;334 delete downloadPromises[siteId][module.id];335 });336 if (!deleted) {337 downloadPromises[siteId][module.id] = prefetchPromise;338 }339 return prefetchPromise;340 };341 /**342 * Prefetch assign submissions.343 *344 * @param {Object} assign Assign.345 * @param {Number} courseId Course ID.346 * @param {String} [siteId] Site ID. If not defined, current site.347 * @param {Number} [userId] User ID. If not defined, current user.348 * @return {Promise} Promise resolved when prefetched, rejected otherwise.349 */350 function prefetchSubmissions(assign, courseId, siteId, userId) {351 siteId = siteId || $mmSite.getId();352 userId = userId || $mmSite.getUserId();353 // Get submissions.354 return $mmaModAssign.getSubmissions(assign.id, siteId).then(function(data) {355 var promises = [],356 blindMarking = assign.blindmarking && !assign.revealidentities;357 if (data.canviewsubmissions) {358 // Teacher.359 // Do not send participants to getSubmissionsUserData to retrieve user profiles.360 promises.push($mmaModAssign.getSubmissionsUserData(data.submissions, courseId, assign.id, blindMarking, false, siteId)361 .then(function(submissions) {362 var subPromises = [];363 angular.forEach(submissions, function(submission) {364 subPromises.push($mmaModAssign.getSubmissionStatus(365 assign.id, submission.submitid, !!submission.blindid, true, false, siteId).then(function(subm) {366 return prefetchSubmission(assign, courseId, subm, siteId);367 }));368 });369 return $q.all(subPromises).catch(function() {370 // Fail silently (Moodle < 3.1)371 });372 }));373 // Get list participants.374 promises.push($mmaModAssign.listParticipants(assign.id, 0, siteId).then(function (participants) {375 angular.forEach(participants, function(participant) {376 if (participant.profileimageurl) {377 $mmFilepool.addToQueueByUrl(siteId, participant.profileimageurl);378 }379 });380 }).catch(function() {381 // Fail silently (Moodle < 3.2)382 }));383 } else {384 // Student.385 promises.push($mmaModAssign.getSubmissionStatus(assign.id, userId, false, true, false, siteId).then(function(subm) {386 return prefetchSubmission(assign, courseId, subm, siteId);387 }));388 }389 promises.push($mmGroups.getActivityAllowedGroups(assign.cmid, false, siteId));390 return $q.all(promises);391 });392 }393 /**394 * Prefetch a submission.395 *396 * @param {Object} assign Assign.397 * @param {Number} courseId Course ID.398 * @param {Object} submission Data returned by $mmaModAssign#getSubmissionStatus.399 * @param {String} [siteId] Site ID. If not defined, current site.400 * @return {Promise} Promise resolved when prefetched, rejected otherwise.401 */402 function prefetchSubmission(assign, courseId, submission, siteId) {403 siteId = siteId || $mmSite.getId();404 var promises = [],405 blindMarking = assign.blindmarking && !assign.revealidentities;406 if (submission.lastattempt) {407 var userSubmission = $mmaModAssign.getSubmissionObjectFromAttempt(assign, submission.lastattempt);408 // Get profile and images of the member who need to submit.409 if (!blindMarking && submission.lastattempt.submissiongroupmemberswhoneedtosubmit) {410 angular.forEach(submission.lastattempt.submissiongroupmemberswhoneedtosubmit, function(member) {411 promises.push($mmUser.getProfile(member, courseId).then(function(profile) {412 if (profile.profileimageurl) {413 $mmFilepool.addToQueueByUrl(siteId, profile.profileimageurl);414 }415 }));416 });417 }418 if (userSubmission && userSubmission.id) {419 // Prefetch submission plugins data.420 angular.forEach(userSubmission.plugins, function(plugin) {421 promises.push($mmaModAssignSubmissionDelegate.prefetch(assign, userSubmission, plugin, siteId));422 });423 // Prefetch user profile.424 if (userSubmission.userid) {425 promises.push($mmUser.getProfile(userSubmission.userid, courseId).then(function(profile) {426 if (profile.profileimageurl) {427 $mmFilepool.addToQueueByUrl(siteId, profile.profileimageurl);428 }429 }));430 }431 }432 }433 // Prefetch feedback.434 if (submission.feedback) {435 // Get profile and image of the grader.436 if (submission.feedback.grade && submission.feedback.grade.grader) {437 promises.push($mmUser.getProfile(submission.feedback.grade.grader, courseId).then(function(profile) {438 if (profile.profileimageurl) {439 $mmFilepool.addToQueueByUrl(siteId, profile.profileimageurl);440 }441 }));442 }443 // Prefetch feedback plugins data.444 angular.forEach(submission.feedback.plugins, function(plugin) {445 promises.push($mmaModAssignFeedbackDelegate.prefetch(assign, submission, plugin, siteId));446 });447 }448 return $q.all(promises);449 }450 return self;...
helper.js
Source:helper.js
1// (C) Copyright 2015 Martin Dougiamas2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14angular.module('mm.addons.mod_assign')15/**16 * Helper to gather some common functions for assign.17 *18 * @module mm.addons.mod_assign19 * @ngdoc service20 * @name $mmaModAssignHelper21 */22.factory('$mmaModAssignHelper', function($mmUtil, $mmaModAssignSubmissionDelegate, $q, $mmSite, $mmFS, $mmFilepool, $mmaModAssign,23 $mmFileUploader, mmaModAssignComponent) {24 var self = {};25 /**26 * Clear plugins temporary data because a submission was cancelled.27 *28 * @module mm.addons.mod_assign29 * @ngdoc method30 * @name $mmaModAssignHelper#clearSubmissionPluginTmpData31 * @param {Object} assign Assignment.32 * @param {Object} submission Submission to clear the data for.33 * @param {Object} inputData Data entered in the submission form.34 * @return {Void}35 */36 self.clearSubmissionPluginTmpData = function(assign, submission, inputData) {37 angular.forEach(submission.plugins, function(plugin) {38 $mmaModAssignSubmissionDelegate.clearTmpData(assign, submission, plugin, inputData);39 });40 };41 /**42 * Copy the data from last submitted attempt to the current submission.43 * Since we don't have any WS for that we'll have to re-submit everything manually.44 *45 * @module mm.addons.mod_assign46 * @ngdoc method47 * @name $mmaModAssignHelper#copyPreviousAttempt48 * @param {Object} assign Assignment.49 * @param {Object} previousSubmission Submission to copy.50 * @return {Promise} Promise resolved when done.51 */52 self.copyPreviousAttempt = function(assign, previousSubmission) {53 var pluginData = {},54 promises = [],55 errorMessage;56 angular.forEach(previousSubmission.plugins, function(plugin) {57 promises.push($mmaModAssignSubmissionDelegate.copyPluginSubmissionData(assign, plugin, pluginData).catch(function(err) {58 errorMessage = err;59 return $q.reject();60 }));61 });62 return $q.all(promises).then(function() {63 // We got the plugin data. Now we need to submit it.64 if (Object.keys(pluginData).length) {65 // There's something to save.66 return $mmaModAssign.saveSubmission(assign.id, pluginData);67 }68 }).catch(function() {69 return $q.reject(errorMessage);70 });71 };72 /**73 * Retrieve the answers entered in a form.74 * We don't use ng-model because it doesn't detect changes done by JavaScript.75 *76 * @module mm.addons.mod_assign77 * @ngdoc method78 * @name $mmaModAssignHelper#getAnswersFromForm79 * @param {Object} form Form (DOM element).80 * @return {Object} Object with the answers.81 */82 self.getAnswersFromForm = function(form) {83 if (!form || !form.elements) {84 return {};85 }86 var answers = {};87 angular.forEach(form.elements, function(element) {88 var name = element.name || '';89 // Ignore flag and submit inputs.90 if (!name || element.type == 'submit' || element.tagName == 'BUTTON') {91 return;92 }93 // Get the value.94 if (element.type == 'checkbox') {95 answers[name] = !!element.checked;96 } else if (element.type == 'radio') {97 if (element.checked) {98 answers[name] = element.value;99 }100 } else {101 answers[name] = element.value;102 }103 });104 return answers;105 };106 /**107 * Get the size that will be uploaded to perform an attempt copy.108 *109 * @module mm.addons.mod_assign110 * @ngdoc method111 * @name $mmaModAssignHelper#getSubmissionSizeForCopy112 * @param {Object} assign Assignment.113 * @param {Object} previousSubmission Submission to copy.114 * @return {Promise} Promise resolved with the size.115 */116 self.getSubmissionSizeForCopy = function(assign, previousSubmission) {117 var totalSize = 0,118 promises = [];119 angular.forEach(previousSubmission.plugins, function(plugin) {120 promises.push($q.when($mmaModAssignSubmissionDelegate.getPluginSizeForCopy(assign, plugin)).then(function(size) {121 totalSize += size;122 }));123 });124 return $q.all(promises).then(function() {125 return totalSize;126 });127 };128 /**129 * Get the size that will be uploaded to save a submission.130 *131 * @module mm.addons.mod_assign132 * @ngdoc method133 * @name $mmaModAssignHelper#getSubmissionSizeForEdit134 * @param {Object} assign Assignment.135 * @param {Object} submission Submission to check data.136 * @param {Object} inputData Data entered in the submission form.137 * @return {Promise} Promise resolved with the size.138 */139 self.getSubmissionSizeForEdit = function(assign, submission, inputData) {140 var totalSize = 0,141 promises = [];142 angular.forEach(submission.plugins, function(plugin) {143 var promise = $q.when($mmaModAssignSubmissionDelegate.getPluginSizeForEdit(assign, submission, plugin, inputData));144 promises.push(promise.then(function(size) {145 totalSize += size;146 }));147 });148 return $q.all(promises).then(function() {149 return totalSize;150 });151 };152 /**153 * Check if the submission data has changed for a certain submission and assign.154 *155 * @module mm.addons.mod_assign156 * @ngdoc method157 * @name $mmaModAssignHelper#hasSubmissionDataChanged158 * @param {Object} assign Assignment.159 * @param {Object} submission Submission to check data.160 * @param {Object} inputData Data entered in the submission form.161 * @return {Promise} Promise resolved with true if data has changed, resolved with false otherwise.162 */163 self.hasSubmissionDataChanged = function(assign, submission, inputData) {164 var hasChanged = false,165 promises = [];166 angular.forEach(submission.plugins, function(plugin) {167 promises.push($mmaModAssignSubmissionDelegate.hasPluginDataChanged(assign, submission, plugin, inputData)168 .then(function(changed) {169 if (changed) {170 hasChanged = true;171 }172 }).catch(function() {173 // Ignore errors.174 }));175 });176 return $mmUtil.allPromises(promises).then(function() {177 return hasChanged;178 });179 };180 /**181 * Prepare and return the plugin data to send for a certain submission and assign.182 *183 * @module mm.addons.mod_assign184 * @ngdoc method185 * @name $mmaModAssignHelper#prepareSubmissionPluginData186 * @param {Object} assign Assignment.187 * @param {Object} submission Submission to check data.188 * @param {Object} inputData Data entered in the submission form.189 * @return {Promise} Promise resolved with plugin data to send to server.190 */191 self.prepareSubmissionPluginData = function(assign, submission, inputData) {192 var pluginData = {},193 promises = [],194 error;195 angular.forEach(submission.plugins, function(plugin) {196 promises.push($mmaModAssignSubmissionDelegate.preparePluginSubmissionData(197 assign, submission, plugin, inputData, pluginData).catch(function(message) {198 error = message;199 return $q.reject();200 }));201 });202 return $mmUtil.allPromises(promises).then(function() {203 return pluginData;204 }).catch(function() {205 return $q.reject(error);206 });207 };208 /**209 * Upload a file to a draft area. If the file is an online file it will be downloaded and then re-uploaded.210 *211 * @module mm.addons.mod_assign212 * @ngdoc method213 * @name $mmaModAssignHelper#uploadFile214 * @param {Number} assignId Assignment ID.215 * @param {Object} file Online file or local FileEntry.216 * @param {Number} [itemId] Draft ID to use. Undefined or 0 to create a new draft ID.217 * @param {String} [siteId] Site ID. If not defined, current site.218 * @return {Promise} Promise resolved with the itemId.219 */220 self.uploadFile = function(assignId, file, itemId, siteId) {221 siteId = siteId || $mmSite.getId();222 var promise,223 fileName;224 if (file.filename) {225 // It's an online file. We need to download it and re-upload it.226 fileName = file.filename;227 promise = $mmFilepool.downloadUrl(siteId, file.fileurl, false, mmaModAssignComponent, assignId).then(function(path) {228 return $mmFS.getExternalFile(path);229 });230 } else {231 // Local file, we already have the file entry.232 fileName = file.name;233 promise = $q.when(file);234 }235 return promise.then(function(fileEntry) {236 // Now upload the file.237 return $mmFileUploader.uploadGenericFile(fileEntry.toURL(), fileName, fileEntry.type, true, 'draft', itemId, siteId)238 .then(function(result) {239 return result.itemid;240 });241 });242 };243 /**244 * Given a list of files (either online files or local files), upload them to a draft area and return the draft ID.245 * Online files will be downloaded and then re-uploaded.246 * If there are no files to upload it will return a fake draft ID (1).247 *248 * @module mm.addons.mod_assign249 * @ngdoc method250 * @name $mmaModAssignHelper#uploadFiles251 * @param {Number} assignId Assignment ID.252 * @param {Object[]} files List of files.253 * @param {String} [siteId] Site ID. If not defined, current site.254 * @return {Promise} Promise resolved with the itemId.255 */256 self.uploadFiles = function(assignId, files, siteId) {257 siteId = siteId || $mmSite.getId();258 if (!files || !files.length) {259 // Return fake draft ID.260 return $q.when(1);261 }262 // Upload only the first file first to get a draft id.263 return self.uploadFile(assignId, files[0]).then(function(itemId) {264 var promises = [],265 error;266 angular.forEach(files, function(file, index) {267 if (index === 0) {268 // First file has already been uploaded.269 return;270 }271 promises.push(self.uploadFile(assignId, file, itemId, siteId).catch(function(message) {272 error = message;273 return $q.reject();274 }));275 });276 return $q.all(promises).then(function() {277 return itemId;278 }).catch(function() {279 return $q.reject(error);280 });281 });282 };283 return self;...
strict-arguments.js
Source:strict-arguments.js
...32assertEq(arraysEqual(args(), []), true);33assertEq(arraysEqual(args(1), [1]), true);34assertEq(arraysEqual(args(1, obj), [1, obj]), true);35assertEq(arraysEqual(args("foopy"), ["foopy"]), true);36function assign(a)37{38 a = 17;39 return arguments;40}41assertEq(arraysEqual(assign(1), [17]), true);42function getLaterAssign(a)43{44 var o = arguments;45 a = 17;46 return o;47}48assertEq(arraysEqual(getLaterAssign(1), [17]), true);49function assignElementGetParameter(a)50{51 arguments[0] = 17;52 return a;53}54assertEq(assignElementGetParameter(42), 17);55function assignParameterGetElement(a)...
index.js
Source:index.js
1// (C) Copyright 2015 Martin Dougiamas2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14angular.module('mm.addons.mod_assign')15/**16 * Assign index controller.17 *18 * @module mm.addons.mod_assign19 * @ngdoc controller20 * @name mmaModAssignIndexCtrl21 */22.controller('mmaModAssignIndexCtrl', function($scope, $stateParams, $mmaModAssign, $mmUtil, $translate, mmaModAssignComponent, $q,23 $state, $ionicPlatform, mmaModAssignSubmissionInvalidatedEvent, $mmEvents, $mmSite, mmaModAssignSubmissionSavedEvent,24 mmaModAssignSubmittedForGradingEvent, $mmCourse) {25 var module = $stateParams.module || {},26 courseId = $stateParams.courseid,27 siteId = $mmSite.getId(),28 userId = $mmSite.getUserId();29 $scope.title = module.name;30 $scope.description = module.description;31 $scope.assignComponent = mmaModAssignComponent;32 $scope.moduleUrl = module.url;33 $scope.courseid = courseId;34 $scope.moduleid = module.id;35 $scope.refreshIcon = 'spinner';36 // Check if submit through app is supported.37 $mmaModAssign.isSaveAndSubmitSupported().then(function(enabled) {38 $scope.submitSupported = enabled;39 });40 $scope.gotoSubmission = function(submit, blind) {41 if ($ionicPlatform.isTablet()) {42 // Show split view on tablet.43 $state.go('site.mod_assign-submission-list', {sid: submit, courseid: courseId, moduleid: module.id,44 modulename: module.name});45 } else {46 $state.go('site.mod_assign-submission', {submitid: submit, blindid: blind, courseid: courseId, moduleid: module.id});47 }48 };49 function fetchAssignment() {50 // Get assignment data.51 return $mmaModAssign.getAssignment(courseId, module.id).then(function(assign) {52 $scope.title = assign.name || $scope.title;53 $scope.description = assign.intro ||Â $scope.description;54 $scope.assign = assign;55 $scope.haveAllParticipants = false;56 // Get assignment submissions.57 return $mmaModAssign.getSubmissions(assign.id).then(function(data) {58 var promises = [],59 time = parseInt(Date.now() / 1000);60 $scope.canviewsubmissions = data.canviewsubmissions;61 if (data.canviewsubmissions) {62 // We want to show the user data on each submission.63 var blindMarking = assign.blindmarking && !assign.revealidentities,64 participants = false;65 promises.push($mmaModAssign.getSubmissionStatus(assign.id).then(function(response) {66 $scope.summary = response.gradingsummary;67 }).catch(function() {68 // Fail silently (WS is not available, fallback).69 return $q.when();70 }));71 if (assign.duedate > 0) {72 if (assign.duedate - time <= 0) {73 $scope.timeRemaining = $translate.instant('mma.mod_assign.assignmentisdue');74 } else {75 $scope.timeRemaining = $mmUtil.formatDuration(assign.duedate - time, 3);76 if (assign.cutoffdate) {77 if (assign.cutoffdate > time) {78 $scope.lateSubmissions = $translate.instant('mma.mod_assign.latesubmissionsaccepted',79 {'$a': moment(assign.cutoffdate*1000).format($translate.instant('mm.core.dfmediumdate'))});80 } else {81 $scope.lateSubmissions = $translate.instant('mma.mod_assign.nomoresubmissionsaccepted');82 }83 }84 }85 }86 promises.push($mmaModAssign.listParticipants(assign.id).then(function(p) {87 participants = p;88 $scope.haveAllParticipants = true;89 }).catch(function() {90 // Silently fail!91 return $q.when();92 }).finally(function() {93 return $mmaModAssign.getSubmissionsUserData(data.submissions, courseId, assign.id, blindMarking,94 participants).then(function(submissions) {95 angular.forEach(submissions, function(submission) {96 submission.statusTranslated = $translate.instant('mma.mod_assign.submissionstatus_' +97 submission.status);98 submission.statusClass = $mmaModAssign.getSubmissionStatusClass(submission.status);99 });100 $scope.submissions = submissions;101 });102 }));103 return $q.all(promises);104 }105 });106 }).catch(function(message) {107 if (message) {108 $mmUtil.showErrorModal(message);109 } else {110 $mmUtil.showErrorModal('Error getting assigment data.');111 }112 return $q.reject();113 });114 }115 // Convenience function to refresh all the data.116 function refreshAllData() {117 var promises = [$mmaModAssign.invalidateAssignmentData(courseId)];118 if ($scope.assign) {119 promises.push($mmaModAssign.invalidateAllSubmissionData($scope.assign.id));120 promises.push($mmaModAssign.invalidateAssignmentUserMappingsData($scope.assign.id));121 promises.push($mmaModAssign.invalidateListParticipantsData($scope.assign.id));122 }123 return $q.all(promises).finally(function() {124 $scope.$broadcast(mmaModAssignSubmissionInvalidatedEvent);125 return fetchAssignment();126 });127 }128 fetchAssignment().then(function() {129 if (!$scope.canviewsubmissions) {130 $mmaModAssign.logSubmissionView($scope.assign.id).catch(function() {131 // Fail silently for Moodle < 3.1.132 });133 } else {134 $mmaModAssign.logGradingView($scope.assign.id).catch(function() {135 // Fail silently for Moodle < 3.0.136 });137 }138 }).finally(function() {139 $scope.assignmentLoaded = true;140 $scope.refreshIcon = 'ion-refresh';141 });142 // Context Menu Description action.143 $scope.expandDescription = function() {144 if ($scope.assign.id && ($scope.description || $scope.assign.introattachments)) {145 // Open a new state with the interpolated contents.146 $state.go('site.mod_assign-description', {147 assignid: $scope.assign.id,148 description: $scope.description,149 files: $scope.assign.introattachments150 });151 }152 };153 $scope.refreshAssignment = function() {154 if ($scope.assignmentLoaded) {155 $scope.refreshIcon = 'spinner';156 refreshAllData().finally(function() {157 $scope.refreshIcon = 'ion-refresh';158 $scope.$broadcast('scroll.refreshComplete');159 });160 }161 };162 // Listen for submission saved event to refresh data.163 var obsSaved = $mmEvents.on(mmaModAssignSubmissionSavedEvent, function(data) {164 if ($scope.assign && data.assignmentId == $scope.assign.id && data.siteId == siteId && data.userId == userId) {165 // Assignment submission saved, refresh data.166 $scope.refreshIcon = 'spinner';167 $scope.assignmentLoaded = false;168 refreshAllData().finally(function() {169 $scope.refreshIcon = 'ion-refresh';170 $scope.assignmentLoaded = true;171 });172 }173 });174 // Listen for submitted for grading event to refresh data.175 var obsSubmitted = $mmEvents.on(mmaModAssignSubmittedForGradingEvent, function(data) {176 if ($scope.assign && data.assignmentId == $scope.assign.id && data.siteId == siteId && data.userId == userId) {177 // Assignment submitted, check completion.178 $mmCourse.checkModuleCompletion(courseId, module.completionstatus);179 }180 });181 $scope.$on('$destroy', function() {182 if (obsSaved && obsSaved.off) {183 obsSaved.off();184 }185 if (obsSubmitted && obsSubmitted.off) {186 obsSubmitted.off();187 }188 });...
submissionlist.js
Source:submissionlist.js
1// (C) Copyright 2015 Martin Dougiamas2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14angular.module('mm.addons.mod_assign')15/**16 * Assign submission list controller.17 *18 * @module mm.addons.mod_assign19 * @ngdoc controller20 * @name mmaModAssignSubmissionListCtrl21 */22.controller('mmaModAssignSubmissionListCtrl', function($scope, $stateParams, $mmaModAssign, $mmUtil, $translate, $q,23 mmaModAssignComponent, mmaModAssignSubmissionInvalidatedEvent) {24 var courseId = $stateParams.courseid;25 $scope.title = $stateParams.modulename;26 $scope.assignComponent = mmaModAssignComponent;27 $scope.courseId = courseId;28 $scope.moduleId = $stateParams.moduleid;29 function fetchAssignment() {30 // Get assignment data.31 return $mmaModAssign.getAssignment(courseId, $scope.moduleId).then(function(assign) {32 $scope.title = assign.name || $scope.title;33 $scope.assign = assign;34 $scope.haveAllParticipants = true;35 // Get assignment submissions.36 return $mmaModAssign.getSubmissions(assign.id).then(function(data) {37 var participants = false,38 blindMarking = assign.blindmarking && !assign.revealidentities;39 if (!data.canviewsubmissions) {40 // You should not be here.41 return $q.reject();42 }43 // We want to show the user data on each submission.44 return $mmaModAssign.listParticipants(assign.id).then(function(p) {45 participants = p;46 $scope.haveAllParticipants = true;47 }).catch(function() {48 $scope.haveAllParticipants = false;49 return $q.when();50 }).finally(function() {51 return $mmaModAssign.getSubmissionsUserData(data.submissions, courseId, assign.id, blindMarking, participants)52 .then(function(submissions) {53 angular.forEach(submissions, function(submission, index) {54 submission.statusTranslated = $translate.instant('mma.mod_assign.submissionstatus_' +55 submission.status);56 submission.statusClass = $mmaModAssign.getSubmissionStatusClass(submission.status);57 if ($stateParams.sid == submission.submitid) {58 $scope.submissionToLoad = index + 1;59 }60 });61 $scope.submissions = submissions;62 });63 });64 });65 }).catch(function(message) {66 if (message) {67 $mmUtil.showErrorModal(message);68 } else {69 $mmUtil.showErrorModal('Error getting assigment data.');70 }71 return $q.reject();72 });73 }74 // Convenience function to refresh all the data.75 function refreshAllData() {76 var promises = [$mmaModAssign.invalidateAssignmentData(courseId)];77 if ($scope.assign) {78 promises.push($mmaModAssign.invalidateAllSubmissionData($scope.assign.id));79 promises.push($mmaModAssign.invalidateAssignmentUserMappingsData($scope.assign.id));80 promises.push($mmaModAssign.invalidateListParticipantsData($scope.assign.id));81 }82 return $q.all(promises).finally(function() {83 $scope.$broadcast(mmaModAssignSubmissionInvalidatedEvent);84 return fetchAssignment();85 });86 }87 fetchAssignment().finally(function() {88 $scope.assignmentLoaded = true;89 });90 // Pull to refresh.91 $scope.refreshSubmissionList = function() {92 refreshAllData().finally(function() {93 $scope.$broadcast('scroll.refreshComplete');94 });95 };...
main.js
Source:main.js
1// (C) Copyright 2015 Martin Dougiamas2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14angular.module('mm.addons.mod_assign', ['mm.core'])15.constant('mmaModAssignComponent', 'mmaModAssign')16.constant('mmaModAssignSubmissionComponent', 'mmaModAssignSubmission')17.constant('mmaModAssignSubmissionStatusNew', 'new')18.constant('mmaModAssignSubmissionStatusReopened', 'reopened')19.constant('mmaModAssignSubmissionStatusDraft', 'draft')20.constant('mmaModAssignSubmissionStatusSubmitted', 'submitted')21.constant('mmaModAssignAttemptReopenMethodNone', 'none')22.constant('mmaModAssignUnlimitedAttempts', -1)23.constant('mmaModAssignGradingStatusGraded', 'graded')24.constant('mmaModAssignGradingStatusNotGraded', 'notgraded')25.constant('mmaModMarkingWorkflowStateReleased', 'released')26.constant('mmaModAssignSubmissionInvalidatedEvent', 'mma_mod_assign_submission_invalidated')27.constant('mmaModAssignSubmissionSavedEvent', 'mma_mod_assign_submission_saved')28.constant('mmaModAssignSubmittedForGradingEvent', 'mma_mod_assign_submitted_for_grading')29.config(function($stateProvider) {30 $stateProvider31 .state('site.mod_assign', {32 url: '/mod_assign',33 params: {34 module: null,35 courseid: null36 },37 views: {38 'site': {39 controller: 'mmaModAssignIndexCtrl',40 templateUrl: 'addons/mod/assign/templates/index.html'41 }42 }43 })44 .state('site.mod_assign-description', {45 url: '/mod_assign-description',46 params: {47 assignid: null,48 description: null,49 files: null50 },51 views: {52 'site': {53 controller: 'mmaModAssignDescriptionCtrl',54 templateUrl: 'addons/mod/assign/templates/description.html'55 }56 }57 })58 .state('site.mod_assign-submission-list', {59 url: '/mod_assign-submission-list',60 params: {61 moduleid: null,62 modulename: null,63 sid: null,64 courseid: null65 },66 views: {67 'site': {68 controller: 'mmaModAssignSubmissionListCtrl',69 templateUrl: 'addons/mod/assign/templates/submissionlist.html'70 }71 }72 })73 .state('site.mod_assign-submission', {74 url: '/mod_assign-submission',75 params: {76 submitid: null,77 blindid: null,78 moduleid: null,79 courseid: null80 },81 views: {82 'site': {83 controller: 'mmaModAssignSubmissionReviewCtrl',84 templateUrl: 'addons/mod/assign/templates/submissionreview.html'85 }86 }87 })88 .state('site.mod_assign-submission-edit', {89 url: '/mod_assign-submission-edit',90 params: {91 moduleid: null,92 courseid: null,93 userid: null,94 blindid: null95 },96 views: {97 'site': {98 controller: 'mmaModAssignEditCtrl',99 templateUrl: 'addons/mod/assign/templates/edit.html'100 }101 }102 });103})104.config(function($mmCourseDelegateProvider, $mmContentLinksDelegateProvider, $mmCoursePrefetchDelegateProvider) {105 $mmCourseDelegateProvider.registerContentHandler('mmaModAssign', 'assign', '$mmaModAssignHandlers.courseContent');106 $mmContentLinksDelegateProvider.registerLinkHandler('mmaModAssign', '$mmaModAssignHandlers.linksHandler');107 $mmCoursePrefetchDelegateProvider.registerPrefetchHandler('mmaModAssign', 'assign', '$mmaModAssignPrefetchHandler');...
Using AI Code Generation
1var obj1 = {a:1, b:2, c:3};2var obj2 = {d:4, e:5, f:6};3var obj3 = {g:7, h:8, i:9};4Object.assign(obj1, obj2, obj3);5console.log(obj1);6var obj1 = {a:1, b:2, c:3};7var obj2 = {d:4, e:5, f:6};8var obj3 = {g:7, h:8, i:9};9Object.assign(obj1, obj2, obj3);10console.log(obj1);11var obj1 = {a:1, b:2, c:3};12var obj2 = {d:4, e:5, f:6};13var obj3 = {g:7, h:8, i:9};14Object.assign(obj1, obj2, obj3);15console.log(obj1);16var obj1 = {a:1, b:2, c:3};17var obj2 = {d:4, e:5, f:6};18var obj3 = {g:7, h:8, i:9};19Object.assign(obj1, obj2, obj3);20console.log(obj1);21var obj1 = {a:1, b:2, c:3};22var obj2 = {d:4, e:5, f:6};23var obj3 = {g:7, h:8, i:9};24Object.assign(obj1, obj2, obj3);25console.log(obj1);26var obj1 = {a:1, b:2, c:3};27var obj2 = {d:4, e:5, f:6};28var obj3 = {g:7, h:8, i:9};29Object.assign(obj1, obj2, obj3);30console.log(obj1);31var obj1 = {a:1, b:2, c:3};32var obj2 = {d:4, e:5, f:6};33var obj3 = {g:
Using AI Code Generation
1var obj = Object.assign({a: 1}, {b: 2}, {c: 3});2var obj1 = {a: 1};3var obj2 = {b: 2};4var obj3 = {c: 3};5var obj = Object.assign(obj1, obj2, obj3);6var obj1 = {a: 1};7var obj2 = {b: 2};8var obj3 = {c: 3};9var obj = Object.assign(obj1, obj2, obj3);10var obj1 = {a: 1};11var obj2 = {b: 2};12var obj3 = {c: 3};13var obj = Object.assign(obj1, obj2, obj3);14var obj1 = {a: 1};15var obj2 = {b: 2};16var obj3 = {c: 3};17var obj = Object.assign(obj1, obj2, obj3);18var obj1 = {a: 1};19var obj2 = {b: 2};20var obj3 = {c: 3};21var obj = Object.assign(obj1, obj2, obj3);22var obj1 = {a: 1};23var obj2 = {b: 2};24var obj3 = {c: 3};25var obj = Object.assign(obj1, obj2, obj3);
Using AI Code Generation
1var obj1 = { a: 1 };2var obj2 = { b: 2 };3Object.assign(obj1, obj2);4var obj1 = { a: 1 };5var obj2 = { b: 2 };6Object.assign(obj1, obj2);7var obj1 = { a: 1 };8var obj2 = { b: 2 };9Object.assign(obj1, obj2);10var obj1 = { a: 1 };11var obj2 = { b: 2 };12Object.assign(obj1, obj2);13var obj1 = { a: 1 };14var obj2 = { b: 2 };15Object.assign(obj1, obj2);16var obj1 = { a: 1 };17var obj2 = { b: 2 };18Object.assign(obj1, obj2);19var obj1 = { a: 1 };20var obj2 = { b: 2 };21Object.assign(obj1, obj2);22var obj1 = { a: 1 };23var obj2 = { b: 2 };24Object.assign(obj1, obj2);25var obj1 = { a: 1 };26var obj2 = { b: 2 };27Object.assign(obj1, obj2);
Using AI Code Generation
1var obj = Object.assign({a: 0}, {b: 1}, {c: 2});2var obj1 = {a: 0};3var obj2 = {b: 1};4var obj3 = {c: 2};5var obj = Object.assign(obj1, obj2, obj3);6var obj1 = {a: 0};7var obj2 = {b: 1};8var obj3 = {c: 2};9var obj = Object.assign(obj1, obj2, obj3);10var obj1 = {a: 0};11var obj2 = {b: 1};12var obj3 = {c: 2};13var obj = Object.assign(obj1, obj2, obj3);14var obj1 = {a: 0};15var obj2 = {b: 1};16var obj3 = {c: 2};17var obj = Object.assign(obj1, obj2, obj3);18var obj1 = {a: 0};19var obj2 = {b: 1};20var obj3 = {c: 2};21var obj = Object.assign(obj1, obj2, obj3);22var obj1 = {a: 0};23var obj2 = {b: 1};24var obj3 = {c: 2};25var obj = Object.assign(obj1, obj2, obj3);
Using AI Code Generation
1var obj1 = {a: 1, b: 2};2var obj2 = {a: 3, b: 4};3Object.assign(obj1, obj2);4console.log(obj1);5console.log(obj2);6var obj3 = {a: 1, b: 2};7var obj4 = {a: 3, b: 4};8Object.assign(obj3, obj4);
Using AI Code Generation
1var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});2var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});3var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});4var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});5var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});6var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});7var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});8var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});9var obj = Object.assign({}, {a: 1}, {b: 2}, {c: 3});
Using AI Code Generation
1var obj = Object.assign({a: 1}, {b: 2}, {c: 3});2console.log(obj);3{ a: 1, b: 2, c: 3 }4Object.assign(target, ...sources)5var obj = Object.assign({a: 1}, {b: 2}, {a: 4});6console.log(obj);7{ a: 4, b: 2 }8var obj = Object.assign({a: 1}, {b: 2}, {a: 4}, {c: 3});9console.log(obj);10{ a: 4, b: 2, c: 3 }11var obj = Object.assign({a: 1}, {b: 2}, {a: 4}, {c: 3}, {c: 5});12console.log(obj);13{ a: 4, b: 2, c: 5 }14var obj = Object.assign({a: 1}, {b: 2}, {a: 4}, {c:
Using AI Code Generation
1var root = require('root'); 2var object1 = {a:1, b:2};3var object2 = {c:3, d:4};4var object3 = {e:5, f:6};5var object4 = {g:7, h:8};6var object5 = {i:9, j:10};7root.assign(object1, object2, object3, object4, object5);8var root = require('root'); 9var object1 = {a:1, b:2};10var object2 = {c:3, d:4};11var object3 = {e:5, f:6};12var object4 = {g:7, h:8};13var object5 = {i:9, j:10};14root.assign(object1, object2, object3, object4, object5);15var root = require('root'); 16var object1 = {a:1, b:2};17var object2 = {c:3, d:4};18var object3 = {e:5, f:6};19var object4 = {g:7, h:8};20var object5 = {i:9, j:10};21root.assign(object1, object2, object3, object4, object5);22var root = require('root');
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!