Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
}