Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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  use core_competency\competency;
  18  use core_competency\competency_framework;
  19  use core_competency\plan;
  20  
  21  /**
  22   * Behat data generator for core_competency.
  23   *
  24   * @package   core_competency
  25   * @category  test
  26   * @copyright 2022 Noel De Martin
  27   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  28   */
  29  class behat_core_competency_generator extends behat_generator_base {
  30  
  31      /**
  32       * Get a list of the entities that Behat can create using the generator step.
  33       *
  34       * @return array
  35       */
  36      protected function get_creatable_entities(): array {
  37          return [
  38              'competencies' => [
  39                  'singular' => 'competency',
  40                  'datagenerator' => 'competency',
  41                  'required' => ['shortname', 'competencyframework'],
  42                  'switchids' => ['competencyframework' => 'competencyframeworkid'],
  43              ],
  44              'course_competencies' => [
  45                  'singular' => 'course_competency',
  46                  'datagenerator' => 'course_competency',
  47                  'required' => ['course', 'competency'],
  48                  'switchids' => ['course' => 'courseid', 'competency' => 'competencyid'],
  49              ],
  50              'frameworks' => [
  51                  'singular' => 'framework',
  52                  'datagenerator' => 'framework',
  53                  'required' => ['shortname'],
  54                  'switchids' => ['scale' => 'scaleid'],
  55              ],
  56              'plans' => [
  57                  'singular' => 'plan',
  58                  'datagenerator' => 'plan',
  59                  'required' => ['name'],
  60                  'switchids' => ['user' => 'userid'],
  61              ],
  62              'related_competencies' => [
  63                  'singular' => 'related_competency',
  64                  'datagenerator' => 'related_competency',
  65                  'required' => ['competency', 'relatedcompetency'],
  66                  'switchids' => ['competency' => 'competencyid', 'relatedcompetency' => 'relatedcompetencyid'],
  67              ],
  68              'user_competency' => [
  69                  'singular' => 'user_competency',
  70                  'datagenerator' => 'user_competency',
  71                  'required' => ['competency', 'user'],
  72                  'switchids' => ['competency' => 'competencyid', 'user' => 'userid'],
  73              ],
  74              'user_competency_courses' => [
  75                  'singular' => 'user_competency_course',
  76                  'datagenerator' => 'user_competency_course',
  77                  'required' => ['course', 'competency', 'user'],
  78                  'switchids' => ['course' => 'courseid', 'competency' => 'competencyid', 'user' => 'userid'],
  79              ],
  80              'user_competency_plans' => [
  81                  'singular' => 'user_competency_plan',
  82                  'datagenerator' => 'user_competency_plan',
  83                  'required' => ['plan', 'competency', 'user'],
  84                  'switchids' => ['plan' => 'planid', 'competency' => 'competencyid', 'user' => 'userid'],
  85              ],
  86          ];
  87      }
  88  
  89      /**
  90       * Get the competecy framework id using an idnumber.
  91       *
  92       * @param string $idnumber
  93       * @return int The competecy framework id
  94       */
  95      protected function get_competencyframework_id(string $idnumber): int {
  96          global $DB;
  97  
  98          if (!$id = $DB->get_field('competency_framework', 'id', ['idnumber' => $idnumber])) {
  99              throw new Exception('The specified competency framework with idnumber "' . $idnumber . '" could not be found.');
 100          }
 101  
 102          return $id;
 103      }
 104  
 105      /**
 106       * Get the competecy id using an idnumber.
 107       *
 108       * @param string $idnumber
 109       * @return int The competecy id
 110       */
 111      protected function get_competency_id(string $idnumber): int {
 112          global $DB;
 113  
 114          if (!$id = $DB->get_field('competency', 'id', ['idnumber' => $idnumber])) {
 115              throw new Exception('The specified competency with idnumber "' . $idnumber . '" could not be found.');
 116          }
 117  
 118          return $id;
 119      }
 120  
 121      /**
 122       * Get the learning plan id using a name.
 123       *
 124       * @param string $name
 125       * @return int The learning plan id
 126       */
 127      protected function get_plan_id(string $name): int {
 128          global $DB;
 129  
 130          if (!$id = $DB->get_field('competency_plan', 'id', ['name' => $name])) {
 131              throw new Exception('The specified learning plan with name "' . $name . '" could not be found.');
 132          }
 133  
 134          return $id;
 135      }
 136  
 137      /**
 138       * Get the related competecy id using an idnumber.
 139       *
 140       * @param string $idnumber
 141       * @return int The related competecy id
 142       */
 143      protected function get_relatedcompetency_id(string $idnumber): int {
 144          return $this->get_competency_id($idnumber);
 145      }
 146  
 147      /**
 148       * Add a plan.
 149       *
 150       * @param array $data Plan data.
 151       */
 152      public function process_plan(array $data): void {
 153          $generator = $this->get_data_generator();
 154          $competencyids = $data['competencyids'] ?? [];
 155  
 156          unset($data['competencyids']);
 157  
 158          $plan = $generator->create_plan($data);
 159  
 160          foreach ($competencyids as $competencyid) {
 161              $generator->create_plan_competency([
 162                  'planid' => $plan->get('id'),
 163                  'competencyid' => $competencyid,
 164              ]);
 165          }
 166      }
 167  
 168      /**
 169       * Preprocess user competency data.
 170       *
 171       * @param array $data Raw data.
 172       * @return array Processed data.
 173       */
 174      protected function preprocess_user_competency(array $data): array {
 175          $this->prepare_grading($data);
 176  
 177          return $data;
 178      }
 179  
 180      /**
 181       * Preprocess user course competency data.
 182       *
 183       * @param array $data Raw data.
 184       * @return array Processed data.
 185       */
 186      protected function preprocess_user_competency_course(array $data): array {
 187          $this->prepare_grading($data);
 188  
 189          return $data;
 190      }
 191  
 192      /**
 193       * Preprocess user learning plan competency data.
 194       *
 195       * @param array $data Raw data.
 196       * @return array Processed data.
 197       */
 198      protected function preprocess_user_competency_plan(array $data): array {
 199          $this->prepare_grading($data);
 200  
 201          return $data;
 202      }
 203  
 204      /**
 205       * Preprocess plan data.
 206       *
 207       * @param array $data Raw data.
 208       * @return array Processed data.
 209       */
 210      protected function preprocess_plan(array $data): array {
 211          if (isset($data['competencies'])) {
 212              $competencies = array_map('trim', str_getcsv($data['competencies']));
 213              $data['competencyids'] = array_map([$this, 'get_competency_id'], $competencies);
 214  
 215              unset($data['competencies']);
 216          }
 217  
 218          global $USER;
 219  
 220          return $data + [
 221              'userid' => $USER->id,
 222              'status' => plan::STATUS_ACTIVE,
 223          ];
 224      }
 225  
 226      /**
 227       * Prepare grading attributes for record data.
 228       *
 229       * @param array $data Record data.
 230       */
 231      protected function prepare_grading(array &$data): void {
 232          if (!isset($data['grade'])) {
 233              return;
 234          }
 235  
 236          global $DB;
 237  
 238          $competency = competency::get_record(['id' => $data['competencyid']]);
 239          $competencyframework = competency_framework::get_record(['id' => $competency->get('competencyframeworkid')]);
 240          $scale = $DB->get_field('scale', 'scale', ['id' => $competencyframework->get('scaleid')]);
 241          $grades = array_map('trim', explode(',', $scale));
 242          $grade = array_search($data['grade'], $grades);
 243  
 244          if ($grade === false) {
 245              throw new Exception('The grade "'.$data['grade'].'" was not found in the "'.
 246                  $competencyframework->get('shortname').'" competency framework.');
 247          }
 248  
 249          $data['proficiency'] = true;
 250          $data['grade'] = $grade + 1;
 251      }
 252  
 253      /**
 254       * Get the module data generator.
 255       *
 256       * @return core_competency_generator Competency data generator.
 257       */
 258      protected function get_data_generator(): core_competency_generator {
 259          return $this->componentdatagenerator;
 260      }
 261  }