| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 |   | 
        
           |  |  | 3 | // This file is part of Moodle - http://moodle.org/
 | 
        
           |  |  | 4 | //
 | 
        
           |  |  | 5 | // Moodle is free software: you can redistribute it and/or modify
 | 
        
           |  |  | 6 | // it under the terms of the GNU General Public License as published by
 | 
        
           |  |  | 7 | // the Free Software Foundation, either version 3 of the License, or
 | 
        
           |  |  | 8 | // (at your option) any later version.
 | 
        
           |  |  | 9 | //
 | 
        
           |  |  | 10 | // Moodle is distributed in the hope that it will be useful,
 | 
        
           |  |  | 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
        
           |  |  | 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
        
           |  |  | 13 | // GNU General Public License for more details.
 | 
        
           |  |  | 14 | //
 | 
        
           |  |  | 15 | // You should have received a copy of the GNU General Public License
 | 
        
           |  |  | 16 | // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 | 
        
           |  |  | 17 |   | 
        
           |  |  | 18 | /**
 | 
        
           |  |  | 19 |  * Library of workshop module functions needed by Moodle core and other subsystems
 | 
        
           |  |  | 20 |  *
 | 
        
           |  |  | 21 |  * All the functions neeeded by Moodle core, gradebook, file subsystem etc
 | 
        
           |  |  | 22 |  * are placed here.
 | 
        
           |  |  | 23 |  *
 | 
        
           |  |  | 24 |  * @package    mod_workshop
 | 
        
           |  |  | 25 |  * @copyright  2009 David Mudrak <david.mudrak@gmail.com>
 | 
        
           |  |  | 26 |  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 27 |  */
 | 
        
           |  |  | 28 |   | 
        
           |  |  | 29 | defined('MOODLE_INTERNAL') || die();
 | 
        
           |  |  | 30 |   | 
        
           |  |  | 31 | require_once($CFG->dirroot . '/calendar/lib.php');
 | 
        
           |  |  | 32 |   | 
        
           |  |  | 33 | define('WORKSHOP_EVENT_TYPE_SUBMISSION_OPEN',   'opensubmission');
 | 
        
           |  |  | 34 | define('WORKSHOP_EVENT_TYPE_SUBMISSION_CLOSE',  'closesubmission');
 | 
        
           |  |  | 35 | define('WORKSHOP_EVENT_TYPE_ASSESSMENT_OPEN',   'openassessment');
 | 
        
           |  |  | 36 | define('WORKSHOP_EVENT_TYPE_ASSESSMENT_CLOSE',  'closeassessment');
 | 
        
           |  |  | 37 | define('WORKSHOP_SUBMISSION_TYPE_DISABLED', 0);
 | 
        
           |  |  | 38 | define('WORKSHOP_SUBMISSION_TYPE_AVAILABLE', 1);
 | 
        
           |  |  | 39 | define('WORKSHOP_SUBMISSION_TYPE_REQUIRED', 2);
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 42 | // Moodle core API                                                            //
 | 
        
           |  |  | 43 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 44 |   | 
        
           |  |  | 45 | /**
 | 
        
           |  |  | 46 |  * Returns the information if the module supports a feature
 | 
        
           |  |  | 47 |  *
 | 
        
           |  |  | 48 |  * @see plugin_supports() in lib/moodlelib.php
 | 
        
           |  |  | 49 |  * @param string $feature FEATURE_xx constant for requested feature
 | 
        
           |  |  | 50 |  * @return mixed True if module supports feature, false if not, null if doesn't know or string for the module purpose.
 | 
        
           |  |  | 51 |  */
 | 
        
           |  |  | 52 | function workshop_supports($feature) {
 | 
        
           |  |  | 53 |     switch($feature) {
 | 
        
           |  |  | 54 |         case FEATURE_GRADE_HAS_GRADE:   return true;
 | 
        
           |  |  | 55 |         case FEATURE_GROUPS:            return true;
 | 
        
           |  |  | 56 |         case FEATURE_GROUPINGS:         return true;
 | 
        
           |  |  | 57 |         case FEATURE_MOD_INTRO:         return true;
 | 
        
           |  |  | 58 |         case FEATURE_BACKUP_MOODLE2:    return true;
 | 
        
           |  |  | 59 |         case FEATURE_COMPLETION_TRACKS_VIEWS:
 | 
        
           |  |  | 60 |             return true;
 | 
        
           |  |  | 61 |         case FEATURE_SHOW_DESCRIPTION:  return true;
 | 
        
           |  |  | 62 |         case FEATURE_PLAGIARISM:        return true;
 | 
        
           |  |  | 63 |         case FEATURE_MOD_PURPOSE:       return MOD_PURPOSE_ASSESSMENT;
 | 
        
           |  |  | 64 |         default:                        return null;
 | 
        
           |  |  | 65 |     }
 | 
        
           |  |  | 66 | }
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 | /**
 | 
        
           |  |  | 69 |  * Saves a new instance of the workshop into the database
 | 
        
           |  |  | 70 |  *
 | 
        
           |  |  | 71 |  * Given an object containing all the necessary data,
 | 
        
           |  |  | 72 |  * (defined by the form in mod_form.php) this function
 | 
        
           |  |  | 73 |  * will save a new instance and return the id number
 | 
        
           |  |  | 74 |  * of the new instance.
 | 
        
           |  |  | 75 |  *
 | 
        
           |  |  | 76 |  * @param stdClass $workshop An object from the form in mod_form.php
 | 
        
           |  |  | 77 |  * @return int The id of the newly inserted workshop record
 | 
        
           |  |  | 78 |  */
 | 
        
           |  |  | 79 | function workshop_add_instance(stdclass $workshop) {
 | 
        
           |  |  | 80 |     global $CFG, $DB;
 | 
        
           |  |  | 81 |     require_once(__DIR__ . '/locallib.php');
 | 
        
           |  |  | 82 |   | 
        
           |  |  | 83 |     $workshop->phase                 = workshop::PHASE_SETUP;
 | 
        
           |  |  | 84 |     $workshop->timecreated           = time();
 | 
        
           |  |  | 85 |     $workshop->timemodified          = $workshop->timecreated;
 | 
        
           |  |  | 86 |     $workshop->useexamples           = (int)!empty($workshop->useexamples);
 | 
        
           |  |  | 87 |     $workshop->usepeerassessment     = 1;
 | 
        
           |  |  | 88 |     $workshop->useselfassessment     = (int)!empty($workshop->useselfassessment);
 | 
        
           |  |  | 89 |     $workshop->latesubmissions       = (int)!empty($workshop->latesubmissions);
 | 
        
           |  |  | 90 |     $workshop->phaseswitchassessment = (int)!empty($workshop->phaseswitchassessment);
 | 
        
           |  |  | 91 |     $workshop->evaluation            = 'best';
 | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 |     if (isset($workshop->gradinggradepass)) {
 | 
        
           |  |  | 94 |         $workshop->gradinggradepass = (float)unformat_float($workshop->gradinggradepass);
 | 
        
           |  |  | 95 |     }
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 |     if (isset($workshop->submissiongradepass)) {
 | 
        
           |  |  | 98 |         $workshop->submissiongradepass = (float)unformat_float($workshop->submissiongradepass);
 | 
        
           |  |  | 99 |     }
 | 
        
           |  |  | 100 |   | 
        
           |  |  | 101 |     if (isset($workshop->submissionfiletypes)) {
 | 
        
           |  |  | 102 |         $filetypesutil = new \core_form\filetypes_util();
 | 
        
           |  |  | 103 |         $submissionfiletypes = $filetypesutil->normalize_file_types($workshop->submissionfiletypes);
 | 
        
           |  |  | 104 |         $workshop->submissionfiletypes = implode(' ', $submissionfiletypes);
 | 
        
           |  |  | 105 |     }
 | 
        
           |  |  | 106 |   | 
        
           |  |  | 107 |     if (isset($workshop->overallfeedbackfiletypes)) {
 | 
        
           |  |  | 108 |         $filetypesutil = new \core_form\filetypes_util();
 | 
        
           |  |  | 109 |         $overallfeedbackfiletypes = $filetypesutil->normalize_file_types($workshop->overallfeedbackfiletypes);
 | 
        
           |  |  | 110 |         $workshop->overallfeedbackfiletypes = implode(' ', $overallfeedbackfiletypes);
 | 
        
           |  |  | 111 |     }
 | 
        
           |  |  | 112 |   | 
        
           |  |  | 113 |     // insert the new record so we get the id
 | 
        
           |  |  | 114 |     $workshop->id = $DB->insert_record('workshop', $workshop);
 | 
        
           |  |  | 115 |   | 
        
           |  |  | 116 |     // we need to use context now, so we need to make sure all needed info is already in db
 | 
        
           |  |  | 117 |     $cmid = $workshop->coursemodule;
 | 
        
           |  |  | 118 |     $DB->set_field('course_modules', 'instance', $workshop->id, array('id' => $cmid));
 | 
        
           |  |  | 119 |     $context = context_module::instance($cmid);
 | 
        
           |  |  | 120 |   | 
        
           |  |  | 121 |     // process the custom wysiwyg editors
 | 
        
           |  |  | 122 |     if ($draftitemid = $workshop->instructauthorseditor['itemid']) {
 | 
        
           |  |  | 123 |         $workshop->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'instructauthors',
 | 
        
           |  |  | 124 |                 0, workshop::instruction_editors_options($context), $workshop->instructauthorseditor['text']);
 | 
        
           |  |  | 125 |         $workshop->instructauthorsformat = $workshop->instructauthorseditor['format'];
 | 
        
           |  |  | 126 |     }
 | 
        
           |  |  | 127 |   | 
        
           |  |  | 128 |     if ($draftitemid = $workshop->instructreviewerseditor['itemid']) {
 | 
        
           |  |  | 129 |         $workshop->instructreviewers = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'instructreviewers',
 | 
        
           |  |  | 130 |                 0, workshop::instruction_editors_options($context), $workshop->instructreviewerseditor['text']);
 | 
        
           |  |  | 131 |         $workshop->instructreviewersformat = $workshop->instructreviewerseditor['format'];
 | 
        
           |  |  | 132 |     }
 | 
        
           |  |  | 133 |   | 
        
           |  |  | 134 |     if ($draftitemid = $workshop->conclusioneditor['itemid']) {
 | 
        
           |  |  | 135 |         $workshop->conclusion = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'conclusion',
 | 
        
           |  |  | 136 |                 0, workshop::instruction_editors_options($context), $workshop->conclusioneditor['text']);
 | 
        
           |  |  | 137 |         $workshop->conclusionformat = $workshop->conclusioneditor['format'];
 | 
        
           |  |  | 138 |     }
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 |     // re-save the record with the replaced URLs in editor fields
 | 
        
           |  |  | 141 |     $DB->update_record('workshop', $workshop);
 | 
        
           |  |  | 142 |   | 
        
           |  |  | 143 |     // create gradebook items
 | 
        
           |  |  | 144 |     workshop_grade_item_update($workshop);
 | 
        
           |  |  | 145 |     workshop_grade_item_category_update($workshop);
 | 
        
           |  |  | 146 |   | 
        
           |  |  | 147 |     // create calendar events
 | 
        
           |  |  | 148 |     workshop_calendar_update($workshop, $workshop->coursemodule);
 | 
        
           |  |  | 149 |     if (!empty($workshop->completionexpected)) {
 | 
        
           |  |  | 150 |         \core_completion\api::update_completion_date_event($cmid, 'workshop', $workshop->id, $workshop->completionexpected);
 | 
        
           |  |  | 151 |     }
 | 
        
           |  |  | 152 |   | 
        
           |  |  | 153 |     return $workshop->id;
 | 
        
           |  |  | 154 | }
 | 
        
           |  |  | 155 |   | 
        
           |  |  | 156 | /**
 | 
        
           |  |  | 157 |  * Given an object containing all the necessary data,
 | 
        
           |  |  | 158 |  * (defined by the form in mod_form.php) this function
 | 
        
           |  |  | 159 |  * will update an existing instance with new data.
 | 
        
           |  |  | 160 |  *
 | 
        
           |  |  | 161 |  * @param stdClass $workshop An object from the form in mod_form.php
 | 
        
           |  |  | 162 |  * @return bool success
 | 
        
           |  |  | 163 |  */
 | 
        
           |  |  | 164 | function workshop_update_instance(stdclass $workshop) {
 | 
        
           |  |  | 165 |     global $CFG, $DB;
 | 
        
           |  |  | 166 |     require_once(__DIR__ . '/locallib.php');
 | 
        
           |  |  | 167 |   | 
        
           |  |  | 168 |     $workshop->timemodified          = time();
 | 
        
           |  |  | 169 |     $workshop->id                    = $workshop->instance;
 | 
        
           |  |  | 170 |     $workshop->useexamples           = (int)!empty($workshop->useexamples);
 | 
        
           |  |  | 171 |     $workshop->usepeerassessment     = 1;
 | 
        
           |  |  | 172 |     $workshop->useselfassessment     = (int)!empty($workshop->useselfassessment);
 | 
        
           |  |  | 173 |     $workshop->latesubmissions       = (int)!empty($workshop->latesubmissions);
 | 
        
           |  |  | 174 |     $workshop->phaseswitchassessment = (int)!empty($workshop->phaseswitchassessment);
 | 
        
           |  |  | 175 |   | 
        
           |  |  | 176 |     if (isset($workshop->gradinggradepass)) {
 | 
        
           |  |  | 177 |         $workshop->gradinggradepass = (float)unformat_float($workshop->gradinggradepass);
 | 
        
           |  |  | 178 |     }
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 |     if (isset($workshop->submissiongradepass)) {
 | 
        
           |  |  | 181 |         $workshop->submissiongradepass = (float)unformat_float($workshop->submissiongradepass);
 | 
        
           |  |  | 182 |     }
 | 
        
           |  |  | 183 |   | 
        
           |  |  | 184 |     if (isset($workshop->submissionfiletypes)) {
 | 
        
           |  |  | 185 |         $filetypesutil = new \core_form\filetypes_util();
 | 
        
           |  |  | 186 |         $submissionfiletypes = $filetypesutil->normalize_file_types($workshop->submissionfiletypes);
 | 
        
           |  |  | 187 |         $workshop->submissionfiletypes = implode(' ', $submissionfiletypes);
 | 
        
           |  |  | 188 |     }
 | 
        
           |  |  | 189 |   | 
        
           |  |  | 190 |     if (isset($workshop->overallfeedbackfiletypes)) {
 | 
        
           |  |  | 191 |         $filetypesutil = new \core_form\filetypes_util();
 | 
        
           |  |  | 192 |         $overallfeedbackfiletypes = $filetypesutil->normalize_file_types($workshop->overallfeedbackfiletypes);
 | 
        
           |  |  | 193 |         $workshop->overallfeedbackfiletypes = implode(' ', $overallfeedbackfiletypes);
 | 
        
           |  |  | 194 |     }
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 |     // todo - if the grading strategy is being changed, we may want to replace all aggregated peer grades with nulls
 | 
        
           |  |  | 197 |   | 
        
           |  |  | 198 |     $DB->update_record('workshop', $workshop);
 | 
        
           |  |  | 199 |     $context = context_module::instance($workshop->coursemodule);
 | 
        
           |  |  | 200 |   | 
        
           |  |  | 201 |     // process the custom wysiwyg editors
 | 
        
           |  |  | 202 |     if ($draftitemid = $workshop->instructauthorseditor['itemid']) {
 | 
        
           |  |  | 203 |         $workshop->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'instructauthors',
 | 
        
           |  |  | 204 |                 0, workshop::instruction_editors_options($context), $workshop->instructauthorseditor['text']);
 | 
        
           |  |  | 205 |         $workshop->instructauthorsformat = $workshop->instructauthorseditor['format'];
 | 
        
           |  |  | 206 |     }
 | 
        
           |  |  | 207 |   | 
        
           |  |  | 208 |     if ($draftitemid = $workshop->instructreviewerseditor['itemid']) {
 | 
        
           |  |  | 209 |         $workshop->instructreviewers = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'instructreviewers',
 | 
        
           |  |  | 210 |                 0, workshop::instruction_editors_options($context), $workshop->instructreviewerseditor['text']);
 | 
        
           |  |  | 211 |         $workshop->instructreviewersformat = $workshop->instructreviewerseditor['format'];
 | 
        
           |  |  | 212 |     }
 | 
        
           |  |  | 213 |   | 
        
           |  |  | 214 |     if ($draftitemid = $workshop->conclusioneditor['itemid']) {
 | 
        
           |  |  | 215 |         $workshop->conclusion = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'conclusion',
 | 
        
           |  |  | 216 |                 0, workshop::instruction_editors_options($context), $workshop->conclusioneditor['text']);
 | 
        
           |  |  | 217 |         $workshop->conclusionformat = $workshop->conclusioneditor['format'];
 | 
        
           |  |  | 218 |     }
 | 
        
           |  |  | 219 |   | 
        
           |  |  | 220 |     // re-save the record with the replaced URLs in editor fields
 | 
        
           |  |  | 221 |     $DB->update_record('workshop', $workshop);
 | 
        
           |  |  | 222 |   | 
        
           |  |  | 223 |     // update gradebook items
 | 
        
           |  |  | 224 |     workshop_grade_item_update($workshop);
 | 
        
           |  |  | 225 |     workshop_grade_item_category_update($workshop);
 | 
        
           |  |  | 226 |   | 
        
           |  |  | 227 |     // update calendar events
 | 
        
           |  |  | 228 |     workshop_calendar_update($workshop, $workshop->coursemodule);
 | 
        
           |  |  | 229 |     $completionexpected = (!empty($workshop->completionexpected)) ? $workshop->completionexpected : null;
 | 
        
           |  |  | 230 |     \core_completion\api::update_completion_date_event($workshop->coursemodule, 'workshop', $workshop->id, $completionexpected);
 | 
        
           |  |  | 231 |   | 
        
           |  |  | 232 |     return true;
 | 
        
           |  |  | 233 | }
 | 
        
           |  |  | 234 |   | 
        
           |  |  | 235 | /**
 | 
        
           |  |  | 236 |  * Given an ID of an instance of this module,
 | 
        
           |  |  | 237 |  * this function will permanently delete the instance
 | 
        
           |  |  | 238 |  * and any data that depends on it.
 | 
        
           |  |  | 239 |  *
 | 
        
           |  |  | 240 |  * @param int $id Id of the module instance
 | 
        
           |  |  | 241 |  * @return boolean Success/Failure
 | 
        
           |  |  | 242 |  */
 | 
        
           |  |  | 243 | function workshop_delete_instance($id) {
 | 
        
           |  |  | 244 |     global $CFG, $DB;
 | 
        
           |  |  | 245 |     require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 246 |   | 
        
           |  |  | 247 |     if (! $workshop = $DB->get_record('workshop', array('id' => $id))) {
 | 
        
           |  |  | 248 |         return false;
 | 
        
           |  |  | 249 |     }
 | 
        
           |  |  | 250 |   | 
        
           |  |  | 251 |     // delete all associated aggregations
 | 
        
           |  |  | 252 |     $DB->delete_records('workshop_aggregations', array('workshopid' => $workshop->id));
 | 
        
           |  |  | 253 |   | 
        
           |  |  | 254 |     // get the list of ids of all submissions
 | 
        
           |  |  | 255 |     $submissions = $DB->get_records('workshop_submissions', array('workshopid' => $workshop->id), '', 'id');
 | 
        
           |  |  | 256 |   | 
        
           |  |  | 257 |     // get the list of all allocated assessments
 | 
        
           |  |  | 258 |     $assessments = $DB->get_records_list('workshop_assessments', 'submissionid', array_keys($submissions), '', 'id');
 | 
        
           |  |  | 259 |   | 
        
           |  |  | 260 |     // delete the associated records from the workshop core tables
 | 
        
           |  |  | 261 |     $DB->delete_records_list('workshop_grades', 'assessmentid', array_keys($assessments));
 | 
        
           |  |  | 262 |     $DB->delete_records_list('workshop_assessments', 'id', array_keys($assessments));
 | 
        
           |  |  | 263 |     $DB->delete_records_list('workshop_submissions', 'id', array_keys($submissions));
 | 
        
           |  |  | 264 |   | 
        
           |  |  | 265 |     // call the static clean-up methods of all available subplugins
 | 
        
           |  |  | 266 |     $strategies = core_component::get_plugin_list('workshopform');
 | 
        
           |  |  | 267 |     foreach ($strategies as $strategy => $path) {
 | 
        
           |  |  | 268 |         require_once($path.'/lib.php');
 | 
        
           |  |  | 269 |         $classname = 'workshop_'.$strategy.'_strategy';
 | 
        
           |  |  | 270 |         call_user_func($classname.'::delete_instance', $workshop->id);
 | 
        
           |  |  | 271 |     }
 | 
        
           |  |  | 272 |   | 
        
           |  |  | 273 |     $allocators = core_component::get_plugin_list('workshopallocation');
 | 
        
           |  |  | 274 |     foreach ($allocators as $allocator => $path) {
 | 
        
           |  |  | 275 |         require_once($path.'/lib.php');
 | 
        
           |  |  | 276 |         $classname = 'workshop_'.$allocator.'_allocator';
 | 
        
           |  |  | 277 |         call_user_func($classname.'::delete_instance', $workshop->id);
 | 
        
           |  |  | 278 |     }
 | 
        
           |  |  | 279 |   | 
        
           |  |  | 280 |     $evaluators = core_component::get_plugin_list('workshopeval');
 | 
        
           |  |  | 281 |     foreach ($evaluators as $evaluator => $path) {
 | 
        
           |  |  | 282 |         require_once($path.'/lib.php');
 | 
        
           |  |  | 283 |         $classname = 'workshop_'.$evaluator.'_evaluation';
 | 
        
           |  |  | 284 |         call_user_func($classname.'::delete_instance', $workshop->id);
 | 
        
           |  |  | 285 |     }
 | 
        
           |  |  | 286 |   | 
        
           |  |  | 287 |     // delete the calendar events
 | 
        
           |  |  | 288 |     $events = $DB->get_records('event', array('modulename' => 'workshop', 'instance' => $workshop->id));
 | 
        
           |  |  | 289 |     foreach ($events as $event) {
 | 
        
           |  |  | 290 |         $event = calendar_event::load($event);
 | 
        
           |  |  | 291 |         $event->delete();
 | 
        
           |  |  | 292 |     }
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 |     // gradebook cleanup
 | 
        
           |  |  | 295 |     grade_update('mod/workshop', $workshop->course, 'mod', 'workshop', $workshop->id, 0, null, array('deleted' => true));
 | 
        
           |  |  | 296 |     grade_update('mod/workshop', $workshop->course, 'mod', 'workshop', $workshop->id, 1, null, array('deleted' => true));
 | 
        
           |  |  | 297 |   | 
        
           |  |  | 298 |     // finally remove the workshop record itself
 | 
        
           |  |  | 299 |     // We must delete the module record after we delete the grade item.
 | 
        
           |  |  | 300 |     $DB->delete_records('workshop', array('id' => $workshop->id));
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 |     return true;
 | 
        
           |  |  | 303 | }
 | 
        
           |  |  | 304 |   | 
        
           |  |  | 305 | /**
 | 
        
           |  |  | 306 |  * This standard function will check all instances of this module
 | 
        
           |  |  | 307 |  * and make sure there are up-to-date events created for each of them.
 | 
        
           |  |  | 308 |  * If courseid = 0, then every workshop event in the site is checked, else
 | 
        
           |  |  | 309 |  * only workshop events belonging to the course specified are checked.
 | 
        
           |  |  | 310 |  *
 | 
        
           |  |  | 311 |  * @param  integer $courseid The Course ID.
 | 
        
           |  |  | 312 |  * @param int|stdClass $instance workshop module instance or ID.
 | 
        
           |  |  | 313 |  * @param int|stdClass $cm Course module object or ID.
 | 
        
           |  |  | 314 |  * @return bool Returns true if the calendar events were successfully updated.
 | 
        
           |  |  | 315 |  */
 | 
        
           |  |  | 316 | function workshop_refresh_events($courseid = 0, $instance = null, $cm = null) {
 | 
        
           |  |  | 317 |     global $DB;
 | 
        
           |  |  | 318 |   | 
        
           |  |  | 319 |     // If we have instance information then we can just update the one event instead of updating all events.
 | 
        
           |  |  | 320 |     if (isset($instance)) {
 | 
        
           |  |  | 321 |         if (!is_object($instance)) {
 | 
        
           |  |  | 322 |             $instance = $DB->get_record('workshop', array('id' => $instance), '*', MUST_EXIST);
 | 
        
           |  |  | 323 |         }
 | 
        
           |  |  | 324 |         if (isset($cm)) {
 | 
        
           |  |  | 325 |             if (!is_object($cm)) {
 | 
        
           |  |  | 326 |                 $cm = (object)array('id' => $cm);
 | 
        
           |  |  | 327 |             }
 | 
        
           |  |  | 328 |         } else {
 | 
        
           |  |  | 329 |             $cm = get_coursemodule_from_instance('workshop', $instance->id);
 | 
        
           |  |  | 330 |         }
 | 
        
           |  |  | 331 |         workshop_calendar_update($instance, $cm->id);
 | 
        
           |  |  | 332 |         return true;
 | 
        
           |  |  | 333 |     }
 | 
        
           |  |  | 334 |   | 
        
           |  |  | 335 |     if ($courseid) {
 | 
        
           |  |  | 336 |         // Make sure that the course id is numeric.
 | 
        
           |  |  | 337 |         if (!is_numeric($courseid)) {
 | 
        
           |  |  | 338 |             return false;
 | 
        
           |  |  | 339 |         }
 | 
        
           |  |  | 340 |         if (!$workshops = $DB->get_records('workshop', array('course' => $courseid))) {
 | 
        
           |  |  | 341 |             return false;
 | 
        
           |  |  | 342 |         }
 | 
        
           |  |  | 343 |     } else {
 | 
        
           |  |  | 344 |         if (!$workshops = $DB->get_records('workshop')) {
 | 
        
           |  |  | 345 |             return false;
 | 
        
           |  |  | 346 |         }
 | 
        
           |  |  | 347 |     }
 | 
        
           |  |  | 348 |     foreach ($workshops as $workshop) {
 | 
        
           |  |  | 349 |         if (!$cm = get_coursemodule_from_instance('workshop', $workshop->id, $courseid, false)) {
 | 
        
           |  |  | 350 |             continue;
 | 
        
           |  |  | 351 |         }
 | 
        
           |  |  | 352 |         workshop_calendar_update($workshop, $cm->id);
 | 
        
           |  |  | 353 |     }
 | 
        
           |  |  | 354 |     return true;
 | 
        
           |  |  | 355 | }
 | 
        
           |  |  | 356 |   | 
        
           |  |  | 357 | /**
 | 
        
           |  |  | 358 |  * List the actions that correspond to a view of this module.
 | 
        
           |  |  | 359 |  * This is used by the participation report.
 | 
        
           |  |  | 360 |  *
 | 
        
           |  |  | 361 |  * Note: This is not used by new logging system. Event with
 | 
        
           |  |  | 362 |  *       crud = 'r' and edulevel = LEVEL_PARTICIPATING will
 | 
        
           |  |  | 363 |  *       be considered as view action.
 | 
        
           |  |  | 364 |  *
 | 
        
           |  |  | 365 |  * @return array
 | 
        
           |  |  | 366 |  */
 | 
        
           |  |  | 367 | function workshop_get_view_actions() {
 | 
        
           |  |  | 368 |     return array('view', 'view all', 'view submission', 'view example');
 | 
        
           |  |  | 369 | }
 | 
        
           |  |  | 370 |   | 
        
           |  |  | 371 | /**
 | 
        
           |  |  | 372 |  * List the actions that correspond to a post of this module.
 | 
        
           |  |  | 373 |  * This is used by the participation report.
 | 
        
           |  |  | 374 |  *
 | 
        
           |  |  | 375 |  * Note: This is not used by new logging system. Event with
 | 
        
           |  |  | 376 |  *       crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING
 | 
        
           |  |  | 377 |  *       will be considered as post action.
 | 
        
           |  |  | 378 |  *
 | 
        
           |  |  | 379 |  * @return array
 | 
        
           |  |  | 380 |  */
 | 
        
           |  |  | 381 | function workshop_get_post_actions() {
 | 
        
           |  |  | 382 |     return array('add', 'add assessment', 'add example', 'add submission',
 | 
        
           |  |  | 383 |                  'update', 'update assessment', 'update example', 'update submission');
 | 
        
           |  |  | 384 | }
 | 
        
           |  |  | 385 |   | 
        
           |  |  | 386 | /**
 | 
        
           |  |  | 387 |  * Return a small object with summary information about what a
 | 
        
           |  |  | 388 |  * user has done with a given particular instance of this module
 | 
        
           |  |  | 389 |  * Used for user activity reports.
 | 
        
           |  |  | 390 |  * $return->time = the time they did it
 | 
        
           |  |  | 391 |  * $return->info = a short text description
 | 
        
           |  |  | 392 |  *
 | 
        
           |  |  | 393 |  * @param stdClass $course The course record.
 | 
        
           |  |  | 394 |  * @param stdClass $user The user record.
 | 
        
           |  |  | 395 |  * @param cm_info|stdClass $mod The course module info object or record.
 | 
        
           |  |  | 396 |  * @param stdClass $workshop The workshop instance record.
 | 
        
           |  |  | 397 |  * @return stdclass|null
 | 
        
           |  |  | 398 |  */
 | 
        
           |  |  | 399 | function workshop_user_outline($course, $user, $mod, $workshop) {
 | 
        
           |  |  | 400 |     global $CFG, $DB;
 | 
        
           |  |  | 401 |     require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 402 |   | 
        
           |  |  | 403 |     $grades = grade_get_grades($course->id, 'mod', 'workshop', $workshop->id, $user->id);
 | 
        
           |  |  | 404 |   | 
        
           |  |  | 405 |     $submissiongrade = null;
 | 
        
           |  |  | 406 |     $assessmentgrade = null;
 | 
        
           |  |  | 407 |   | 
        
           |  |  | 408 |     $info = '';
 | 
        
           |  |  | 409 |     $time = 0;
 | 
        
           |  |  | 410 |   | 
        
           |  |  | 411 |     if (!empty($grades->items[0]->grades)) {
 | 
        
           |  |  | 412 |         $submissiongrade = reset($grades->items[0]->grades);
 | 
        
           |  |  | 413 |         $time = max($time, $submissiongrade->dategraded);
 | 
        
           |  |  | 414 |         if (!$submissiongrade->hidden || has_capability('moodle/grade:viewhidden', context_course::instance($course->id))) {
 | 
        
           |  |  | 415 |             $info .= get_string('submissiongrade', 'workshop') . ': ' . $submissiongrade->str_long_grade
 | 
        
           |  |  | 416 |                 . html_writer::empty_tag('br');
 | 
        
           |  |  | 417 |         } else {
 | 
        
           |  |  | 418 |             $info .= get_string('submissiongrade', 'workshop') . ': ' . get_string('hidden', 'grades')
 | 
        
           |  |  | 419 |                 . html_writer::empty_tag('br');
 | 
        
           |  |  | 420 |         }
 | 
        
           |  |  | 421 |     }
 | 
        
           |  |  | 422 |     if (!empty($grades->items[1]->grades)) {
 | 
        
           |  |  | 423 |         $assessmentgrade = reset($grades->items[1]->grades);
 | 
        
           |  |  | 424 |         $time = max($time, $assessmentgrade->dategraded);
 | 
        
           |  |  | 425 |         if (!$assessmentgrade->hidden || has_capability('moodle/grade:viewhidden', context_course::instance($course->id))) {
 | 
        
           |  |  | 426 |             $info .= get_string('gradinggrade', 'workshop') . ': ' . $assessmentgrade->str_long_grade;
 | 
        
           |  |  | 427 |         } else {
 | 
        
           |  |  | 428 |             $info .= get_string('gradinggrade', 'workshop') . ': ' . get_string('hidden', 'grades');
 | 
        
           |  |  | 429 |         }
 | 
        
           |  |  | 430 |     }
 | 
        
           |  |  | 431 |   | 
        
           |  |  | 432 |     if (!empty($info) and !empty($time)) {
 | 
        
           |  |  | 433 |         $return = new stdclass();
 | 
        
           |  |  | 434 |         $return->time = $time;
 | 
        
           |  |  | 435 |         $return->info = $info;
 | 
        
           |  |  | 436 |         return $return;
 | 
        
           |  |  | 437 |     }
 | 
        
           |  |  | 438 |   | 
        
           |  |  | 439 |     return null;
 | 
        
           |  |  | 440 | }
 | 
        
           |  |  | 441 |   | 
        
           |  |  | 442 | /**
 | 
        
           |  |  | 443 |  * Print a detailed representation of what a user has done with
 | 
        
           |  |  | 444 |  * a given particular instance of this module, for user activity reports.
 | 
        
           |  |  | 445 |  *
 | 
        
           |  |  | 446 |  * @param stdClass $course The course record.
 | 
        
           |  |  | 447 |  * @param stdClass $user The user record.
 | 
        
           |  |  | 448 |  * @param cm_info|stdClass $mod The course module info object or record.
 | 
        
           |  |  | 449 |  * @param stdClass $workshop The workshop instance record.
 | 
        
           |  |  | 450 |  * @return string HTML
 | 
        
           |  |  | 451 |  */
 | 
        
           |  |  | 452 | function workshop_user_complete($course, $user, $mod, $workshop) {
 | 
        
           |  |  | 453 |     global $CFG, $DB, $OUTPUT;
 | 
        
           |  |  | 454 |     require_once(__DIR__.'/locallib.php');
 | 
        
           |  |  | 455 |     require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 456 |   | 
        
           |  |  | 457 |     $workshop   = new workshop($workshop, $mod, $course);
 | 
        
           |  |  | 458 |     $grades     = grade_get_grades($course->id, 'mod', 'workshop', $workshop->id, $user->id);
 | 
        
           |  |  | 459 |   | 
        
           |  |  | 460 |     if (!empty($grades->items[0]->grades)) {
 | 
        
           |  |  | 461 |         $submissiongrade = reset($grades->items[0]->grades);
 | 
        
           |  |  | 462 |         if (!$submissiongrade->hidden || has_capability('moodle/grade:viewhidden', context_course::instance($course->id))) {
 | 
        
           |  |  | 463 |             $info = get_string('submissiongrade', 'workshop') . ': ' . $submissiongrade->str_long_grade;
 | 
        
           |  |  | 464 |         } else {
 | 
        
           |  |  | 465 |             $info = get_string('submissiongrade', 'workshop') . ': ' . get_string('hidden', 'grades');
 | 
        
           |  |  | 466 |         }
 | 
        
           |  |  | 467 |         echo html_writer::tag('li', $info, array('class'=>'submissiongrade'));
 | 
        
           |  |  | 468 |     }
 | 
        
           |  |  | 469 |     if (!empty($grades->items[1]->grades)) {
 | 
        
           |  |  | 470 |         $assessmentgrade = reset($grades->items[1]->grades);
 | 
        
           |  |  | 471 |         if (!$assessmentgrade->hidden || has_capability('moodle/grade:viewhidden', context_course::instance($course->id))) {
 | 
        
           |  |  | 472 |             $info = get_string('gradinggrade', 'workshop') . ': ' . $assessmentgrade->str_long_grade;
 | 
        
           |  |  | 473 |         } else {
 | 
        
           |  |  | 474 |             $info = get_string('gradinggrade', 'workshop') . ': ' . get_string('hidden', 'grades');
 | 
        
           |  |  | 475 |         }
 | 
        
           |  |  | 476 |         echo html_writer::tag('li', $info, array('class'=>'gradinggrade'));
 | 
        
           |  |  | 477 |     }
 | 
        
           |  |  | 478 |   | 
        
           |  |  | 479 |     if (has_capability('mod/workshop:viewallsubmissions', $workshop->context)) {
 | 
        
           |  |  | 480 |         $canviewsubmission = true;
 | 
        
           |  |  | 481 |         if (groups_get_activity_groupmode($workshop->cm) == SEPARATEGROUPS) {
 | 
        
           |  |  | 482 |             // user must have accessallgroups or share at least one group with the submission author
 | 
        
           |  |  | 483 |             if (!has_capability('moodle/site:accessallgroups', $workshop->context)) {
 | 
        
           |  |  | 484 |                 $usersgroups = groups_get_activity_allowed_groups($workshop->cm);
 | 
        
           |  |  | 485 |                 $authorsgroups = groups_get_all_groups($workshop->course->id, $user->id, $workshop->cm->groupingid, 'g.id');
 | 
        
           |  |  | 486 |                 $sharedgroups = array_intersect_key($usersgroups, $authorsgroups);
 | 
        
           |  |  | 487 |                 if (empty($sharedgroups)) {
 | 
        
           |  |  | 488 |                     $canviewsubmission = false;
 | 
        
           |  |  | 489 |                 }
 | 
        
           |  |  | 490 |             }
 | 
        
           |  |  | 491 |         }
 | 
        
           |  |  | 492 |         if ($canviewsubmission and $submission = $workshop->get_submission_by_author($user->id)) {
 | 
        
           |  |  | 493 |             $title      = format_string($submission->title);
 | 
        
           |  |  | 494 |             $url        = $workshop->submission_url($submission->id);
 | 
        
           |  |  | 495 |             $link       = html_writer::link($url, $title);
 | 
        
           |  |  | 496 |             $info       = get_string('submission', 'workshop').': '.$link;
 | 
        
           |  |  | 497 |             echo html_writer::tag('li', $info, array('class'=>'submission'));
 | 
        
           |  |  | 498 |         }
 | 
        
           |  |  | 499 |     }
 | 
        
           |  |  | 500 |   | 
        
           |  |  | 501 |     if (has_capability('mod/workshop:viewallassessments', $workshop->context)) {
 | 
        
           |  |  | 502 |         if ($assessments = $workshop->get_assessments_by_reviewer($user->id)) {
 | 
        
           |  |  | 503 |             foreach ($assessments as $assessment) {
 | 
        
           |  |  | 504 |                 $a = new stdclass();
 | 
        
           |  |  | 505 |                 $a->submissionurl = $workshop->submission_url($assessment->submissionid)->out();
 | 
        
           |  |  | 506 |                 $a->assessmenturl = $workshop->assess_url($assessment->id)->out();
 | 
        
           |  |  | 507 |                 $a->submissiontitle = s($assessment->submissiontitle);
 | 
        
           |  |  | 508 |                 echo html_writer::tag('li', get_string('assessmentofsubmission', 'workshop', $a));
 | 
        
           |  |  | 509 |             }
 | 
        
           |  |  | 510 |         }
 | 
        
           |  |  | 511 |     }
 | 
        
           |  |  | 512 | }
 | 
        
           |  |  | 513 |   | 
        
           |  |  | 514 | /**
 | 
        
           |  |  | 515 |  * Given a course and a time, this module should find recent activity
 | 
        
           |  |  | 516 |  * that has occurred in workshop activities and print it out.
 | 
        
           |  |  | 517 |  * Return true if there was output, or false is there was none.
 | 
        
           |  |  | 518 |  *
 | 
        
           |  |  | 519 |  * @param stdClass $course
 | 
        
           |  |  | 520 |  * @param bool $viewfullnames
 | 
        
           |  |  | 521 |  * @param int $timestart
 | 
        
           |  |  | 522 |  * @return boolean
 | 
        
           |  |  | 523 |  */
 | 
        
           |  |  | 524 | function workshop_print_recent_activity($course, $viewfullnames, $timestart) {
 | 
        
           |  |  | 525 |     global $CFG, $USER, $DB, $OUTPUT;
 | 
        
           |  |  | 526 |   | 
        
           |  |  | 527 |     $userfieldsapi = \core_user\fields::for_name();
 | 
        
           |  |  | 528 |     $authoramefields = $userfieldsapi->get_sql('author', false, 'author', '', false)->selects;
 | 
        
           |  |  | 529 |     $reviewerfields = $userfieldsapi->get_sql('reviewer', false, 'reviewer', '', false)->selects;
 | 
        
           |  |  | 530 |   | 
        
           |  |  | 531 |     $sql = "SELECT s.id AS submissionid, s.title AS submissiontitle, s.timemodified AS submissionmodified,
 | 
        
           |  |  | 532 |                    author.id AS authorid, $authoramefields, a.id AS assessmentid, a.timemodified AS assessmentmodified,
 | 
        
           |  |  | 533 |                    reviewer.id AS reviewerid, $reviewerfields, cm.id AS cmid
 | 
        
           |  |  | 534 |               FROM {workshop} w
 | 
        
           |  |  | 535 |         INNER JOIN {course_modules} cm ON cm.instance = w.id
 | 
        
           |  |  | 536 |         INNER JOIN {modules} md ON md.id = cm.module
 | 
        
           |  |  | 537 |         INNER JOIN {workshop_submissions} s ON s.workshopid = w.id
 | 
        
           |  |  | 538 |         INNER JOIN {user} author ON s.authorid = author.id
 | 
        
           |  |  | 539 |          LEFT JOIN {workshop_assessments} a ON a.submissionid = s.id
 | 
        
           |  |  | 540 |          LEFT JOIN {user} reviewer ON a.reviewerid = reviewer.id
 | 
        
           |  |  | 541 |              WHERE cm.course = ?
 | 
        
           |  |  | 542 |                    AND md.name = 'workshop'
 | 
        
           |  |  | 543 |                    AND s.example = 0
 | 
        
           |  |  | 544 |                    AND (s.timemodified > ? OR a.timemodified > ?)
 | 
        
           |  |  | 545 |           ORDER BY s.timemodified";
 | 
        
           |  |  | 546 |   | 
        
           |  |  | 547 |     $rs = $DB->get_recordset_sql($sql, array($course->id, $timestart, $timestart));
 | 
        
           |  |  | 548 |   | 
        
           |  |  | 549 |     $modinfo = get_fast_modinfo($course); // reference needed because we might load the groups
 | 
        
           |  |  | 550 |   | 
        
           |  |  | 551 |     $submissions = array(); // recent submissions indexed by submission id
 | 
        
           |  |  | 552 |     $assessments = array(); // recent assessments indexed by assessment id
 | 
        
           |  |  | 553 |     $users       = array();
 | 
        
           |  |  | 554 |   | 
        
           |  |  | 555 |     foreach ($rs as $activity) {
 | 
        
           |  |  | 556 |         if (!array_key_exists($activity->cmid, $modinfo->cms)) {
 | 
        
           |  |  | 557 |             // this should not happen but just in case
 | 
        
           |  |  | 558 |             continue;
 | 
        
           |  |  | 559 |         }
 | 
        
           |  |  | 560 |   | 
        
           |  |  | 561 |         $cm = $modinfo->cms[$activity->cmid];
 | 
        
           |  |  | 562 |         if (!$cm->uservisible) {
 | 
        
           |  |  | 563 |             continue;
 | 
        
           |  |  | 564 |         }
 | 
        
           |  |  | 565 |   | 
        
           |  |  | 566 |         // remember all user names we can use later
 | 
        
           |  |  | 567 |         if (empty($users[$activity->authorid])) {
 | 
        
           |  |  | 568 |             $u = new stdclass();
 | 
        
           |  |  | 569 |             $users[$activity->authorid] = username_load_fields_from_object($u, $activity, 'author');
 | 
        
           |  |  | 570 |         }
 | 
        
           |  |  | 571 |         if ($activity->reviewerid and empty($users[$activity->reviewerid])) {
 | 
        
           |  |  | 572 |             $u = new stdclass();
 | 
        
           |  |  | 573 |             $users[$activity->reviewerid] = username_load_fields_from_object($u, $activity, 'reviewer');
 | 
        
           |  |  | 574 |         }
 | 
        
           |  |  | 575 |   | 
        
           |  |  | 576 |         $context = context_module::instance($cm->id);
 | 
        
           |  |  | 577 |         $groupmode = groups_get_activity_groupmode($cm, $course);
 | 
        
           |  |  | 578 |   | 
        
           |  |  | 579 |         if ($activity->submissionmodified > $timestart and empty($submissions[$activity->submissionid])) {
 | 
        
           |  |  | 580 |             $s = new stdclass();
 | 
        
           |  |  | 581 |             $s->title = $activity->submissiontitle;
 | 
        
           |  |  | 582 |             $s->authorid = $activity->authorid;
 | 
        
           |  |  | 583 |             $s->timemodified = $activity->submissionmodified;
 | 
        
           |  |  | 584 |             $s->cmid = $activity->cmid;
 | 
        
           |  |  | 585 |             if ($activity->authorid == $USER->id || has_capability('mod/workshop:viewauthornames', $context)) {
 | 
        
           |  |  | 586 |                 $s->authornamevisible = true;
 | 
        
           |  |  | 587 |             } else {
 | 
        
           |  |  | 588 |                 $s->authornamevisible = false;
 | 
        
           |  |  | 589 |             }
 | 
        
           |  |  | 590 |   | 
        
           |  |  | 591 |             // the following do-while wrapper allows to break from deeply nested if-statements
 | 
        
           |  |  | 592 |             do {
 | 
        
           |  |  | 593 |                 if ($s->authorid === $USER->id) {
 | 
        
           |  |  | 594 |                     // own submissions always visible
 | 
        
           |  |  | 595 |                     $submissions[$activity->submissionid] = $s;
 | 
        
           |  |  | 596 |                     break;
 | 
        
           |  |  | 597 |                 }
 | 
        
           |  |  | 598 |   | 
        
           |  |  | 599 |                 if (has_capability('mod/workshop:viewallsubmissions', $context)) {
 | 
        
           |  |  | 600 |                     if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
 | 
        
           |  |  | 601 |                         if (isguestuser()) {
 | 
        
           |  |  | 602 |                             // shortcut - guest user does not belong into any group
 | 
        
           |  |  | 603 |                             break;
 | 
        
           |  |  | 604 |                         }
 | 
        
           |  |  | 605 |   | 
        
           |  |  | 606 |                         // this might be slow - show only submissions by users who share group with me in this cm
 | 
        
           |  |  | 607 |                         if (!$modinfo->get_groups($cm->groupingid)) {
 | 
        
           |  |  | 608 |                             break;
 | 
        
           |  |  | 609 |                         }
 | 
        
           |  |  | 610 |                         $authorsgroups = groups_get_all_groups($course->id, $s->authorid, $cm->groupingid);
 | 
        
           |  |  | 611 |                         if (is_array($authorsgroups)) {
 | 
        
           |  |  | 612 |                             $authorsgroups = array_keys($authorsgroups);
 | 
        
           |  |  | 613 |                             $intersect = array_intersect($authorsgroups, $modinfo->get_groups($cm->groupingid));
 | 
        
           |  |  | 614 |                             if (empty($intersect)) {
 | 
        
           |  |  | 615 |                                 break;
 | 
        
           |  |  | 616 |                             } else {
 | 
        
           |  |  | 617 |                                 // can see all submissions and shares a group with the author
 | 
        
           |  |  | 618 |                                 $submissions[$activity->submissionid] = $s;
 | 
        
           |  |  | 619 |                                 break;
 | 
        
           |  |  | 620 |                             }
 | 
        
           |  |  | 621 |                         }
 | 
        
           |  |  | 622 |   | 
        
           |  |  | 623 |                     } else {
 | 
        
           |  |  | 624 |                         // can see all submissions from all groups
 | 
        
           |  |  | 625 |                         $submissions[$activity->submissionid] = $s;
 | 
        
           |  |  | 626 |                     }
 | 
        
           |  |  | 627 |                 }
 | 
        
           |  |  | 628 |             } while (0);
 | 
        
           |  |  | 629 |         }
 | 
        
           |  |  | 630 |   | 
        
           |  |  | 631 |         if ($activity->assessmentmodified > $timestart and empty($assessments[$activity->assessmentid])) {
 | 
        
           |  |  | 632 |             $a = new stdclass();
 | 
        
           |  |  | 633 |             $a->submissionid = $activity->submissionid;
 | 
        
           |  |  | 634 |             $a->submissiontitle = $activity->submissiontitle;
 | 
        
           |  |  | 635 |             $a->reviewerid = $activity->reviewerid;
 | 
        
           |  |  | 636 |             $a->timemodified = $activity->assessmentmodified;
 | 
        
           |  |  | 637 |             $a->cmid = $activity->cmid;
 | 
        
           |  |  | 638 |             if ($activity->reviewerid == $USER->id || has_capability('mod/workshop:viewreviewernames', $context)) {
 | 
        
           |  |  | 639 |                 $a->reviewernamevisible = true;
 | 
        
           |  |  | 640 |             } else {
 | 
        
           |  |  | 641 |                 $a->reviewernamevisible = false;
 | 
        
           |  |  | 642 |             }
 | 
        
           |  |  | 643 |   | 
        
           |  |  | 644 |             // the following do-while wrapper allows to break from deeply nested if-statements
 | 
        
           |  |  | 645 |             do {
 | 
        
           |  |  | 646 |                 if ($a->reviewerid === $USER->id) {
 | 
        
           |  |  | 647 |                     // own assessments always visible
 | 
        
           |  |  | 648 |                     $assessments[$activity->assessmentid] = $a;
 | 
        
           |  |  | 649 |                     break;
 | 
        
           |  |  | 650 |                 }
 | 
        
           |  |  | 651 |   | 
        
           |  |  | 652 |                 if (has_capability('mod/workshop:viewallassessments', $context)) {
 | 
        
           |  |  | 653 |                     if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
 | 
        
           |  |  | 654 |                         if (isguestuser()) {
 | 
        
           |  |  | 655 |                             // shortcut - guest user does not belong into any group
 | 
        
           |  |  | 656 |                             break;
 | 
        
           |  |  | 657 |                         }
 | 
        
           |  |  | 658 |   | 
        
           |  |  | 659 |                         // this might be slow - show only submissions by users who share group with me in this cm
 | 
        
           |  |  | 660 |                         if (!$modinfo->get_groups($cm->groupingid)) {
 | 
        
           |  |  | 661 |                             break;
 | 
        
           |  |  | 662 |                         }
 | 
        
           |  |  | 663 |                         $reviewersgroups = groups_get_all_groups($course->id, $a->reviewerid, $cm->groupingid);
 | 
        
           |  |  | 664 |                         if (is_array($reviewersgroups)) {
 | 
        
           |  |  | 665 |                             $reviewersgroups = array_keys($reviewersgroups);
 | 
        
           |  |  | 666 |                             $intersect = array_intersect($reviewersgroups, $modinfo->get_groups($cm->groupingid));
 | 
        
           |  |  | 667 |                             if (empty($intersect)) {
 | 
        
           |  |  | 668 |                                 break;
 | 
        
           |  |  | 669 |                             } else {
 | 
        
           |  |  | 670 |                                 // can see all assessments and shares a group with the reviewer
 | 
        
           |  |  | 671 |                                 $assessments[$activity->assessmentid] = $a;
 | 
        
           |  |  | 672 |                                 break;
 | 
        
           |  |  | 673 |                             }
 | 
        
           |  |  | 674 |                         }
 | 
        
           |  |  | 675 |   | 
        
           |  |  | 676 |                     } else {
 | 
        
           |  |  | 677 |                         // can see all assessments from all groups
 | 
        
           |  |  | 678 |                         $assessments[$activity->assessmentid] = $a;
 | 
        
           |  |  | 679 |                     }
 | 
        
           |  |  | 680 |                 }
 | 
        
           |  |  | 681 |             } while (0);
 | 
        
           |  |  | 682 |         }
 | 
        
           |  |  | 683 |     }
 | 
        
           |  |  | 684 |     $rs->close();
 | 
        
           |  |  | 685 |   | 
        
           |  |  | 686 |     $shown = false;
 | 
        
           |  |  | 687 |   | 
        
           |  |  | 688 |     if (!empty($submissions)) {
 | 
        
           |  |  | 689 |         $shown = true;
 | 
        
           |  |  | 690 |         echo $OUTPUT->heading(get_string('recentsubmissions', 'workshop') . ':', 6);
 | 
        
           |  |  | 691 |         foreach ($submissions as $id => $submission) {
 | 
        
           |  |  | 692 |             $link = new moodle_url('/mod/workshop/submission.php', array('id'=>$id, 'cmid'=>$submission->cmid));
 | 
        
           |  |  | 693 |             if ($submission->authornamevisible) {
 | 
        
           |  |  | 694 |                 $author = $users[$submission->authorid];
 | 
        
           |  |  | 695 |             } else {
 | 
        
           |  |  | 696 |                 $author = null;
 | 
        
           |  |  | 697 |             }
 | 
        
           |  |  | 698 |             print_recent_activity_note($submission->timemodified, $author, $submission->title, $link->out(), false, $viewfullnames);
 | 
        
           |  |  | 699 |         }
 | 
        
           |  |  | 700 |     }
 | 
        
           |  |  | 701 |   | 
        
           |  |  | 702 |     if (!empty($assessments)) {
 | 
        
           |  |  | 703 |         $shown = true;
 | 
        
           |  |  | 704 |         echo $OUTPUT->heading(get_string('recentassessments', 'workshop') . ':', 6);
 | 
        
           |  |  | 705 |         core_collator::asort_objects_by_property($assessments, 'timemodified');
 | 
        
           |  |  | 706 |         foreach ($assessments as $id => $assessment) {
 | 
        
           |  |  | 707 |             $link = new moodle_url('/mod/workshop/assessment.php', array('asid' => $id));
 | 
        
           |  |  | 708 |             if ($assessment->reviewernamevisible) {
 | 
        
           |  |  | 709 |                 $reviewer = $users[$assessment->reviewerid];
 | 
        
           |  |  | 710 |             } else {
 | 
        
           |  |  | 711 |                 $reviewer = null;
 | 
        
           |  |  | 712 |             }
 | 
        
           |  |  | 713 |             print_recent_activity_note($assessment->timemodified, $reviewer, $assessment->submissiontitle, $link->out(), false, $viewfullnames);
 | 
        
           |  |  | 714 |         }
 | 
        
           |  |  | 715 |     }
 | 
        
           |  |  | 716 |   | 
        
           |  |  | 717 |     if ($shown) {
 | 
        
           |  |  | 718 |         return true;
 | 
        
           |  |  | 719 |     }
 | 
        
           |  |  | 720 |   | 
        
           |  |  | 721 |     return false;
 | 
        
           |  |  | 722 | }
 | 
        
           |  |  | 723 |   | 
        
           |  |  | 724 | /**
 | 
        
           |  |  | 725 |  * Returns all activity in course workshops since a given time
 | 
        
           |  |  | 726 |  *
 | 
        
           |  |  | 727 |  * @param array $activities sequentially indexed array of objects
 | 
        
           |  |  | 728 |  * @param int $index
 | 
        
           |  |  | 729 |  * @param int $timestart
 | 
        
           |  |  | 730 |  * @param int $courseid
 | 
        
           |  |  | 731 |  * @param int $cmid
 | 
        
           |  |  | 732 |  * @param int $userid defaults to 0
 | 
        
           |  |  | 733 |  * @param int $groupid defaults to 0
 | 
        
           |  |  | 734 |  * @return void adds items into $activities and increases $index
 | 
        
           |  |  | 735 |  */
 | 
        
           |  |  | 736 | function workshop_get_recent_mod_activity(&$activities, &$index, $timestart, $courseid, $cmid, $userid=0, $groupid=0) {
 | 
        
           |  |  | 737 |     global $CFG, $COURSE, $USER, $DB;
 | 
        
           |  |  | 738 |   | 
        
           |  |  | 739 |     if ($COURSE->id == $courseid) {
 | 
        
           |  |  | 740 |         $course = $COURSE;
 | 
        
           |  |  | 741 |     } else {
 | 
        
           |  |  | 742 |         $course = $DB->get_record('course', array('id'=>$courseid));
 | 
        
           |  |  | 743 |     }
 | 
        
           |  |  | 744 |   | 
        
           |  |  | 745 |     $modinfo = get_fast_modinfo($course);
 | 
        
           |  |  | 746 |   | 
        
           |  |  | 747 |     $cm = $modinfo->cms[$cmid];
 | 
        
           |  |  | 748 |   | 
        
           |  |  | 749 |     $params = array();
 | 
        
           |  |  | 750 |     if ($userid) {
 | 
        
           |  |  | 751 |         $userselect = "AND (author.id = :authorid OR reviewer.id = :reviewerid)";
 | 
        
           |  |  | 752 |         $params['authorid'] = $userid;
 | 
        
           |  |  | 753 |         $params['reviewerid'] = $userid;
 | 
        
           |  |  | 754 |     } else {
 | 
        
           |  |  | 755 |         $userselect = "";
 | 
        
           |  |  | 756 |     }
 | 
        
           |  |  | 757 |   | 
        
           |  |  | 758 |     if ($groupid) {
 | 
        
           |  |  | 759 |         $groupselect = "AND (authorgroupmembership.groupid = :authorgroupid OR reviewergroupmembership.groupid = :reviewergroupid)";
 | 
        
           |  |  | 760 |         $groupjoin   = "LEFT JOIN {groups_members} authorgroupmembership ON authorgroupmembership.userid = author.id
 | 
        
           |  |  | 761 |                         LEFT JOIN {groups_members} reviewergroupmembership ON reviewergroupmembership.userid = reviewer.id";
 | 
        
           |  |  | 762 |         $params['authorgroupid'] = $groupid;
 | 
        
           |  |  | 763 |         $params['reviewergroupid'] = $groupid;
 | 
        
           |  |  | 764 |     } else {
 | 
        
           |  |  | 765 |         $groupselect = "";
 | 
        
           |  |  | 766 |         $groupjoin   = "";
 | 
        
           |  |  | 767 |     }
 | 
        
           |  |  | 768 |   | 
        
           |  |  | 769 |     $params['cminstance'] = $cm->instance;
 | 
        
           |  |  | 770 |     $params['submissionmodified'] = $timestart;
 | 
        
           |  |  | 771 |     $params['assessmentmodified'] = $timestart;
 | 
        
           |  |  | 772 |   | 
        
           |  |  | 773 |     $userfieldsapi = \core_user\fields::for_name();
 | 
        
           |  |  | 774 |     $authornamefields = $userfieldsapi->get_sql('author', false, 'author', '', false)->selects;
 | 
        
           |  |  | 775 |     $reviewerfields = $userfieldsapi->get_sql('reviewer', false, 'reviewer', '', false)->selects;
 | 
        
           |  |  | 776 |   | 
        
           |  |  | 777 |     $sql = "SELECT s.id AS submissionid, s.title AS submissiontitle, s.timemodified AS submissionmodified,
 | 
        
           |  |  | 778 |                    author.id AS authorid, $authornamefields, author.picture AS authorpicture, author.imagealt AS authorimagealt,
 | 
        
           |  |  | 779 |                    author.email AS authoremail, a.id AS assessmentid, a.timemodified AS assessmentmodified,
 | 
        
           |  |  | 780 |                    reviewer.id AS reviewerid, $reviewerfields, reviewer.picture AS reviewerpicture,
 | 
        
           |  |  | 781 |                    reviewer.imagealt AS reviewerimagealt, reviewer.email AS revieweremail
 | 
        
           |  |  | 782 |               FROM {workshop_submissions} s
 | 
        
           |  |  | 783 |         INNER JOIN {workshop} w ON s.workshopid = w.id
 | 
        
           |  |  | 784 |         INNER JOIN {user} author ON s.authorid = author.id
 | 
        
           |  |  | 785 |          LEFT JOIN {workshop_assessments} a ON a.submissionid = s.id
 | 
        
           |  |  | 786 |          LEFT JOIN {user} reviewer ON a.reviewerid = reviewer.id
 | 
        
           |  |  | 787 |         $groupjoin
 | 
        
           |  |  | 788 |              WHERE w.id = :cminstance
 | 
        
           |  |  | 789 |                    AND s.example = 0
 | 
        
           |  |  | 790 |                    $userselect $groupselect
 | 
        
           |  |  | 791 |                    AND (s.timemodified > :submissionmodified OR a.timemodified > :assessmentmodified)
 | 
        
           |  |  | 792 |           ORDER BY s.timemodified ASC, a.timemodified ASC";
 | 
        
           |  |  | 793 |   | 
        
           |  |  | 794 |     $rs = $DB->get_recordset_sql($sql, $params);
 | 
        
           |  |  | 795 |   | 
        
           |  |  | 796 |     $groupmode       = groups_get_activity_groupmode($cm, $course);
 | 
        
           |  |  | 797 |     $context         = context_module::instance($cm->id);
 | 
        
           |  |  | 798 |     $grader          = has_capability('moodle/grade:viewall', $context);
 | 
        
           |  |  | 799 |     $accessallgroups = has_capability('moodle/site:accessallgroups', $context);
 | 
        
           |  |  | 800 |     $viewauthors     = has_capability('mod/workshop:viewauthornames', $context);
 | 
        
           |  |  | 801 |     $viewreviewers   = has_capability('mod/workshop:viewreviewernames', $context);
 | 
        
           |  |  | 802 |   | 
        
           |  |  | 803 |     $submissions = array(); // recent submissions indexed by submission id
 | 
        
           |  |  | 804 |     $assessments = array(); // recent assessments indexed by assessment id
 | 
        
           |  |  | 805 |     $users       = array();
 | 
        
           |  |  | 806 |   | 
        
           |  |  | 807 |     foreach ($rs as $activity) {
 | 
        
           |  |  | 808 |   | 
        
           |  |  | 809 |         // remember all user names we can use later
 | 
        
           |  |  | 810 |         if (empty($users[$activity->authorid])) {
 | 
        
           |  |  | 811 |             $u = new stdclass();
 | 
        
           |  |  | 812 |             $additionalfields = explode(',', implode(',', \core_user\fields::get_picture_fields()));
 | 
        
           |  |  | 813 |             $u = username_load_fields_from_object($u, $activity, 'author', $additionalfields);
 | 
        
           |  |  | 814 |             $users[$activity->authorid] = $u;
 | 
        
           |  |  | 815 |         }
 | 
        
           |  |  | 816 |         if ($activity->reviewerid and empty($users[$activity->reviewerid])) {
 | 
        
           |  |  | 817 |             $u = new stdclass();
 | 
        
           |  |  | 818 |             $additionalfields = explode(',', implode(',', \core_user\fields::get_picture_fields()));
 | 
        
           |  |  | 819 |             $u = username_load_fields_from_object($u, $activity, 'reviewer', $additionalfields);
 | 
        
           |  |  | 820 |             $users[$activity->reviewerid] = $u;
 | 
        
           |  |  | 821 |         }
 | 
        
           |  |  | 822 |   | 
        
           |  |  | 823 |         if ($activity->submissionmodified > $timestart and empty($submissions[$activity->submissionid])) {
 | 
        
           |  |  | 824 |             $s = new stdclass();
 | 
        
           |  |  | 825 |             $s->id = $activity->submissionid;
 | 
        
           |  |  | 826 |             $s->title = $activity->submissiontitle;
 | 
        
           |  |  | 827 |             $s->authorid = $activity->authorid;
 | 
        
           |  |  | 828 |             $s->timemodified = $activity->submissionmodified;
 | 
        
           |  |  | 829 |             if ($activity->authorid == $USER->id || has_capability('mod/workshop:viewauthornames', $context)) {
 | 
        
           |  |  | 830 |                 $s->authornamevisible = true;
 | 
        
           |  |  | 831 |             } else {
 | 
        
           |  |  | 832 |                 $s->authornamevisible = false;
 | 
        
           |  |  | 833 |             }
 | 
        
           |  |  | 834 |   | 
        
           |  |  | 835 |             // the following do-while wrapper allows to break from deeply nested if-statements
 | 
        
           |  |  | 836 |             do {
 | 
        
           |  |  | 837 |                 if ($s->authorid === $USER->id) {
 | 
        
           |  |  | 838 |                     // own submissions always visible
 | 
        
           |  |  | 839 |                     $submissions[$activity->submissionid] = $s;
 | 
        
           |  |  | 840 |                     break;
 | 
        
           |  |  | 841 |                 }
 | 
        
           |  |  | 842 |   | 
        
           |  |  | 843 |                 if (has_capability('mod/workshop:viewallsubmissions', $context)) {
 | 
        
           |  |  | 844 |                     if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
 | 
        
           |  |  | 845 |                         if (isguestuser()) {
 | 
        
           |  |  | 846 |                             // shortcut - guest user does not belong into any group
 | 
        
           |  |  | 847 |                             break;
 | 
        
           |  |  | 848 |                         }
 | 
        
           |  |  | 849 |   | 
        
           |  |  | 850 |                         // this might be slow - show only submissions by users who share group with me in this cm
 | 
        
           |  |  | 851 |                         if (!$modinfo->get_groups($cm->groupingid)) {
 | 
        
           |  |  | 852 |                             break;
 | 
        
           |  |  | 853 |                         }
 | 
        
           |  |  | 854 |                         $authorsgroups = groups_get_all_groups($course->id, $s->authorid, $cm->groupingid);
 | 
        
           |  |  | 855 |                         if (is_array($authorsgroups)) {
 | 
        
           |  |  | 856 |                             $authorsgroups = array_keys($authorsgroups);
 | 
        
           |  |  | 857 |                             $intersect = array_intersect($authorsgroups, $modinfo->get_groups($cm->groupingid));
 | 
        
           |  |  | 858 |                             if (empty($intersect)) {
 | 
        
           |  |  | 859 |                                 break;
 | 
        
           |  |  | 860 |                             } else {
 | 
        
           |  |  | 861 |                                 // can see all submissions and shares a group with the author
 | 
        
           |  |  | 862 |                                 $submissions[$activity->submissionid] = $s;
 | 
        
           |  |  | 863 |                                 break;
 | 
        
           |  |  | 864 |                             }
 | 
        
           |  |  | 865 |                         }
 | 
        
           |  |  | 866 |   | 
        
           |  |  | 867 |                     } else {
 | 
        
           |  |  | 868 |                         // can see all submissions from all groups
 | 
        
           |  |  | 869 |                         $submissions[$activity->submissionid] = $s;
 | 
        
           |  |  | 870 |                     }
 | 
        
           |  |  | 871 |                 }
 | 
        
           |  |  | 872 |             } while (0);
 | 
        
           |  |  | 873 |         }
 | 
        
           |  |  | 874 |   | 
        
           |  |  | 875 |         if ($activity->assessmentmodified > $timestart and empty($assessments[$activity->assessmentid])) {
 | 
        
           |  |  | 876 |             $a = new stdclass();
 | 
        
           |  |  | 877 |             $a->id = $activity->assessmentid;
 | 
        
           |  |  | 878 |             $a->submissionid = $activity->submissionid;
 | 
        
           |  |  | 879 |             $a->submissiontitle = $activity->submissiontitle;
 | 
        
           |  |  | 880 |             $a->reviewerid = $activity->reviewerid;
 | 
        
           |  |  | 881 |             $a->timemodified = $activity->assessmentmodified;
 | 
        
           |  |  | 882 |             if ($activity->reviewerid == $USER->id || has_capability('mod/workshop:viewreviewernames', $context)) {
 | 
        
           |  |  | 883 |                 $a->reviewernamevisible = true;
 | 
        
           |  |  | 884 |             } else {
 | 
        
           |  |  | 885 |                 $a->reviewernamevisible = false;
 | 
        
           |  |  | 886 |             }
 | 
        
           |  |  | 887 |   | 
        
           |  |  | 888 |             // the following do-while wrapper allows to break from deeply nested if-statements
 | 
        
           |  |  | 889 |             do {
 | 
        
           |  |  | 890 |                 if ($a->reviewerid === $USER->id) {
 | 
        
           |  |  | 891 |                     // own assessments always visible
 | 
        
           |  |  | 892 |                     $assessments[$activity->assessmentid] = $a;
 | 
        
           |  |  | 893 |                     break;
 | 
        
           |  |  | 894 |                 }
 | 
        
           |  |  | 895 |   | 
        
           |  |  | 896 |                 if (has_capability('mod/workshop:viewallassessments', $context)) {
 | 
        
           |  |  | 897 |                     if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
 | 
        
           |  |  | 898 |                         if (isguestuser()) {
 | 
        
           |  |  | 899 |                             // shortcut - guest user does not belong into any group
 | 
        
           |  |  | 900 |                             break;
 | 
        
           |  |  | 901 |                         }
 | 
        
           |  |  | 902 |   | 
        
           |  |  | 903 |                         // this might be slow - show only submissions by users who share group with me in this cm
 | 
        
           |  |  | 904 |                         if (!$modinfo->get_groups($cm->groupingid)) {
 | 
        
           |  |  | 905 |                             break;
 | 
        
           |  |  | 906 |                         }
 | 
        
           |  |  | 907 |                         $reviewersgroups = groups_get_all_groups($course->id, $a->reviewerid, $cm->groupingid);
 | 
        
           |  |  | 908 |                         if (is_array($reviewersgroups)) {
 | 
        
           |  |  | 909 |                             $reviewersgroups = array_keys($reviewersgroups);
 | 
        
           |  |  | 910 |                             $intersect = array_intersect($reviewersgroups, $modinfo->get_groups($cm->groupingid));
 | 
        
           |  |  | 911 |                             if (empty($intersect)) {
 | 
        
           |  |  | 912 |                                 break;
 | 
        
           |  |  | 913 |                             } else {
 | 
        
           |  |  | 914 |                                 // can see all assessments and shares a group with the reviewer
 | 
        
           |  |  | 915 |                                 $assessments[$activity->assessmentid] = $a;
 | 
        
           |  |  | 916 |                                 break;
 | 
        
           |  |  | 917 |                             }
 | 
        
           |  |  | 918 |                         }
 | 
        
           |  |  | 919 |   | 
        
           |  |  | 920 |                     } else {
 | 
        
           |  |  | 921 |                         // can see all assessments from all groups
 | 
        
           |  |  | 922 |                         $assessments[$activity->assessmentid] = $a;
 | 
        
           |  |  | 923 |                     }
 | 
        
           |  |  | 924 |                 }
 | 
        
           |  |  | 925 |             } while (0);
 | 
        
           |  |  | 926 |         }
 | 
        
           |  |  | 927 |     }
 | 
        
           |  |  | 928 |     $rs->close();
 | 
        
           |  |  | 929 |   | 
        
           |  |  | 930 |     $workshopname = format_string($cm->name, true);
 | 
        
           |  |  | 931 |   | 
        
           |  |  | 932 |     if ($grader) {
 | 
        
           |  |  | 933 |         require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 934 |         $grades = grade_get_grades($courseid, 'mod', 'workshop', $cm->instance, array_keys($users));
 | 
        
           |  |  | 935 |     }
 | 
        
           |  |  | 936 |   | 
        
           |  |  | 937 |     foreach ($submissions as $submission) {
 | 
        
           |  |  | 938 |         $tmpactivity                = new stdclass();
 | 
        
           |  |  | 939 |         $tmpactivity->type          = 'workshop';
 | 
        
           |  |  | 940 |         $tmpactivity->cmid          = $cm->id;
 | 
        
           |  |  | 941 |         $tmpactivity->name          = $workshopname;
 | 
        
           |  |  | 942 |         $tmpactivity->sectionnum    = $cm->sectionnum;
 | 
        
           |  |  | 943 |         $tmpactivity->timestamp     = $submission->timemodified;
 | 
        
           |  |  | 944 |         $tmpactivity->subtype       = 'submission';
 | 
        
           |  |  | 945 |         $tmpactivity->content       = $submission;
 | 
        
           |  |  | 946 |         if ($grader) {
 | 
        
           |  |  | 947 |             $tmpactivity->grade     = $grades->items[0]->grades[$submission->authorid]->str_long_grade;
 | 
        
           |  |  | 948 |         }
 | 
        
           |  |  | 949 |         if ($submission->authornamevisible and !empty($users[$submission->authorid])) {
 | 
        
           |  |  | 950 |             $tmpactivity->user      = $users[$submission->authorid];
 | 
        
           |  |  | 951 |         }
 | 
        
           |  |  | 952 |         $activities[$index++]       = $tmpactivity;
 | 
        
           |  |  | 953 |     }
 | 
        
           |  |  | 954 |   | 
        
           |  |  | 955 |     foreach ($assessments as $assessment) {
 | 
        
           |  |  | 956 |         $tmpactivity                = new stdclass();
 | 
        
           |  |  | 957 |         $tmpactivity->type          = 'workshop';
 | 
        
           |  |  | 958 |         $tmpactivity->cmid          = $cm->id;
 | 
        
           |  |  | 959 |         $tmpactivity->name          = $workshopname;
 | 
        
           |  |  | 960 |         $tmpactivity->sectionnum    = $cm->sectionnum;
 | 
        
           |  |  | 961 |         $tmpactivity->timestamp     = $assessment->timemodified;
 | 
        
           |  |  | 962 |         $tmpactivity->subtype       = 'assessment';
 | 
        
           |  |  | 963 |         $tmpactivity->content       = $assessment;
 | 
        
           |  |  | 964 |         if ($grader) {
 | 
        
           |  |  | 965 |             $tmpactivity->grade     = $grades->items[1]->grades[$assessment->reviewerid]->str_long_grade;
 | 
        
           |  |  | 966 |         }
 | 
        
           |  |  | 967 |         if ($assessment->reviewernamevisible and !empty($users[$assessment->reviewerid])) {
 | 
        
           |  |  | 968 |             $tmpactivity->user      = $users[$assessment->reviewerid];
 | 
        
           |  |  | 969 |         }
 | 
        
           |  |  | 970 |         $activities[$index++]       = $tmpactivity;
 | 
        
           |  |  | 971 |     }
 | 
        
           |  |  | 972 | }
 | 
        
           |  |  | 973 |   | 
        
           |  |  | 974 | /**
 | 
        
           |  |  | 975 |  * Print single activity item prepared by {@see workshop_get_recent_mod_activity()}
 | 
        
           |  |  | 976 |  */
 | 
        
           |  |  | 977 | function workshop_print_recent_mod_activity($activity, $courseid, $detail, $modnames, $viewfullnames) {
 | 
        
           |  |  | 978 |     global $CFG, $OUTPUT;
 | 
        
           |  |  | 979 |   | 
        
           |  |  | 980 |     if (!empty($activity->user)) {
 | 
        
           |  |  | 981 |         echo html_writer::tag('div', $OUTPUT->user_picture($activity->user, array('courseid'=>$courseid)),
 | 
        
           |  |  | 982 |                 array('style' => 'float: left; padding: 7px;'));
 | 
        
           |  |  | 983 |     }
 | 
        
           |  |  | 984 |   | 
        
           |  |  | 985 |     if ($activity->subtype == 'submission') {
 | 
        
           |  |  | 986 |         echo html_writer::start_tag('div', array('class'=>'submission', 'style'=>'padding: 7px; float:left;'));
 | 
        
           |  |  | 987 |   | 
        
           |  |  | 988 |         if ($detail) {
 | 
        
           |  |  | 989 |             echo html_writer::start_tag('h4', array('class'=>'workshop'));
 | 
        
           |  |  | 990 |             $url = new moodle_url('/mod/workshop/view.php', array('id'=>$activity->cmid));
 | 
        
           |  |  | 991 |             $name = s($activity->name);
 | 
        
           |  |  | 992 |             echo $OUTPUT->image_icon('monologo', $name, $activity->type);
 | 
        
           |  |  | 993 |             echo ' ' . $modnames[$activity->type];
 | 
        
           |  |  | 994 |             echo html_writer::link($url, $name, array('class'=>'name', 'style'=>'margin-left: 5px'));
 | 
        
           |  |  | 995 |             echo html_writer::end_tag('h4');
 | 
        
           |  |  | 996 |         }
 | 
        
           |  |  | 997 |   | 
        
           |  |  | 998 |         echo html_writer::start_tag('div', array('class'=>'title'));
 | 
        
           |  |  | 999 |         $url = new moodle_url('/mod/workshop/submission.php', array('cmid'=>$activity->cmid, 'id'=>$activity->content->id));
 | 
        
           |  |  | 1000 |         $name = s($activity->content->title);
 | 
        
           |  |  | 1001 |         echo html_writer::tag('strong', html_writer::link($url, $name));
 | 
        
           |  |  | 1002 |         echo html_writer::end_tag('div');
 | 
        
           |  |  | 1003 |   | 
        
           |  |  | 1004 |         if (!empty($activity->user)) {
 | 
        
           |  |  | 1005 |             echo html_writer::start_tag('div', array('class'=>'user'));
 | 
        
           |  |  | 1006 |             $url = new moodle_url('/user/view.php', array('id'=>$activity->user->id, 'course'=>$courseid));
 | 
        
           |  |  | 1007 |             $name = fullname($activity->user);
 | 
        
           |  |  | 1008 |             $link = html_writer::link($url, $name);
 | 
        
           |  |  | 1009 |             echo get_string('submissionby', 'workshop', $link);
 | 
        
           |  |  | 1010 |             echo ' - '.userdate($activity->timestamp);
 | 
        
           |  |  | 1011 |             echo html_writer::end_tag('div');
 | 
        
           |  |  | 1012 |         } else {
 | 
        
           |  |  | 1013 |             echo html_writer::start_tag('div', array('class'=>'anonymous'));
 | 
        
           |  |  | 1014 |             echo get_string('submission', 'workshop');
 | 
        
           |  |  | 1015 |             echo ' - '.userdate($activity->timestamp);
 | 
        
           |  |  | 1016 |             echo html_writer::end_tag('div');
 | 
        
           |  |  | 1017 |         }
 | 
        
           |  |  | 1018 |   | 
        
           |  |  | 1019 |         echo html_writer::end_tag('div');
 | 
        
           |  |  | 1020 |     }
 | 
        
           |  |  | 1021 |   | 
        
           |  |  | 1022 |     if ($activity->subtype == 'assessment') {
 | 
        
           |  |  | 1023 |         echo html_writer::start_tag('div', array('class'=>'assessment', 'style'=>'padding: 7px; float:left;'));
 | 
        
           |  |  | 1024 |   | 
        
           |  |  | 1025 |         if ($detail) {
 | 
        
           |  |  | 1026 |             echo html_writer::start_tag('h4', array('class'=>'workshop'));
 | 
        
           |  |  | 1027 |             $url = new moodle_url('/mod/workshop/view.php', array('id'=>$activity->cmid));
 | 
        
           |  |  | 1028 |             $name = s($activity->name);
 | 
        
           |  |  | 1029 |             echo $OUTPUT->image_icon('monologo', $name, $activity->type);
 | 
        
           |  |  | 1030 |             echo ' ' . $modnames[$activity->type];
 | 
        
           |  |  | 1031 |             echo html_writer::link($url, $name, array('class'=>'name', 'style'=>'margin-left: 5px'));
 | 
        
           |  |  | 1032 |             echo html_writer::end_tag('h4');
 | 
        
           |  |  | 1033 |         }
 | 
        
           |  |  | 1034 |   | 
        
           |  |  | 1035 |         echo html_writer::start_tag('div', array('class'=>'title'));
 | 
        
           |  |  | 1036 |         $url = new moodle_url('/mod/workshop/assessment.php', array('asid'=>$activity->content->id));
 | 
        
           |  |  | 1037 |         $name = s($activity->content->submissiontitle);
 | 
        
           |  |  | 1038 |         echo html_writer::tag('em', html_writer::link($url, $name));
 | 
        
           |  |  | 1039 |         echo html_writer::end_tag('div');
 | 
        
           |  |  | 1040 |   | 
        
           |  |  | 1041 |         if (!empty($activity->user)) {
 | 
        
           |  |  | 1042 |             echo html_writer::start_tag('div', array('class'=>'user'));
 | 
        
           |  |  | 1043 |             $url = new moodle_url('/user/view.php', array('id'=>$activity->user->id, 'course'=>$courseid));
 | 
        
           |  |  | 1044 |             $name = fullname($activity->user);
 | 
        
           |  |  | 1045 |             $link = html_writer::link($url, $name);
 | 
        
           |  |  | 1046 |             echo get_string('assessmentbyfullname', 'workshop', $link);
 | 
        
           |  |  | 1047 |             echo ' - '.userdate($activity->timestamp);
 | 
        
           |  |  | 1048 |             echo html_writer::end_tag('div');
 | 
        
           |  |  | 1049 |         } else {
 | 
        
           |  |  | 1050 |             echo html_writer::start_tag('div', array('class'=>'anonymous'));
 | 
        
           |  |  | 1051 |             echo get_string('assessment', 'workshop');
 | 
        
           |  |  | 1052 |             echo ' - '.userdate($activity->timestamp);
 | 
        
           |  |  | 1053 |             echo html_writer::end_tag('div');
 | 
        
           |  |  | 1054 |         }
 | 
        
           |  |  | 1055 |   | 
        
           |  |  | 1056 |         echo html_writer::end_tag('div');
 | 
        
           |  |  | 1057 |     }
 | 
        
           |  |  | 1058 |   | 
        
           |  |  | 1059 |     echo html_writer::empty_tag('br', array('style'=>'clear:both'));
 | 
        
           |  |  | 1060 | }
 | 
        
           |  |  | 1061 |   | 
        
           |  |  | 1062 | /**
 | 
        
           |  |  | 1063 |  * Is a given scale used by any instance of workshop?
 | 
        
           |  |  | 1064 |  *
 | 
        
           |  |  | 1065 |  * The function asks all installed grading strategy subplugins. The workshop
 | 
        
           |  |  | 1066 |  * core itself does not use scales. Both grade for submission and grade for
 | 
        
           |  |  | 1067 |  * assessments do not use scales.
 | 
        
           |  |  | 1068 |  *
 | 
        
           |  |  | 1069 |  * @param int $scaleid id of the scale to check
 | 
        
           |  |  | 1070 |  * @return bool
 | 
        
           |  |  | 1071 |  */
 | 
        
           |  |  | 1072 | function workshop_scale_used_anywhere($scaleid) {
 | 
        
           |  |  | 1073 |     global $CFG; // other files included from here
 | 
        
           |  |  | 1074 |   | 
        
           |  |  | 1075 |     $strategies = core_component::get_plugin_list('workshopform');
 | 
        
           |  |  | 1076 |     foreach ($strategies as $strategy => $strategypath) {
 | 
        
           |  |  | 1077 |         $strategylib = $strategypath . '/lib.php';
 | 
        
           |  |  | 1078 |         if (is_readable($strategylib)) {
 | 
        
           |  |  | 1079 |             require_once($strategylib);
 | 
        
           |  |  | 1080 |         } else {
 | 
        
           |  |  | 1081 |             throw new coding_exception('the grading forms subplugin must contain library ' . $strategylib);
 | 
        
           |  |  | 1082 |         }
 | 
        
           |  |  | 1083 |         $classname = 'workshop_' . $strategy . '_strategy';
 | 
        
           |  |  | 1084 |         if (method_exists($classname, 'scale_used')) {
 | 
        
           |  |  | 1085 |             if (call_user_func(array($classname, 'scale_used'), $scaleid)) {
 | 
        
           |  |  | 1086 |                 // no need to include any other files - scale is used
 | 
        
           |  |  | 1087 |                 return true;
 | 
        
           |  |  | 1088 |             }
 | 
        
           |  |  | 1089 |         }
 | 
        
           |  |  | 1090 |     }
 | 
        
           |  |  | 1091 |   | 
        
           |  |  | 1092 |     return false;
 | 
        
           |  |  | 1093 | }
 | 
        
           |  |  | 1094 |   | 
        
           |  |  | 1095 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1096 | // Gradebook API                                                              //
 | 
        
           |  |  | 1097 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1098 |   | 
        
           |  |  | 1099 | /**
 | 
        
           |  |  | 1100 |  * Creates or updates grade items for the give workshop instance
 | 
        
           |  |  | 1101 |  *
 | 
        
           |  |  | 1102 |  * Needed by grade_update_mod_grades() in lib/gradelib.php. Also used by
 | 
        
           |  |  | 1103 |  * {@link workshop_update_grades()}.
 | 
        
           |  |  | 1104 |  *
 | 
        
           |  |  | 1105 |  * @param stdClass $workshop instance object with extra cmidnumber property
 | 
        
           |  |  | 1106 |  * @param stdClass $submissiongrades data for the first grade item
 | 
        
           |  |  | 1107 |  * @param stdClass $assessmentgrades data for the second grade item
 | 
        
           |  |  | 1108 |  * @return void
 | 
        
           |  |  | 1109 |  */
 | 
        
           |  |  | 1110 | function workshop_grade_item_update(stdclass $workshop, $submissiongrades=null, $assessmentgrades=null) {
 | 
        
           |  |  | 1111 |     global $CFG;
 | 
        
           |  |  | 1112 |     require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 1113 |   | 
        
           |  |  | 1114 |     $a = new stdclass();
 | 
        
           |  |  | 1115 |     $a->workshopname = clean_param($workshop->name, PARAM_NOTAGS);
 | 
        
           |  |  | 1116 |   | 
        
           |  |  | 1117 |     $item = array();
 | 
        
           |  |  | 1118 |     $item['itemname'] = get_string('gradeitemsubmission', 'workshop', $a);
 | 
        
           |  |  | 1119 |     $item['gradetype'] = GRADE_TYPE_VALUE;
 | 
        
           |  |  | 1120 |     $item['grademax']  = $workshop->grade;
 | 
        
           |  |  | 1121 |     $item['grademin']  = 0;
 | 
        
           |  |  | 1122 |     grade_update('mod/workshop', $workshop->course, 'mod', 'workshop', $workshop->id, 0, $submissiongrades , $item);
 | 
        
           |  |  | 1123 |   | 
        
           |  |  | 1124 |     $item = array();
 | 
        
           |  |  | 1125 |     $item['itemname'] = get_string('gradeitemassessment', 'workshop', $a);
 | 
        
           |  |  | 1126 |     $item['gradetype'] = GRADE_TYPE_VALUE;
 | 
        
           |  |  | 1127 |     $item['grademax']  = $workshop->gradinggrade;
 | 
        
           |  |  | 1128 |     $item['grademin']  = 0;
 | 
        
           |  |  | 1129 |     grade_update('mod/workshop', $workshop->course, 'mod', 'workshop', $workshop->id, 1, $assessmentgrades, $item);
 | 
        
           |  |  | 1130 | }
 | 
        
           |  |  | 1131 |   | 
        
           |  |  | 1132 | /**
 | 
        
           |  |  | 1133 |  * Update workshop grades in the gradebook
 | 
        
           |  |  | 1134 |  *
 | 
        
           |  |  | 1135 |  * Needed by grade_update_mod_grades() in lib/gradelib.php
 | 
        
           |  |  | 1136 |  *
 | 
        
           |  |  | 1137 |  * @category grade
 | 
        
           |  |  | 1138 |  * @param stdClass $workshop instance object with extra cmidnumber and modname property
 | 
        
           |  |  | 1139 |  * @param int $userid        update grade of specific user only, 0 means all participants
 | 
        
           |  |  | 1140 |  * @return void
 | 
        
           |  |  | 1141 |  */
 | 
        
           |  |  | 1142 | function workshop_update_grades(stdclass $workshop, $userid=0) {
 | 
        
           |  |  | 1143 |     global $CFG, $DB;
 | 
        
           |  |  | 1144 |     require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 1145 |   | 
        
           |  |  | 1146 |     $whereuser = $userid ? ' AND authorid = :userid' : '';
 | 
        
           |  |  | 1147 |     $params = array('workshopid' => $workshop->id, 'userid' => $userid);
 | 
        
           |  |  | 1148 |     $sql = 'SELECT authorid, grade, gradeover, gradeoverby, feedbackauthor, feedbackauthorformat, timemodified, timegraded
 | 
        
           |  |  | 1149 |               FROM {workshop_submissions}
 | 
        
           |  |  | 1150 |              WHERE workshopid = :workshopid AND example=0' . $whereuser;
 | 
        
           |  |  | 1151 |     $records = $DB->get_records_sql($sql, $params);
 | 
        
           |  |  | 1152 |     $submissiongrades = array();
 | 
        
           |  |  | 1153 |     foreach ($records as $record) {
 | 
        
           |  |  | 1154 |         $grade = new stdclass();
 | 
        
           |  |  | 1155 |         $grade->userid = $record->authorid;
 | 
        
           |  |  | 1156 |         if (!is_null($record->gradeover)) {
 | 
        
           |  |  | 1157 |             $grade->rawgrade = grade_floatval($workshop->grade * $record->gradeover / 100);
 | 
        
           |  |  | 1158 |             $grade->usermodified = $record->gradeoverby;
 | 
        
           |  |  | 1159 |         } else {
 | 
        
           |  |  | 1160 |             $grade->rawgrade = grade_floatval($workshop->grade * $record->grade / 100);
 | 
        
           |  |  | 1161 |         }
 | 
        
           |  |  | 1162 |         $grade->feedback = $record->feedbackauthor;
 | 
        
           |  |  | 1163 |         $grade->feedbackformat = $record->feedbackauthorformat;
 | 
        
           |  |  | 1164 |         $grade->datesubmitted = $record->timemodified;
 | 
        
           |  |  | 1165 |         $grade->dategraded = $record->timegraded;
 | 
        
           |  |  | 1166 |         $submissiongrades[$record->authorid] = $grade;
 | 
        
           |  |  | 1167 |     }
 | 
        
           |  |  | 1168 |   | 
        
           |  |  | 1169 |     $whereuser = $userid ? ' AND userid = :userid' : '';
 | 
        
           |  |  | 1170 |     $params = array('workshopid' => $workshop->id, 'userid' => $userid);
 | 
        
           |  |  | 1171 |     $sql = 'SELECT userid, gradinggrade, timegraded
 | 
        
           |  |  | 1172 |               FROM {workshop_aggregations}
 | 
        
           |  |  | 1173 |              WHERE workshopid = :workshopid' . $whereuser;
 | 
        
           |  |  | 1174 |     $records = $DB->get_records_sql($sql, $params);
 | 
        
           |  |  | 1175 |     $assessmentgrades = array();
 | 
        
           |  |  | 1176 |     foreach ($records as $record) {
 | 
        
           |  |  | 1177 |         $grade = new stdclass();
 | 
        
           |  |  | 1178 |         $grade->userid = $record->userid;
 | 
        
           |  |  | 1179 |         $grade->rawgrade = grade_floatval($workshop->gradinggrade * $record->gradinggrade / 100);
 | 
        
           |  |  | 1180 |         $grade->dategraded = $record->timegraded;
 | 
        
           |  |  | 1181 |         $assessmentgrades[$record->userid] = $grade;
 | 
        
           |  |  | 1182 |     }
 | 
        
           |  |  | 1183 |   | 
        
           |  |  | 1184 |     workshop_grade_item_update($workshop, $submissiongrades, $assessmentgrades);
 | 
        
           |  |  | 1185 | }
 | 
        
           |  |  | 1186 |   | 
        
           |  |  | 1187 | /**
 | 
        
           |  |  | 1188 |  * Update the grade items categories if they are changed via mod_form.php
 | 
        
           |  |  | 1189 |  *
 | 
        
           |  |  | 1190 |  * We must do it manually here in the workshop module because modedit supports only
 | 
        
           |  |  | 1191 |  * single grade item while we use two.
 | 
        
           |  |  | 1192 |  *
 | 
        
           |  |  | 1193 |  * @param stdClass $workshop An object from the form in mod_form.php
 | 
        
           |  |  | 1194 |  */
 | 
        
           |  |  | 1195 | function workshop_grade_item_category_update($workshop) {
 | 
        
           |  |  | 1196 |   | 
        
           |  |  | 1197 |     $gradeitems = grade_item::fetch_all(array(
 | 
        
           |  |  | 1198 |         'itemtype'      => 'mod',
 | 
        
           |  |  | 1199 |         'itemmodule'    => 'workshop',
 | 
        
           |  |  | 1200 |         'iteminstance'  => $workshop->id,
 | 
        
           |  |  | 1201 |         'courseid'      => $workshop->course));
 | 
        
           |  |  | 1202 |   | 
        
           |  |  | 1203 |     if (!empty($gradeitems)) {
 | 
        
           |  |  | 1204 |         foreach ($gradeitems as $gradeitem) {
 | 
        
           |  |  | 1205 |             if ($gradeitem->itemnumber == 0) {
 | 
        
           |  |  | 1206 |                 if (isset($workshop->submissiongradepass) &&
 | 
        
           |  |  | 1207 |                         $gradeitem->gradepass != $workshop->submissiongradepass) {
 | 
        
           |  |  | 1208 |                     $gradeitem->gradepass = $workshop->submissiongradepass;
 | 
        
           |  |  | 1209 |                     $gradeitem->update();
 | 
        
           |  |  | 1210 |                 }
 | 
        
           |  |  | 1211 |                 if ($gradeitem->categoryid != $workshop->gradecategory) {
 | 
        
           |  |  | 1212 |                     $gradeitem->set_parent($workshop->gradecategory);
 | 
        
           |  |  | 1213 |                 }
 | 
        
           |  |  | 1214 |             } else if ($gradeitem->itemnumber == 1) {
 | 
        
           |  |  | 1215 |                 if (isset($workshop->gradinggradepass) &&
 | 
        
           |  |  | 1216 |                         $gradeitem->gradepass != $workshop->gradinggradepass) {
 | 
        
           |  |  | 1217 |                     $gradeitem->gradepass = $workshop->gradinggradepass;
 | 
        
           |  |  | 1218 |                     $gradeitem->update();
 | 
        
           |  |  | 1219 |                 }
 | 
        
           |  |  | 1220 |                 if ($gradeitem->categoryid != $workshop->gradinggradecategory) {
 | 
        
           |  |  | 1221 |                     $gradeitem->set_parent($workshop->gradinggradecategory);
 | 
        
           |  |  | 1222 |                 }
 | 
        
           |  |  | 1223 |             }
 | 
        
           |  |  | 1224 |         }
 | 
        
           |  |  | 1225 |     }
 | 
        
           |  |  | 1226 | }
 | 
        
           |  |  | 1227 |   | 
        
           |  |  | 1228 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1229 | // File API                                                                   //
 | 
        
           |  |  | 1230 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1231 |   | 
        
           |  |  | 1232 | /**
 | 
        
           |  |  | 1233 |  * Returns the lists of all browsable file areas within the given module context
 | 
        
           |  |  | 1234 |  *
 | 
        
           |  |  | 1235 |  * The file area workshop_intro for the activity introduction field is added automatically
 | 
        
           |  |  | 1236 |  * by {@link file_browser::get_file_info_context_module()}
 | 
        
           |  |  | 1237 |  *
 | 
        
           |  |  | 1238 |  * @package  mod_workshop
 | 
        
           |  |  | 1239 |  * @category files
 | 
        
           |  |  | 1240 |  *
 | 
        
           |  |  | 1241 |  * @param stdClass $course
 | 
        
           |  |  | 1242 |  * @param stdClass $cm
 | 
        
           |  |  | 1243 |  * @param stdClass $context
 | 
        
           |  |  | 1244 |  * @return array of [(string)filearea] => (string)description
 | 
        
           |  |  | 1245 |  */
 | 
        
           |  |  | 1246 | function workshop_get_file_areas($course, $cm, $context) {
 | 
        
           |  |  | 1247 |     $areas = array();
 | 
        
           |  |  | 1248 |     $areas['instructauthors']          = get_string('areainstructauthors', 'workshop');
 | 
        
           |  |  | 1249 |     $areas['instructreviewers']        = get_string('areainstructreviewers', 'workshop');
 | 
        
           |  |  | 1250 |     $areas['submission_content']       = get_string('areasubmissioncontent', 'workshop');
 | 
        
           |  |  | 1251 |     $areas['submission_attachment']    = get_string('areasubmissionattachment', 'workshop');
 | 
        
           |  |  | 1252 |     $areas['conclusion']               = get_string('areaconclusion', 'workshop');
 | 
        
           |  |  | 1253 |     $areas['overallfeedback_content']  = get_string('areaoverallfeedbackcontent', 'workshop');
 | 
        
           |  |  | 1254 |     $areas['overallfeedback_attachment'] = get_string('areaoverallfeedbackattachment', 'workshop');
 | 
        
           |  |  | 1255 |   | 
        
           |  |  | 1256 |     return $areas;
 | 
        
           |  |  | 1257 | }
 | 
        
           |  |  | 1258 |   | 
        
           |  |  | 1259 | /**
 | 
        
           |  |  | 1260 |  * Serves the files from the workshop file areas
 | 
        
           |  |  | 1261 |  *
 | 
        
           |  |  | 1262 |  * Apart from module intro (handled by pluginfile.php automatically), workshop files may be
 | 
        
           |  |  | 1263 |  * media inserted into submission content (like images) and submission attachments. For these two,
 | 
        
           |  |  | 1264 |  * the fileareas submission_content and submission_attachment are used.
 | 
        
           |  |  | 1265 |  * Besides that, areas instructauthors, instructreviewers and conclusion contain the media
 | 
        
           |  |  | 1266 |  * embedded using the mod_form.php.
 | 
        
           |  |  | 1267 |  *
 | 
        
           |  |  | 1268 |  * @package  mod_workshop
 | 
        
           |  |  | 1269 |  * @category files
 | 
        
           |  |  | 1270 |  *
 | 
        
           |  |  | 1271 |  * @param stdClass $course the course object
 | 
        
           |  |  | 1272 |  * @param stdClass $cm the course module object
 | 
        
           |  |  | 1273 |  * @param stdClass $context the workshop's context
 | 
        
           |  |  | 1274 |  * @param string $filearea the name of the file area
 | 
        
           |  |  | 1275 |  * @param array $args extra arguments (itemid, path)
 | 
        
           |  |  | 1276 |  * @param bool $forcedownload whether or not force download
 | 
        
           |  |  | 1277 |  * @param array $options additional options affecting the file serving
 | 
        
           |  |  | 1278 |  * @return bool false if the file not found, just send the file otherwise and do not return anything
 | 
        
           |  |  | 1279 |  */
 | 
        
           |  |  | 1280 | function workshop_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload, array $options=array()) {
 | 
        
           |  |  | 1281 |     global $DB, $CFG, $USER;
 | 
        
           |  |  | 1282 |   | 
        
           |  |  | 1283 |     if ($context->contextlevel != CONTEXT_MODULE) {
 | 
        
           |  |  | 1284 |         return false;
 | 
        
           |  |  | 1285 |     }
 | 
        
           |  |  | 1286 |   | 
        
           |  |  | 1287 |     require_login($course, true, $cm);
 | 
        
           |  |  | 1288 |   | 
        
           |  |  | 1289 |     if ($filearea === 'instructauthors' or $filearea === 'instructreviewers' or $filearea === 'conclusion') {
 | 
        
           |  |  | 1290 |         // The $args are supposed to contain just the path, not the item id.
 | 
        
           |  |  | 1291 |         $relativepath = implode('/', $args);
 | 
        
           |  |  | 1292 |         $fullpath = "/$context->id/mod_workshop/$filearea/0/$relativepath";
 | 
        
           |  |  | 1293 |   | 
        
           |  |  | 1294 |         $fs = get_file_storage();
 | 
        
           |  |  | 1295 |         if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
 | 
        
           |  |  | 1296 |             send_file_not_found();
 | 
        
           |  |  | 1297 |         }
 | 
        
           |  |  | 1298 |         send_stored_file($file, null, 0, $forcedownload, $options);
 | 
        
           |  |  | 1299 |   | 
        
           |  |  | 1300 |     } else if ($filearea === 'submission_content' or $filearea === 'submission_attachment') {
 | 
        
           |  |  | 1301 |         $itemid = (int)array_shift($args);
 | 
        
           |  |  | 1302 |         if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) {
 | 
        
           |  |  | 1303 |             return false;
 | 
        
           |  |  | 1304 |         }
 | 
        
           |  |  | 1305 |         if (!$submission = $DB->get_record('workshop_submissions', array('id' => $itemid, 'workshopid' => $workshop->id))) {
 | 
        
           |  |  | 1306 |             return false;
 | 
        
           |  |  | 1307 |         }
 | 
        
           |  |  | 1308 |   | 
        
           |  |  | 1309 |         // make sure the user is allowed to see the file
 | 
        
           |  |  | 1310 |         if (empty($submission->example)) {
 | 
        
           |  |  | 1311 |             if ($USER->id != $submission->authorid) {
 | 
        
           |  |  | 1312 |                 if ($submission->published == 1 and $workshop->phase == 50
 | 
        
           |  |  | 1313 |                         and has_capability('mod/workshop:viewpublishedsubmissions', $context)) {
 | 
        
           |  |  | 1314 |                     // Published submission, we can go (workshop does not take the group mode
 | 
        
           |  |  | 1315 |                     // into account in this case yet).
 | 
        
           |  |  | 1316 |                 } else if (!$DB->record_exists('workshop_assessments', array('submissionid' => $submission->id, 'reviewerid' => $USER->id))) {
 | 
        
           |  |  | 1317 |                     if (!has_capability('mod/workshop:viewallsubmissions', $context)) {
 | 
        
           |  |  | 1318 |                         send_file_not_found();
 | 
        
           |  |  | 1319 |                     } else {
 | 
        
           |  |  | 1320 |                         $gmode = groups_get_activity_groupmode($cm, $course);
 | 
        
           |  |  | 1321 |                         if ($gmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
 | 
        
           |  |  | 1322 |                             // check there is at least one common group with both the $USER
 | 
        
           |  |  | 1323 |                             // and the submission author
 | 
        
           |  |  | 1324 |                             $sql = "SELECT 'x'
 | 
        
           |  |  | 1325 |                                       FROM {workshop_submissions} s
 | 
        
           |  |  | 1326 |                                       JOIN {user} a ON (a.id = s.authorid)
 | 
        
           |  |  | 1327 |                                       JOIN {groups_members} agm ON (a.id = agm.userid)
 | 
        
           |  |  | 1328 |                                       JOIN {user} u ON (u.id = ?)
 | 
        
           |  |  | 1329 |                                       JOIN {groups_members} ugm ON (u.id = ugm.userid)
 | 
        
           |  |  | 1330 |                                      WHERE s.example = 0 AND s.workshopid = ? AND s.id = ? AND agm.groupid = ugm.groupid";
 | 
        
           |  |  | 1331 |                             $params = array($USER->id, $workshop->id, $submission->id);
 | 
        
           |  |  | 1332 |                             if (!$DB->record_exists_sql($sql, $params)) {
 | 
        
           |  |  | 1333 |                                 send_file_not_found();
 | 
        
           |  |  | 1334 |                             }
 | 
        
           |  |  | 1335 |                         }
 | 
        
           |  |  | 1336 |                     }
 | 
        
           |  |  | 1337 |                 }
 | 
        
           |  |  | 1338 |             }
 | 
        
           |  |  | 1339 |         }
 | 
        
           |  |  | 1340 |   | 
        
           |  |  | 1341 |         $fs = get_file_storage();
 | 
        
           |  |  | 1342 |         $relativepath = implode('/', $args);
 | 
        
           |  |  | 1343 |         $fullpath = "/$context->id/mod_workshop/$filearea/$itemid/$relativepath";
 | 
        
           |  |  | 1344 |         if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
 | 
        
           |  |  | 1345 |             return false;
 | 
        
           |  |  | 1346 |         }
 | 
        
           |  |  | 1347 |         // finally send the file
 | 
        
           |  |  | 1348 |         // these files are uploaded by students - forcing download for security reasons
 | 
        
           |  |  | 1349 |         send_stored_file($file, 0, 0, true, $options);
 | 
        
           |  |  | 1350 |   | 
        
           |  |  | 1351 |     } else if ($filearea === 'overallfeedback_content' or $filearea === 'overallfeedback_attachment') {
 | 
        
           |  |  | 1352 |         $itemid = (int)array_shift($args);
 | 
        
           |  |  | 1353 |         if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) {
 | 
        
           |  |  | 1354 |             return false;
 | 
        
           |  |  | 1355 |         }
 | 
        
           |  |  | 1356 |         if (!$assessment = $DB->get_record('workshop_assessments', array('id' => $itemid))) {
 | 
        
           |  |  | 1357 |             return false;
 | 
        
           |  |  | 1358 |         }
 | 
        
           |  |  | 1359 |         if (!$submission = $DB->get_record('workshop_submissions', array('id' => $assessment->submissionid, 'workshopid' => $workshop->id))) {
 | 
        
           |  |  | 1360 |             return false;
 | 
        
           |  |  | 1361 |         }
 | 
        
           |  |  | 1362 |   | 
        
           |  |  | 1363 |         if ($USER->id == $assessment->reviewerid) {
 | 
        
           |  |  | 1364 |             // Reviewers can always see their own files.
 | 
        
           |  |  | 1365 |         } else if ($USER->id == $submission->authorid and $workshop->phase == 50) {
 | 
        
           |  |  | 1366 |             // Authors can see the feedback once the workshop is closed.
 | 
        
           |  |  | 1367 |         } else if (!empty($submission->example) and $assessment->weight == 1) {
 | 
        
           |  |  | 1368 |             // Reference assessments of example submissions can be displayed.
 | 
        
           |  |  | 1369 |         } else if (!has_capability('mod/workshop:viewallassessments', $context)) {
 | 
        
           |  |  | 1370 |             send_file_not_found();
 | 
        
           |  |  | 1371 |         } else {
 | 
        
           |  |  | 1372 |             $gmode = groups_get_activity_groupmode($cm, $course);
 | 
        
           |  |  | 1373 |             if ($gmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
 | 
        
           |  |  | 1374 |                 // Check there is at least one common group with both the $USER
 | 
        
           |  |  | 1375 |                 // and the submission author.
 | 
        
           |  |  | 1376 |                 $sql = "SELECT 'x'
 | 
        
           |  |  | 1377 |                           FROM {workshop_submissions} s
 | 
        
           |  |  | 1378 |                           JOIN {user} a ON (a.id = s.authorid)
 | 
        
           |  |  | 1379 |                           JOIN {groups_members} agm ON (a.id = agm.userid)
 | 
        
           |  |  | 1380 |                           JOIN {user} u ON (u.id = ?)
 | 
        
           |  |  | 1381 |                           JOIN {groups_members} ugm ON (u.id = ugm.userid)
 | 
        
           |  |  | 1382 |                          WHERE s.example = 0 AND s.workshopid = ? AND s.id = ? AND agm.groupid = ugm.groupid";
 | 
        
           |  |  | 1383 |                 $params = array($USER->id, $workshop->id, $submission->id);
 | 
        
           |  |  | 1384 |                 if (!$DB->record_exists_sql($sql, $params)) {
 | 
        
           |  |  | 1385 |                     send_file_not_found();
 | 
        
           |  |  | 1386 |                 }
 | 
        
           |  |  | 1387 |             }
 | 
        
           |  |  | 1388 |         }
 | 
        
           |  |  | 1389 |   | 
        
           |  |  | 1390 |         $fs = get_file_storage();
 | 
        
           |  |  | 1391 |         $relativepath = implode('/', $args);
 | 
        
           |  |  | 1392 |         $fullpath = "/$context->id/mod_workshop/$filearea/$itemid/$relativepath";
 | 
        
           |  |  | 1393 |         if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
 | 
        
           |  |  | 1394 |             return false;
 | 
        
           |  |  | 1395 |         }
 | 
        
           |  |  | 1396 |         // finally send the file
 | 
        
           |  |  | 1397 |         // these files are uploaded by students - forcing download for security reasons
 | 
        
           |  |  | 1398 |         send_stored_file($file, 0, 0, true, $options);
 | 
        
           |  |  | 1399 |     }
 | 
        
           |  |  | 1400 |   | 
        
           |  |  | 1401 |     return false;
 | 
        
           |  |  | 1402 | }
 | 
        
           |  |  | 1403 |   | 
        
           |  |  | 1404 | /**
 | 
        
           |  |  | 1405 |  * File browsing support for workshop file areas
 | 
        
           |  |  | 1406 |  *
 | 
        
           |  |  | 1407 |  * @package  mod_workshop
 | 
        
           |  |  | 1408 |  * @category files
 | 
        
           |  |  | 1409 |  *
 | 
        
           |  |  | 1410 |  * @param file_browser $browser
 | 
        
           |  |  | 1411 |  * @param array $areas
 | 
        
           |  |  | 1412 |  * @param stdClass $course
 | 
        
           |  |  | 1413 |  * @param stdClass $cm
 | 
        
           |  |  | 1414 |  * @param stdClass $context
 | 
        
           |  |  | 1415 |  * @param string $filearea
 | 
        
           |  |  | 1416 |  * @param int $itemid
 | 
        
           |  |  | 1417 |  * @param string $filepath
 | 
        
           |  |  | 1418 |  * @param string $filename
 | 
        
           |  |  | 1419 |  * @return file_info instance or null if not found
 | 
        
           |  |  | 1420 |  */
 | 
        
           |  |  | 1421 | function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
 | 
        
           |  |  | 1422 |     global $CFG, $DB, $USER;
 | 
        
           |  |  | 1423 |   | 
        
           |  |  | 1424 |     /** @var array internal cache for author names */
 | 
        
           |  |  | 1425 |     static $submissionauthors = array();
 | 
        
           |  |  | 1426 |   | 
        
           |  |  | 1427 |     $fs = get_file_storage();
 | 
        
           |  |  | 1428 |   | 
        
           |  |  | 1429 |     if ($filearea === 'submission_content' or $filearea === 'submission_attachment') {
 | 
        
           |  |  | 1430 |   | 
        
           |  |  | 1431 |         if (!has_capability('mod/workshop:viewallsubmissions', $context)) {
 | 
        
           |  |  | 1432 |             return null;
 | 
        
           |  |  | 1433 |         }
 | 
        
           |  |  | 1434 |   | 
        
           |  |  | 1435 |         if (is_null($itemid)) {
 | 
        
           |  |  | 1436 |             // no itemid (submissionid) passed, display the list of all submissions
 | 
        
           |  |  | 1437 |             require_once($CFG->dirroot . '/mod/workshop/fileinfolib.php');
 | 
        
           |  |  | 1438 |             return new workshop_file_info_submissions_container($browser, $course, $cm, $context, $areas, $filearea);
 | 
        
           |  |  | 1439 |         }
 | 
        
           |  |  | 1440 |   | 
        
           |  |  | 1441 |         // make sure the user can see the particular submission in separate groups mode
 | 
        
           |  |  | 1442 |         $gmode = groups_get_activity_groupmode($cm, $course);
 | 
        
           |  |  | 1443 |   | 
        
           |  |  | 1444 |         if ($gmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
 | 
        
           |  |  | 1445 |             // check there is at least one common group with both the $USER
 | 
        
           |  |  | 1446 |             // and the submission author (this is not expected to be a frequent
 | 
        
           |  |  | 1447 |             // usecase so we can live with pretty ineffective one query per submission here...)
 | 
        
           |  |  | 1448 |             $sql = "SELECT 'x'
 | 
        
           |  |  | 1449 |                       FROM {workshop_submissions} s
 | 
        
           |  |  | 1450 |                       JOIN {user} a ON (a.id = s.authorid)
 | 
        
           |  |  | 1451 |                       JOIN {groups_members} agm ON (a.id = agm.userid)
 | 
        
           |  |  | 1452 |                       JOIN {user} u ON (u.id = ?)
 | 
        
           |  |  | 1453 |                       JOIN {groups_members} ugm ON (u.id = ugm.userid)
 | 
        
           |  |  | 1454 |                      WHERE s.example = 0 AND s.workshopid = ? AND s.id = ? AND agm.groupid = ugm.groupid";
 | 
        
           |  |  | 1455 |             $params = array($USER->id, $cm->instance, $itemid);
 | 
        
           |  |  | 1456 |             if (!$DB->record_exists_sql($sql, $params)) {
 | 
        
           |  |  | 1457 |                 return null;
 | 
        
           |  |  | 1458 |             }
 | 
        
           |  |  | 1459 |         }
 | 
        
           |  |  | 1460 |   | 
        
           |  |  | 1461 |         // we are inside some particular submission container
 | 
        
           |  |  | 1462 |   | 
        
           |  |  | 1463 |         $filepath = is_null($filepath) ? '/' : $filepath;
 | 
        
           |  |  | 1464 |         $filename = is_null($filename) ? '.' : $filename;
 | 
        
           |  |  | 1465 |   | 
        
           |  |  | 1466 |         if (!$storedfile = $fs->get_file($context->id, 'mod_workshop', $filearea, $itemid, $filepath, $filename)) {
 | 
        
           |  |  | 1467 |             if ($filepath === '/' and $filename === '.') {
 | 
        
           |  |  | 1468 |                 $storedfile = new virtual_root_file($context->id, 'mod_workshop', $filearea, $itemid);
 | 
        
           |  |  | 1469 |             } else {
 | 
        
           |  |  | 1470 |                 // not found
 | 
        
           |  |  | 1471 |                 return null;
 | 
        
           |  |  | 1472 |             }
 | 
        
           |  |  | 1473 |         }
 | 
        
           |  |  | 1474 |   | 
        
           |  |  | 1475 |         // Checks to see if the user can manage files or is the owner.
 | 
        
           |  |  | 1476 |         // TODO MDL-33805 - Do not use userid here and move the capability check above.
 | 
        
           |  |  | 1477 |         if (!has_capability('moodle/course:managefiles', $context) && $storedfile->get_userid() != $USER->id) {
 | 
        
           |  |  | 1478 |             return null;
 | 
        
           |  |  | 1479 |         }
 | 
        
           |  |  | 1480 |   | 
        
           |  |  | 1481 |         // let us display the author's name instead of itemid (submission id)
 | 
        
           |  |  | 1482 |   | 
        
           |  |  | 1483 |         if (isset($submissionauthors[$itemid])) {
 | 
        
           |  |  | 1484 |             $topvisiblename = $submissionauthors[$itemid];
 | 
        
           |  |  | 1485 |   | 
        
           |  |  | 1486 |         } else {
 | 
        
           |  |  | 1487 |   | 
        
           |  |  | 1488 |             $userfieldsapi = \core_user\fields::for_name();
 | 
        
           |  |  | 1489 |             $userfields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
 | 
        
           |  |  | 1490 |             $sql = "SELECT s.id, $userfields
 | 
        
           |  |  | 1491 |                       FROM {workshop_submissions} s
 | 
        
           |  |  | 1492 |                       JOIN {user} u ON (s.authorid = u.id)
 | 
        
           |  |  | 1493 |                      WHERE s.example = 0 AND s.workshopid = ?";
 | 
        
           |  |  | 1494 |             $params = array($cm->instance);
 | 
        
           |  |  | 1495 |             $rs = $DB->get_recordset_sql($sql, $params);
 | 
        
           |  |  | 1496 |   | 
        
           |  |  | 1497 |             foreach ($rs as $submissionauthor) {
 | 
        
           |  |  | 1498 |                 $title = s(fullname($submissionauthor)); // this is generally not unique...
 | 
        
           |  |  | 1499 |                 $submissionauthors[$submissionauthor->id] = $title;
 | 
        
           |  |  | 1500 |             }
 | 
        
           |  |  | 1501 |             $rs->close();
 | 
        
           |  |  | 1502 |   | 
        
           |  |  | 1503 |             if (!isset($submissionauthors[$itemid])) {
 | 
        
           |  |  | 1504 |                 // should not happen
 | 
        
           |  |  | 1505 |                 return null;
 | 
        
           |  |  | 1506 |             } else {
 | 
        
           |  |  | 1507 |                 $topvisiblename = $submissionauthors[$itemid];
 | 
        
           |  |  | 1508 |             }
 | 
        
           |  |  | 1509 |         }
 | 
        
           |  |  | 1510 |   | 
        
           |  |  | 1511 |         $urlbase = $CFG->wwwroot . '/pluginfile.php';
 | 
        
           |  |  | 1512 |         // do not allow manual modification of any files!
 | 
        
           |  |  | 1513 |         return new file_info_stored($browser, $context, $storedfile, $urlbase, $topvisiblename, true, true, false, false);
 | 
        
           |  |  | 1514 |     }
 | 
        
           |  |  | 1515 |   | 
        
           |  |  | 1516 |     if ($filearea === 'overallfeedback_content' or $filearea === 'overallfeedback_attachment') {
 | 
        
           |  |  | 1517 |   | 
        
           |  |  | 1518 |         if (!has_capability('mod/workshop:viewallassessments', $context)) {
 | 
        
           |  |  | 1519 |             return null;
 | 
        
           |  |  | 1520 |         }
 | 
        
           |  |  | 1521 |   | 
        
           |  |  | 1522 |         if (is_null($itemid)) {
 | 
        
           |  |  | 1523 |             // No itemid (assessmentid) passed, display the list of all assessments.
 | 
        
           |  |  | 1524 |             require_once($CFG->dirroot . '/mod/workshop/fileinfolib.php');
 | 
        
           |  |  | 1525 |             return new workshop_file_info_overallfeedback_container($browser, $course, $cm, $context, $areas, $filearea);
 | 
        
           |  |  | 1526 |         }
 | 
        
           |  |  | 1527 |   | 
        
           |  |  | 1528 |         // Make sure the user can see the particular assessment in separate groups mode.
 | 
        
           |  |  | 1529 |         $gmode = groups_get_activity_groupmode($cm, $course);
 | 
        
           |  |  | 1530 |         if ($gmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
 | 
        
           |  |  | 1531 |             // Check there is at least one common group with both the $USER
 | 
        
           |  |  | 1532 |             // and the submission author.
 | 
        
           |  |  | 1533 |             $sql = "SELECT 'x'
 | 
        
           |  |  | 1534 |                       FROM {workshop_submissions} s
 | 
        
           |  |  | 1535 |                       JOIN {user} a ON (a.id = s.authorid)
 | 
        
           |  |  | 1536 |                       JOIN {groups_members} agm ON (a.id = agm.userid)
 | 
        
           |  |  | 1537 |                       JOIN {user} u ON (u.id = ?)
 | 
        
           |  |  | 1538 |                       JOIN {groups_members} ugm ON (u.id = ugm.userid)
 | 
        
           |  |  | 1539 |                      WHERE s.example = 0 AND s.workshopid = ? AND s.id = ? AND agm.groupid = ugm.groupid";
 | 
        
           |  |  | 1540 |             $params = array($USER->id, $cm->instance, $itemid);
 | 
        
           |  |  | 1541 |             if (!$DB->record_exists_sql($sql, $params)) {
 | 
        
           |  |  | 1542 |                 return null;
 | 
        
           |  |  | 1543 |             }
 | 
        
           |  |  | 1544 |         }
 | 
        
           |  |  | 1545 |   | 
        
           |  |  | 1546 |         // We are inside a particular assessment container.
 | 
        
           |  |  | 1547 |         $filepath = is_null($filepath) ? '/' : $filepath;
 | 
        
           |  |  | 1548 |         $filename = is_null($filename) ? '.' : $filename;
 | 
        
           |  |  | 1549 |   | 
        
           |  |  | 1550 |         if (!$storedfile = $fs->get_file($context->id, 'mod_workshop', $filearea, $itemid, $filepath, $filename)) {
 | 
        
           |  |  | 1551 |             if ($filepath === '/' and $filename === '.') {
 | 
        
           |  |  | 1552 |                 $storedfile = new virtual_root_file($context->id, 'mod_workshop', $filearea, $itemid);
 | 
        
           |  |  | 1553 |             } else {
 | 
        
           |  |  | 1554 |                 // Not found
 | 
        
           |  |  | 1555 |                 return null;
 | 
        
           |  |  | 1556 |             }
 | 
        
           |  |  | 1557 |         }
 | 
        
           |  |  | 1558 |   | 
        
           |  |  | 1559 |         // Check to see if the user can manage files or is the owner.
 | 
        
           |  |  | 1560 |         if (!has_capability('moodle/course:managefiles', $context) and $storedfile->get_userid() != $USER->id) {
 | 
        
           |  |  | 1561 |             return null;
 | 
        
           |  |  | 1562 |         }
 | 
        
           |  |  | 1563 |   | 
        
           |  |  | 1564 |         $urlbase = $CFG->wwwroot . '/pluginfile.php';
 | 
        
           |  |  | 1565 |   | 
        
           |  |  | 1566 |         // Do not allow manual modification of any files.
 | 
        
           |  |  | 1567 |         return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false);
 | 
        
           |  |  | 1568 |     }
 | 
        
           |  |  | 1569 |   | 
        
           |  |  | 1570 |     if ($filearea == 'instructauthors' or $filearea == 'instructreviewers' or $filearea == 'conclusion') {
 | 
        
           |  |  | 1571 |         // always only itemid 0
 | 
        
           |  |  | 1572 |   | 
        
           |  |  | 1573 |         $filepath = is_null($filepath) ? '/' : $filepath;
 | 
        
           |  |  | 1574 |         $filename = is_null($filename) ? '.' : $filename;
 | 
        
           |  |  | 1575 |   | 
        
           |  |  | 1576 |         $urlbase = $CFG->wwwroot.'/pluginfile.php';
 | 
        
           |  |  | 1577 |         if (!$storedfile = $fs->get_file($context->id, 'mod_workshop', $filearea, 0, $filepath, $filename)) {
 | 
        
           |  |  | 1578 |             if ($filepath === '/' and $filename === '.') {
 | 
        
           |  |  | 1579 |                 $storedfile = new virtual_root_file($context->id, 'mod_workshop', $filearea, 0);
 | 
        
           |  |  | 1580 |             } else {
 | 
        
           |  |  | 1581 |                 // not found
 | 
        
           |  |  | 1582 |                 return null;
 | 
        
           |  |  | 1583 |             }
 | 
        
           |  |  | 1584 |         }
 | 
        
           |  |  | 1585 |         return new file_info_stored($browser, $context, $storedfile, $urlbase, $areas[$filearea], false, true, true, false);
 | 
        
           |  |  | 1586 |     }
 | 
        
           |  |  | 1587 | }
 | 
        
           |  |  | 1588 |   | 
        
           |  |  | 1589 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1590 | // Navigation API                                                             //
 | 
        
           |  |  | 1591 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1592 |   | 
        
           |  |  | 1593 | /**
 | 
        
           |  |  | 1594 |  * Extends the global navigation tree by adding workshop nodes if there is a relevant content
 | 
        
           |  |  | 1595 |  *
 | 
        
           |  |  | 1596 |  * This can be called by an AJAX request so do not rely on $PAGE as it might not be set up properly.
 | 
        
           |  |  | 1597 |  *
 | 
        
           |  |  | 1598 |  * @param navigation_node $navref An object representing the navigation tree node of the workshop module instance
 | 
        
           |  |  | 1599 |  * @param stdClass $course
 | 
        
           |  |  | 1600 |  * @param stdClass $module
 | 
        
           |  |  | 1601 |  * @param cm_info $cm
 | 
        
           |  |  | 1602 |  */
 | 
        
           |  |  | 1603 | function workshop_extend_navigation(navigation_node $navref, stdclass $course, stdclass $module, cm_info $cm) {
 | 
        
           |  |  | 1604 |     global $CFG;
 | 
        
           |  |  | 1605 |   | 
        
           |  |  | 1606 |     if (has_capability('mod/workshop:submit', context_module::instance($cm->id))) {
 | 
        
           |  |  | 1607 |         $url = new moodle_url('/mod/workshop/submission.php', array('cmid' => $cm->id));
 | 
        
           |  |  | 1608 |         $mysubmission = $navref->add(get_string('mysubmission', 'workshop'), $url);
 | 
        
           |  |  | 1609 |         $mysubmission->mainnavonly = true;
 | 
        
           |  |  | 1610 |     }
 | 
        
           |  |  | 1611 | }
 | 
        
           |  |  | 1612 |   | 
        
           |  |  | 1613 | /**
 | 
        
           |  |  | 1614 |  * Extends the settings navigation with the Workshop settings
 | 
        
           |  |  | 1615 |   | 
        
           |  |  | 1616 |  * This function is called when the context for the page is a workshop module. This is not called by AJAX
 | 
        
           |  |  | 1617 |  * so it is safe to rely on the $PAGE.
 | 
        
           |  |  | 1618 |  *
 | 
        
           |  |  | 1619 |  * @param settings_navigation $settingsnav {@link settings_navigation}
 | 
        
           |  |  | 1620 |  * @param navigation_node $workshopnode {@link navigation_node}
 | 
        
           |  |  | 1621 |  */
 | 
        
           | 1441 | ariadna | 1622 | function workshop_extend_settings_navigation(settings_navigation $settingsnav, ?navigation_node $workshopnode=null) {
 | 
        
           | 1 | efrain | 1623 |     if (has_capability('mod/workshop:editdimensions', $settingsnav->get_page()->cm->context)) {
 | 
        
           |  |  | 1624 |         $url = new moodle_url('/mod/workshop/editform.php', array('cmid' => $settingsnav->get_page()->cm->id));
 | 
        
           |  |  | 1625 |         $workshopnode->add(get_string('assessmentform', 'workshop'), $url,
 | 
        
           |  |  | 1626 |         settings_navigation::TYPE_SETTING, null, 'workshopassessement');
 | 
        
           |  |  | 1627 |     }
 | 
        
           |  |  | 1628 |     if (has_capability('mod/workshop:allocate', $settingsnav->get_page()->cm->context)) {
 | 
        
           |  |  | 1629 |         $url = new moodle_url('/mod/workshop/allocation.php', array('cmid' => $settingsnav->get_page()->cm->id));
 | 
        
           |  |  | 1630 |         $workshopnode->add(get_string('submissionsallocation', 'workshop'), $url, settings_navigation::TYPE_SETTING);
 | 
        
           |  |  | 1631 |     }
 | 
        
           |  |  | 1632 | }
 | 
        
           |  |  | 1633 |   | 
        
           |  |  | 1634 | /**
 | 
        
           |  |  | 1635 |  * Return a list of page types
 | 
        
           |  |  | 1636 |  * @param string $pagetype current page type
 | 
        
           |  |  | 1637 |  * @param stdClass $parentcontext Block's parent context
 | 
        
           |  |  | 1638 |  * @param stdClass $currentcontext Current context of block
 | 
        
           |  |  | 1639 |  */
 | 
        
           |  |  | 1640 | function workshop_page_type_list($pagetype, $parentcontext, $currentcontext) {
 | 
        
           |  |  | 1641 |     $module_pagetype = array('mod-workshop-*'=>get_string('page-mod-workshop-x', 'workshop'));
 | 
        
           |  |  | 1642 |     return $module_pagetype;
 | 
        
           |  |  | 1643 | }
 | 
        
           |  |  | 1644 |   | 
        
           |  |  | 1645 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1646 | // Calendar API                                                               //
 | 
        
           |  |  | 1647 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1648 |   | 
        
           |  |  | 1649 | /**
 | 
        
           |  |  | 1650 |  * Updates the calendar events associated to the given workshop
 | 
        
           |  |  | 1651 |  *
 | 
        
           |  |  | 1652 |  * @param stdClass $workshop the workshop instance record
 | 
        
           |  |  | 1653 |  * @param int $cmid course module id
 | 
        
           |  |  | 1654 |  */
 | 
        
           |  |  | 1655 | function workshop_calendar_update(stdClass $workshop, $cmid) {
 | 
        
           |  |  | 1656 |     global $DB;
 | 
        
           |  |  | 1657 |   | 
        
           |  |  | 1658 |     // get the currently registered events so that we can re-use their ids
 | 
        
           |  |  | 1659 |     $currentevents = $DB->get_records('event', array('modulename' => 'workshop', 'instance' => $workshop->id));
 | 
        
           |  |  | 1660 |   | 
        
           |  |  | 1661 |     // the common properties for all events
 | 
        
           |  |  | 1662 |     $base = new stdClass();
 | 
        
           |  |  | 1663 |     $base->description  = format_module_intro('workshop', $workshop, $cmid, false);
 | 
        
           |  |  | 1664 |     $base->format       = FORMAT_HTML;
 | 
        
           |  |  | 1665 |     $base->courseid     = $workshop->course;
 | 
        
           |  |  | 1666 |     $base->groupid      = 0;
 | 
        
           |  |  | 1667 |     $base->userid       = 0;
 | 
        
           |  |  | 1668 |     $base->modulename   = 'workshop';
 | 
        
           |  |  | 1669 |     $base->instance     = $workshop->id;
 | 
        
           |  |  | 1670 |     $base->visible      = instance_is_visible('workshop', $workshop);
 | 
        
           |  |  | 1671 |     $base->timeduration = 0;
 | 
        
           |  |  | 1672 |   | 
        
           |  |  | 1673 |     if ($workshop->submissionstart) {
 | 
        
           |  |  | 1674 |         $event = clone($base);
 | 
        
           |  |  | 1675 |         $event->name = get_string('submissionstartevent', 'mod_workshop', $workshop->name);
 | 
        
           |  |  | 1676 |         $event->eventtype = WORKSHOP_EVENT_TYPE_SUBMISSION_OPEN;
 | 
        
           |  |  | 1677 |         $event->type = empty($workshop->submissionend) ? CALENDAR_EVENT_TYPE_ACTION : CALENDAR_EVENT_TYPE_STANDARD;
 | 
        
           |  |  | 1678 |         $event->timestart = $workshop->submissionstart;
 | 
        
           |  |  | 1679 |         $event->timesort  = $workshop->submissionstart;
 | 
        
           |  |  | 1680 |         if ($reusedevent = array_shift($currentevents)) {
 | 
        
           |  |  | 1681 |             $event->id = $reusedevent->id;
 | 
        
           |  |  | 1682 |         } else {
 | 
        
           |  |  | 1683 |             // should not be set but just in case
 | 
        
           |  |  | 1684 |             unset($event->id);
 | 
        
           |  |  | 1685 |         }
 | 
        
           |  |  | 1686 |         // update() will reuse a db record if the id field is set
 | 
        
           |  |  | 1687 |         $eventobj = new calendar_event($event);
 | 
        
           |  |  | 1688 |         $eventobj->update($event, false);
 | 
        
           |  |  | 1689 |     }
 | 
        
           |  |  | 1690 |   | 
        
           |  |  | 1691 |     if ($workshop->submissionend) {
 | 
        
           |  |  | 1692 |         $event = clone($base);
 | 
        
           |  |  | 1693 |         $event->name = get_string('submissionendevent', 'mod_workshop', $workshop->name);
 | 
        
           |  |  | 1694 |         $event->eventtype = WORKSHOP_EVENT_TYPE_SUBMISSION_CLOSE;
 | 
        
           |  |  | 1695 |         $event->type      = CALENDAR_EVENT_TYPE_ACTION;
 | 
        
           |  |  | 1696 |         $event->timestart = $workshop->submissionend;
 | 
        
           |  |  | 1697 |         $event->timesort  = $workshop->submissionend;
 | 
        
           |  |  | 1698 |         if ($reusedevent = array_shift($currentevents)) {
 | 
        
           |  |  | 1699 |             $event->id = $reusedevent->id;
 | 
        
           |  |  | 1700 |         } else {
 | 
        
           |  |  | 1701 |             // should not be set but just in case
 | 
        
           |  |  | 1702 |             unset($event->id);
 | 
        
           |  |  | 1703 |         }
 | 
        
           |  |  | 1704 |         // update() will reuse a db record if the id field is set
 | 
        
           |  |  | 1705 |         $eventobj = new calendar_event($event);
 | 
        
           |  |  | 1706 |         $eventobj->update($event, false);
 | 
        
           |  |  | 1707 |     }
 | 
        
           |  |  | 1708 |   | 
        
           |  |  | 1709 |     if ($workshop->assessmentstart) {
 | 
        
           |  |  | 1710 |         $event = clone($base);
 | 
        
           |  |  | 1711 |         $event->name = get_string('assessmentstartevent', 'mod_workshop', $workshop->name);
 | 
        
           |  |  | 1712 |         $event->eventtype = WORKSHOP_EVENT_TYPE_ASSESSMENT_OPEN;
 | 
        
           |  |  | 1713 |         $event->type      = empty($workshop->assessmentend) ? CALENDAR_EVENT_TYPE_ACTION : CALENDAR_EVENT_TYPE_STANDARD;
 | 
        
           |  |  | 1714 |         $event->timestart = $workshop->assessmentstart;
 | 
        
           |  |  | 1715 |         $event->timesort  = $workshop->assessmentstart;
 | 
        
           |  |  | 1716 |         if ($reusedevent = array_shift($currentevents)) {
 | 
        
           |  |  | 1717 |             $event->id = $reusedevent->id;
 | 
        
           |  |  | 1718 |         } else {
 | 
        
           |  |  | 1719 |             // should not be set but just in case
 | 
        
           |  |  | 1720 |             unset($event->id);
 | 
        
           |  |  | 1721 |         }
 | 
        
           |  |  | 1722 |         // update() will reuse a db record if the id field is set
 | 
        
           |  |  | 1723 |         $eventobj = new calendar_event($event);
 | 
        
           |  |  | 1724 |         $eventobj->update($event, false);
 | 
        
           |  |  | 1725 |     }
 | 
        
           |  |  | 1726 |   | 
        
           |  |  | 1727 |     if ($workshop->assessmentend) {
 | 
        
           |  |  | 1728 |         $event = clone($base);
 | 
        
           |  |  | 1729 |         $event->name = get_string('assessmentendevent', 'mod_workshop', $workshop->name);
 | 
        
           |  |  | 1730 |         $event->eventtype = WORKSHOP_EVENT_TYPE_ASSESSMENT_CLOSE;
 | 
        
           |  |  | 1731 |         $event->type      = CALENDAR_EVENT_TYPE_ACTION;
 | 
        
           |  |  | 1732 |         $event->timestart = $workshop->assessmentend;
 | 
        
           |  |  | 1733 |         $event->timesort  = $workshop->assessmentend;
 | 
        
           |  |  | 1734 |         if ($reusedevent = array_shift($currentevents)) {
 | 
        
           |  |  | 1735 |             $event->id = $reusedevent->id;
 | 
        
           |  |  | 1736 |         } else {
 | 
        
           |  |  | 1737 |             // should not be set but just in case
 | 
        
           |  |  | 1738 |             unset($event->id);
 | 
        
           |  |  | 1739 |         }
 | 
        
           |  |  | 1740 |         // update() will reuse a db record if the id field is set
 | 
        
           |  |  | 1741 |         $eventobj = new calendar_event($event);
 | 
        
           |  |  | 1742 |         $eventobj->update($event, false);
 | 
        
           |  |  | 1743 |     }
 | 
        
           |  |  | 1744 |   | 
        
           |  |  | 1745 |     // delete any leftover events
 | 
        
           |  |  | 1746 |     foreach ($currentevents as $oldevent) {
 | 
        
           |  |  | 1747 |         $oldevent = calendar_event::load($oldevent);
 | 
        
           |  |  | 1748 |         $oldevent->delete();
 | 
        
           |  |  | 1749 |     }
 | 
        
           |  |  | 1750 | }
 | 
        
           |  |  | 1751 |   | 
        
           |  |  | 1752 | /**
 | 
        
           |  |  | 1753 |  * This function receives a calendar event and returns the action associated with it, or null if there is none.
 | 
        
           |  |  | 1754 |  *
 | 
        
           |  |  | 1755 |  * This is used by block_myoverview in order to display the event appropriately. If null is returned then the event
 | 
        
           |  |  | 1756 |  * is not displayed on the block.
 | 
        
           |  |  | 1757 |  *
 | 
        
           |  |  | 1758 |  * @param calendar_event $event
 | 
        
           |  |  | 1759 |  * @param \core_calendar\action_factory $factory
 | 
        
           |  |  | 1760 |  * @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default).
 | 
        
           |  |  | 1761 |  * @return \core_calendar\local\event\entities\action_interface|null
 | 
        
           |  |  | 1762 |  */
 | 
        
           |  |  | 1763 | function mod_workshop_core_calendar_provide_event_action(calendar_event $event,
 | 
        
           |  |  | 1764 |         \core_calendar\action_factory $factory, int $userid = 0) {
 | 
        
           |  |  | 1765 |     global $USER;
 | 
        
           |  |  | 1766 |   | 
        
           |  |  | 1767 |     if (!$userid) {
 | 
        
           |  |  | 1768 |         $userid = $USER->id;
 | 
        
           |  |  | 1769 |     }
 | 
        
           |  |  | 1770 |   | 
        
           |  |  | 1771 |     $cm = get_fast_modinfo($event->courseid, $userid)->instances['workshop'][$event->instance];
 | 
        
           |  |  | 1772 |   | 
        
           |  |  | 1773 |     if (!$cm->uservisible) {
 | 
        
           |  |  | 1774 |         // The module is not visible to the user for any reason.
 | 
        
           |  |  | 1775 |         return null;
 | 
        
           |  |  | 1776 |     }
 | 
        
           |  |  | 1777 |   | 
        
           |  |  | 1778 |     $completion = new \completion_info($cm->get_course());
 | 
        
           |  |  | 1779 |   | 
        
           |  |  | 1780 |     $completiondata = $completion->get_data($cm, false, $userid);
 | 
        
           |  |  | 1781 |   | 
        
           |  |  | 1782 |     if ($completiondata->completionstate != COMPLETION_INCOMPLETE) {
 | 
        
           |  |  | 1783 |         return null;
 | 
        
           |  |  | 1784 |     }
 | 
        
           |  |  | 1785 |   | 
        
           |  |  | 1786 |     return $factory->create_instance(
 | 
        
           |  |  | 1787 |         get_string('viewworkshopsummary', 'workshop'),
 | 
        
           |  |  | 1788 |         new \moodle_url('/mod/workshop/view.php', array('id' => $cm->id)),
 | 
        
           |  |  | 1789 |         1,
 | 
        
           |  |  | 1790 |         true
 | 
        
           |  |  | 1791 |     );
 | 
        
           |  |  | 1792 | }
 | 
        
           |  |  | 1793 |   | 
        
           |  |  | 1794 | /**
 | 
        
           |  |  | 1795 |  * This function calculates the minimum and maximum cutoff values for the timestart of
 | 
        
           |  |  | 1796 |  * the given event.
 | 
        
           |  |  | 1797 |  *
 | 
        
           |  |  | 1798 |  * It will return an array with two values, the first being the minimum cutoff value and
 | 
        
           |  |  | 1799 |  * the second being the maximum cutoff value. Either or both values can be null, which
 | 
        
           |  |  | 1800 |  * indicates there is no minimum or maximum, respectively.
 | 
        
           |  |  | 1801 |  *
 | 
        
           |  |  | 1802 |  * If a cutoff is required then the function must return an array containing the cutoff
 | 
        
           |  |  | 1803 |  * timestamp and error string to display to the user if the cutoff value is violated.
 | 
        
           |  |  | 1804 |  *
 | 
        
           |  |  | 1805 |  * A minimum and maximum cutoff return value will look like:
 | 
        
           |  |  | 1806 |  * [
 | 
        
           |  |  | 1807 |  *     [1505704373, 'The date must be after this date'],
 | 
        
           |  |  | 1808 |  *     [1506741172, 'The date must be before this date']
 | 
        
           |  |  | 1809 |  * ]
 | 
        
           |  |  | 1810 |  *
 | 
        
           |  |  | 1811 |  * @param calendar_event $event The calendar event to get the time range for
 | 
        
           |  |  | 1812 |  * @param stdClass $workshop The module instance to get the range from
 | 
        
           |  |  | 1813 |  * @return array Returns an array with min and max date.
 | 
        
           |  |  | 1814 |  */
 | 
        
           |  |  | 1815 | function mod_workshop_core_calendar_get_valid_event_timestart_range(\calendar_event $event, \stdClass $workshop): array {
 | 
        
           |  |  | 1816 |     $mindate = null;
 | 
        
           |  |  | 1817 |     $maxdate = null;
 | 
        
           |  |  | 1818 |   | 
        
           |  |  | 1819 |     $phasesubmissionend = max($workshop->submissionstart, $workshop->submissionend);
 | 
        
           |  |  | 1820 |     $phaseassessmentstart = min($workshop->assessmentstart, $workshop->assessmentend);
 | 
        
           |  |  | 1821 |     if ($phaseassessmentstart == 0) {
 | 
        
           |  |  | 1822 |         $phaseassessmentstart = max($workshop->assessmentstart, $workshop->assessmentend);
 | 
        
           |  |  | 1823 |     }
 | 
        
           |  |  | 1824 |   | 
        
           |  |  | 1825 |     switch ($event->eventtype) {
 | 
        
           |  |  | 1826 |         case WORKSHOP_EVENT_TYPE_SUBMISSION_OPEN:
 | 
        
           |  |  | 1827 |             if (!empty($workshop->submissionend)) {
 | 
        
           |  |  | 1828 |                 $maxdate = [
 | 
        
           |  |  | 1829 |                     $workshop->submissionend - 1,   // The submissionstart and submissionend cannot be exactly the same.
 | 
        
           |  |  | 1830 |                     get_string('submissionendbeforestart', 'mod_workshop')
 | 
        
           |  |  | 1831 |                 ];
 | 
        
           |  |  | 1832 |             } else if ($phaseassessmentstart) {
 | 
        
           |  |  | 1833 |                 $maxdate = [
 | 
        
           |  |  | 1834 |                     $phaseassessmentstart,
 | 
        
           |  |  | 1835 |                     get_string('phasesoverlap', 'mod_workshop')
 | 
        
           |  |  | 1836 |                 ];
 | 
        
           |  |  | 1837 |             }
 | 
        
           |  |  | 1838 |             break;
 | 
        
           |  |  | 1839 |         case WORKSHOP_EVENT_TYPE_SUBMISSION_CLOSE:
 | 
        
           |  |  | 1840 |             if (!empty($workshop->submissionstart)) {
 | 
        
           |  |  | 1841 |                 $mindate = [
 | 
        
           |  |  | 1842 |                     $workshop->submissionstart + 1, // The submissionstart and submissionend cannot be exactly the same.
 | 
        
           |  |  | 1843 |                     get_string('submissionendbeforestart', 'mod_workshop')
 | 
        
           |  |  | 1844 |                 ];
 | 
        
           |  |  | 1845 |             }
 | 
        
           |  |  | 1846 |             if ($phaseassessmentstart) {
 | 
        
           |  |  | 1847 |                 $maxdate = [
 | 
        
           |  |  | 1848 |                     $phaseassessmentstart,
 | 
        
           |  |  | 1849 |                     get_string('phasesoverlap', 'mod_workshop')
 | 
        
           |  |  | 1850 |                 ];
 | 
        
           |  |  | 1851 |             }
 | 
        
           |  |  | 1852 |             break;
 | 
        
           |  |  | 1853 |         case WORKSHOP_EVENT_TYPE_ASSESSMENT_OPEN:
 | 
        
           |  |  | 1854 |             if ($phasesubmissionend) {
 | 
        
           |  |  | 1855 |                 $mindate = [
 | 
        
           |  |  | 1856 |                     $phasesubmissionend,
 | 
        
           |  |  | 1857 |                     get_string('phasesoverlap', 'mod_workshop')
 | 
        
           |  |  | 1858 |                 ];
 | 
        
           |  |  | 1859 |             }
 | 
        
           |  |  | 1860 |             if (!empty($workshop->assessmentend)) {
 | 
        
           |  |  | 1861 |                 $maxdate = [
 | 
        
           |  |  | 1862 |                     $workshop->assessmentend - 1,   // The assessmentstart and assessmentend cannot be exactly the same.
 | 
        
           |  |  | 1863 |                     get_string('assessmentendbeforestart', 'mod_workshop')
 | 
        
           |  |  | 1864 |                 ];
 | 
        
           |  |  | 1865 |             }
 | 
        
           |  |  | 1866 |             break;
 | 
        
           |  |  | 1867 |         case WORKSHOP_EVENT_TYPE_ASSESSMENT_CLOSE:
 | 
        
           |  |  | 1868 |             if (!empty($workshop->assessmentstart)) {
 | 
        
           |  |  | 1869 |                 $mindate = [
 | 
        
           |  |  | 1870 |                     $workshop->assessmentstart + 1, // The assessmentstart and assessmentend cannot be exactly the same.
 | 
        
           |  |  | 1871 |                     get_string('assessmentendbeforestart', 'mod_workshop')
 | 
        
           |  |  | 1872 |                 ];
 | 
        
           |  |  | 1873 |             } else if ($phasesubmissionend) {
 | 
        
           |  |  | 1874 |                 $mindate = [
 | 
        
           |  |  | 1875 |                     $phasesubmissionend,
 | 
        
           |  |  | 1876 |                     get_string('phasesoverlap', 'mod_workshop')
 | 
        
           |  |  | 1877 |                 ];
 | 
        
           |  |  | 1878 |             }
 | 
        
           |  |  | 1879 |             break;
 | 
        
           |  |  | 1880 |     }
 | 
        
           |  |  | 1881 |   | 
        
           |  |  | 1882 |     return [$mindate, $maxdate];
 | 
        
           |  |  | 1883 | }
 | 
        
           |  |  | 1884 |   | 
        
           |  |  | 1885 | /**
 | 
        
           |  |  | 1886 |  * This function will update the workshop module according to the
 | 
        
           |  |  | 1887 |  * event that has been modified.
 | 
        
           |  |  | 1888 |  *
 | 
        
           |  |  | 1889 |  * @param \calendar_event $event
 | 
        
           |  |  | 1890 |  * @param stdClass $workshop The module instance to get the range from
 | 
        
           |  |  | 1891 |  */
 | 
        
           |  |  | 1892 | function mod_workshop_core_calendar_event_timestart_updated(\calendar_event $event, \stdClass $workshop): void {
 | 
        
           |  |  | 1893 |     global $DB;
 | 
        
           |  |  | 1894 |   | 
        
           |  |  | 1895 |     $courseid = $event->courseid;
 | 
        
           |  |  | 1896 |     $modulename = $event->modulename;
 | 
        
           |  |  | 1897 |     $instanceid = $event->instance;
 | 
        
           |  |  | 1898 |   | 
        
           |  |  | 1899 |     // Something weird going on. The event is for a different module so
 | 
        
           |  |  | 1900 |     // we should ignore it.
 | 
        
           |  |  | 1901 |     if ($modulename != 'workshop') {
 | 
        
           |  |  | 1902 |         return;
 | 
        
           |  |  | 1903 |     }
 | 
        
           |  |  | 1904 |   | 
        
           |  |  | 1905 |     if ($workshop->id != $instanceid) {
 | 
        
           |  |  | 1906 |         return;
 | 
        
           |  |  | 1907 |     }
 | 
        
           |  |  | 1908 |   | 
        
           |  |  | 1909 |     if (!in_array(
 | 
        
           |  |  | 1910 |             $event->eventtype,
 | 
        
           |  |  | 1911 |             [
 | 
        
           |  |  | 1912 |                 WORKSHOP_EVENT_TYPE_SUBMISSION_OPEN,
 | 
        
           |  |  | 1913 |                 WORKSHOP_EVENT_TYPE_SUBMISSION_CLOSE,
 | 
        
           |  |  | 1914 |                 WORKSHOP_EVENT_TYPE_ASSESSMENT_OPEN,
 | 
        
           |  |  | 1915 |                 WORKSHOP_EVENT_TYPE_ASSESSMENT_CLOSE
 | 
        
           |  |  | 1916 |             ]
 | 
        
           |  |  | 1917 |     )) {
 | 
        
           |  |  | 1918 |         return;
 | 
        
           |  |  | 1919 |     }
 | 
        
           |  |  | 1920 |   | 
        
           |  |  | 1921 |     $coursemodule = get_fast_modinfo($courseid)->instances[$modulename][$instanceid];
 | 
        
           |  |  | 1922 |     $context = context_module::instance($coursemodule->id);
 | 
        
           |  |  | 1923 |   | 
        
           |  |  | 1924 |     // The user does not have the capability to modify this activity.
 | 
        
           |  |  | 1925 |     if (!has_capability('moodle/course:manageactivities', $context)) {
 | 
        
           |  |  | 1926 |         return;
 | 
        
           |  |  | 1927 |     }
 | 
        
           |  |  | 1928 |   | 
        
           |  |  | 1929 |     $modified = false;
 | 
        
           |  |  | 1930 |   | 
        
           |  |  | 1931 |     switch ($event->eventtype) {
 | 
        
           |  |  | 1932 |         case WORKSHOP_EVENT_TYPE_SUBMISSION_OPEN:
 | 
        
           |  |  | 1933 |             if ($event->timestart != $workshop->submissionstart) {
 | 
        
           |  |  | 1934 |                 $workshop->submissionstart = $event->timestart;
 | 
        
           |  |  | 1935 |                 $modified = true;
 | 
        
           |  |  | 1936 |             }
 | 
        
           |  |  | 1937 |             break;
 | 
        
           |  |  | 1938 |         case WORKSHOP_EVENT_TYPE_SUBMISSION_CLOSE:
 | 
        
           |  |  | 1939 |             if ($event->timestart != $workshop->submissionend) {
 | 
        
           |  |  | 1940 |                 $workshop->submissionend = $event->timestart;
 | 
        
           |  |  | 1941 |                 $modified = true;
 | 
        
           |  |  | 1942 |             }
 | 
        
           |  |  | 1943 |             break;
 | 
        
           |  |  | 1944 |         case WORKSHOP_EVENT_TYPE_ASSESSMENT_OPEN:
 | 
        
           |  |  | 1945 |             if ($event->timestart != $workshop->assessmentstart) {
 | 
        
           |  |  | 1946 |                 $workshop->assessmentstart = $event->timestart;
 | 
        
           |  |  | 1947 |                 $modified = true;
 | 
        
           |  |  | 1948 |             }
 | 
        
           |  |  | 1949 |             break;
 | 
        
           |  |  | 1950 |         case WORKSHOP_EVENT_TYPE_ASSESSMENT_CLOSE:
 | 
        
           |  |  | 1951 |             if ($event->timestart != $workshop->assessmentend) {
 | 
        
           |  |  | 1952 |                 $workshop->assessmentend = $event->timestart;
 | 
        
           |  |  | 1953 |                 $modified = true;
 | 
        
           |  |  | 1954 |             }
 | 
        
           |  |  | 1955 |             break;
 | 
        
           |  |  | 1956 |     }
 | 
        
           |  |  | 1957 |   | 
        
           |  |  | 1958 |     if ($modified) {
 | 
        
           |  |  | 1959 |         $workshop->timemodified = time();
 | 
        
           |  |  | 1960 |         // Persist the assign instance changes.
 | 
        
           |  |  | 1961 |         $DB->update_record('workshop', $workshop);
 | 
        
           |  |  | 1962 |         $event = \core\event\course_module_updated::create_from_cm($coursemodule, $context);
 | 
        
           |  |  | 1963 |         $event->trigger();
 | 
        
           |  |  | 1964 |     }
 | 
        
           |  |  | 1965 | }
 | 
        
           |  |  | 1966 |   | 
        
           |  |  | 1967 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1968 | // Course reset API                                                           //
 | 
        
           |  |  | 1969 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1970 |   | 
        
           |  |  | 1971 | /**
 | 
        
           |  |  | 1972 |  * Extends the course reset form with workshop specific settings.
 | 
        
           |  |  | 1973 |  *
 | 
        
           |  |  | 1974 |  * @param MoodleQuickForm $mform
 | 
        
           |  |  | 1975 |  */
 | 
        
           |  |  | 1976 | function workshop_reset_course_form_definition($mform) {
 | 
        
           |  |  | 1977 |   | 
        
           |  |  | 1978 |     $mform->addElement('header', 'workshopheader', get_string('modulenameplural', 'mod_workshop'));
 | 
        
           |  |  | 1979 |   | 
        
           | 1441 | ariadna | 1980 |     $mform->addElement('advcheckbox', 'reset_workshop_phase', get_string('resetphase', 'mod_workshop'));
 | 
        
           |  |  | 1981 |     $mform->addHelpButton('reset_workshop_phase', 'resetphase', 'mod_workshop');
 | 
        
           |  |  | 1982 |   | 
        
           |  |  | 1983 |     $mform->addElement('static', 'workshopdelete', get_string('delete'));
 | 
        
           |  |  | 1984 |   | 
        
           | 1 | efrain | 1985 |     $mform->addElement('advcheckbox', 'reset_workshop_submissions', get_string('resetsubmissions', 'mod_workshop'));
 | 
        
           |  |  | 1986 |     $mform->addHelpButton('reset_workshop_submissions', 'resetsubmissions', 'mod_workshop');
 | 
        
           |  |  | 1987 |   | 
        
           |  |  | 1988 |     $mform->addElement('advcheckbox', 'reset_workshop_assessments', get_string('resetassessments', 'mod_workshop'));
 | 
        
           |  |  | 1989 |     $mform->addHelpButton('reset_workshop_assessments', 'resetassessments', 'mod_workshop');
 | 
        
           | 1441 | ariadna | 1990 |     $mform->hideIf('reset_workshop_assessments', 'reset_workshop_submissions', 'checked');
 | 
        
           | 1 | efrain | 1991 | }
 | 
        
           |  |  | 1992 |   | 
        
           |  |  | 1993 | /**
 | 
        
           |  |  | 1994 |  * Provides default values for the workshop settings in the course reset form.
 | 
        
           |  |  | 1995 |  *
 | 
        
           |  |  | 1996 |  * @param stdClass $course The course to be reset.
 | 
        
           |  |  | 1997 |  */
 | 
        
           |  |  | 1998 | function workshop_reset_course_form_defaults(stdClass $course) {
 | 
        
           |  |  | 1999 |   | 
        
           |  |  | 2000 |     $defaults = array(
 | 
        
           |  |  | 2001 |         'reset_workshop_submissions'    => 1,
 | 
        
           |  |  | 2002 |         'reset_workshop_assessments'    => 1,
 | 
        
           |  |  | 2003 |         'reset_workshop_phase'          => 1,
 | 
        
           |  |  | 2004 |     );
 | 
        
           |  |  | 2005 |   | 
        
           |  |  | 2006 |     return $defaults;
 | 
        
           |  |  | 2007 | }
 | 
        
           |  |  | 2008 |   | 
        
           |  |  | 2009 | /**
 | 
        
           |  |  | 2010 |  * Performs the reset of all workshop instances in the course.
 | 
        
           |  |  | 2011 |  *
 | 
        
           |  |  | 2012 |  * @param stdClass $data The actual course reset settings.
 | 
        
           |  |  | 2013 |  * @return array List of results, each being array[(string)component, (string)item, (string)error]
 | 
        
           |  |  | 2014 |  */
 | 
        
           |  |  | 2015 | function workshop_reset_userdata(stdClass $data) {
 | 
        
           |  |  | 2016 |     global $CFG, $DB;
 | 
        
           |  |  | 2017 |   | 
        
           |  |  | 2018 |     // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
 | 
        
           |  |  | 2019 |     // See MDL-9367.
 | 
        
           | 1441 | ariadna | 2020 |     shift_course_mod_dates(
 | 
        
           |  |  | 2021 |         'workshop',
 | 
        
           |  |  | 2022 |         ['submissionstart', 'submissionend', 'assessmentstart', 'assessmentend'],
 | 
        
           |  |  | 2023 |         $data->timeshift, $data->courseid,
 | 
        
           |  |  | 2024 |     );
 | 
        
           |  |  | 2025 |     $status[] = [
 | 
        
           |  |  | 2026 |         'component' => get_string('modulenameplural', 'workshop'),
 | 
        
           |  |  | 2027 |         'item' => get_string('date'),
 | 
        
           |  |  | 2028 |         'error' => false,
 | 
        
           |  |  | 2029 |     ];
 | 
        
           | 1 | efrain | 2030 |   | 
        
           |  |  | 2031 |     if (empty($data->reset_workshop_submissions)
 | 
        
           |  |  | 2032 |             and empty($data->reset_workshop_assessments)
 | 
        
           |  |  | 2033 |             and empty($data->reset_workshop_phase) ) {
 | 
        
           |  |  | 2034 |         // Nothing to do here.
 | 
        
           |  |  | 2035 |         return $status;
 | 
        
           |  |  | 2036 |     }
 | 
        
           |  |  | 2037 |   | 
        
           | 1441 | ariadna | 2038 |     $workshoprecords = $DB->get_records('workshop', ['course' => $data->courseid]);
 | 
        
           | 1 | efrain | 2039 |   | 
        
           |  |  | 2040 |     if (empty($workshoprecords)) {
 | 
        
           | 1441 | ariadna | 2041 |         // What a boring course - no workshops here.
 | 
        
           | 1 | efrain | 2042 |         return $status;
 | 
        
           |  |  | 2043 |     }
 | 
        
           |  |  | 2044 |   | 
        
           |  |  | 2045 |     require_once($CFG->dirroot . '/mod/workshop/locallib.php');
 | 
        
           |  |  | 2046 |   | 
        
           | 1441 | ariadna | 2047 |     $course = $DB->get_record('course', ['id' => $data->courseid], '*', MUST_EXIST);
 | 
        
           | 1 | efrain | 2048 |   | 
        
           |  |  | 2049 |     foreach ($workshoprecords as $workshoprecord) {
 | 
        
           |  |  | 2050 |         $cm = get_coursemodule_from_instance('workshop', $workshoprecord->id, $course->id, false, MUST_EXIST);
 | 
        
           |  |  | 2051 |         $workshop = new workshop($workshoprecord, $cm, $course);
 | 
        
           |  |  | 2052 |         $status = array_merge($status, $workshop->reset_userdata($data));
 | 
        
           |  |  | 2053 |     }
 | 
        
           |  |  | 2054 |   | 
        
           |  |  | 2055 |     return $status;
 | 
        
           |  |  | 2056 | }
 | 
        
           |  |  | 2057 |   | 
        
           |  |  | 2058 | /**
 | 
        
           |  |  | 2059 |  * Get icon mapping for font-awesome.
 | 
        
           |  |  | 2060 |  */
 | 
        
           |  |  | 2061 | function mod_workshop_get_fontawesome_icon_map() {
 | 
        
           |  |  | 2062 |     return [
 | 
        
           | 1441 | ariadna | 2063 |         'mod_workshop:userplan/task-done' => 'fa-clipboard-check text-success',
 | 
        
           |  |  | 2064 |         'mod_workshop:userplan/task-fail' => 'fa-xmark text-danger',
 | 
        
           |  |  | 2065 |         'mod_workshop:userplan/task-info' => 'fa-circle-info text-info',
 | 
        
           |  |  | 2066 |         'mod_workshop:userplan/task-todo' => 'fa-regular fa-clipboard',
 | 
        
           | 1 | efrain | 2067 |     ];
 | 
        
           |  |  | 2068 | }
 | 
        
           |  |  | 2069 |   | 
        
           |  |  | 2070 | /**
 | 
        
           |  |  | 2071 |  * Check if the module has any update that affects the current user since a given time.
 | 
        
           |  |  | 2072 |  *
 | 
        
           |  |  | 2073 |  * @param  cm_info $cm course module data
 | 
        
           |  |  | 2074 |  * @param  int $from the time to check updates from
 | 
        
           |  |  | 2075 |  * @param  array $filter  if we need to check only specific updates
 | 
        
           |  |  | 2076 |  * @return stdClass an object with the different type of areas indicating if they were updated or not
 | 
        
           |  |  | 2077 |  * @since Moodle 3.4
 | 
        
           |  |  | 2078 |  */
 | 
        
           |  |  | 2079 | function workshop_check_updates_since(cm_info $cm, $from, $filter = array()) {
 | 
        
           |  |  | 2080 |     global $DB, $USER;
 | 
        
           |  |  | 2081 |   | 
        
           |  |  | 2082 |     $updates = course_check_module_updates_since($cm, $from, array('instructauthors', 'instructreviewers', 'conclusion'), $filter);
 | 
        
           |  |  | 2083 |   | 
        
           |  |  | 2084 |     // Check if there are new submissions, assessments or assessments grades in the workshop.
 | 
        
           |  |  | 2085 |     $updates->submissions = (object) array('updated' => false);
 | 
        
           |  |  | 2086 |     $updates->assessments = (object) array('updated' => false);
 | 
        
           |  |  | 2087 |     $updates->assessmentgrades = (object) array('updated' => false);
 | 
        
           |  |  | 2088 |   | 
        
           |  |  | 2089 |     $select = 'workshopid = ? AND authorid = ? AND (timecreated > ? OR timegraded > ? OR timemodified > ?)';
 | 
        
           |  |  | 2090 |     $params = array($cm->instance, $USER->id, $from, $from, $from);
 | 
        
           |  |  | 2091 |     $submissions = $DB->get_records_select('workshop_submissions', $select, $params, '', 'id');
 | 
        
           |  |  | 2092 |     if (!empty($submissions)) {
 | 
        
           |  |  | 2093 |         $updates->submissions->updated = true;
 | 
        
           |  |  | 2094 |         $updates->submissions->itemids = array_keys($submissions);
 | 
        
           |  |  | 2095 |     }
 | 
        
           |  |  | 2096 |   | 
        
           |  |  | 2097 |     // Get assessments updates (both submissions reviewed by me or reviews by others).
 | 
        
           |  |  | 2098 |     $select = "SELECT a.id
 | 
        
           |  |  | 2099 |                  FROM {workshop_assessments} a
 | 
        
           |  |  | 2100 |                  JOIN {workshop_submissions} s ON a.submissionid = s.id
 | 
        
           |  |  | 2101 |                  WHERE s.workshopid = ? AND (a.timecreated > ? OR a.timemodified > ?) AND (s.authorid = ? OR a.reviewerid = ?)";
 | 
        
           |  |  | 2102 |     $params = array($cm->instance, $from, $from, $USER->id, $USER->id);
 | 
        
           |  |  | 2103 |     $assessments = $DB->get_records_sql($select, $params);
 | 
        
           |  |  | 2104 |     if (!empty($assessments)) {
 | 
        
           |  |  | 2105 |         $updates->assessments->updated = true;
 | 
        
           |  |  | 2106 |         $updates->assessments->itemids = array_keys($assessments);
 | 
        
           |  |  | 2107 |     }
 | 
        
           |  |  | 2108 |     // Finally assessment aggregated grades.
 | 
        
           |  |  | 2109 |     $select = 'workshopid = ? AND userid = ? AND timegraded > ?';
 | 
        
           |  |  | 2110 |     $params = array($cm->instance, $USER->id, $from);
 | 
        
           |  |  | 2111 |     $assessmentgrades = $DB->get_records_select('workshop_aggregations', $select, $params, '', 'id');
 | 
        
           |  |  | 2112 |     if (!empty($assessmentgrades)) {
 | 
        
           |  |  | 2113 |         $updates->assessmentgrades->updated = true;
 | 
        
           |  |  | 2114 |         $updates->assessmentgrades->itemids = array_keys($assessmentgrades);
 | 
        
           |  |  | 2115 |     }
 | 
        
           |  |  | 2116 |   | 
        
           |  |  | 2117 |     // Now, teachers should see other students updates.
 | 
        
           |  |  | 2118 |     $canviewallsubmissions = has_capability('mod/workshop:viewallsubmissions', $cm->context);
 | 
        
           |  |  | 2119 |     $canviewallassessments = has_capability('mod/workshop:viewallassessments', $cm->context);
 | 
        
           |  |  | 2120 |     if ($canviewallsubmissions || $canviewallassessments) {
 | 
        
           |  |  | 2121 |   | 
        
           |  |  | 2122 |         $insql = '';
 | 
        
           |  |  | 2123 |         $inparams = array();
 | 
        
           |  |  | 2124 |         // To filter by users in my groups when separated groups are forced.
 | 
        
           |  |  | 2125 |         if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
 | 
        
           |  |  | 2126 |             $groupusers = array_keys(groups_get_activity_shared_group_members($cm));
 | 
        
           |  |  | 2127 |             if (empty($groupusers)) {
 | 
        
           |  |  | 2128 |                 return $updates;
 | 
        
           |  |  | 2129 |             }
 | 
        
           |  |  | 2130 |             list($insql, $inparams) = $DB->get_in_or_equal($groupusers);
 | 
        
           |  |  | 2131 |         }
 | 
        
           |  |  | 2132 |   | 
        
           |  |  | 2133 |         if ($canviewallsubmissions) {
 | 
        
           |  |  | 2134 |             $updates->usersubmissions = (object) array('updated' => false);
 | 
        
           |  |  | 2135 |             $select = 'workshopid = ? AND (timecreated > ? OR timegraded > ? OR timemodified > ?)';
 | 
        
           |  |  | 2136 |             $params = array($cm->instance, $from, $from, $from);
 | 
        
           |  |  | 2137 |             if (!empty($insql)) {
 | 
        
           |  |  | 2138 |                 $select .= " AND authorid $insql";
 | 
        
           |  |  | 2139 |                 $params = array_merge($params, $inparams);
 | 
        
           |  |  | 2140 |             }
 | 
        
           |  |  | 2141 |             $usersubmissions = $DB->get_records_select('workshop_submissions', $select, $params, '', 'id');
 | 
        
           |  |  | 2142 |             if (!empty($usersubmissions)) {
 | 
        
           |  |  | 2143 |                 $updates->usersubmissions->updated = true;
 | 
        
           |  |  | 2144 |                 $updates->usersubmissions->itemids = array_keys($usersubmissions);
 | 
        
           |  |  | 2145 |             }
 | 
        
           |  |  | 2146 |         }
 | 
        
           |  |  | 2147 |   | 
        
           |  |  | 2148 |         if ($canviewallassessments) {
 | 
        
           |  |  | 2149 |             $updates->userassessments = (object) array('updated' => false);
 | 
        
           |  |  | 2150 |             $select = "SELECT a.id
 | 
        
           |  |  | 2151 |                          FROM {workshop_assessments} a
 | 
        
           |  |  | 2152 |                          JOIN {workshop_submissions} s ON a.submissionid = s.id
 | 
        
           |  |  | 2153 |                         WHERE s.workshopid = ? AND (a.timecreated > ? OR a.timemodified > ?)";
 | 
        
           |  |  | 2154 |             $params = array($cm->instance, $from, $from);
 | 
        
           |  |  | 2155 |             if (!empty($insql)) {
 | 
        
           |  |  | 2156 |                 $select .= " AND s.reviewerid $insql";
 | 
        
           |  |  | 2157 |                 $params = array_merge($params, $inparams);
 | 
        
           |  |  | 2158 |             }
 | 
        
           |  |  | 2159 |             $userassessments = $DB->get_records_sql($select, $params);
 | 
        
           |  |  | 2160 |             if (!empty($userassessments)) {
 | 
        
           |  |  | 2161 |                 $updates->userassessments->updated = true;
 | 
        
           |  |  | 2162 |                 $updates->userassessments->itemids = array_keys($userassessments);
 | 
        
           |  |  | 2163 |             }
 | 
        
           |  |  | 2164 |   | 
        
           |  |  | 2165 |             $updates->userassessmentgrades = (object) array('updated' => false);
 | 
        
           |  |  | 2166 |             $select = 'workshopid = ? AND timegraded > ?';
 | 
        
           |  |  | 2167 |             $params = array($cm->instance, $USER->id);
 | 
        
           |  |  | 2168 |             if (!empty($insql)) {
 | 
        
           |  |  | 2169 |                 $select .= " AND userid $insql";
 | 
        
           |  |  | 2170 |                 $params = array_merge($params, $inparams);
 | 
        
           |  |  | 2171 |             }
 | 
        
           |  |  | 2172 |             $userassessmentgrades = $DB->get_records_select('workshop_aggregations', $select, $params, '', 'id');
 | 
        
           |  |  | 2173 |             if (!empty($userassessmentgrades)) {
 | 
        
           |  |  | 2174 |                 $updates->userassessmentgrades->updated = true;
 | 
        
           |  |  | 2175 |                 $updates->userassessmentgrades->itemids = array_keys($userassessmentgrades);
 | 
        
           |  |  | 2176 |             }
 | 
        
           |  |  | 2177 |         }
 | 
        
           |  |  | 2178 |     }
 | 
        
           |  |  | 2179 |     return $updates;
 | 
        
           |  |  | 2180 | }
 | 
        
           |  |  | 2181 |   | 
        
           |  |  | 2182 | /**
 | 
        
           |  |  | 2183 |  * Given an array with a file path, it returns the itemid and the filepath for the defined filearea.
 | 
        
           |  |  | 2184 |  *
 | 
        
           |  |  | 2185 |  * @param  string $filearea The filearea.
 | 
        
           |  |  | 2186 |  * @param  array  $args The path (the part after the filearea and before the filename).
 | 
        
           |  |  | 2187 |  * @return array|null The itemid and the filepath inside the $args path, for the defined filearea.
 | 
        
           |  |  | 2188 |  */
 | 
        
           |  |  | 2189 | function mod_workshop_get_path_from_pluginfile(string $filearea, array $args): ?array {
 | 
        
           |  |  | 2190 |     if ($filearea !== 'instructauthors' && $filearea !== 'instructreviewers' && $filearea !== 'conclusion') {
 | 
        
           |  |  | 2191 |         return null;
 | 
        
           |  |  | 2192 |     }
 | 
        
           |  |  | 2193 |   | 
        
           |  |  | 2194 |     // Workshop only has empty itemid for some of the fileareas.
 | 
        
           |  |  | 2195 |     array_shift($args);
 | 
        
           |  |  | 2196 |   | 
        
           |  |  | 2197 |     // Get the filepath.
 | 
        
           |  |  | 2198 |     if (empty($args)) {
 | 
        
           |  |  | 2199 |         $filepath = '/';
 | 
        
           |  |  | 2200 |     } else {
 | 
        
           |  |  | 2201 |         $filepath = '/' . implode('/', $args) . '/';
 | 
        
           |  |  | 2202 |     }
 | 
        
           |  |  | 2203 |   | 
        
           |  |  | 2204 |     return [
 | 
        
           |  |  | 2205 |         'itemid' => 0,
 | 
        
           |  |  | 2206 |         'filepath' => $filepath,
 | 
        
           |  |  | 2207 |     ];
 | 
        
           |  |  | 2208 | }
 | 
        
           |  |  | 2209 |   | 
        
           |  |  | 2210 | /**
 | 
        
           |  |  | 2211 |  * Add a get_coursemodule_info function in case any feedback type wants to add 'extra' information
 | 
        
           |  |  | 2212 |  * for the course (see resource).
 | 
        
           |  |  | 2213 |  *
 | 
        
           |  |  | 2214 |  * Given a course_module object, this function returns any "extra" information that may be needed
 | 
        
           |  |  | 2215 |  * when printing this activity in a course listing.  See get_array_of_activities() in course/lib.php.
 | 
        
           |  |  | 2216 |  *
 | 
        
           |  |  | 2217 |  * @param stdClass $coursemodule The coursemodule object (record).
 | 
        
           |  |  | 2218 |  * @return cached_cm_info|false An object on information that the courses will know about (most noticeably, an icon).
 | 
        
           |  |  | 2219 |  */
 | 
        
           |  |  | 2220 | function workshop_get_coursemodule_info($coursemodule) {
 | 
        
           |  |  | 2221 |     global $DB;
 | 
        
           |  |  | 2222 |   | 
        
           |  |  | 2223 |     $dbparams = ['id' => $coursemodule->instance];
 | 
        
           |  |  | 2224 |     $fields = 'id, name, intro, introformat, submissionstart, submissionend, assessmentstart, assessmentend';
 | 
        
           |  |  | 2225 |     if (!$workshop = $DB->get_record('workshop', $dbparams, $fields)) {
 | 
        
           |  |  | 2226 |         return false;
 | 
        
           |  |  | 2227 |     }
 | 
        
           |  |  | 2228 |   | 
        
           |  |  | 2229 |     $result = new cached_cm_info();
 | 
        
           |  |  | 2230 |     $result->name = $workshop->name;
 | 
        
           |  |  | 2231 |   | 
        
           |  |  | 2232 |     if ($coursemodule->showdescription) {
 | 
        
           |  |  | 2233 |         // Convert intro to html. Do not filter cached version, filters run at display time.
 | 
        
           |  |  | 2234 |         $result->content = format_module_intro('workshop', $workshop, $coursemodule->id, false);
 | 
        
           |  |  | 2235 |     }
 | 
        
           |  |  | 2236 |   | 
        
           |  |  | 2237 |     // Populate some other values that can be used in calendar or on dashboard.
 | 
        
           |  |  | 2238 |     if ($workshop->submissionstart) {
 | 
        
           |  |  | 2239 |         $result->customdata['submissionstart'] = $workshop->submissionstart;
 | 
        
           |  |  | 2240 |     }
 | 
        
           |  |  | 2241 |     if ($workshop->submissionend) {
 | 
        
           |  |  | 2242 |         $result->customdata['submissionend'] = $workshop->submissionend;
 | 
        
           |  |  | 2243 |     }
 | 
        
           |  |  | 2244 |     if ($workshop->assessmentstart) {
 | 
        
           |  |  | 2245 |         $result->customdata['assessmentstart'] = $workshop->assessmentstart;
 | 
        
           |  |  | 2246 |     }
 | 
        
           |  |  | 2247 |     if ($workshop->assessmentend) {
 | 
        
           |  |  | 2248 |         $result->customdata['assessmentend'] = $workshop->assessmentend;
 | 
        
           |  |  | 2249 |     }
 | 
        
           |  |  | 2250 |   | 
        
           |  |  | 2251 |     return $result;
 | 
        
           |  |  | 2252 | }
 | 
        
           |  |  | 2253 |   | 
        
           |  |  | 2254 | /**
 | 
        
           |  |  | 2255 |  * Get the current user preferences that are available
 | 
        
           |  |  | 2256 |  *
 | 
        
           |  |  | 2257 |  * @return array[]
 | 
        
           |  |  | 2258 |  */
 | 
        
           |  |  | 2259 | function mod_workshop_user_preferences(): array {
 | 
        
           |  |  | 2260 |     $preferencedefinition = [
 | 
        
           |  |  | 2261 |         'type' => PARAM_BOOL,
 | 
        
           |  |  | 2262 |         'null' => NULL_NOT_ALLOWED,
 | 
        
           |  |  | 2263 |         'default' => false,
 | 
        
           |  |  | 2264 |         'permissioncallback' => [core_user::class, 'is_current_user'],
 | 
        
           |  |  | 2265 |     ];
 | 
        
           |  |  | 2266 |   | 
        
           |  |  | 2267 |     return [
 | 
        
           |  |  | 2268 |         'workshop-viewlet-allexamples-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2269 |         'workshop-viewlet-allsubmissions-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2270 |         'workshop-viewlet-assessmentform-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2271 |         'workshop-viewlet-assignedassessments-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2272 |         'workshop-viewlet-cleargrades-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2273 |         'workshop-viewlet-conclusion-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2274 |         'workshop-viewlet-examples-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2275 |         'workshop-viewlet-examplesfail-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2276 |         'workshop-viewlet-gradereport-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2277 |         'workshop-viewlet-instructauthors-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2278 |         'workshop-viewlet-instructreviewers-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2279 |         'workshop-viewlet-intro-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2280 |         'workshop-viewlet-ownsubmission-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2281 |         'workshop-viewlet-publicsubmissions-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2282 |         'workshop-viewlet-yourgrades-collapsed' => $preferencedefinition,
 | 
        
           |  |  | 2283 |     ];
 | 
        
           |  |  | 2284 | }
 | 
        
           |  |  | 2285 |   | 
        
           |  |  | 2286 | /**
 | 
        
           |  |  | 2287 |  * Callback to fetch the activity event type lang string.
 | 
        
           |  |  | 2288 |  *
 | 
        
           |  |  | 2289 |  * @param string $eventtype The event type.
 | 
        
           |  |  | 2290 |  * @return lang_string The event type lang string.
 | 
        
           |  |  | 2291 |  */
 | 
        
           |  |  | 2292 | function mod_workshop_core_calendar_get_event_action_string($eventtype): string {
 | 
        
           |  |  | 2293 |     $modulename = get_string('modulename', 'workshop');
 | 
        
           |  |  | 2294 |   | 
        
           |  |  | 2295 |     switch ($eventtype) {
 | 
        
           |  |  | 2296 |         case WORKSHOP_EVENT_TYPE_SUBMISSION_OPEN:
 | 
        
           |  |  | 2297 |             $identifier = 'submissionstartevent';
 | 
        
           |  |  | 2298 |             break;
 | 
        
           |  |  | 2299 |         case WORKSHOP_EVENT_TYPE_SUBMISSION_CLOSE:
 | 
        
           |  |  | 2300 |             $identifier = 'submissionendevent';
 | 
        
           |  |  | 2301 |             break;
 | 
        
           |  |  | 2302 |         case WORKSHOP_EVENT_TYPE_ASSESSMENT_OPEN:
 | 
        
           |  |  | 2303 |             $identifier = 'assessmentstartevent';
 | 
        
           |  |  | 2304 |             break;
 | 
        
           |  |  | 2305 |         case WORKSHOP_EVENT_TYPE_ASSESSMENT_CLOSE;
 | 
        
           |  |  | 2306 |             $identifier = 'assessmentendevent';
 | 
        
           |  |  | 2307 |             break;
 | 
        
           |  |  | 2308 |         default:
 | 
        
           |  |  | 2309 |             return get_string('requiresaction', 'calendar', $modulename);
 | 
        
           |  |  | 2310 |     }
 | 
        
           |  |  | 2311 |   | 
        
           |  |  | 2312 |     return get_string($identifier, 'workshop', $modulename);
 | 
        
           |  |  | 2313 | }
 |