MDL-68169 user: Limit the number of filter conditions
[moodle.git] / lib / table / classes / external / dynamic / fetch.php
CommitLineData
1592c3c4
SL
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 * Table external API.
19 *
20 * @package core_table
21 * @category external
22 * @copyright 2020 Simey Lameze <simey@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26namespace core_table\external\dynamic;
27
28use external_api;
29use external_function_parameters;
30use external_multiple_structure;
31use external_single_structure;
32use external_value;
33use external_warnings;
34use moodle_url;
35
36/**
37 * Core table external functions.
38 *
39 * @package core_table
40 * @category external
41 * @copyright 2020 Simey Lameze <simey@moodle.com>
42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43 */
44class fetch extends external_api {
45
46 /**
47 * Describes the parameters for fetching the table html.
48 *
49 * @return external_function_parameters
50 * @since Moodle 3.9
51 */
52 public static function execute_parameters(): external_function_parameters {
53 return new external_function_parameters ([
4cf97b7f
SL
54 'component' => new external_value(
55 PARAM_COMPONENT,
56 'Component',
57 VALUE_REQUIRED
58 ),
1592c3c4
SL
59 'handler' => new external_value(
60 // Note: We do not have a PARAM_CLASSNAME which would have been ideal.
4cf97b7f 61 PARAM_ALPHANUMEXT,
1592c3c4
SL
62 'Handler',
63 VALUE_REQUIRED
64 ),
65 'uniqueid' => new external_value(
66 PARAM_ALPHANUMEXT,
67 'Unique ID for the container',
68 VALUE_REQUIRED
69 ),
a31a2b6d
AN
70 'sortdata' => new external_multiple_structure(
71 new external_single_structure([
72 'sortby' => new external_value(
73 PARAM_ALPHANUMEXT,
74 'The name of a sortable column',
75 VALUE_REQUIRED
76 ),
77 'sortorder' => new external_value(
78 PARAM_ALPHANUMEXT,
79 'The direction that this column should be sorted by',
80 VALUE_REQUIRED
81 ),
82 ]),
83 'The combined sort order of the table. Multiple fields can be specified.',
84 VALUE_OPTIONAL,
85 []
1592c3c4
SL
86 ),
87 'filters' => new external_multiple_structure(
88 new external_single_structure([
89 'name' => new external_value(PARAM_ALPHANUM, 'Name of the filter', VALUE_REQUIRED),
90 'jointype' => new external_value(PARAM_INT, 'Type of join for filter values', VALUE_REQUIRED),
91 'values' => new external_multiple_structure(
92 new external_value(PARAM_RAW, 'Filter value'),
93 'The value to filter on',
94 VALUE_REQUIRED
95 )
96 ]),
97 'The filters that will be applied in the request',
98 VALUE_OPTIONAL
99 ),
100 'jointype' => new external_value(PARAM_INT, 'Type of join to join all filters together', VALUE_REQUIRED),
c540a575
AN
101 'firstinitial' => new external_value(
102 PARAM_ALPHANUMEXT,
103 'The first initial to sort filter on',
104 VALUE_REQUIRED,
105 null
106 ),
107 'lastinitial' => new external_value(
108 PARAM_ALPHANUMEXT,
109 'The last initial to sort filter on',
110 VALUE_REQUIRED,
111 null
112 ),
f7b84afe
SL
113 'pagenumber' => new external_value(
114 PARAM_INT,
115 'The page number',
116 VALUE_REQUIRED,
117 null
118 ),
119 'pagesize' => new external_value(
120 PARAM_INT,
121 'The number of records per page',
122 VALUE_REQUIRED,
123 null
124 ),
e2f12c22
SL
125 'hiddencolumns' => new external_multiple_structure(
126 new external_value(
127 PARAM_ALPHANUMEXT,
128 'Name of column',
129 VALUE_REQUIRED,
130 null
131 )
132 ),
68c46a28
SL
133 'resetpreferences' => new external_value(
134 PARAM_BOOL,
135 'Whether the table preferences should be reset',
136 VALUE_REQUIRED,
137 null
138 ),
1592c3c4
SL
139 ]);
140 }
141
142 /**
143 * External function to fetch a table view.
144 *
4cf97b7f 145 * @param string $component The component.
1592c3c4
SL
146 * @param string $handler Dynamic table class name.
147 * @param string $uniqueid Unique ID for the container.
a31a2b6d 148 * @param array $sortdata The columns and order to sort by
1592c3c4
SL
149 * @param array $filters The filters that will be applied in the request.
150 * @param string $jointype The join type.
c540a575
AN
151 * @param string $firstinitial The first name initial to filter on
152 * @param string $lastinitial The last name initial to filter on
f7b84afe
SL
153 * @param int $pagenumber The page number.
154 * @param int $pagesize The number of records.
68c46a28
SL
155 * @param string $jointype The join type.
156 * @param bool $resetpreferences Whether it is resetting table preferences or not.
1592c3c4
SL
157 *
158 * @return array
159 */
c540a575 160 public static function execute(
4cf97b7f 161 string $component,
c540a575
AN
162 string $handler,
163 string $uniqueid,
a31a2b6d 164 array $sortdata,
c540a575
AN
165 ?array $filters = null,
166 ?string $jointype = null,
167 ?string $firstinitial = null,
f7b84afe
SL
168 ?string $lastinitial = null,
169 ?int $pagenumber = null,
e2f12c22 170 ?int $pagesize = null,
68c46a28
SL
171 ?array $hiddencolumns = null,
172 ?bool $resetpreferences = null
c540a575 173 ) {
1592c3c4
SL
174 global $PAGE;
175
1592c3c4 176 [
4cf97b7f 177 'component' => $component,
1592c3c4
SL
178 'handler' => $handler,
179 'uniqueid' => $uniqueid,
a31a2b6d 180 'sortdata' => $sortdata,
1592c3c4
SL
181 'filters' => $filters,
182 'jointype' => $jointype,
c540a575
AN
183 'firstinitial' => $firstinitial,
184 'lastinitial' => $lastinitial,
f7b84afe
SL
185 'pagenumber' => $pagenumber,
186 'pagesize' => $pagesize,
e2f12c22 187 'hiddencolumns' => $hiddencolumns,
68c46a28 188 'resetpreferences' => $resetpreferences,
1592c3c4 189 ] = self::validate_parameters(self::execute_parameters(), [
4cf97b7f 190 'component' => $component,
1592c3c4
SL
191 'handler' => $handler,
192 'uniqueid' => $uniqueid,
a31a2b6d 193 'sortdata' => $sortdata,
1592c3c4
SL
194 'filters' => $filters,
195 'jointype' => $jointype,
c540a575
AN
196 'firstinitial' => $firstinitial,
197 'lastinitial' => $lastinitial,
f7b84afe
SL
198 'pagenumber' => $pagenumber,
199 'pagesize' => $pagesize,
e2f12c22 200 'hiddencolumns' => $hiddencolumns,
68c46a28 201 'resetpreferences' => $resetpreferences,
1592c3c4
SL
202 ]);
203
4cf97b7f
SL
204 $tableclass = "\\{$component}\\table\\{$handler}";
205 if (!class_exists($tableclass)) {
206 throw new \UnexpectedValueException("Table handler class {$tableclass} not found. " .
207 "Please make sure that your table handler class is under the \\{$component}\\table namespace.");
208 }
209
210 if (!is_subclass_of($tableclass, \core_table\dynamic::class)) {
211 throw new \UnexpectedValueException("Table handler class {$tableclass} does not support dynamic updating.");
212 }
213
214 $filtersetclass = "{$tableclass}_filterset";
215 if (!class_exists($filtersetclass)) {
216 throw new \UnexpectedValueException("The filter specified ({$filtersetclass}) is invalid.");
217 }
218
219 $filterset = new $filtersetclass();
110f3ebf 220 $filterset->set_join_type($jointype);
1592c3c4
SL
221 foreach ($filters as $rawfilter) {
222 $filterset->add_filter_from_params(
223 $rawfilter['name'],
224 $rawfilter['jointype'],
225 $rawfilter['values']
226 );
227 }
228
4cf97b7f 229 $instance = new $tableclass($uniqueid);
1592c3c4 230 $instance->set_filterset($filterset);
5615a772
AN
231 self::validate_context($instance->get_context());
232
a31a2b6d 233 $instance->set_sortdata($sortdata);
1592c3c4 234
c540a575
AN
235 if ($firstinitial !== null) {
236 $instance->set_first_initial($firstinitial);
237 }
238
239 if ($lastinitial !== null) {
240 $instance->set_last_initial($lastinitial);
241 }
242
f7b84afe
SL
243 if ($pagenumber !== null) {
244 $instance->set_page_number($pagenumber);
245 }
1592c3c4 246
f7b84afe
SL
247 if ($pagesize === null) {
248 $pagesize = 20;
249 }
250
e2f12c22
SL
251 if ($hiddencolumns !== null) {
252 $instance->set_hidden_columns($hiddencolumns);
253 }
254
68c46a28
SL
255 if ($resetpreferences === true) {
256 $instance->mark_table_to_reset();
257 }
258
259 $PAGE->set_url($instance->baseurl);
260
1592c3c4 261 ob_start();
f7b84afe 262 $instance->out($pagesize, true);
fb17c31c 263 $tablehtml = ob_get_contents();
1592c3c4
SL
264 ob_end_clean();
265
266 return [
fb17c31c 267 'html' => $tablehtml,
1592c3c4
SL
268 'warnings' => []
269 ];
270 }
271
272 /**
273 * Describes the data returned from the external function.
274 *
275 * @return external_single_structure
276 * @since Moodle 3.9
277 */
278 public static function execute_returns(): external_single_structure {
279 return new external_single_structure([
280 'html' => new external_value(PARAM_RAW, 'The raw html of the requested table.'),
281 'warnings' => new external_warnings()
282 ]);
283 }
284}