[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/badges/criteria/ -> award_criteria.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   * Badge award criteria
  19   *
  20   * @package    core
  21   * @subpackage badges
  22   * @copyright  2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @author     Yuliya Bozhko <yuliya.bozhko@totaralms.com>
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  /*
  30   * Role completion criteria type
  31   * Criteria type constant, primarily for storing criteria type in the database.
  32   */
  33  define('BADGE_CRITERIA_TYPE_OVERALL', 0);
  34  
  35  /*
  36   * Activity completion criteria type
  37   * Criteria type constant, primarily for storing criteria type in the database.
  38   */
  39  define('BADGE_CRITERIA_TYPE_ACTIVITY', 1);
  40  
  41  /*
  42   * Duration completion criteria type
  43   * Criteria type constant, primarily for storing criteria type in the database.
  44   */
  45  define('BADGE_CRITERIA_TYPE_MANUAL', 2);
  46  
  47  /*
  48   * Grade completion criteria type
  49   * Criteria type constant, primarily for storing criteria type in the database.
  50   */
  51  define('BADGE_CRITERIA_TYPE_SOCIAL', 3);
  52  
  53  /*
  54   * Course completion criteria type
  55   * Criteria type constant, primarily for storing criteria type in the database.
  56  */
  57  define('BADGE_CRITERIA_TYPE_COURSE', 4);
  58  
  59  /*
  60   * Courseset completion criteria type
  61   * Criteria type constant, primarily for storing criteria type in the database.
  62   */
  63  define('BADGE_CRITERIA_TYPE_COURSESET', 5);
  64  
  65  /*
  66   * Course completion criteria type
  67   * Criteria type constant, primarily for storing criteria type in the database.
  68   */
  69  define('BADGE_CRITERIA_TYPE_PROFILE', 6);
  70  
  71  /*
  72   * Criteria type constant to class name mapping
  73   */
  74  global $BADGE_CRITERIA_TYPES;
  75  $BADGE_CRITERIA_TYPES = array(
  76      BADGE_CRITERIA_TYPE_OVERALL   => 'overall',
  77      BADGE_CRITERIA_TYPE_ACTIVITY  => 'activity',
  78      BADGE_CRITERIA_TYPE_MANUAL    => 'manual',
  79      BADGE_CRITERIA_TYPE_SOCIAL    => 'social',
  80      BADGE_CRITERIA_TYPE_COURSE    => 'course',
  81      BADGE_CRITERIA_TYPE_COURSESET => 'courseset',
  82      BADGE_CRITERIA_TYPE_PROFILE   => 'profile'
  83  );
  84  
  85  /**
  86   * Award criteria abstract definition
  87   *
  88   */
  89  abstract class award_criteria {
  90  
  91      /**
  92       * ID of the criterion.
  93       * @var integer
  94       */
  95      public $id;
  96  
  97      /**
  98       * Aggregation method [BADGE_CRITERIA_AGGREGATION_ANY, BADGE_CRITERIA_AGGREGATION_ALL].
  99       * @var integer
 100       */
 101      public $method;
 102  
 103      /**
 104       * ID of a badge this criterion belongs to.
 105       * @var integer
 106       */
 107      public $badgeid;
 108  
 109      /**
 110       * Criterion HTML/plain text description.
 111       * @var string
 112       */
 113      public $description;
 114  
 115      /**
 116       * Format of the criterion description.
 117       * @var integer
 118       */
 119      public $descriptionformat;
 120  
 121      /**
 122       * Any additional parameters.
 123       * @var array
 124       */
 125      public $params = array();
 126  
 127      /**
 128       * The base constructor
 129       *
 130       * @param array $params
 131       */
 132      public function __construct($params) {
 133          $this->id = isset($params['id']) ? $params['id'] : 0;
 134          $this->method = isset($params['method']) ? $params['method'] : BADGE_CRITERIA_AGGREGATION_ANY;
 135          $this->badgeid = $params['badgeid'];
 136          $this->description = isset($params['description']) ? $params['description'] : '';
 137          $this->descriptionformat = isset($params['descriptionformat']) ? $params['descriptionformat'] : FORMAT_HTML;
 138          if (isset($params['id'])) {
 139              $this->params = $this->get_params($params['id']);
 140          }
 141      }
 142  
 143      /**
 144       * Factory method for creating criteria class object
 145       *
 146       * @param array $params associative arrays varname => value
 147       * @return award_criteria
 148       */
 149      public static function build($params) {
 150          global $CFG, $BADGE_CRITERIA_TYPES;
 151  
 152          if (!isset($params['criteriatype']) || !isset($BADGE_CRITERIA_TYPES[$params['criteriatype']])) {
 153              print_error('error:invalidcriteriatype', 'badges');
 154          }
 155  
 156          $class = 'award_criteria_' . $BADGE_CRITERIA_TYPES[$params['criteriatype']];
 157          require_once($CFG->dirroot . '/badges/criteria/' . $class . '.php');
 158  
 159          return new $class($params);
 160      }
 161  
 162      /**
 163       * Return criteria title
 164       *
 165       * @return string
 166       */
 167      public function get_title() {
 168          return get_string('criteria_' . $this->criteriatype, 'badges');
 169      }
 170  
 171      /**
 172       * Get criteria details for displaying to users
 173       *
 174       * @param string $short Print short version of criteria
 175       * @return string
 176       */
 177      abstract public function get_details($short = '');
 178  
 179      /**
 180       * Add appropriate criteria options to the form
 181       *
 182       */
 183      abstract public function get_options(&$mform);
 184  
 185      /**
 186       * Add appropriate parameter elements to the criteria form
 187       *
 188       */
 189      public function config_options(&$mform, $param) {
 190          global $OUTPUT;
 191          $prefix = $this->required_param . '_';
 192  
 193          if ($param['error']) {
 194              $parameter[] =& $mform->createElement('advcheckbox', $prefix . $param['id'], '',
 195                      $OUTPUT->error_text($param['name']), null, array(0, $param['id']));
 196              $mform->addGroup($parameter, 'param_' . $prefix . $param['id'], '', array(' '), false);
 197          } else {
 198              $parameter[] =& $mform->createElement('advcheckbox', $prefix . $param['id'], '', $param['name'], null, array(0, $param['id']));
 199              $parameter[] =& $mform->createElement('static', 'break_start_' . $param['id'], null, '<div style="margin-left: 3em;">');
 200  
 201              if (in_array('grade', $this->optional_params)) {
 202                  $parameter[] =& $mform->createElement('static', 'mgrade_' . $param['id'], null, get_string('mingrade', 'badges'));
 203                  $parameter[] =& $mform->createElement('text', 'grade_' . $param['id'], '', array('size' => '5'));
 204                  $mform->setType('grade_' . $param['id'], PARAM_INT);
 205              }
 206  
 207              if (in_array('bydate', $this->optional_params)) {
 208                  $parameter[] =& $mform->createElement('static', 'complby_' . $param['id'], null, get_string('bydate', 'badges'));
 209                  $parameter[] =& $mform->createElement('date_selector', 'bydate_' . $param['id'], "", array('optional' => true));
 210              }
 211  
 212              $parameter[] =& $mform->createElement('static', 'break_end_' . $param['id'], null, '</div>');
 213              $mform->addGroup($parameter, 'param_' . $prefix . $param['id'], '', array(' '), false);
 214              if (in_array('grade', $this->optional_params)) {
 215                  $mform->addGroupRule('param_' . $prefix . $param['id'], array(
 216                      'grade_' . $param['id'] => array(array(get_string('err_numeric', 'form'), 'numeric', '', 'client'))));
 217              }
 218              $mform->disabledIf('bydate_' . $param['id'] . '[day]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked');
 219              $mform->disabledIf('bydate_' . $param['id'] . '[month]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked');
 220              $mform->disabledIf('bydate_' . $param['id'] . '[year]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked');
 221              $mform->disabledIf('param_' . $prefix . $param['id'], $prefix . $param['id'], 'notchecked');
 222          }
 223  
 224          // Set default values.
 225          $mform->setDefault($prefix . $param['id'], $param['checked']);
 226          if (isset($param['bydate'])) {
 227              $mform->setDefault('bydate_' . $param['id'], $param['bydate']);
 228          }
 229          if (isset($param['grade'])) {
 230              $mform->setDefault('grade_' . $param['id'], $param['grade']);
 231          }
 232      }
 233  
 234      /**
 235       * Add appropriate criteria elements
 236       *
 237       * @param stdClass $data details of various criteria
 238       */
 239      public function config_form_criteria($data) {
 240          global $OUTPUT;
 241          $agg = $data->get_aggregation_methods();
 242  
 243          $editurl = new moodle_url('/badges/criteria_settings.php',
 244                  array('badgeid' => $this->badgeid, 'edit' => true, 'type' => $this->criteriatype, 'crit' => $this->id));
 245          $deleteurl = new moodle_url('/badges/criteria_action.php',
 246                  array('badgeid' => $this->badgeid, 'delete' => true, 'type' => $this->criteriatype));
 247          $editaction = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('edit')), null, array('class' => 'criteria-action'));
 248          $deleteaction = $OUTPUT->action_icon($deleteurl, new pix_icon('t/delete', get_string('delete')), null, array('class' => 'criteria-action'));
 249  
 250          echo $OUTPUT->box_start();
 251          if (!$data->is_locked() && !$data->is_active()) {
 252              echo $OUTPUT->box($deleteaction . $editaction, array('criteria-header'));
 253          }
 254          echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help');
 255  
 256          if (!empty($this->description)) {
 257              $badge = new badge($this->badgeid);
 258              echo $OUTPUT->box(
 259                  format_text($this->description, $this->descriptionformat, array('context' => $badge->get_context())),
 260                  'criteria-description'
 261                  );
 262          }
 263  
 264          if (!empty($this->params)) {
 265              if (count($this->params) > 1) {
 266                  echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges',
 267                          core_text::strtoupper($agg[$data->get_aggregation_method($this->criteriatype)])), array('clearfix'));
 268              } else {
 269                  echo $OUTPUT->box(get_string('criteria_descr_single_' . $this->criteriatype , 'badges'), array('clearfix'));
 270              }
 271              echo $OUTPUT->box($this->get_details(), array('clearfix'));
 272          }
 273          echo $OUTPUT->box_end();
 274      }
 275  
 276      /**
 277       * Review this criteria and decide if the user has completed
 278       *
 279       * @param int $userid User whose criteria completion needs to be reviewed.
 280       * @param bool $filtered An additional parameter indicating that user list
 281       *        has been reduced and some expensive checks can be skipped.
 282       *
 283       * @return bool Whether criteria is complete
 284       */
 285      abstract public function review($userid, $filtered = false);
 286  
 287      /**
 288       * Returns array with sql code and parameters returning all ids
 289       * of users who meet this particular criterion.
 290       *
 291       * @return array list($join, $where, $params)
 292       */
 293      abstract public function get_completed_criteria_sql();
 294  
 295      /**
 296       * Mark this criteria as complete for a user
 297       *
 298       * @param int $userid User whose criteria is completed.
 299       */
 300      public function mark_complete($userid) {
 301          global $DB;
 302          $obj = array();
 303          $obj['critid'] = $this->id;
 304          $obj['userid'] = $userid;
 305          $obj['datemet'] = time();
 306          if (!$DB->record_exists('badge_criteria_met', array('critid' => $this->id, 'userid' => $userid))) {
 307              $DB->insert_record('badge_criteria_met', $obj);
 308          }
 309      }
 310  
 311      /**
 312       * Return criteria parameters
 313       *
 314       * @param int $critid Criterion ID
 315       * @return array
 316       */
 317      public function get_params($cid) {
 318          global $DB;
 319          $params = array();
 320  
 321          $records = $DB->get_records('badge_criteria_param', array('critid' => $cid));
 322          foreach ($records as $rec) {
 323              $arr = explode('_', $rec->name);
 324              $params[$arr[1]][$arr[0]] = $rec->value;
 325          }
 326  
 327          return $params;
 328      }
 329  
 330      /**
 331       * Delete this criterion
 332       *
 333       */
 334      public function delete() {
 335          global $DB, $PAGE;
 336  
 337          // Remove any records if it has already been met.
 338          $DB->delete_records('badge_criteria_met', array('critid' => $this->id));
 339  
 340          // Remove all parameters records.
 341          $DB->delete_records('badge_criteria_param', array('critid' => $this->id));
 342  
 343          // Finally remove criterion itself.
 344          $DB->delete_records('badge_criteria', array('id' => $this->id));
 345  
 346          // Trigger event, badge criteria deleted.
 347          $eventparams = array('objectid' => $this->id,
 348              'context' => $PAGE->context,
 349              'other' => array('badgeid' => $this->badgeid));
 350          $event = \core\event\badge_criteria_deleted::create($eventparams);
 351          $event->trigger();
 352      }
 353  
 354      /**
 355       * Saves intial criteria records with required parameters set up.
 356       *
 357       * @param array $params Values from the form or any other array.
 358       */
 359      public function save($params = array()) {
 360          global $DB, $PAGE;
 361  
 362          // Figure out criteria description.
 363          // If it is coming from the form editor, it is an array(text, format).
 364          $description = '';
 365          $descriptionformat = FORMAT_HTML;
 366          if (isset($params['description']['text'])) {
 367              $description = $params['description']['text'];
 368              $descriptionformat = $params['description']['format'];
 369          } else if (isset($params['description'])) {
 370              $description = $params['description'];
 371          }
 372  
 373          $fordb = new stdClass();
 374          $fordb->criteriatype = $this->criteriatype;
 375          $fordb->method = isset($params['agg']) ? $params['agg'] : BADGE_CRITERIA_AGGREGATION_ALL;
 376          $fordb->badgeid = $this->badgeid;
 377          $fordb->description = $description;
 378          $fordb->descriptionformat = $descriptionformat;
 379          $t = $DB->start_delegated_transaction();
 380  
 381          // Pick only params that are required by this criterion.
 382          // Filter out empty values first.
 383          $params = array_filter($params);
 384          // Find out which param matches optional and required ones.
 385          $match = array_merge($this->optional_params, array($this->required_param));
 386          $regex = implode('|', array_map(create_function('$a', 'return $a . "_";'), $match));
 387          $requiredkeys = preg_grep('/^(' . $regex . ').*$/', array_keys($params));
 388  
 389          if ($this->id !== 0) {
 390              $cid = $this->id;
 391  
 392              // Update criteria before doing anything with parameters.
 393              $fordb->id = $cid;
 394              $DB->update_record('badge_criteria', $fordb, true);
 395  
 396              // Trigger event: badge_criteria_updated.
 397              $eventparams = array('objectid' => $this->id,
 398                  'context' => $PAGE->context,
 399                  'other' => array('badgeid' => $this->badgeid));
 400              $event = \core\event\badge_criteria_updated::create($eventparams);
 401              $event->trigger();
 402  
 403              $existing = $DB->get_fieldset_select('badge_criteria_param', 'name', 'critid = ?', array($cid));
 404              $todelete = array_diff($existing, $requiredkeys);
 405  
 406              if (!empty($todelete)) {
 407                  // A workaround to add some disabled elements that are still being submitted from the form.
 408                  foreach ($todelete as $del) {
 409                      $name = explode('_', $del);
 410                      if ($name[0] == $this->required_param) {
 411                          foreach ($this->optional_params as $opt) {
 412                              $todelete[] = $opt . '_' . $name[1];
 413                          }
 414                      }
 415                  }
 416                  $todelete = array_unique($todelete);
 417                  list($sql, $sqlparams) = $DB->get_in_or_equal($todelete, SQL_PARAMS_NAMED, 'd', true);
 418                  $sqlparams = array_merge(array('critid' => $cid), $sqlparams);
 419                  $DB->delete_records_select('badge_criteria_param', 'critid = :critid AND name ' . $sql, $sqlparams);
 420              }
 421  
 422              foreach ($requiredkeys as $key) {
 423                  if (in_array($key, $existing)) {
 424                      $updp = $DB->get_record('badge_criteria_param', array('name' => $key, 'critid' => $cid));
 425                      $updp->value = $params[$key];
 426                      $DB->update_record('badge_criteria_param', $updp, true);
 427                  } else {
 428                      $newp = new stdClass();
 429                      $newp->critid = $cid;
 430                      $newp->name = $key;
 431                      $newp->value = $params[$key];
 432                      $DB->insert_record('badge_criteria_param', $newp);
 433                  }
 434              }
 435          } else {
 436              $cid = $DB->insert_record('badge_criteria', $fordb, true);
 437              if ($cid) {
 438                  foreach ($requiredkeys as $key) {
 439                      $newp = new stdClass();
 440                      $newp->critid = $cid;
 441                      $newp->name = $key;
 442                      $newp->value = $params[$key];
 443                      $DB->insert_record('badge_criteria_param', $newp, false, true);
 444                  }
 445              }
 446              // Trigger event: badge_criteria_created.
 447              $eventparams = array('objectid' => $this->id,
 448                  'context' => $PAGE->context,
 449                  'other' => array('badgeid' => $this->badgeid));
 450              $event = \core\event\badge_criteria_created::create($eventparams);
 451              $event->trigger();
 452          }
 453          $t->allow_commit();
 454      }
 455  
 456      /**
 457       * Saves intial criteria records with required parameters set up.
 458       */
 459      public function make_clone($newbadgeid) {
 460          global $DB;
 461  
 462          $fordb = new stdClass();
 463          $fordb->criteriatype = $this->criteriatype;
 464          $fordb->method = $this->method;
 465          $fordb->badgeid = $newbadgeid;
 466          $fordb->description = $this->description;
 467          $fordb->descriptionformat = $this->descriptionformat;
 468          if (($newcrit = $DB->insert_record('badge_criteria', $fordb, true)) && isset($this->params)) {
 469              foreach ($this->params as $k => $param) {
 470                  foreach ($param as $key => $value) {
 471                      $paramdb = new stdClass();
 472                      $paramdb->critid = $newcrit;
 473                      $paramdb->name = $key . '_' . $k;
 474                      $paramdb->value = $value;
 475                      $DB->insert_record('badge_criteria_param', $paramdb);
 476                  }
 477              }
 478          }
 479      }
 480  }


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