[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/tests/behat/ -> behat_data_generators.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   * Data generators for acceptance testing.
  19   *
  20   * @package   core
  21   * @category  test
  22   * @copyright 2012 David Monllaó
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
  27  
  28  require_once (__DIR__ . '/../../behat/behat_base.php');
  29  
  30  use Behat\Gherkin\Node\TableNode as TableNode;
  31  use Behat\Behat\Exception\PendingException as PendingException;
  32  
  33  /**
  34   * Class to set up quickly a Given environment.
  35   *
  36   * Acceptance tests are block-boxed, so this steps definitions should only
  37   * be used to set up the test environment as we are not replicating user steps.
  38   *
  39   * All data generators should be in lib/testing/generator/*, shared between phpunit
  40   * and behat and they should be called from here, if possible using the standard
  41   * 'create_$elementname($options)' and if it's not possible (data generators arguments will not be
  42   * always the same) or the element is not suitable to be a data generator, create a
  43   * 'process_$elementname($options)' method and use the data generator from there if possible.
  44   *
  45   * @todo      If the available elements list grows too much this class must be split into smaller pieces
  46   * @package   core
  47   * @category  test
  48   * @copyright 2012 David Monllaó
  49   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  50   */
  51  class behat_data_generators extends behat_base {
  52  
  53      /**
  54       * @var testing_data_generator
  55       */
  56      protected $datagenerator;
  57  
  58      /**
  59       * Each element specifies:
  60       * - The data generator sufix used.
  61       * - The required fields.
  62       * - The mapping between other elements references and database field names.
  63       * @var array
  64       */
  65      protected static $elements = array(
  66          'users' => array(
  67              'datagenerator' => 'user',
  68              'required' => array('username')
  69          ),
  70          'categories' => array(
  71              'datagenerator' => 'category',
  72              'required' => array('idnumber'),
  73              'switchids' => array('category' => 'parent')
  74          ),
  75          'courses' => array(
  76              'datagenerator' => 'course',
  77              'required' => array('shortname'),
  78              'switchids' => array('category' => 'category')
  79          ),
  80          'groups' => array(
  81              'datagenerator' => 'group',
  82              'required' => array('idnumber', 'course'),
  83              'switchids' => array('course' => 'courseid')
  84          ),
  85          'groupings' => array(
  86              'datagenerator' => 'grouping',
  87              'required' => array('idnumber', 'course'),
  88              'switchids' => array('course' => 'courseid')
  89          ),
  90          'course enrolments' => array(
  91              'datagenerator' => 'enrol_user',
  92              'required' => array('user', 'course', 'role'),
  93              'switchids' => array('user' => 'userid', 'course' => 'courseid', 'role' => 'roleid')
  94          ),
  95          'permission overrides' => array(
  96              'datagenerator' => 'permission_override',
  97              'required' => array('capability', 'permission', 'role', 'contextlevel', 'reference'),
  98              'switchids' => array('role' => 'roleid')
  99          ),
 100          'system role assigns' => array(
 101              'datagenerator' => 'system_role_assign',
 102              'required' => array('user', 'role'),
 103              'switchids' => array('user' => 'userid', 'role' => 'roleid')
 104          ),
 105          'role assigns' => array(
 106              'datagenerator' => 'role_assign',
 107              'required' => array('user', 'role', 'contextlevel', 'reference'),
 108              'switchids' => array('user' => 'userid', 'role' => 'roleid')
 109          ),
 110          'activities' => array(
 111              'datagenerator' => 'activity',
 112              'required' => array('activity', 'idnumber', 'course'),
 113              'switchids' => array('course' => 'course', 'gradecategory' => 'gradecat')
 114          ),
 115          'blocks' => array(
 116              'datagenerator' => 'block_instance',
 117              'required' => array('blockname', 'contextlevel', 'reference'),
 118          ),
 119          'group members' => array(
 120              'datagenerator' => 'group_member',
 121              'required' => array('user', 'group'),
 122              'switchids' => array('user' => 'userid', 'group' => 'groupid')
 123          ),
 124          'grouping groups' => array(
 125              'datagenerator' => 'grouping_group',
 126              'required' => array('grouping', 'group'),
 127              'switchids' => array('grouping' => 'groupingid', 'group' => 'groupid')
 128          ),
 129          'cohorts' => array(
 130              'datagenerator' => 'cohort',
 131              'required' => array('idnumber')
 132          ),
 133          'cohort members' => array(
 134              'datagenerator' => 'cohort_member',
 135              'required' => array('user', 'cohort'),
 136              'switchids' => array('user' => 'userid', 'cohort' => 'cohortid')
 137          ),
 138          'roles' => array(
 139              'datagenerator' => 'role',
 140              'required' => array('shortname')
 141          ),
 142          'grade categories' => array(
 143              'datagenerator' => 'grade_category',
 144              'required' => array('fullname', 'course'),
 145              'switchids' => array('course' => 'courseid', 'gradecategory' => 'parent')
 146          ),
 147          'grade items' => array(
 148              'datagenerator' => 'grade_item',
 149              'required' => array('course'),
 150              'switchids' => array('scale' => 'scaleid', 'outcome' => 'outcomeid', 'course' => 'courseid',
 151                                   'gradecategory' => 'categoryid')
 152          ),
 153          'grade outcomes' => array(
 154              'datagenerator' => 'grade_outcome',
 155              'required' => array('shortname', 'scale'),
 156              'switchids' => array('course' => 'courseid', 'gradecategory' => 'categoryid', 'scale' => 'scaleid')
 157          ),
 158          'scales' => array(
 159              'datagenerator' => 'scale',
 160              'required' => array('name', 'scale'),
 161              'switchids' => array('course' => 'courseid')
 162          ),
 163          'question categories' => array(
 164              'datagenerator' => 'question_category',
 165              'required' => array('name', 'contextlevel', 'reference'),
 166              'switchids' => array('questioncategory' => 'category')
 167          ),
 168          'questions' => array(
 169              'datagenerator' => 'question',
 170              'required' => array('qtype', 'questioncategory', 'name'),
 171              'switchids' => array('questioncategory' => 'category', 'user' => 'createdby')
 172          ),
 173          'tags' => array(
 174              'datagenerator' => 'tag',
 175              'required' => array('name')
 176          ),
 177      );
 178  
 179      /**
 180       * Creates the specified element. More info about available elements in http://docs.moodle.org/dev/Acceptance_testing#Fixtures.
 181       *
 182       * @Given /^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/
 183       *
 184       * @throws Exception
 185       * @throws PendingException
 186       * @param string    $elementname The name of the entity to add
 187       * @param TableNode $data
 188       */
 189      public function the_following_exist($elementname, TableNode $data) {
 190  
 191          // Now that we need them require the data generators.
 192          require_once (__DIR__ . '/../../testing/generator/lib.php');
 193  
 194          if (empty(self::$elements[$elementname])) {
 195              throw new PendingException($elementname . ' data generator is not implemented');
 196          }
 197  
 198          $this->datagenerator = testing_util::get_data_generator();
 199  
 200          $elementdatagenerator = self::$elements[$elementname]['datagenerator'];
 201          $requiredfields = self::$elements[$elementname]['required'];
 202          if (!empty(self::$elements[$elementname]['switchids'])) {
 203              $switchids = self::$elements[$elementname]['switchids'];
 204          }
 205  
 206          foreach ($data->getHash() as $elementdata) {
 207  
 208              // Check if all the required fields are there.
 209              foreach ($requiredfields as $requiredfield) {
 210                  if (!isset($elementdata[$requiredfield])) {
 211                      throw new Exception($elementname . ' requires the field ' . $requiredfield . ' to be specified');
 212                  }
 213              }
 214  
 215              // Switch from human-friendly references to ids.
 216              if (isset($switchids)) {
 217                  foreach ($switchids as $element => $field) {
 218                      $methodname = 'get_' . $element . '_id';
 219  
 220                      // Not all the switch fields are required, default vars will be assigned by data generators.
 221                      if (isset($elementdata[$element])) {
 222                          // Temp $id var to avoid problems when $element == $field.
 223                          $id = $this->{$methodname}($elementdata[$element]);
 224                          unset($elementdata[$element]);
 225                          $elementdata[$field] = $id;
 226                      }
 227                  }
 228              }
 229  
 230              // Preprocess the entities that requires a special treatment.
 231              if (method_exists($this, 'preprocess_' . $elementdatagenerator)) {
 232                  $elementdata = $this->{'preprocess_' . $elementdatagenerator}($elementdata);
 233              }
 234  
 235              // Creates element.
 236              $methodname = 'create_' . $elementdatagenerator;
 237              if (method_exists($this->datagenerator, $methodname)) {
 238                  // Using data generators directly.
 239                  $this->datagenerator->{$methodname}($elementdata);
 240  
 241              } else if (method_exists($this, 'process_' . $elementdatagenerator)) {
 242                  // Using an alternative to the direct data generator call.
 243                  $this->{'process_' . $elementdatagenerator}($elementdata);
 244              } else {
 245                  throw new PendingException($elementname . ' data generator is not implemented');
 246              }
 247          }
 248  
 249      }
 250  
 251      /**
 252       * If password is not set it uses the username.
 253       * @param array $data
 254       * @return array
 255       */
 256      protected function preprocess_user($data) {
 257          if (!isset($data['password'])) {
 258              $data['password'] = $data['username'];
 259          }
 260          return $data;
 261      }
 262  
 263      /**
 264       * If contextlevel and reference are specified for cohort, transform them to the contextid.
 265       *
 266       * @param array $data
 267       * @return array
 268       */
 269      protected function preprocess_cohort($data) {
 270          if (isset($data['contextlevel'])) {
 271              if (!isset($data['reference'])) {
 272                  throw new Exception('If field contextlevel is specified, field reference must also be present');
 273              }
 274              $context = $this->get_context($data['contextlevel'], $data['reference']);
 275              unset($data['contextlevel']);
 276              unset($data['reference']);
 277              $data['contextid'] = $context->id;
 278          }
 279          return $data;
 280      }
 281  
 282      /**
 283       * Preprocesses the creation of a grade item. Converts gradetype text to a number.
 284       * @param array $data
 285       * @return array
 286       */
 287      protected function preprocess_grade_item($data) {
 288          global $CFG;
 289          require_once("$CFG->libdir/grade/constants.php");
 290  
 291          if (isset($data['gradetype'])) {
 292              $data['gradetype'] = constant("GRADE_TYPE_" . strtoupper($data['gradetype']));
 293          }
 294  
 295          if (!empty($data['category']) && !empty($data['courseid'])) {
 296              $cat = grade_category::fetch(array('fullname' => $data['category'], 'courseid' => $data['courseid']));
 297              if (!$cat) {
 298                  throw new Exception('Could not resolve category with name "' . $data['category'] . '"');
 299              }
 300              unset($data['category']);
 301              $data['categoryid'] = $cat->id;
 302          }
 303  
 304          return $data;
 305      }
 306  
 307      /**
 308       * Adapter to modules generator
 309       * @throws Exception Custom exception for test writers
 310       * @param array $data
 311       * @return void
 312       */
 313      protected function process_activity($data) {
 314          global $DB, $CFG;
 315  
 316          // The the_following_exists() method checks that the field exists.
 317          $activityname = $data['activity'];
 318          unset($data['activity']);
 319  
 320          // Convert scale name into scale id (negative number indicates using scale).
 321          if (isset($data['grade']) && strlen($data['grade']) && !is_number($data['grade'])) {
 322              $data['grade'] = - $this->get_scale_id($data['grade']);
 323              require_once("$CFG->libdir/grade/constants.php");
 324  
 325              if (!isset($data['gradetype'])) {
 326                  $data['gradetype'] = GRADE_TYPE_SCALE;
 327              }
 328          }
 329  
 330          // We split $data in the activity $record and the course module $options.
 331          $cmoptions = array();
 332          $cmcolumns = $DB->get_columns('course_modules');
 333          foreach ($cmcolumns as $key => $value) {
 334              if (isset($data[$key])) {
 335                  $cmoptions[$key] = $data[$key];
 336              }
 337          }
 338  
 339          // Custom exception.
 340          try {
 341              $this->datagenerator->create_module($activityname, $data, $cmoptions);
 342          } catch (coding_exception $e) {
 343              throw new Exception('\'' . $activityname . '\' activity can not be added using this step,' .
 344                  ' use the step \'I add a "ACTIVITY_OR_RESOURCE_NAME_STRING" to section "SECTION_NUMBER"\' instead');
 345          }
 346      }
 347  
 348      /**
 349       * Add a block to a page.
 350       *
 351       * @param array $data should mostly match the fields of the block_instances table.
 352       *     The block type is specified by blockname.
 353       *     The parentcontextid is set from contextlevel and reference.
 354       *     Missing values are filled in by testing_block_generator::prepare_record.
 355       *     $data is passed to create_block as both $record and $options. Normally
 356       *     the keys are different, so this is a way to let people set values in either place.
 357       */
 358      protected function process_block_instance($data) {
 359  
 360          if (empty($data['blockname'])) {
 361              throw new Exception('\'blocks\' requires the field \'block\' type to be specified');
 362          }
 363  
 364          if (empty($data['contextlevel'])) {
 365              throw new Exception('\'blocks\' requires the field \'contextlevel\' to be specified');
 366          }
 367  
 368          if (!isset($data['reference'])) {
 369              throw new Exception('\'blocks\' requires the field \'reference\' to be specified');
 370          }
 371  
 372          $context = $this->get_context($data['contextlevel'], $data['reference']);
 373          $data['parentcontextid'] = $context->id;
 374  
 375          // Pass $data as both $record and $options. I think that is unlikely to
 376          // cause problems since the relevant key names are different.
 377          // $options is not used in most blocks I have seen, but where it is, it is necessary.
 378          $this->datagenerator->create_block($data['blockname'], $data, $data);
 379      }
 380  
 381      /**
 382       * Adapter to enrol_user() data generator.
 383       * @throws Exception
 384       * @param array $data
 385       * @return void
 386       */
 387      protected function process_enrol_user($data) {
 388          global $SITE;
 389  
 390          if (empty($data['roleid'])) {
 391              throw new Exception('\'course enrolments\' requires the field \'role\' to be specified');
 392          }
 393  
 394          if (!isset($data['userid'])) {
 395              throw new Exception('\'course enrolments\' requires the field \'user\' to be specified');
 396          }
 397  
 398          if (!isset($data['courseid'])) {
 399              throw new Exception('\'course enrolments\' requires the field \'course\' to be specified');
 400          }
 401  
 402          if (!isset($data['enrol'])) {
 403              $data['enrol'] = 'manual';
 404          }
 405  
 406          if (!isset($data['timestart'])) {
 407              $data['timestart'] = 0;
 408          }
 409  
 410          if (!isset($data['timeend'])) {
 411              $data['timeend'] = 0;
 412          }
 413  
 414          if (!isset($data['status'])) {
 415              $data['status'] = null;
 416          }
 417  
 418          // If the provided course shortname is the site shortname we consider it a system role assign.
 419          if ($data['courseid'] == $SITE->id) {
 420              // Frontpage course assign.
 421              $context = context_course::instance($data['courseid']);
 422              role_assign($data['roleid'], $data['userid'], $context->id);
 423  
 424          } else {
 425              // Course assign.
 426              $this->datagenerator->enrol_user($data['userid'], $data['courseid'], $data['roleid'], $data['enrol'],
 427                      $data['timestart'], $data['timeend'], $data['status']);
 428          }
 429  
 430      }
 431  
 432      /**
 433       * Allows/denies a capability at the specified context
 434       *
 435       * @throws Exception
 436       * @param array $data
 437       * @return void
 438       */
 439      protected function process_permission_override($data) {
 440  
 441          // Will throw an exception if it does not exist.
 442          $context = $this->get_context($data['contextlevel'], $data['reference']);
 443  
 444          switch ($data['permission']) {
 445              case get_string('allow', 'role'):
 446                  $permission = CAP_ALLOW;
 447                  break;
 448              case get_string('prevent', 'role'):
 449                  $permission = CAP_PREVENT;
 450                  break;
 451              case get_string('prohibit', 'role'):
 452                  $permission = CAP_PROHIBIT;
 453                  break;
 454              default:
 455                  throw new Exception('The \'' . $data['permission'] . '\' permission does not exist');
 456                  break;
 457          }
 458  
 459          if (is_null(get_capability_info($data['capability']))) {
 460              throw new Exception('The \'' . $data['capability'] . '\' capability does not exist');
 461          }
 462  
 463          role_change_permission($data['roleid'], $context, $data['capability'], $permission);
 464      }
 465  
 466      /**
 467       * Assigns a role to a user at system context
 468       *
 469       * Used by "system role assigns" can be deleted when
 470       * system role assign will be deprecated in favour of
 471       * "role assigns"
 472       *
 473       * @throws Exception
 474       * @param array $data
 475       * @return void
 476       */
 477      protected function process_system_role_assign($data) {
 478  
 479          if (empty($data['roleid'])) {
 480              throw new Exception('\'system role assigns\' requires the field \'role\' to be specified');
 481          }
 482  
 483          if (!isset($data['userid'])) {
 484              throw new Exception('\'system role assigns\' requires the field \'user\' to be specified');
 485          }
 486  
 487          $context = context_system::instance();
 488  
 489          $this->datagenerator->role_assign($data['roleid'], $data['userid'], $context->id);
 490      }
 491  
 492      /**
 493       * Assigns a role to a user at the specified context
 494       *
 495       * @throws Exception
 496       * @param array $data
 497       * @return void
 498       */
 499      protected function process_role_assign($data) {
 500  
 501          if (empty($data['roleid'])) {
 502              throw new Exception('\'role assigns\' requires the field \'role\' to be specified');
 503          }
 504  
 505          if (!isset($data['userid'])) {
 506              throw new Exception('\'role assigns\' requires the field \'user\' to be specified');
 507          }
 508  
 509          if (empty($data['contextlevel'])) {
 510              throw new Exception('\'role assigns\' requires the field \'contextlevel\' to be specified');
 511          }
 512  
 513          if (!isset($data['reference'])) {
 514              throw new Exception('\'role assigns\' requires the field \'reference\' to be specified');
 515          }
 516  
 517          // Getting the context id.
 518          $context = $this->get_context($data['contextlevel'], $data['reference']);
 519  
 520          $this->datagenerator->role_assign($data['roleid'], $data['userid'], $context->id);
 521      }
 522  
 523      /**
 524       * Creates a role.
 525       *
 526       * @param array $data
 527       * @return void
 528       */
 529      protected function process_role($data) {
 530  
 531          // We require the user to fill the role shortname.
 532          if (empty($data['shortname'])) {
 533              throw new Exception('\'role\' requires the field \'shortname\' to be specified');
 534          }
 535  
 536          $this->datagenerator->create_role($data);
 537      }
 538  
 539      /**
 540       * Adds members to cohorts
 541       *
 542       * @param array $data
 543       * @return void
 544       */
 545      protected function process_cohort_member($data) {
 546          cohort_add_member($data['cohortid'], $data['userid']);
 547      }
 548  
 549      /**
 550       * Create a question category.
 551       *
 552       * @param array $data the row of data from the behat script.
 553       */
 554      protected function process_question_category($data) {
 555          $context = $this->get_context($data['contextlevel'], $data['reference']);
 556          $data['contextid'] = $context->id;
 557          $this->datagenerator->get_plugin_generator('core_question')->create_question_category($data);
 558      }
 559  
 560      /**
 561       * Create a question.
 562       *
 563       * Creating questions relies on the question/type/.../tests/helper.php mechanism.
 564       * We start with test_question_maker::get_question_form_data($data['qtype'], $data['template'])
 565       * and then overlay the values from any other fields of $data that are set.
 566       *
 567       * @param array $data the row of data from the behat script.
 568       */
 569      protected function process_question($data) {
 570          if (array_key_exists('questiontext', $data)) {
 571              $data['questiontext'] = array(
 572                      'text'   => $data['questiontext'],
 573                      'format' => FORMAT_HTML,
 574                  );
 575          }
 576  
 577          if (array_key_exists('generalfeedback', $data)) {
 578              $data['generalfeedback'] = array(
 579                      'text'   => $data['generalfeedback'],
 580                      'format' => FORMAT_HTML,
 581                  );
 582          }
 583  
 584          $which = null;
 585          if (!empty($data['template'])) {
 586              $which = $data['template'];
 587          }
 588  
 589          $this->datagenerator->get_plugin_generator('core_question')->create_question($data['qtype'], $which, $data);
 590      }
 591  
 592      /**
 593       * Gets the grade category id from the grade category fullname
 594       * @throws Exception
 595       * @param string $username
 596       * @return int
 597       */
 598      protected function get_gradecategory_id($fullname) {
 599          global $DB;
 600  
 601          if (!$id = $DB->get_field('grade_categories', 'id', array('fullname' => $fullname))) {
 602              throw new Exception('The specified grade category with fullname "' . $fullname . '" does not exist');
 603          }
 604          return $id;
 605      }
 606  
 607      /**
 608       * Gets the user id from it's username.
 609       * @throws Exception
 610       * @param string $username
 611       * @return int
 612       */
 613      protected function get_user_id($username) {
 614          global $DB;
 615  
 616          if (!$id = $DB->get_field('user', 'id', array('username' => $username))) {
 617              throw new Exception('The specified user with username "' . $username . '" does not exist');
 618          }
 619          return $id;
 620      }
 621  
 622      /**
 623       * Gets the role id from it's shortname.
 624       * @throws Exception
 625       * @param string $roleshortname
 626       * @return int
 627       */
 628      protected function get_role_id($roleshortname) {
 629          global $DB;
 630  
 631          if (!$id = $DB->get_field('role', 'id', array('shortname' => $roleshortname))) {
 632              throw new Exception('The specified role with shortname "' . $roleshortname . '" does not exist');
 633          }
 634  
 635          return $id;
 636      }
 637  
 638      /**
 639       * Gets the category id from it's idnumber.
 640       * @throws Exception
 641       * @param string $idnumber
 642       * @return int
 643       */
 644      protected function get_category_id($idnumber) {
 645          global $DB;
 646  
 647          // If no category was specified use the data generator one.
 648          if ($idnumber == false) {
 649              return null;
 650          }
 651  
 652          if (!$id = $DB->get_field('course_categories', 'id', array('idnumber' => $idnumber))) {
 653              throw new Exception('The specified category with idnumber "' . $idnumber . '" does not exist');
 654          }
 655  
 656          return $id;
 657      }
 658  
 659      /**
 660       * Gets the course id from it's shortname.
 661       * @throws Exception
 662       * @param string $shortname
 663       * @return int
 664       */
 665      protected function get_course_id($shortname) {
 666          global $DB;
 667  
 668          if (!$id = $DB->get_field('course', 'id', array('shortname' => $shortname))) {
 669              throw new Exception('The specified course with shortname "' . $shortname . '" does not exist');
 670          }
 671          return $id;
 672      }
 673  
 674      /**
 675       * Gets the group id from it's idnumber.
 676       * @throws Exception
 677       * @param string $idnumber
 678       * @return int
 679       */
 680      protected function get_group_id($idnumber) {
 681          global $DB;
 682  
 683          if (!$id = $DB->get_field('groups', 'id', array('idnumber' => $idnumber))) {
 684              throw new Exception('The specified group with idnumber "' . $idnumber . '" does not exist');
 685          }
 686          return $id;
 687      }
 688  
 689      /**
 690       * Gets the grouping id from it's idnumber.
 691       * @throws Exception
 692       * @param string $idnumber
 693       * @return int
 694       */
 695      protected function get_grouping_id($idnumber) {
 696          global $DB;
 697  
 698          if (!$id = $DB->get_field('groupings', 'id', array('idnumber' => $idnumber))) {
 699              throw new Exception('The specified grouping with idnumber "' . $idnumber . '" does not exist');
 700          }
 701          return $id;
 702      }
 703  
 704      /**
 705       * Gets the cohort id from it's idnumber.
 706       * @throws Exception
 707       * @param string $idnumber
 708       * @return int
 709       */
 710      protected function get_cohort_id($idnumber) {
 711          global $DB;
 712  
 713          if (!$id = $DB->get_field('cohort', 'id', array('idnumber' => $idnumber))) {
 714              throw new Exception('The specified cohort with idnumber "' . $idnumber . '" does not exist');
 715          }
 716          return $id;
 717      }
 718  
 719      /**
 720       * Gets the outcome item id from its shortname.
 721       * @throws Exception
 722       * @param string $shortname
 723       * @return int
 724       */
 725      protected function get_outcome_id($shortname) {
 726          global $DB;
 727  
 728          if (!$id = $DB->get_field('grade_outcomes', 'id', array('shortname' => $shortname))) {
 729              throw new Exception('The specified outcome with shortname "' . $shortname . '" does not exist');
 730          }
 731          return $id;
 732      }
 733  
 734      /**
 735       * Get the id of a named scale.
 736       * @param string $name the name of the scale.
 737       * @return int the scale id.
 738       */
 739      protected function get_scale_id($name) {
 740          global $DB;
 741  
 742          if (!$id = $DB->get_field('scale', 'id', array('name' => $name))) {
 743              throw new Exception('The specified scale with name "' . $name . '" does not exist');
 744          }
 745          return $id;
 746      }
 747  
 748      /**
 749       * Get the id of a named question category (must be globally unique).
 750       * Note that 'Top' is a special value, used when setting the parent of another
 751       * category, meaning top-level.
 752       *
 753       * @param string $name the question category name.
 754       * @return int the question category id.
 755       */
 756      protected function get_questioncategory_id($name) {
 757          global $DB;
 758  
 759          if ($name == 'Top') {
 760              return 0;
 761          }
 762  
 763          if (!$id = $DB->get_field('question_categories', 'id', array('name' => $name))) {
 764              throw new Exception('The specified question category with name "' . $name . '" does not exist');
 765          }
 766          return $id;
 767      }
 768  
 769      /**
 770       * Gets the internal context id from the context reference.
 771       *
 772       * The context reference changes depending on the context
 773       * level, it can be the system, a user, a category, a course or
 774       * a module.
 775       *
 776       * @throws Exception
 777       * @param string $levelname The context level string introduced by the test writer
 778       * @param string $contextref The context reference introduced by the test writer
 779       * @return context
 780       */
 781      protected function get_context($levelname, $contextref) {
 782          global $DB;
 783  
 784          // Getting context levels and names (we will be using the English ones as it is the test site language).
 785          $contextlevels = context_helper::get_all_levels();
 786          $contextnames = array();
 787          foreach ($contextlevels as $level => $classname) {
 788              $contextnames[context_helper::get_level_name($level)] = $level;
 789          }
 790  
 791          if (empty($contextnames[$levelname])) {
 792              throw new Exception('The specified "' . $levelname . '" context level does not exist');
 793          }
 794          $contextlevel = $contextnames[$levelname];
 795  
 796          // Return it, we don't need to look for other internal ids.
 797          if ($contextlevel == CONTEXT_SYSTEM) {
 798              return context_system::instance();
 799          }
 800  
 801          switch ($contextlevel) {
 802  
 803              case CONTEXT_USER:
 804                  $instanceid = $DB->get_field('user', 'id', array('username' => $contextref));
 805                  break;
 806  
 807              case CONTEXT_COURSECAT:
 808                  $instanceid = $DB->get_field('course_categories', 'id', array('idnumber' => $contextref));
 809                  break;
 810  
 811              case CONTEXT_COURSE:
 812                  $instanceid = $DB->get_field('course', 'id', array('shortname' => $contextref));
 813                  break;
 814  
 815              case CONTEXT_MODULE:
 816                  $instanceid = $DB->get_field('course_modules', 'id', array('idnumber' => $contextref));
 817                  break;
 818  
 819              default:
 820                  break;
 821          }
 822  
 823          $contextclass = $contextlevels[$contextlevel];
 824          if (!$context = $contextclass::instance($instanceid, IGNORE_MISSING)) {
 825              throw new Exception('The specified "' . $contextref . '" context reference does not exist');
 826          }
 827  
 828          return $context;
 829      }
 830  
 831  }


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