[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/admin/tool/uploadcourse/classes/ -> helper.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   * File containing the helper class.
  19   *
  20   * @package    tool_uploadcourse
  21   * @copyright  2013 Frédéric Massart
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  require_once($CFG->libdir . '/coursecatlib.php');
  27  require_once($CFG->dirroot . '/cache/lib.php');
  28  require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
  29  require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
  30  
  31  /**
  32   * Class containing a set of helpers.
  33   *
  34   * @package    tool_uploadcourse
  35   * @copyright  2013 Frédéric Massart
  36   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class tool_uploadcourse_helper {
  39  
  40      /**
  41       * Generate a shortname based on a template.
  42       *
  43       * @param array|object $data course data.
  44       * @param string $templateshortname template of shortname.
  45       * @return null|string shortname based on the template, or null when an error occured.
  46       */
  47      public static function generate_shortname($data, $templateshortname) {
  48          if (empty($templateshortname) && !is_numeric($templateshortname)) {
  49              return null;
  50          }
  51          if (strpos($templateshortname, '%') === false) {
  52              return $templateshortname;
  53          }
  54  
  55          $course = (object) $data;
  56          $fullname   = isset($course->fullname) ? $course->fullname : '';
  57          $idnumber   = isset($course->idnumber) ? $course->idnumber  : '';
  58  
  59          $callback = partial(array('tool_uploadcourse_helper', 'generate_shortname_callback'), $fullname, $idnumber);
  60          $result = preg_replace_callback('/(?<!%)%([+~-])?(\d)*([fi])/', $callback, $templateshortname);
  61  
  62          if (!is_null($result)) {
  63              $result = clean_param($result, PARAM_TEXT);
  64          }
  65  
  66          if (empty($result) && !is_numeric($result)) {
  67              $result = null;
  68          }
  69  
  70          return $result;
  71      }
  72  
  73      /**
  74       * Callback used when generating a shortname based on a template.
  75       *
  76       * @param string $fullname full name.
  77       * @param string $idnumber ID number.
  78       * @param array $block result from preg_replace_callback.
  79       * @return string
  80       */
  81      public static function generate_shortname_callback($fullname, $idnumber, $block) {
  82          switch ($block[3]) {
  83              case 'f':
  84                  $repl = $fullname;
  85                  break;
  86              case 'i':
  87                  $repl = $idnumber;
  88                  break;
  89              default:
  90                  return $block[0];
  91          }
  92  
  93          switch ($block[1]) {
  94              case '+':
  95                  $repl = core_text::strtoupper($repl);
  96                  break;
  97              case '-':
  98                  $repl = core_text::strtolower($repl);
  99                  break;
 100              case '~':
 101                  $repl = core_text::strtotitle($repl);
 102                  break;
 103          }
 104  
 105          if (!empty($block[2])) {
 106              $repl = core_text::substr($repl, 0, $block[2]);
 107          }
 108  
 109          return $repl;
 110      }
 111  
 112      /**
 113       * Return the available course formats.
 114       *
 115       * @return array
 116       */
 117      public static function get_course_formats() {
 118          return array_keys(core_component::get_plugin_list('format'));
 119      }
 120  
 121      /**
 122       * Extract enrolment data from passed data.
 123       *
 124       * Constructs an array of methods, and their options:
 125       * array(
 126       *     'method1' => array(
 127       *         'option1' => value,
 128       *         'option2' => value
 129       *     ),
 130       *     'method2' => array(
 131       *         'option1' => value,
 132       *         'option2' => value
 133       *     )
 134       * )
 135       *
 136       * @param array $data data to extract the enrolment data from.
 137       * @return array
 138       */
 139      public static function get_enrolment_data($data) {
 140          $enrolmethods = array();
 141          $enroloptions = array();
 142          foreach ($data as $field => $value) {
 143  
 144              // Enrolmnent data.
 145              $matches = array();
 146              if (preg_match('/^enrolment_(\d+)(_(.+))?$/', $field, $matches)) {
 147                  $key = $matches[1];
 148                  if (!isset($enroloptions[$key])) {
 149                      $enroloptions[$key] = array();
 150                  }
 151                  if (empty($matches[3])) {
 152                      $enrolmethods[$key] = $value;
 153                  } else {
 154                      $enroloptions[$key][$matches[3]] = $value;
 155                  }
 156              }
 157          }
 158  
 159          // Combining enrolment methods and their options in a single array.
 160          $enrolmentdata = array();
 161          if (!empty($enrolmethods)) {
 162              $enrolmentplugins = self::get_enrolment_plugins();
 163              foreach ($enrolmethods as $key => $method) {
 164                  if (!array_key_exists($method, $enrolmentplugins)) {
 165                      // Error!
 166                      continue;
 167                  }
 168                  $enrolmentdata[$enrolmethods[$key]] = $enroloptions[$key];
 169              }
 170          }
 171          return $enrolmentdata;
 172      }
 173  
 174      /**
 175       * Return the enrolment plugins.
 176       *
 177       * The result is cached for faster execution.
 178       *
 179       * @return array
 180       */
 181      public static function get_enrolment_plugins() {
 182          $cache = cache::make('tool_uploadcourse', 'helper');
 183          if (($enrol = $cache->get('enrol')) === false) {
 184              $enrol = enrol_get_plugins(false);
 185              $cache->set('enrol', $enrol);
 186          }
 187          return $enrol;
 188      }
 189  
 190      /**
 191       * Get the restore content tempdir.
 192       *
 193       * The tempdir is the sub directory in which the backup has been extracted.
 194       *
 195       * This caches the result for better performance, but $CFG->keeptempdirectoriesonbackup
 196       * needs to be enabled, otherwise the cache is ignored.
 197       *
 198       * @param string $backupfile path to a backup file.
 199       * @param string $shortname shortname of a course.
 200       * @param array $errors will be populated with errors found.
 201       * @return string|false false when the backup couldn't retrieved.
 202       */
 203      public static function get_restore_content_dir($backupfile = null, $shortname = null, &$errors = array()) {
 204          global $CFG, $DB, $USER;
 205  
 206          $cachekey = null;
 207          if (!empty($backupfile)) {
 208              $backupfile = realpath($backupfile);
 209              if (empty($backupfile) || !is_readable($backupfile)) {
 210                  $errors['cannotreadbackupfile'] = new lang_string('cannotreadbackupfile', 'tool_uploadcourse');
 211                  return false;
 212              }
 213              $cachekey = 'backup_path:' . $backupfile;
 214          } else if (!empty($shortname) || is_numeric($shortname)) {
 215              $cachekey = 'backup_sn:' . $shortname;
 216          }
 217  
 218          if (empty($cachekey)) {
 219              return false;
 220          }
 221  
 222          // If $CFG->keeptempdirectoriesonbackup is not set to true, any restore happening would
 223          // automatically delete the backup directory... causing the cache to return an unexisting directory.
 224          $usecache = !empty($CFG->keeptempdirectoriesonbackup);
 225          if ($usecache) {
 226              $cache = cache::make('tool_uploadcourse', 'helper');
 227          }
 228  
 229          // If we don't use the cache, or if we do and not set, or the directory doesn't exist any more.
 230          if (!$usecache || (($backupid = $cache->get($cachekey)) === false || !is_dir("$CFG->tempdir/backup/$backupid"))) {
 231  
 232              // Use null instead of false because it would consider that the cache key has not been set.
 233              $backupid = null;
 234  
 235              if (!empty($backupfile)) {
 236                  // Extracting the backup file.
 237                  $packer = get_file_packer('application/vnd.moodle.backup');
 238                  $backupid = restore_controller::get_tempdir_name(SITEID, $USER->id);
 239                  $path = "$CFG->tempdir/backup/$backupid/";
 240                  $result = $packer->extract_to_pathname($backupfile, $path);
 241                  if (!$result) {
 242                      $errors['invalidbackupfile'] = new lang_string('invalidbackupfile', 'tool_uploadcourse');
 243                  }
 244              } else if (!empty($shortname) || is_numeric($shortname)) {
 245                  // Creating restore from an existing course.
 246                  $courseid = $DB->get_field('course', 'id', array('shortname' => $shortname), IGNORE_MISSING);
 247                  if (!empty($courseid)) {
 248                      $bc = new backup_controller(backup::TYPE_1COURSE, $courseid, backup::FORMAT_MOODLE,
 249                          backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id);
 250                      $bc->execute_plan();
 251                      $backupid = $bc->get_backupid();
 252                      $bc->destroy();
 253                  } else {
 254                      $errors['coursetorestorefromdoesnotexist'] =
 255                          new lang_string('coursetorestorefromdoesnotexist', 'tool_uploadcourse');
 256                  }
 257              }
 258  
 259              if ($usecache) {
 260                  $cache->set($cachekey, $backupid);
 261              }
 262          }
 263  
 264          if ($backupid === null) {
 265              $backupid = false;
 266          }
 267          return $backupid;
 268      }
 269  
 270      /**
 271       * Return the role IDs.
 272       *
 273       * The result is cached for faster execution.
 274       *
 275       * @return array
 276       */
 277      public static function get_role_ids() {
 278          $cache = cache::make('tool_uploadcourse', 'helper');
 279          if (($roles = $cache->get('roles')) === false) {
 280              $roles = array();
 281              $rolesraw = get_all_roles();
 282              foreach ($rolesraw as $role) {
 283                  $roles[$role->shortname] = $role->id;
 284              }
 285              $cache->set('roles', $roles);
 286          }
 287          return $roles;
 288      }
 289  
 290      /**
 291       * Get the role renaming data from the passed data.
 292       *
 293       * @param array $data data to extract the names from.
 294       * @param array $errors will be populated with errors found.
 295       * @return array where the key is the role_<id>, the value is the new name.
 296       */
 297      public static function get_role_names($data, &$errors = array()) {
 298          $rolenames = array();
 299          $rolesids = self::get_role_ids();
 300          $invalidroles = array();
 301          foreach ($data as $field => $value) {
 302  
 303              $matches = array();
 304              if (preg_match('/^role_(.+)?$/', $field, $matches)) {
 305                  if (!isset($rolesids[$matches[1]])) {
 306                      $invalidroles[] = $matches[1];
 307                      continue;
 308                  }
 309                  $rolenames['role_' . $rolesids[$matches[1]]] = $value;
 310              }
 311  
 312          }
 313  
 314          if (!empty($invalidroles)) {
 315              $errors['invalidroles'] = new lang_string('invalidroles', 'tool_uploadcourse', implode(', ', $invalidroles));
 316          }
 317  
 318          // Roles names.
 319          return $rolenames;
 320      }
 321  
 322      /**
 323       * Helper to increment an ID number.
 324       *
 325       * This first checks if the ID number is in use.
 326       *
 327       * @param string $idnumber ID number to increment.
 328       * @return string new ID number.
 329       */
 330      public static function increment_idnumber($idnumber) {
 331          global $DB;
 332          while ($DB->record_exists('course', array('idnumber' => $idnumber))) {
 333              $matches = array();
 334              if (!preg_match('/(.*?)([0-9]+)$/', $idnumber, $matches)) {
 335                  $newidnumber = $idnumber . '_2';
 336              } else {
 337                  $newidnumber = $matches[1] . ((int) $matches[2] + 1);
 338              }
 339              $idnumber = $newidnumber;
 340          }
 341          return $idnumber;
 342      }
 343  
 344      /**
 345       * Helper to increment a shortname.
 346       *
 347       * This considers that the shortname passed has to be incremented.
 348       *
 349       * @param string $shortname shortname to increment.
 350       * @return string new shortname.
 351       */
 352      public static function increment_shortname($shortname) {
 353          global $DB;
 354          do {
 355              $matches = array();
 356              if (!preg_match('/(.*?)([0-9]+)$/', $shortname, $matches)) {
 357                  $newshortname = $shortname . '_2';
 358              } else {
 359                  $newshortname = $matches[1] . ($matches[2]+1);
 360              }
 361              $shortname = $newshortname;
 362          } while ($DB->record_exists('course', array('shortname' => $shortname)));
 363          return $shortname;
 364      }
 365  
 366      /**
 367       * Resolve a category based on the data passed.
 368       *
 369       * Key accepted are:
 370       * - category, which is supposed to be a category ID.
 371       * - category_idnumber
 372       * - category_path, array of categories from parent to child.
 373       *
 374       * @param array $data to resolve the category from.
 375       * @param array $errors will be populated with errors found.
 376       * @return int category ID.
 377       */
 378      public static function resolve_category($data, &$errors = array()) {
 379          $catid = null;
 380  
 381          if (!empty($data['category'])) {
 382              $category = coursecat::get((int) $data['category'], IGNORE_MISSING);
 383              if (!empty($category) && !empty($category->id)) {
 384                  $catid = $category->id;
 385              } else {
 386                  $errors['couldnotresolvecatgorybyid'] =
 387                      new lang_string('couldnotresolvecatgorybyid', 'tool_uploadcourse');
 388              }
 389          }
 390  
 391          if (empty($catid) && !empty($data['category_idnumber'])) {
 392              $catid = self::resolve_category_by_idnumber($data['category_idnumber']);
 393              if (empty($catid)) {
 394                  $errors['couldnotresolvecatgorybyidnumber'] =
 395                      new lang_string('couldnotresolvecatgorybyidnumber', 'tool_uploadcourse');
 396              }
 397          }
 398          if (empty($catid) && !empty($data['category_path'])) {
 399              $catid = self::resolve_category_by_path(explode(' / ', $data['category_path']));
 400              if (empty($catid)) {
 401                  $errors['couldnotresolvecatgorybypath'] =
 402                      new lang_string('couldnotresolvecatgorybypath', 'tool_uploadcourse');
 403              }
 404          }
 405  
 406          return $catid;
 407      }
 408  
 409      /**
 410       * Resolve a category by ID number.
 411       *
 412       * @param string $idnumber category ID number.
 413       * @return int category ID.
 414       */
 415      public static function resolve_category_by_idnumber($idnumber) {
 416          global $DB;
 417          $cache = cache::make('tool_uploadcourse', 'helper');
 418          $cachekey = 'cat_idn_' . $idnumber;
 419          if (($id = $cache->get($cachekey)) === false) {
 420              $params = array('idnumber' => $idnumber);
 421              $id = $DB->get_field_select('course_categories', 'id', 'idnumber = :idnumber', $params, IGNORE_MISSING);
 422  
 423              // Little hack to be able to differenciate between the cache not set and a category not found.
 424              if ($id === false) {
 425                  $id = -1;
 426              }
 427  
 428              $cache->set($cachekey, $id);
 429          }
 430  
 431          // Little hack to be able to differenciate between the cache not set and a category not found.
 432          if ($id == -1) {
 433              $id = false;
 434          }
 435  
 436          return $id;
 437      }
 438  
 439      /**
 440       * Resolve a category by path.
 441       *
 442       * @param array $path category names indexed from parent to children.
 443       * @return int category ID.
 444       */
 445      public static function resolve_category_by_path(array $path) {
 446          global $DB;
 447          $cache = cache::make('tool_uploadcourse', 'helper');
 448          $cachekey = 'cat_path_' . serialize($path);
 449          if (($id = $cache->get($cachekey)) === false) {
 450              $parent = 0;
 451              $sql = 'name = :name AND parent = :parent';
 452              while ($name = array_shift($path)) {
 453                  $params = array('name' => $name, 'parent' => $parent);
 454                  if ($records = $DB->get_records_select('course_categories', $sql, $params, null, 'id, parent')) {
 455                      if (count($records) > 1) {
 456                          // Too many records with the same name!
 457                          $id = -1;
 458                          break;
 459                      }
 460                      $record = reset($records);
 461                      $id = $record->id;
 462                      $parent = $record->id;
 463                  } else {
 464                      // Not found.
 465                      $id = -1;
 466                      break;
 467                  }
 468              }
 469              $cache->set($cachekey, $id);
 470          }
 471  
 472          // We save -1 when the category has not been found to be able to know if the cache was set.
 473          if ($id == -1) {
 474              $id = false;
 475          }
 476          return $id;
 477      }
 478  
 479  }


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