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 * External interface library for customfields component
19 *
20 * @package   core_customfield
21 * @copyright 2018 David Matamoros <davidmc@moodle.com>
22 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25defined('MOODLE_INTERNAL') || die;
26
27require_once($CFG->libdir . "/externallib.php");
28
29/**
30 * Class core_customfield_external
31 *
32 * @copyright 2018 David Matamoros <davidmc@moodle.com>
33 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34 */
35class core_customfield_external extends external_api {
36
37    /**
38     * Parameters for delete_field
39     *
40     * @return external_function_parameters
41     */
42    public static function delete_field_parameters() {
43        return new external_function_parameters(
44                array('id' => new external_value(PARAM_INT, 'Custom field ID to delete', VALUE_REQUIRED))
45        );
46    }
47
48    /**
49     * Delete custom field function
50     *
51     * @param int $id
52     */
53    public static function delete_field($id) {
54        $params = self::validate_parameters(self::delete_field_parameters(), ['id' => $id]);
55
56        $record = \core_customfield\field_controller::create($params['id']);
57        $handler = $record->get_handler();
58        if (!$handler->can_configure()) {
59            throw new moodle_exception('nopermissionconfigure', 'core_customfield');
60        }
61        $handler->delete_field_configuration($record);
62    }
63
64    /**
65     * Return for delete_field
66     */
67    public static function delete_field_returns() {
68    }
69
70    /**
71     * Parameters for reload template function
72     *
73     * @return external_function_parameters
74     */
75    public static function reload_template_parameters() {
76        return new external_function_parameters(
77            array(
78                'component' => new external_value(PARAM_COMPONENT, 'component', VALUE_REQUIRED),
79                'area' => new external_value(PARAM_ALPHANUMEXT, 'area', VALUE_REQUIRED),
80                'itemid' => new external_value(PARAM_INT, 'itemid', VALUE_REQUIRED)
81            )
82        );
83    }
84
85    /**
86     * Reload template function
87     *
88     * @param string $component
89     * @param string $area
90     * @param int $itemid
91     * @return array|object|stdClass
92     */
93    public static function reload_template($component, $area, $itemid) {
94        global $PAGE;
95
96        $params = self::validate_parameters(self::reload_template_parameters(),
97                      ['component' => $component, 'area' => $area, 'itemid' => $itemid]);
98
99        $PAGE->set_context(context_system::instance());
100        $handler = \core_customfield\handler::get_handler($params['component'], $params['area'], $params['itemid']);
101        self::validate_context($handler->get_configuration_context());
102        if (!$handler->can_configure()) {
103            throw new moodle_exception('nopermissionconfigure', 'core_customfield');
104        }
105        $output = $PAGE->get_renderer('core_customfield');
106        $outputpage = new \core_customfield\output\management($handler);
107        return $outputpage->export_for_template($output);
108    }
109
110    /**
111     * Ajax returns on reload template.
112     *
113     * @return external_single_structure
114     */
115    public static function reload_template_returns() {
116        return new external_single_structure(
117            array(
118                'component' => new external_value(PARAM_COMPONENT, 'component'),
119                'area' => new external_value(PARAM_ALPHANUMEXT, 'area'),
120                'itemid' => new external_value(PARAM_INT, 'itemid'),
121                'usescategories' => new external_value(PARAM_BOOL, 'view has categories'),
122                'categories' => new external_multiple_structure(
123                    new external_single_structure(
124                        array(
125                            'id' => new external_value(PARAM_INT, 'id'),
126                            'nameeditable' => new external_value(PARAM_RAW, 'inplace editable name'),
127                            'addfieldmenu' => new external_value(PARAM_RAW, 'addfieldmenu'),
128                            'fields' => new external_multiple_structure(
129                                new external_single_structure(
130                                    array(
131                                        'name' => new external_value(PARAM_NOTAGS, 'name'),
132                                        'shortname' => new external_value(PARAM_NOTAGS, 'shortname'),
133                                        'type' => new external_value(PARAM_NOTAGS, 'type'),
134                                        'editfieldurl' => new external_value(PARAM_URL, 'edit field url'),
135                                        'id' => new external_value(PARAM_INT, 'id'),
136                                    )
137                                )
138                            , '', VALUE_OPTIONAL),
139                        )
140                    )
141                ),
142            )
143        );
144    }
145
146    /**
147     * Parameters for delete category
148     *
149     * @return external_function_parameters
150     */
151    public static function delete_category_parameters() {
152        return new external_function_parameters(
153                array('id' => new external_value(PARAM_INT, 'category ID to delete', VALUE_REQUIRED))
154        );
155    }
156
157    /**
158     * Delete category function
159     *
160     * @param int $id
161     */
162    public static function delete_category($id) {
163        $category = core_customfield\category_controller::create($id);
164        $handler = $category->get_handler();
165        self::validate_context($handler->get_configuration_context());
166        if (!$handler->can_configure()) {
167            throw new moodle_exception('nopermissionconfigure', 'core_customfield');
168        }
169        $handler->delete_category($category);
170    }
171
172    /**
173     * Return for delete category
174     */
175    public static function delete_category_returns() {
176    }
177
178
179    /**
180     * Parameters for create category
181     *
182     * @return external_function_parameters
183     */
184    public static function create_category_parameters() {
185        return new external_function_parameters(
186            array(
187                'component' => new external_value(PARAM_COMPONENT, 'component', VALUE_REQUIRED),
188                'area' => new external_value(PARAM_ALPHANUMEXT, 'area', VALUE_REQUIRED),
189                'itemid' => new external_value(PARAM_INT, 'itemid', VALUE_REQUIRED)
190            )
191        );
192    }
193
194    /**
195     * Create category function
196     *
197     * @param string $component
198     * @param string $area
199     * @param int    $itemid
200     * @return mixed
201     */
202    public static function create_category($component, $area, $itemid) {
203        $params = self::validate_parameters(self::create_category_parameters(),
204            ['component' => $component, 'area' => $area, 'itemid' => $itemid]);
205
206        $handler = \core_customfield\handler::get_handler($params['component'], $params['area'], $params['itemid']);
207        self::validate_context($handler->get_configuration_context());
208        if (!$handler->can_configure()) {
209            throw new moodle_exception('nopermissionconfigure', 'core_customfield');
210        }
211        return $handler->create_category();
212    }
213
214    /**
215     * Return for create category
216     */
217    public static function create_category_returns() {
218        return new external_value(PARAM_INT, 'Id of the category');
219    }
220
221    /**
222     * Parameters for move field.
223     *
224     * @return external_function_parameters
225     */
226    public static function move_field_parameters() {
227        return new external_function_parameters(
228                ['id' => new external_value(PARAM_INT, 'Id of the field to move', VALUE_REQUIRED),
229                 'categoryid' => new external_value(PARAM_INT, 'New parent category id', VALUE_REQUIRED),
230                 'beforeid'   => new external_value(PARAM_INT, 'Id of the field before which it needs to be moved',
231                     VALUE_DEFAULT, 0)]
232        );
233    }
234
235    /**
236     * Move/reorder field. Move a field to another category and/or change sortorder of fields
237     *
238     * @param int $id field id
239     * @param int $categoryid
240     * @param int $beforeid
241     */
242    public static function move_field($id, $categoryid, $beforeid) {
243        $params = self::validate_parameters(self::move_field_parameters(),
244            ['id' => $id, 'categoryid' => $categoryid, 'beforeid' => $beforeid]);
245        $field = \core_customfield\field_controller::create($params['id']);
246        $handler = $field->get_handler();
247        self::validate_context($handler->get_configuration_context());
248        if (!$handler->can_configure()) {
249            throw new moodle_exception('nopermissionconfigure', 'core_customfield');
250        }
251        $handler->move_field($field, $params['categoryid'], $params['beforeid']);
252    }
253
254    /**
255     * Return for move field
256     */
257    public static function move_field_returns() {
258    }
259
260    /**
261     * Return for move category
262     *
263     * @return external_function_parameters
264     */
265    public static function move_category_parameters() {
266        return new external_function_parameters(
267                ['id' => new external_value(PARAM_INT, 'Category ID to move', VALUE_REQUIRED),
268                 'beforeid'   => new external_value(PARAM_INT, 'Id of the category before which it needs to be moved',
269                     VALUE_DEFAULT, 0)]
270        );
271    }
272
273    /**
274     * Reorder categories. Move category to the new position
275     *
276     * @param int $id category id
277     * @param int $beforeid
278     */
279    public static function move_category(int $id, int $beforeid) {
280        $params = self::validate_parameters(self::move_category_parameters(),
281            ['id' => $id, 'beforeid' => $beforeid]);
282        $category = core_customfield\category_controller::create($id);
283        $handler = $category->get_handler();
284        self::validate_context($handler->get_configuration_context());
285        if (!$handler->can_configure()) {
286            throw new moodle_exception('nopermissionconfigure', 'core_customfield');
287        }
288        $handler->move_category($category, $params['beforeid']);
289    }
290
291    /**
292     * Return for move category
293     */
294    public static function move_category_returns() {
295    }
296}
297