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 * Repository data generator 19 * 20 * @package repository 21 * @category test 22 * @copyright 2013 Frédéric Massart 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 /** 29 * Repository data generator class 30 * 31 * @package core 32 * @category test 33 * @copyright 2013 Frédéric Massart 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 * @since Moodle 2.5.1 36 */ 37 class testing_repository_generator extends component_generator_base { 38 39 /** 40 * Number of instances created 41 * @var int 42 */ 43 protected $instancecount = 0; 44 45 /** 46 * To be called from data reset code only, 47 * do not use in tests. 48 * @return void 49 */ 50 public function reset() { 51 $this->instancecount = 0; 52 } 53 54 /** 55 * Returns repository type name 56 * 57 * @return string name of the type of repository 58 * @throws coding_exception if class invalid 59 */ 60 public function get_typename() { 61 $matches = null; 62 if (!preg_match('/^repository_([a-z0-9_]+)_generator$/', get_class($this), $matches)) { 63 throw new coding_exception('Invalid repository generator class name: '.get_class($this)); 64 } 65 if (empty($matches[1])) { 66 throw new coding_exception('Invalid repository generator class name: '.get_class($this)); 67 } 68 return $matches[1]; 69 } 70 71 /** 72 * Fill in record defaults. 73 * 74 * @param array $record 75 * @return array 76 */ 77 protected function prepare_record(array $record) { 78 if (!isset($record['name'])) { 79 $record['name'] = $this->get_typename() . ' ' . $this->instancecount; 80 } 81 if (!isset($record['contextid'])) { 82 $record['contextid'] = context_system::instance()->id; 83 } 84 return $record; 85 } 86 87 /** 88 * Fill in type record defaults. 89 * 90 * @param array $record 91 * @return array 92 */ 93 protected function prepare_type_record(array $record) { 94 if (!isset($record['pluginname'])) { 95 $record['pluginname'] = ''; 96 } 97 if (!isset($record['enableuserinstances'])) { 98 $record['enableuserinstances'] = 1; 99 } 100 if (!isset($record['enablecourseinstances'])) { 101 $record['enablecourseinstances'] = 1; 102 } 103 return $record; 104 } 105 106 /** 107 * Create a test repository instance. 108 * 109 * @param array|stdClass $record 110 * @param array $options 111 * @return stdClass repository instance record 112 */ 113 public function create_instance($record = null, array $options = null) { 114 global $CFG, $DB, $PAGE; 115 require_once($CFG->dirroot . '/repository/lib.php'); 116 117 $this->instancecount++; 118 $record = (array) $record; 119 120 // Creating a repository is a back end operation, which should not cause any output to happen. 121 // This will allow us to check that the theme was not initialised while creating the repository instance. 122 $outputstartedbefore = $PAGE->get_where_theme_was_initialised(); 123 124 $typeid = $DB->get_field('repository', 'id', array('type' => $this->get_typename()), MUST_EXIST); 125 $instanceoptions = repository::static_function($this->get_typename(), 'get_instance_option_names'); 126 127 if (empty($instanceoptions)) { 128 // There can only be one instance of this repository, and it should have been created along with the type. 129 $id = $DB->get_field('repository_instances', 'id', array('typeid' => $typeid), MUST_EXIST); 130 } else { 131 // Create the new instance, but first make sure all the required parameters are set. 132 $record = $this->prepare_record($record); 133 134 if (empty($record['contextid'])) { 135 throw new coding_exception('contextid must be present in testing_repository_generator::create_instance() $record'); 136 } 137 138 foreach ($instanceoptions as $option) { 139 if (!isset($record[$option])) { 140 throw new coding_exception("$option must be present in testing_repository_generator::create_instance() \$record"); 141 } 142 } 143 144 $context = context::instance_by_id($record['contextid']); 145 unset($record['contextid']); 146 if (!in_array($context->contextlevel, array(CONTEXT_SYSTEM, CONTEXT_COURSE, CONTEXT_USER))) { 147 throw new coding_exception('Wrong contextid passed in testing_repository_generator::create_instance() $record'); 148 } 149 150 $id = repository::static_function($this->get_typename(), 'create', $this->get_typename(), 0, $context, $record); 151 } 152 153 // If the theme was initialised while creating the repository instance, something somewhere called an output 154 // function. Rather than leaving this as a hard-to-debug situation, let's make it fail with a clear error. 155 $outputstartedafter = $PAGE->get_where_theme_was_initialised(); 156 157 if ($outputstartedbefore === null && $outputstartedafter !== null) { 158 throw new coding_exception('Creating a repository_' . $this->get_typename() . ' initialised the theme and output!', 159 'This should not happen. Creating a repository should be a pure back-end operation. Unnecessarily initialising ' . 160 'the output mechanism at the wrong time can cause subtle bugs and is a significant performance hit. There is ' . 161 'likely a call to an output function that caused it:' . PHP_EOL . PHP_EOL . 162 format_backtrace($outputstartedafter, true)); 163 } 164 165 return $DB->get_record('repository_instances', array('id' => $id), '*', MUST_EXIST); 166 } 167 168 /** 169 * Create the type of repository. 170 * 171 * @param stdClass|array $record data to use to set up the type 172 * @param array $options options for the set up of the type 173 * 174 * @return stdClass repository type record 175 */ 176 public function create_type($record = null, array $options = null) { 177 global $CFG, $DB; 178 require_once($CFG->dirroot . '/repository/lib.php'); 179 180 $record = (array) $record; 181 $type = $this->get_typename(); 182 183 $typeoptions = repository::static_function($type, 'get_type_option_names'); 184 $instanceoptions = repository::static_function($type, 'get_instance_option_names'); 185 186 // The type allow for user and course instances. 187 if (!empty($instanceoptions)) { 188 $typeoptions[] = 'enableuserinstances'; 189 $typeoptions[] = 'enablecourseinstances'; 190 } 191 192 // Make sure all the parameters are set. 193 $record = $this->prepare_type_record($record); 194 foreach ($typeoptions as $option) { 195 if (!isset($record[$option])) { 196 throw new coding_exception("$option must be present in testing::create_repository_type() for $type"); 197 } 198 } 199 200 // Limit to allowed options. 201 $record = array_intersect_key($record, array_flip($typeoptions)); 202 203 // Create the type. 204 $plugintype = new repository_type($type, $record); 205 $plugintype->create(false); 206 207 return $DB->get_record('repository', array('type' => $type)); 208 } 209 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body