[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Activity completion condition. 19 * 20 * @package availability_completion 21 * @copyright 2014 The Open University 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace availability_completion; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once($CFG->libdir . '/completionlib.php'); 30 31 /** 32 * Activity completion condition. 33 * 34 * @package availability_completion 35 * @copyright 2014 The Open University 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class condition extends \core_availability\condition { 39 /** @var int ID of module that this depends on */ 40 protected $cmid; 41 42 /** @var int Expected completion type (one of the COMPLETE_xx constants) */ 43 protected $expectedcompletion; 44 45 /** @var array Array of modules used in these conditions for course */ 46 protected static $modsusedincondition = array(); 47 48 /** 49 * Constructor. 50 * 51 * @param \stdClass $structure Data structure from JSON decode 52 * @throws \coding_exception If invalid data structure. 53 */ 54 public function __construct($structure) { 55 // Get cmid. 56 if (isset($structure->cm) && is_number($structure->cm)) { 57 $this->cmid = (int)$structure->cm; 58 } else { 59 throw new \coding_exception('Missing or invalid ->cm for completion condition'); 60 } 61 62 // Get expected completion. 63 if (isset($structure->e) && in_array($structure->e, 64 array(COMPLETION_COMPLETE, COMPLETION_INCOMPLETE, 65 COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL))) { 66 $this->expectedcompletion = $structure->e; 67 } else { 68 throw new \coding_exception('Missing or invalid ->e for completion condition'); 69 } 70 } 71 72 public function save() { 73 return (object)array('type' => 'completion', 74 'cm' => $this->cmid, 'e' => $this->expectedcompletion); 75 } 76 77 /** 78 * Returns a JSON object which corresponds to a condition of this type. 79 * 80 * Intended for unit testing, as normally the JSON values are constructed 81 * by JavaScript code. 82 * 83 * @param int $cmid Course-module id of other activity 84 * @param int $expectedcompletion Expected completion value (COMPLETION_xx) 85 * @return stdClass Object representing condition 86 */ 87 public static function get_json($cmid, $expectedcompletion) { 88 return (object)array('type' => 'completion', 'cm' => (int)$cmid, 89 'e' => (int)$expectedcompletion); 90 } 91 92 public function is_available($not, \core_availability\info $info, $grabthelot, $userid) { 93 $modinfo = $info->get_modinfo(); 94 $completion = new \completion_info($modinfo->get_course()); 95 if (!array_key_exists($this->cmid, $modinfo->cms)) { 96 // If the cmid cannot be found, always return false regardless 97 // of the condition or $not state. (Will be displayed in the 98 // information message.) 99 $allow = false; 100 } else { 101 // The completion system caches its own data so no caching needed here. 102 $completiondata = $completion->get_data((object)array('id' => $this->cmid), 103 $grabthelot, $userid, $modinfo); 104 105 $allow = true; 106 if ($this->expectedcompletion == COMPLETION_COMPLETE) { 107 // Complete also allows the pass, fail states. 108 switch ($completiondata->completionstate) { 109 case COMPLETION_COMPLETE: 110 case COMPLETION_COMPLETE_FAIL: 111 case COMPLETION_COMPLETE_PASS: 112 break; 113 default: 114 $allow = false; 115 } 116 } else { 117 // Other values require exact match. 118 if ($completiondata->completionstate != $this->expectedcompletion) { 119 $allow = false; 120 } 121 } 122 123 if ($not) { 124 $allow = !$allow; 125 } 126 } 127 128 return $allow; 129 } 130 131 /** 132 * Returns a more readable keyword corresponding to a completion state. 133 * 134 * Used to make lang strings easier to read. 135 * 136 * @param int $completionstate COMPLETION_xx constant 137 * @return string Readable keyword 138 */ 139 protected static function get_lang_string_keyword($completionstate) { 140 switch($completionstate) { 141 case COMPLETION_INCOMPLETE: 142 return 'incomplete'; 143 case COMPLETION_COMPLETE: 144 return 'complete'; 145 case COMPLETION_COMPLETE_PASS: 146 return 'complete_pass'; 147 case COMPLETION_COMPLETE_FAIL: 148 return 'complete_fail'; 149 default: 150 throw new \coding_exception('Unexpected completion state: ' . $completionstate); 151 } 152 } 153 154 public function get_description($full, $not, \core_availability\info $info) { 155 // Get name for module. 156 $modinfo = $info->get_modinfo(); 157 if (!array_key_exists($this->cmid, $modinfo->cms)) { 158 $modname = get_string('missing', 'availability_completion'); 159 } else { 160 $modname = '<AVAILABILITY_CMNAME_' . $modinfo->cms[$this->cmid]->id . '/>'; 161 } 162 163 // Work out which lang string to use. 164 if ($not) { 165 // Convert NOT strings to use the equivalent where possible. 166 switch ($this->expectedcompletion) { 167 case COMPLETION_INCOMPLETE: 168 $str = 'requires_' . self::get_lang_string_keyword(COMPLETION_COMPLETE); 169 break; 170 case COMPLETION_COMPLETE: 171 $str = 'requires_' . self::get_lang_string_keyword(COMPLETION_INCOMPLETE); 172 break; 173 default: 174 // The other two cases do not have direct opposites. 175 $str = 'requires_not_' . self::get_lang_string_keyword($this->expectedcompletion); 176 break; 177 } 178 } else { 179 $str = 'requires_' . self::get_lang_string_keyword($this->expectedcompletion); 180 } 181 182 return get_string($str, 'availability_completion', $modname); 183 } 184 185 protected function get_debug_string() { 186 switch ($this->expectedcompletion) { 187 case COMPLETION_COMPLETE : 188 $type = 'COMPLETE'; 189 break; 190 case COMPLETION_INCOMPLETE : 191 $type = 'INCOMPLETE'; 192 break; 193 case COMPLETION_COMPLETE_PASS: 194 $type = 'COMPLETE_PASS'; 195 break; 196 case COMPLETION_COMPLETE_FAIL: 197 $type = 'COMPLETE_FAIL'; 198 break; 199 default: 200 throw new \coding_exception('Unexpected expected completion'); 201 } 202 return 'cm' . $this->cmid . ' ' . $type; 203 } 204 205 public function update_after_restore($restoreid, $courseid, \base_logger $logger, $name) { 206 global $DB; 207 $rec = \restore_dbops::get_backup_ids_record($restoreid, 'course_module', $this->cmid); 208 if (!$rec || !$rec->newitemid) { 209 // If we are on the same course (e.g. duplicate) then we can just 210 // use the existing one. 211 if ($DB->record_exists('course_modules', 212 array('id' => $this->cmid, 'course' => $courseid))) { 213 return false; 214 } 215 // Otherwise it's a warning. 216 $this->cmid = 0; 217 $logger->process('Restored item (' . $name . 218 ') has availability condition on module that was not restored', 219 \backup::LOG_WARNING); 220 } else { 221 $this->cmid = (int)$rec->newitemid; 222 } 223 return true; 224 } 225 226 /** 227 * Used in course/lib.php because we need to disable the completion JS if 228 * a completion value affects a conditional activity. 229 * 230 * @param \stdClass $course Moodle course object 231 * @param int $cmid Course-module id 232 * @return bool True if this is used in a condition, false otherwise 233 */ 234 public static function completion_value_used($course, $cmid) { 235 // Have we already worked out a list of required completion values 236 // for this course? If so just use that. 237 if (!array_key_exists($course->id, self::$modsusedincondition)) { 238 // We don't have data for this course, build it. 239 $modinfo = get_fast_modinfo($course); 240 self::$modsusedincondition[$course->id] = array(); 241 242 // Activities. 243 foreach ($modinfo->cms as $othercm) { 244 if (is_null($othercm->availability)) { 245 continue; 246 } 247 $ci = new \core_availability\info_module($othercm); 248 $tree = $ci->get_availability_tree(); 249 foreach ($tree->get_all_children('availability_completion\condition') as $cond) { 250 self::$modsusedincondition[$course->id][$cond->cmid] = true; 251 } 252 } 253 254 // Sections. 255 foreach ($modinfo->get_section_info_all() as $section) { 256 if (is_null($section->availability)) { 257 continue; 258 } 259 $ci = new \core_availability\info_section($section); 260 $tree = $ci->get_availability_tree(); 261 foreach ($tree->get_all_children('availability_completion\condition') as $cond) { 262 self::$modsusedincondition[$course->id][$cond->cmid] = true; 263 } 264 } 265 } 266 return array_key_exists($cmid, self::$modsusedincondition[$course->id]); 267 } 268 269 /** 270 * Wipes the static cache of modules used in a condition (for unit testing). 271 */ 272 public static function wipe_static_cache() { 273 self::$modsusedincondition = array(); 274 } 275 276 public function update_dependency_id($table, $oldid, $newid) { 277 if ($table === 'course_modules' && (int)$this->cmid === (int)$oldid) { 278 $this->cmid = $newid; 279 return true; 280 } else { 281 return false; 282 } 283 } 284 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |