[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/availability/condition/completion/classes/ -> condition.php (source)

   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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1