PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.76
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.76
5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 5.5.41 5.5.42 5.5.43 All 159 releases
wp-data-access / WPDataAccess / API / WPDA_Apps.php

WPDA_Apps.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.76, at WPDataAccess/API/WPDA_Apps.php

2,586 lines 104.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDataAccess\API;
4
5 use stdClass;
6 use WPDataAccess\Connection\WPDADB;
7 use WPDataAccess\Data_Dictionary\WPDA_List_Columns_Cache;
8 use WPDataAccess\Plugin_Table_Models\WPDA_App_Container_Model;
9 use WPDataAccess\Plugin_Table_Models\WPDA_App_Apps_Model;
10 use WPDataAccess\Plugin_Table_Models\WPDA_App_Model;
11 use WPDataAccess\Plugin_Table_Models\WPDA_Table_Settings_Model;
12 use WPDataAccess\Utilities\WPDA_App_Localization;
13 use WPDataAccess\WPDA;
14 class WPDA_Apps extends WPDA_API_Core {
15 const METHODS = array('httpGet', 'httpPost', 'httpRequest');
16
17 const WPDA_APP_DEFAULT_LANG = 'wpda_app_default_lang';
18
19 private function sanitize_settings( $value ) {
20 if ( is_array( $value ) ) {
21 foreach ( $value as $index => $item ) {
22 $value[$index] = $this->sanitize_settings( $item );
23 }
24 } elseif ( is_object( $value ) ) {
25 $object_vars = get_object_vars( $value );
26 foreach ( $object_vars as $property_name => $property_value ) {
27 $value->{$property_name} = $this->sanitize_settings( $property_value );
28 }
29 } else {
30 // Allow HTML and onclick for computed fields
31 $value = apply_filters(
32 'wp_kses_post',
33 $value,
34 "",
35 ["onclick"]
36 );
37 }
38 return $value;
39 }
40
41 public function register_rest_routes() {
42 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/init', array(
43 'methods' => array('POST'),
44 'callback' => array($this, 'app_init'),
45 'permission_callback' => '__return_true',
46 ) );
47 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/list', array(
48 'methods' => array('POST'),
49 'callback' => array($this, 'app_list'),
50 'permission_callback' => '__return_true',
51 ) );
52 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/meta', array(
53 'methods' => array('POST'),
54 'callback' => array($this, 'app_meta'),
55 'permission_callback' => '__return_true',
56 'args' => array(
57 'app_id' => $this->get_param( 'app_id' ),
58 ),
59 ) );
60 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lang', array(
61 'methods' => array('POST'),
62 'callback' => array($this, 'app_lang'),
63 'permission_callback' => '__return_true',
64 'args' => array(
65 'lang' => array(
66 'required' => true,
67 'type' => 'string',
68 'description' => __( 'App default language', 'wp-data-access' ),
69 'sanitize_callback' => 'sanitize_text_field',
70 'validate_callback' => 'rest_validate_request_arg',
71 ),
72 ),
73 ) );
74 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/table/meta', array(
75 'methods' => array('POST'),
76 'callback' => array($this, 'app_table_meta'),
77 'permission_callback' => '__return_true',
78 'args' => array(
79 'dbs' => $this->get_param( 'dbs' ),
80 'tbl' => $this->get_param( 'tbl' ),
81 'waa' => array(
82 'required' => false,
83 'type' => 'boolean',
84 'description' => __( 'With admin actions (to support table exports)', 'wp-data-access' ),
85 ),
86 ),
87 ) );
88 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/create', array(
89 'methods' => array('POST'),
90 'callback' => array($this, 'app_create'),
91 'permission_callback' => '__return_true',
92 'args' => array(
93 'app_name' => $this->get_param( 'app_name' ),
94 'app_title' => $this->get_param( 'app_title' ),
95 'app_type' => $this->get_param( 'app_type' ),
96 'app_settings' => $this->get_param( 'app_settings' ),
97 'app_dbs' => $this->get_param( 'dbs' ),
98 'app_tbl' => $this->get_param( 'tbl' ),
99 'app_cls' => $this->get_param( 'app_cls' ),
100 'app_table' => array(
101 'required' => true,
102 'type' => 'string',
103 'description' => __( 'App table', 'wp-data-access' ),
104 'sanitize_callback' => 'sanitize_text_field',
105 'validate_callback' => 'rest_validate_request_arg',
106 ),
107 'app_query' => $this->get_param( 'app_query' ),
108 ),
109 ) );
110 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/createapp', array(
111 'methods' => array('POST'),
112 'callback' => array($this, 'app_createapp'),
113 'permission_callback' => '__return_true',
114 'args' => array(
115 'app_name' => $this->get_param( 'app_name' ),
116 'app_title' => $this->get_param( 'app_title' ),
117 'app_type' => $this->get_param( 'app_type' ),
118 'app_settings' => $this->get_param( 'app_settings' ),
119 'app_apps' => $this->get_param( 'app_apps' ),
120 ),
121 ) );
122 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/copy', array(
123 'methods' => array('POST'),
124 'callback' => array($this, 'app_copy'),
125 'permission_callback' => '__return_true',
126 'args' => array(
127 'app_id' => $this->get_param( 'app_id' ),
128 ),
129 ) );
130 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/export', array(
131 'methods' => array('POST'),
132 'callback' => array($this, 'app_export'),
133 'permission_callback' => '__return_true',
134 'args' => array(
135 'app_id' => $this->get_param( 'app_id' ),
136 ),
137 ) );
138 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/details', array(
139 'methods' => array('POST'),
140 'callback' => array($this, 'app_details'),
141 'permission_callback' => '__return_true',
142 'args' => array(
143 'app_id' => $this->get_param( 'app_id' ),
144 'cnt_id' => $this->get_param( 'cnt_id' ),
145 ),
146 ) );
147 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/detailmeta', array(
148 'methods' => array('POST'),
149 'callback' => array($this, 'app_detail_meta'),
150 'permission_callback' => '__return_true',
151 'args' => array(
152 'app_id' => $this->get_param( 'app_id' ),
153 'cnt_id' => $this->get_param( 'cnt_id' ),
154 'rel_tab' => $this->get_param( 'rel_tab' ),
155 ),
156 ) );
157 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/detailreorder', array(
158 'methods' => array('POST'),
159 'callback' => array($this, 'app_detail_reorder'),
160 'permission_callback' => '__return_true',
161 'args' => array(
162 'app_id' => $this->get_param( 'app_id' ),
163 'cnt_id_from' => $this->get_param( 'cnt_id' ),
164 'cnt_id_to' => $this->get_param( 'cnt_id' ),
165 ),
166 ) );
167 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/relationship/create', array(
168 'methods' => array('POST'),
169 'callback' => array($this, 'app_relationship_create'),
170 'permission_callback' => '__return_true',
171 'args' => array(
172 'app_id' => $this->get_param( 'app_id' ),
173 'app_title' => $this->get_param( 'app_title' ),
174 'app_dbs' => $this->get_param( 'dbs' ),
175 'app_tbl' => $this->get_param( 'tbl' ),
176 'app_cls' => $this->get_param( 'app_cls' ),
177 'app_relation' => array(
178 'required' => true,
179 'type' => 'string',
180 'description' => __( 'Table settings', 'wp-data-access' ),
181 'sanitize_callback' => 'sanitize_text_field',
182 'validate_callback' => 'rest_validate_request_arg',
183 ),
184 ),
185 ) );
186 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/relationship/update', array(
187 'methods' => array('POST'),
188 'callback' => array($this, 'app_relationship_update'),
189 'permission_callback' => '__return_true',
190 'args' => array(
191 'app_id' => $this->get_param( 'app_id' ),
192 'app_cnt' => $this->get_param( 'cnt_id' ),
193 'app_title' => $this->get_param( 'app_title' ),
194 'app_dbs' => $this->get_param( 'dbs' ),
195 'app_tbl' => $this->get_param( 'tbl' ),
196 'app_cls' => $this->get_param( 'app_cls' ),
197 'app_relation' => array(
198 'required' => true,
199 'type' => 'string',
200 'description' => __( 'Table settings', 'wp-data-access' ),
201 'sanitize_callback' => 'sanitize_text_field',
202 'validate_callback' => 'rest_validate_request_arg',
203 ),
204 ),
205 ) );
206 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/relationship/delete', array(
207 'methods' => array('POST'),
208 'callback' => array($this, 'app_relationship_delete'),
209 'permission_callback' => '__return_true',
210 'args' => array(
211 'cnt_id' => $this->get_param( 'cnt_id' ),
212 ),
213 ) );
214 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/save', array(
215 'methods' => array('POST'),
216 'callback' => array($this, 'app_save'),
217 'permission_callback' => '__return_true',
218 'args' => array(
219 'app_id' => $this->get_param( 'app_id' ),
220 'app_name' => $this->get_param( 'app_name' ),
221 'app_title' => $this->get_param( 'app_title' ),
222 'app_type' => $this->get_param( 'app_type' ),
223 'app_settings' => $this->get_param( 'app_settings' ),
224 'app_add_to_menu' => $this->get_param( 'app_add_to_menu' ),
225 'app_dbs' => $this->get_param( 'dbs' ),
226 'app_tbl' => $this->get_param( 'tbl' ),
227 'app_cls' => $this->get_param( 'app_cls' ),
228 'app_query' => $this->get_param( 'app_query' ),
229 ),
230 ) );
231 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/saveapp', array(
232 'methods' => array('POST'),
233 'callback' => array($this, 'app_saveapp'),
234 'permission_callback' => '__return_true',
235 'args' => array(
236 'app_id' => $this->get_param( 'app_id' ),
237 'app_name' => $this->get_param( 'app_name' ),
238 'app_title' => $this->get_param( 'app_title' ),
239 'app_type' => $this->get_param( 'app_type' ),
240 'app_settings' => $this->get_param( 'app_settings' ),
241 'app_add_to_menu' => $this->get_param( 'app_add_to_menu' ),
242 'app_apps' => $this->get_param( 'app_apps' ),
243 ),
244 ) );
245 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/remove', array(
246 'methods' => array('POST'),
247 'callback' => array($this, 'app_remove'),
248 'permission_callback' => '__return_true',
249 'args' => array(
250 'app_id' => $this->get_param( 'app_id' ),
251 ),
252 ) );
253 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/settings', array(
254 'methods' => array('POST'),
255 'callback' => array($this, 'app_settings'),
256 'permission_callback' => '__return_true',
257 'args' => array(
258 'app_id' => $this->get_param( 'app_id' ),
259 'cnt_id' => $this->get_param( 'cnt_id' ),
260 'target' => array(
261 'required' => true,
262 'type' => 'string',
263 'description' => __( 'Setting target', 'wp-data-access' ),
264 'sanitize_callback' => 'sanitize_text_field',
265 'validate_callback' => 'rest_validate_request_arg',
266 ),
267 'settings' => array(
268 'required' => false,
269 'type' => 'string',
270 'description' => __( 'App settings - JSON string', 'wp-data-access' ),
271 'sanitize_callback' => function ( $param ) {
272 $sanitized_settings = $this->sanitize_settings( json_decode( (string) $param, true ) );
273 // Save sanitized JSON as string
274 return json_encode( $sanitized_settings );
275 },
276 'validate_callback' => 'rest_validate_request_arg',
277 ),
278 'map' => array(
279 'required' => false,
280 'type' => 'string',
281 'description' => __( 'Map settings - JSON string', 'wp-data-access' ),
282 'sanitize_callback' => 'wp_kses_post',
283 'validate_callback' => 'rest_validate_request_arg',
284 ),
285 'chart' => array(
286 'required' => false,
287 'type' => 'string',
288 'description' => __( 'Chart settings - JSON string', 'wp-data-access' ),
289 'sanitize_callback' => 'sanitize_text_field',
290 'validate_callback' => 'rest_validate_request_arg',
291 ),
292 'theme' => array(
293 'required' => false,
294 'type' => 'string',
295 'description' => __( 'Theme settings - JSON string', 'wp-data-access' ),
296 'sanitize_callback' => 'sanitize_text_field',
297 'validate_callback' => 'rest_validate_request_arg',
298 ),
299 ),
300 ) );
301 // DML
302 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/select', array(
303 'methods' => array('POST'),
304 'callback' => array($this, 'app_select'),
305 'permission_callback' => '__return_true',
306 'args' => array(
307 'app_id' => $this->get_param( 'app_id' ),
308 'cnt_id' => $this->get_param( 'cnt_id' ),
309 'col' => $this->get_param( 'cols' ),
310 'page_index' => $this->get_param( 'page_index' ),
311 'page_size' => $this->get_param( 'page_size' ),
312 'search' => $this->get_param( 'search' ),
313 'search_columns' => $this->get_param( 'search_columns' ),
314 'search_column_fns' => $this->get_param( 'search_column_fns' ),
315 'search_column_lov' => $this->get_param( 'search_column_lov' ),
316 'search_data_types' => $this->get_param( 'search_data_types' ),
317 'search_custom' => $this->get_param( 'search_custom' ),
318 'search_params' => $this->get_param( 'search_params' ),
319 'shortcode_params' => $this->get_param( 'search_params' ),
320 'md' => $this->get_param( 'md' ),
321 'sorting' => $this->get_param( 'sorting' ),
322 'row_count' => $this->get_param( 'row_count' ),
323 'row_count_estimate' => $this->get_param( 'row_count_estimate' ),
324 'media' => $this->get_param( 'media' ),
325 'rel_tab' => $this->get_param( 'rel_tab' ),
326 'client_side' => $this->get_param( 'client_side' ),
327 'geo_radius' => array(
328 'required' => false,
329 'type' => 'mixed',
330 'description' => __( 'Geo radius segment', 'wp-data-access' ),
331 'sanitize_callback' => function ( $param ) {
332 $geo_radius = array();
333 if ( isset(
334 $param['col']['lat'],
335 $param['col']['lng'],
336 $param['loc']['lat'],
337 $param['loc']['lng'],
338 $param['radius'],
339 $param['unit']
340 ) && is_numeric( $param['loc']['lat'] ) && is_numeric( $param['loc']['lng'] ) && is_numeric( $param['radius'] ) && ('km' === $param['unit'] || 'miles' === $param['unit']) ) {
341 $geo_radius['col']['lat'] = WPDA::remove_backticks( sanitize_text_field( $param['col']['lat'] ) );
342 $geo_radius['col']['lng'] = WPDA::remove_backticks( sanitize_text_field( $param['col']['lng'] ) );
343 $geo_radius['loc']['lat'] = (float) sanitize_text_field( $param['loc']['lat'] );
344 $geo_radius['loc']['lng'] = (float) sanitize_text_field( $param['loc']['lng'] );
345 $geo_radius['radius'] = (float) sanitize_text_field( $param['radius'] );
346 $geo_radius['unit'] = sanitize_text_field( $param['unit'] );
347 }
348 return $geo_radius;
349 },
350 ),
351 ),
352 ) );
353 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/get', array(
354 'methods' => array('POST'),
355 'callback' => array($this, 'app_get'),
356 'permission_callback' => '__return_true',
357 'args' => array(
358 'app_id' => $this->get_param( 'app_id' ),
359 'cnt_id' => $this->get_param( 'cnt_id' ),
360 'key' => $this->get_param( 'key' ),
361 'media' => $this->get_param( 'media' ),
362 'rel_tab' => $this->get_param( 'rel_tab' ),
363 ),
364 ) );
365 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/insert', array(
366 'methods' => array('POST'),
367 'callback' => array($this, 'app_insert'),
368 'permission_callback' => '__return_true',
369 'args' => array(
370 'app_id' => $this->get_param( 'app_id' ),
371 'cnt_id' => $this->get_param( 'cnt_id' ),
372 'val' => $this->get_param( 'val' ),
373 'join_tab' => $this->get_param( 'join_tab' ),
374 'rel_tab' => $this->get_param( 'rel_tab' ),
375 ),
376 ) );
377 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/update', array(
378 'methods' => array('POST'),
379 'callback' => array($this, 'app_update'),
380 'permission_callback' => '__return_true',
381 'args' => array(
382 'app_id' => $this->get_param( 'app_id' ),
383 'cnt_id' => $this->get_param( 'cnt_id' ),
384 'key' => $this->get_param( 'key' ),
385 'val' => $this->get_param( 'val' ),
386 'join_tab' => $this->get_param( 'join_tab' ),
387 'rel_tab' => $this->get_param( 'rel_tab' ),
388 ),
389 ) );
390 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/update/inline', array(
391 'methods' => array('POST'),
392 'callback' => array($this, 'app_update_inline'),
393 'permission_callback' => '__return_true',
394 'args' => array(
395 'app_id' => $this->get_param( 'app_id' ),
396 'cnt_id' => $this->get_param( 'cnt_id' ),
397 'key' => $this->get_param( 'key' ),
398 'val' => $this->get_param( 'val' ),
399 ),
400 ) );
401 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/delete', array(
402 'methods' => array('POST'),
403 'callback' => array($this, 'app_delete'),
404 'permission_callback' => '__return_true',
405 'args' => array(
406 'app_id' => $this->get_param( 'app_id' ),
407 'cnt_id' => $this->get_param( 'cnt_id' ),
408 'key' => $this->get_param( 'key' ),
409 ),
410 ) );
411 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lov', array(
412 'methods' => array('POST'),
413 'callback' => array($this, 'app_lov'),
414 'permission_callback' => '__return_true',
415 'args' => array(
416 'app_id' => $this->get_param( 'app_id' ),
417 'cnt_id' => $this->get_param( 'cnt_id' ),
418 'col' => $this->get_param( 'col' ),
419 'cols' => $this->get_param( 'cols' ),
420 'search' => $this->get_param( 'search' ),
421 'search_columns' => $this->get_param( 'search_columns' ),
422 'search_column_fns' => $this->get_param( 'search_column_fns' ),
423 'search_column_lov' => $this->get_param( 'search_column_lov' ),
424 'search_data_types' => $this->get_param( 'search_data_types' ),
425 'search_custom' => $this->get_param( 'search_custom' ),
426 'search_params' => $this->get_param( 'search_params' ),
427 'shortcode_params' => $this->get_param( 'search_params' ),
428 'md' => $this->get_param( 'md' ),
429 'cascade' => $this->get_param( 'cascade' ),
430 ),
431 ) );
432 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lookup', array(
433 'methods' => array('POST'),
434 'callback' => array($this, 'app_lookup'),
435 'permission_callback' => '__return_true',
436 'args' => array(
437 'app_id' => $this->get_param( 'app_id' ),
438 'cnt_id' => $this->get_param( 'cnt_id' ),
439 'target' => array(
440 'required' => true,
441 'type' => 'string',
442 'description' => __( 'Target: table or (r)form', 'wp-data-access' ),
443 'sanitize_callback' => 'sanitize_text_field',
444 'validate_callback' => 'rest_validate_request_arg',
445 ),
446 'col' => $this->get_param( 'col' ),
447 'colk' => $this->get_param( 'col' ),
448 'colv' => $this->get_param( 'col' ),
449 'cold' => $this->get_param( 'key' ),
450 'cols' => $this->get_param( 'cols' ),
451 'search' => $this->get_param( 'search' ),
452 'search_columns' => $this->get_param( 'search_columns' ),
453 'search_column_fns' => $this->get_param( 'search_column_fns' ),
454 'search_column_lov' => $this->get_param( 'search_column_lov' ),
455 'search_data_types' => $this->get_param( 'search_data_types' ),
456 'search_custom' => $this->get_param( 'search_custom' ),
457 'search_params' => $this->get_param( 'search_params' ),
458 'shortcode_params' => $this->get_param( 'search_params' ),
459 'md' => $this->get_param( 'md' ),
460 'cascade' => $this->get_param( 'cascade' ),
461 'values' => $this->get_param( 'md' ),
462 ),
463 ) );
464 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lookup/dbs', array(
465 'methods' => array('POST'),
466 'callback' => array($this, 'app_lookup_dbs'),
467 'permission_callback' => '__return_true',
468 'args' => array(
469 'app_id' => $this->get_param( 'app_id' ),
470 'cnt_id' => $this->get_param( 'cnt_id' ),
471 ),
472 ) );
473 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lookup/tbl', array(
474 'methods' => array('POST'),
475 'callback' => array($this, 'app_lookup_tbl'),
476 'permission_callback' => '__return_true',
477 'args' => array(
478 'app_id' => $this->get_param( 'app_id' ),
479 'cnt_id' => $this->get_param( 'cnt_id' ),
480 'dbs' => $this->get_param( 'dbs' ),
481 ),
482 ) );
483 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lookup/cls', array(
484 'methods' => array('POST'),
485 'callback' => array($this, 'app_lookup_cls'),
486 'permission_callback' => '__return_true',
487 'args' => array(
488 'app_id' => $this->get_param( 'app_id' ),
489 'cnt_id' => $this->get_param( 'cnt_id' ),
490 'dbs' => $this->get_param( 'dbs' ),
491 'tbl' => $this->get_param( 'tbl' ),
492 ),
493 ) );
494 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/qb/list', array(
495 'methods' => array('POST'),
496 'callback' => array($this, 'app_qb_list'),
497 'permission_callback' => '__return_true',
498 ) );
499 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/chart/data', array(
500 'methods' => array('POST'),
501 'callback' => array($this, 'app_chart_data'),
502 'permission_callback' => '__return_true',
503 'args' => array(
504 'app_id' => $this->get_param( 'app_id' ),
505 'search_custom' => $this->get_param( 'search_custom' ),
506 'shortcode_params' => $this->get_param( 'search_params' ),
507 ),
508 ) );
509 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/dbs/rename', array(
510 'methods' => array('POST'),
511 'callback' => array($this, 'app_dbs_rename'),
512 'permission_callback' => '__return_true',
513 'args' => array(
514 'dbs_source' => $this->get_param( 'dbs' ),
515 'dbs_destination' => $this->get_param( 'dbs' ),
516 ),
517 ) );
518 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lang/get', array(
519 'methods' => array('POST'),
520 'callback' => array($this, 'app_lang_get'),
521 'permission_callback' => '__return_true',
522 ) );
523 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lang/set', array(
524 'methods' => array('POST'),
525 'callback' => array($this, 'app_lang_set'),
526 'permission_callback' => '__return_true',
527 'args' => array(
528 'localizations' => array(
529 'required' => true,
530 'type' => 'mixed',
531 'description' => __( 'Custom side translations (JSON as string)', 'wp-data-access' ),
532 'sanitize_callback' => 'sanitize_text_field',
533 'validate_callback' => 'rest_validate_request_arg',
534 ),
535 ),
536 ) );
537 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/call', array(
538 'methods' => array('POST'),
539 'callback' => array($this, 'app_call'),
540 'permission_callback' => '__return_true',
541 'args' => array(
542 'app_id' => $this->get_param( 'app_id' ),
543 'cls' => array(
544 'required' => true,
545 'type' => 'string',
546 'description' => __( 'Class name', 'wp-data-access' ),
547 'sanitize_callback' => 'sanitize_text_field',
548 'validate_callback' => 'rest_validate_request_arg',
549 ),
550 'fnc' => array(
551 'required' => true,
552 'type' => 'string',
553 'description' => __( 'Function name', 'wp-data-access' ),
554 'sanitize_callback' => 'sanitize_text_field',
555 'validate_callback' => 'rest_validate_request_arg',
556 ),
557 'arg' => array(
558 'required' => true,
559 'type' => 'mixed',
560 'description' => __( 'Arguments', 'wp-data-access' ),
561 'sanitize_callback' => 'sanitize_text_field',
562 'validate_callback' => 'rest_validate_request_arg',
563 ),
564 ),
565 ) );
566 }
567
568 public function app_call( $request ) {
569 }
570
571 public function app_lang_get( $request ) {
572 if ( !$this->current_user_can_access() ) {
573 // Only admins
574 return $this->unauthorized();
575 }
576 if ( !$this->current_user_token_valid( $request ) ) {
577 return $this->invalid_nonce();
578 }
579 return $this->WPDA_Rest_Response( '', WPDA_App_Localization::get() );
580 }
581
582 public function app_lang_set( $request ) {
583 if ( !$this->current_user_can_access() ) {
584 // Only admins
585 return $this->unauthorized();
586 }
587 if ( !$this->current_user_token_valid( $request ) ) {
588 return $this->invalid_nonce();
589 }
590 $localizations = $request->get_param( 'localizations' );
591 WPDA_App_Localization::set( $localizations );
592 return $this->WPDA_Rest_Response( 'Translation successfully saved' );
593 }
594
595 private function get_app_columns( $columns ) {
596 if ( !is_array( $columns ) ) {
597 return false;
598 }
599 return array_map( function ( $value ) {
600 return $value['columnName'];
601 }, array_filter( $columns, function ( $column ) {
602 return $column['isSelected'];
603 } ) );
604 }
605
606 private function get_app_table_columns( $settings, $table_settings ) {
607 if ( !isset( $settings['columns'] ) ) {
608 return false;
609 }
610 $columns = $this->get_app_columns( $settings['columns'] );
611 if ( false === $columns ) {
612 return false;
613 }
614 $columns_available = array_flip( $columns );
615 if ( !isset( $settings['table'] ) ) {
616 return array_map( function () {
617 return true;
618 }, $columns_available );
619 }
620 if ( !is_array( $table_settings ) || !isset( $table_settings['columns'] ) ) {
621 return false;
622 }
623 $table_columns = $table_settings['columns'];
624 for ($i = 0; $i < count( $columns ); $i++) {
625 if ( isset( $columns_available[$columns[$i]] ) ) {
626 $column_name = $columns[$i];
627 $columns_available[$columns[$i]] = count( array_filter( $table_columns, function ( $column ) use($columns, $column_name) {
628 if ( !isset( $column['columnName'], $column['queryable'] ) ) {
629 return false;
630 }
631 $queryable = $column['queryable'];
632 return $column_name === $column['columnName'] && true === $queryable;
633 } ) ) > 0;
634 }
635 }
636 return $columns_available;
637 }
638
639 private function get_app_form_columns( $settings ) {
640 if ( !isset( $settings['columns'] ) ) {
641 return false;
642 }
643 return $this->get_app_columns( $settings['columns'] );
644 }
645
646 public function app_export( $request ) {
647 $app_id = $request->get_param( 'app_id' );
648 if ( !$this->main_app_access( $app_id, $msg ) ) {
649 if ( 'rest_cookie_invalid_nonce' === $msg ) {
650 return $this->invalid_nonce();
651 }
652 return $this->unauthorized();
653 }
654 if ( !$this->current_user_token_valid( $request ) ) {
655 return $this->invalid_nonce();
656 }
657 return $this->do_app_export( $app_id );
658 }
659
660 public function app_copy( $request ) {
661 $app_id = $request->get_param( 'app_id' );
662 if ( !$this->main_app_access( $app_id, $msg ) ) {
663 if ( 'rest_cookie_invalid_nonce' === $msg ) {
664 return $this->invalid_nonce();
665 }
666 return $this->unauthorized();
667 }
668 if ( !$this->current_user_token_valid( $request ) ) {
669 return $this->invalid_nonce();
670 }
671 return $this->do_app_copy( $app_id );
672 }
673
674 public function app_details( $request ) {
675 $app_id = $request->get_param( 'app_id' );
676 $cnt_id = $request->get_param( 'cnt_id' );
677 if ( $this->check_app_access(
678 $app_id,
679 $cnt_id,
680 'select',
681 $dbs,
682 $tbl,
683 $msg,
684 $settings
685 ) ) {
686 return $this->WPDA_Rest_Response( '', WPDA_App_Container_Model::select( $app_id, 1 ) );
687 } else {
688 if ( 'rest_cookie_invalid_nonce' === $msg ) {
689 return $this->invalid_nonce();
690 } else {
691 return new \WP_Error('error', $msg, array(
692 'status' => 401,
693 ));
694 }
695 }
696 }
697
698 public function app_detail_meta( $request ) {
699 $app_id = $request->get_param( 'app_id' );
700 $cnt_id = $request->get_param( 'cnt_id' );
701 $rel_tab = $request->get_param( 'rel_tab' );
702 if ( $this->check_app_access(
703 $app_id,
704 $cnt_id,
705 'select',
706 $dbs,
707 $tbl,
708 $msg,
709 $settings
710 ) ) {
711 $container = WPDA_App_Container_Model::get_container( $app_id, $cnt_id );
712 if ( !isset( $container[0] ) ) {
713 return $this->bad_request();
714 }
715 return $this->get_app_container_meta( $app_id, $container, $rel_tab );
716 } else {
717 if ( 'rest_cookie_invalid_nonce' === $msg ) {
718 return $this->invalid_nonce();
719 } else {
720 return new \WP_Error('error', $msg, array(
721 'status' => 401,
722 ));
723 }
724 }
725 }
726
727 public function app_detail_reorder( $request ) {
728 $app_id = $request->get_param( 'app_id' );
729 $cnt_id_from = $request->get_param( 'cnt_id_from' );
730 $cnt_id_to = $request->get_param( 'cnt_id_to' );
731 if ( $this->check_app_access(
732 $app_id,
733 $cnt_id_from,
734 'select',
735 $dbs,
736 $tbl,
737 $msg,
738 $settings
739 ) ) {
740 $container = WPDA_App_Container_Model::get_container( $app_id, $cnt_id_from );
741 if ( !isset( $container[0] ) ) {
742 return $this->bad_request();
743 }
744 $container = WPDA_App_Container_Model::get_container( $app_id, $cnt_id_to );
745 if ( !isset( $container[0] ) ) {
746 return $this->bad_request();
747 }
748 return $this->reorder_details( $app_id, $cnt_id_from, $cnt_id_to );
749 } else {
750 if ( 'rest_cookie_invalid_nonce' === $msg ) {
751 return $this->invalid_nonce();
752 } else {
753 return new \WP_Error('error', $msg, array(
754 'status' => 401,
755 ));
756 }
757 }
758 }
759
760 public function app_relationship_create( $request ) {
761 if ( !$this->current_user_can_access() ) {
762 return $this->unauthorized();
763 }
764 if ( !$this->current_user_token_valid( $request ) ) {
765 return $this->invalid_nonce();
766 }
767 $app_id = $request->get_param( 'app_id' );
768 $app_title = $request->get_param( 'app_title' );
769 $app_dbs = $request->get_param( 'app_dbs' );
770 $app_tbl = $request->get_param( 'app_tbl' );
771 $app_cls = $request->get_param( 'app_cls' );
772 $app_relation = $request->get_param( 'app_relation' );
773 return $this->WPDA_Rest_Response( '', WPDA_App_Container_Model::create(
774 $app_id,
775 $app_dbs,
776 $app_tbl,
777 json_encode( $app_cls ),
778 $app_title,
779 1,
780 null,
781 $app_relation
782 ) );
783 }
784
785 public function app_relationship_update( $request ) {
786 if ( !$this->current_user_can_access() ) {
787 return $this->unauthorized();
788 }
789 if ( !$this->current_user_token_valid( $request ) ) {
790 return $this->invalid_nonce();
791 }
792 $app_id = $request->get_param( 'app_id' );
793 $app_cnt = $request->get_param( 'app_cnt' );
794 $app_title = $request->get_param( 'app_title' );
795 $app_dbs = $request->get_param( 'app_dbs' );
796 $app_tbl = $request->get_param( 'app_tbl' );
797 $app_cls = $request->get_param( 'app_cls' );
798 $app_relation = $request->get_param( 'app_relation' );
799 return $this->WPDA_Rest_Response( '', WPDA_App_Container_Model::update(
800 $app_id,
801 $app_cnt,
802 $app_dbs,
803 $app_tbl,
804 json_encode( $app_cls ),
805 $app_title,
806 $app_relation
807 ) );
808 }
809
810 public function app_relationship_delete( $request ) {
811 if ( !$this->current_user_can_access() ) {
812 return $this->unauthorized();
813 }
814 if ( !$this->current_user_token_valid( $request ) ) {
815 return $this->invalid_nonce();
816 }
817 $cnt_id = $request->get_param( 'cnt_id' );
818 return $this->WPDA_Rest_Response( '', WPDA_App_Container_Model::delete_container( $cnt_id ) );
819 }
820
821 private function build_lookups(
822 $table_settings,
823 $dbs,
824 &$search_columns,
825 $search_column_lov,
826 $search_column_fns,
827 &$default_where,
828 &$lookups
829 ) {
830 }
831
832 private function build_relationships(
833 $container,
834 &$m2m_relationship,
835 $tbl,
836 &$default_where
837 ) {
838 }
839
840 public function app_select( $request ) {
841 $app_id = $request->get_param( 'app_id' );
842 $cnt_id = $request->get_param( 'cnt_id' );
843 $col = $request->get_param( 'col' );
844 $page_index = $request->get_param( 'page_index' );
845 $page_size = $request->get_param( 'page_size' );
846 $search = $request->get_param( 'search' );
847 $search_columns = $request->get_param( 'search_columns' );
848 $search_column_fns = $request->get_param( 'search_column_fns' );
849 $search_column_lov = $request->get_param( 'search_column_lov' );
850 $search_data_types = $request->get_param( 'search_data_types' );
851 $search_custom = $request->get_param( 'search_custom' );
852 $search_params = $request->get_param( 'search_params' );
853 $shortcode_params = $request->get_param( 'shortcode_params' );
854 $md = $request->get_param( 'md' );
855 $sorting = $request->get_param( 'sorting' );
856 $row_count = $request->get_param( 'row_count' );
857 $row_count_estimate = $request->get_param( 'row_count_estimate' );
858 $media = $request->get_param( 'media' );
859 $rel_tab = $request->get_param( 'rel_tab' );
860 $client_side = '1' === $request->get_param( 'client_side' );
861 $geo_radius = $request->get_param( 'geo_radius' );
862 $default_where = '';
863 $default_orderby = '';
864 $lookups = array();
865 $m2m_relationship = array();
866 if ( $client_side ) {
867 // Delete search values on refresh
868 $search = '';
869 $search_columns = array();
870 }
871 if ( $this->check_app_access(
872 $app_id,
873 $cnt_id,
874 'select',
875 $dbs,
876 $tbl,
877 $msg,
878 $settings
879 ) ) {
880 $container = WPDA_App_Container_Model::get_container( $app_id, $cnt_id );
881 $app = WPDA_App_Model::get_by_id( $app_id );
882 if ( isset( $app[0]['app_type'], $container[0]['cnt_map'] ) && '2' == $app[0]['app_type'] && null !== $container[0]['cnt_map'] ) {
883 // App = Map
884 // Get default where map
885 $map_json = json_decode( (string) $container[0]['cnt_map'], true );
886 if ( isset( $map_json['setup']['defaultWhere'] ) && null !== $map_json['setup']['defaultWhere'] && '' !== trim( $map_json['setup']['defaultWhere'] ) ) {
887 $default_where = $map_json['setup']['defaultWhere'];
888 }
889 } else {
890 // All other apps (not being a map)
891 if ( '1' === $rel_tab ) {
892 } else {
893 $table_settings = $settings['table'] ?? array();
894 // Get default where clause
895 if ( isset( $table_settings['table']['defaultWhere'] ) ) {
896 $default_where = $table_settings['table']['defaultWhere'];
897 }
898 // Get default order by
899 if ( isset( $table_settings['table']['defaultOrderBy'] ) ) {
900 $default_orderby_db = $table_settings['table']['defaultOrderBy'];
901 if ( is_array( $default_orderby_db ) ) {
902 foreach ( $default_orderby_db as $orderby ) {
903 if ( isset( $orderby['columnName'], $orderby['order'] ) && '' !== trim( $orderby['columnName'] ) ) {
904 $default_orderby .= (( '' === $default_orderby ? 'order by ' : ',' )) . '`' . WPDA::remove_backticks( $orderby['columnName'] ) . '` ' . (( 'desc' === $orderby['order'] ? 'desc' : 'asc' ));
905 }
906 }
907 }
908 }
909 }
910 }
911 $table_api = new WPDA_Table();
912 return $table_api->select(
913 $dbs,
914 $tbl,
915 $col,
916 $page_index,
917 $page_size,
918 $search,
919 $search_columns,
920 $search_column_fns,
921 $sorting,
922 $row_count,
923 $row_count_estimate,
924 $media,
925 $this->process_params(
926 $default_where,
927 $search_custom,
928 $search_params,
929 $shortcode_params
930 ),
931 $default_orderby,
932 $lookups,
933 $md,
934 $m2m_relationship,
935 $search_data_types,
936 $client_side,
937 $geo_radius
938 );
939 } else {
940 if ( 'rest_cookie_invalid_nonce' === $msg ) {
941 return $this->invalid_nonce();
942 } else {
943 return new \WP_Error('error', $msg, array(
944 'status' => 401,
945 ));
946 }
947 }
948 }
949
950 private function get_m2m_relationship( $relationship, $tbl, $cols ) {
951 return array();
952 }
953
954 private function get_lookup_lov( $column_lookup, $search_value, $search_type ) {
955 return null;
956 }
957
958 private function convert_relation_columns( $columns ) {
959 return array_map( function ( $value ) {
960 if ( true === $value['isSelected'] ) {
961 return $value['columnName'];
962 }
963 }, $columns );
964 }
965
966 public function app_get( $request ) {
967 $app_id = $request->get_param( 'app_id' );
968 $cnt_id = $request->get_param( 'cnt_id' );
969 $key = $request->get_param( 'key' );
970 $media = $request->get_param( 'media' );
971 $rel_tab = $request->get_param( 'rel_tab' );
972 if ( $this->check_app_access(
973 $app_id,
974 $cnt_id,
975 'select',
976 $dbs,
977 $tbl,
978 $msg,
979 $settings
980 ) ) {
981 $column_names = $this->get_app_form_columns( $settings );
982 if ( false === $column_names ) {
983 return $this->invalid_app_settings();
984 }
985 $default_where = '';
986 $table_api = new WPDA_Table();
987 return $table_api->get(
988 $dbs,
989 $tbl,
990 $key,
991 $media,
992 $column_names,
993 $default_where
994 );
995 } else {
996 if ( 'rest_cookie_invalid_nonce' === $msg ) {
997 return $this->invalid_nonce();
998 } else {
999 return new \WP_Error('error', $msg, array(
1000 'status' => 401,
1001 ));
1002 }
1003 }
1004 }
1005
1006 public function app_insert( $request ) {
1007 $app_id = $request->get_param( 'app_id' );
1008 $cnt_id = $request->get_param( 'cnt_id' );
1009 $val = $request->get_param( 'val' );
1010 $join_tab = $request->get_param( 'join_tab' );
1011 $rel_tab = $request->get_param( 'rel_tab' );
1012 if ( $this->check_app_access(
1013 $app_id,
1014 $cnt_id,
1015 'insert',
1016 $dbs,
1017 $tbl,
1018 $msg
1019 ) ) {
1020 $table_api = new WPDA_Table();
1021 return $table_api->insert( $dbs, $tbl, $val );
1022 } else {
1023 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1024 return $this->invalid_nonce();
1025 } else {
1026 return new \WP_Error('error', $msg, array(
1027 'status' => 401,
1028 ));
1029 }
1030 }
1031 }
1032
1033 public function app_update( $request ) {
1034 $app_id = $request->get_param( 'app_id' );
1035 $cnt_id = $request->get_param( 'cnt_id' );
1036 $key = $request->get_param( 'key' );
1037 $val = $request->get_param( 'val' );
1038 $join_tab = $request->get_param( 'join_tab' );
1039 $rel_tab = $request->get_param( 'rel_tab' );
1040 if ( $this->check_app_access(
1041 $app_id,
1042 $cnt_id,
1043 'update',
1044 $dbs,
1045 $tbl,
1046 $msg,
1047 $settings
1048 ) ) {
1049 $column_names = $this->get_app_form_columns( $settings );
1050 if ( false === $column_names ) {
1051 $column_names = array();
1052 }
1053 $code_columns = array();
1054 $html_columns = array();
1055 if ( isset( $settings['form']['columns'] ) ) {
1056 foreach ( $settings['form']['columns'] as $column ) {
1057 if ( isset( $column['allowHtml'] ) && false === $column['allowHtml'] ) {
1058 $html_columns[] = $column['columnName'];
1059 }
1060 }
1061 }
1062 $table_api = new WPDA_Table();
1063 return $table_api->update(
1064 $dbs,
1065 $tbl,
1066 $key,
1067 $val,
1068 $column_names,
1069 $code_columns,
1070 $html_columns
1071 );
1072 } else {
1073 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1074 return $this->invalid_nonce();
1075 } else {
1076 return new \WP_Error('error', $msg, array(
1077 'status' => 401,
1078 ));
1079 }
1080 }
1081 }
1082
1083 public function app_update_inline( $request ) {
1084 $app_id = $request->get_param( 'app_id' );
1085 $cnt_id = $request->get_param( 'cnt_id' );
1086 $key = $request->get_param( 'key' );
1087 $val = $request->get_param( 'val' );
1088 if ( $this->check_app_access(
1089 $app_id,
1090 $cnt_id,
1091 'select',
1092 $dbs,
1093 $tbl,
1094 $msg,
1095 $settings
1096 ) ) {
1097 foreach ( $val as $column_name => $column ) {
1098 $found = false;
1099 if ( isset( $settings['table']['columns'] ) ) {
1100 foreach ( $settings['table']['columns'] as $settings_column ) {
1101 if ( isset( $settings_column['columnName'] ) && $column_name === $settings_column['columnName'] ) {
1102 $found = true;
1103 }
1104 }
1105 if ( !$found ) {
1106 return $this->unauthorized();
1107 }
1108 }
1109 }
1110 $column_names = $this->get_app_form_columns( $settings );
1111 if ( false === $column_names ) {
1112 $column_names = array();
1113 }
1114 $table_api = new WPDA_Table();
1115 return $table_api->update(
1116 $dbs,
1117 $tbl,
1118 $key,
1119 $val,
1120 $column_names
1121 );
1122 } else {
1123 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1124 return $this->invalid_nonce();
1125 } else {
1126 return $this->unauthorized();
1127 }
1128 }
1129 }
1130
1131 public function app_delete( $request ) {
1132 $app_id = $request->get_param( 'app_id' );
1133 $cnt_id = $request->get_param( 'cnt_id' );
1134 $key = $request->get_param( 'key' );
1135 if ( $this->check_app_access(
1136 $app_id,
1137 $cnt_id,
1138 'delete',
1139 $dbs,
1140 $tbl,
1141 $msg
1142 ) ) {
1143 $table_api = new WPDA_Table();
1144 return $table_api->delete( $dbs, $tbl, $key );
1145 } else {
1146 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1147 return $this->invalid_nonce();
1148 } else {
1149 return new \WP_Error('error', $msg, array(
1150 'status' => 401,
1151 ));
1152 }
1153 }
1154 }
1155
1156 public function app_lov( $request ) {
1157 return $this->bad_request();
1158 }
1159
1160 public function app_lookup( $request ) {
1161 $app_id = $request->get_param( 'app_id' );
1162 $cnt_id = $request->get_param( 'cnt_id' );
1163 $target = $request->get_param( 'target' );
1164 $col = $request->get_param( 'col' );
1165 $colk = $request->get_param( 'colk' );
1166 $colv = $request->get_param( 'colv' );
1167 $cold = $request->get_param( 'cold' );
1168 $cols = $request->get_param( 'cols' );
1169 $search = $request->get_param( 'search' );
1170 $search_columns = $request->get_param( 'search_columns' );
1171 $search_column_fns = $request->get_param( 'search_column_fns' );
1172 $search_column_lov = $request->get_param( 'search_column_lov' );
1173 $search_data_types = $request->get_param( 'search_data_types' );
1174 $search_custom = $request->get_param( 'search_custom' );
1175 $search_params = $request->get_param( 'search_params' );
1176 $shortcode_params = $request->get_param( 'shortcode_params' );
1177 $md = $request->get_param( 'md' );
1178 $cascade = $request->get_param( 'cascade' );
1179 $values = $request->get_param( 'values' );
1180 $default_where = '';
1181 $default_where_lookup = '';
1182 $lookups = array();
1183 $m2m_relationship = array();
1184 if ( $this->check_app_access(
1185 $app_id,
1186 $cnt_id,
1187 'select',
1188 $dbs,
1189 $tbl,
1190 $msg,
1191 $settings
1192 ) ) {
1193 $container = WPDA_App_Container_Model::get_container( $app_id, $cnt_id );
1194 if ( !isset( $container[0] ) ) {
1195 return $this->bad_request();
1196 }
1197 $lookup = array();
1198 $lookup_dbs = "";
1199 $lookup_tbl = "";
1200 if ( 'form' === $target ) {
1201 // Handle form lookup
1202 if ( isset( $container[0]['cnt_form'] ) ) {
1203 $lookup = json_decode( (string) $container[0]['cnt_form'], true );
1204 }
1205 } else {
1206 if ( 'rform' === $target ) {
1207 // Handle form lookup
1208 if ( isset( $container[0]['cnt_rform'] ) ) {
1209 $lookup = json_decode( (string) $container[0]['cnt_rform'], true );
1210 }
1211 } else {
1212 // Handle table lookup
1213 if ( isset( $container[0]['cnt_table'] ) ) {
1214 $lookup = json_decode( (string) $container[0]['cnt_table'], true );
1215 }
1216 }
1217 }
1218 if ( isset( $lookup['columns'] ) && is_array( $lookup['columns'] ) ) {
1219 foreach ( $lookup['columns'] as $column ) {
1220 if ( $col === $column['columnName'] ) {
1221 if ( !isset( $column['lookup'] ) ) {
1222 return $this->WPDA_Rest_Response( '', [] );
1223 }
1224 $lookup_dbs = $column['lookup']['dbs'];
1225 $lookup_tbl = $column['lookup']['tbl'];
1226 if ( isset( $column['columnName'], $column['lookup']['defaultWhere'] ) ) {
1227 $default_where_lookup = $column['lookup']['defaultWhere'];
1228 }
1229 }
1230 }
1231 }
1232 if ( $lookup_dbs === null || $lookup_dbs === "" || $lookup_tbl === null || $lookup_tbl === "" ) {
1233 return $this->bad_request();
1234 }
1235 $table_api = new WPDA_Table();
1236 return $table_api->lookup(
1237 $lookup_dbs,
1238 $lookup_tbl,
1239 $colk,
1240 $colv,
1241 $cold,
1242 $this->process_params(
1243 $default_where_lookup,
1244 $search_custom,
1245 $search_params,
1246 $shortcode_params,
1247 $values
1248 ),
1249 '1' === $cascade,
1250 $tbl,
1251 $col,
1252 $this->process_params(
1253 $default_where,
1254 $search_custom,
1255 $search_params,
1256 $shortcode_params,
1257 $values
1258 ),
1259 $search,
1260 $cols,
1261 $search_columns,
1262 $search_column_fns,
1263 $lookups,
1264 $md,
1265 $m2m_relationship,
1266 $search_data_types
1267 );
1268 } else {
1269 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1270 return $this->invalid_nonce();
1271 } else {
1272 return new \WP_Error('error', $msg, array(
1273 'status' => 401,
1274 ));
1275 }
1276 }
1277 }
1278
1279 public function app_lookup_dbs( $request ) {
1280 $app_id = $request->get_param( 'app_id' );
1281 $cnt_id = $request->get_param( 'cnt_id' );
1282 if ( $this->check_app_access(
1283 $app_id,
1284 $cnt_id,
1285 'select',
1286 $_dbs,
1287 $_tbl,
1288 $msg
1289 ) ) {
1290 $tree_api = new WPDA_Tree();
1291 return $tree_api->get_dbs();
1292 } else {
1293 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1294 return $this->invalid_nonce();
1295 } else {
1296 return new \WP_Error('error', $msg, array(
1297 'status' => 401,
1298 ));
1299 }
1300 }
1301 }
1302
1303 public function app_lookup_tbl( $request ) {
1304 $app_id = $request->get_param( 'app_id' );
1305 $cnt_id = $request->get_param( 'cnt_id' );
1306 $dbs = $request->get_param( 'dbs' );
1307 if ( $this->check_app_access(
1308 $app_id,
1309 $cnt_id,
1310 'select',
1311 $_dbs,
1312 $_tbl,
1313 $msg
1314 ) ) {
1315 $tree_api = new WPDA_Tree();
1316 return $tree_api->get_tbl_vws( $dbs );
1317 } else {
1318 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1319 return $this->invalid_nonce();
1320 } else {
1321 return new \WP_Error('error', $msg, array(
1322 'status' => 401,
1323 ));
1324 }
1325 }
1326 }
1327
1328 public function app_lookup_cls( $request ) {
1329 $app_id = $request->get_param( 'app_id' );
1330 $cnt_id = $request->get_param( 'cnt_id' );
1331 $dbs = $request->get_param( 'dbs' );
1332 $tbl = $request->get_param( 'tbl' );
1333 if ( $this->check_app_access(
1334 $app_id,
1335 $cnt_id,
1336 'select',
1337 $_dbs,
1338 $_tbl,
1339 $msg
1340 ) ) {
1341 $tree_api = new WPDA_Tree();
1342 return $tree_api->get_cls( $dbs, $tbl );
1343 } else {
1344 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1345 return $this->invalid_nonce();
1346 } else {
1347 return new \WP_Error('error', $msg, array(
1348 'status' => 401,
1349 ));
1350 }
1351 }
1352 }
1353
1354 public function app_qb_list( $request ) {
1355 $qb = new WPDA_QB();
1356 return $qb->open( $request );
1357 }
1358
1359 public function app_dbs_rename( $request ) {
1360 if ( !$this->current_user_can_access() ) {
1361 // Only admins
1362 return $this->unauthorized();
1363 }
1364 if ( !$this->current_user_token_valid( $request ) ) {
1365 return $this->invalid_nonce();
1366 }
1367 $dbs_source = $request->get_param( 'dbs_source' );
1368 $dbs_destination = $request->get_param( 'dbs_destination' );
1369 if ( '' === trim( $dbs_source ) || '' === trim( $dbs_destination ) ) {
1370 return new \WP_Error('error', 'Invalid arguments', array(
1371 'status' => 401,
1372 ));
1373 }
1374 global $wpdb;
1375 $renamed = 0;
1376 $debug_mode = 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_DEBUG );
1377 $debug = array();
1378 $errors = array();
1379 // Rename all occurrences in repository tables and apps
1380 $sqls = array(
1381 "update `{$wpdb->prefix}wpda_publisher` set `pub_schema_name` = %s where `pub_schema_name` = %s",
1382 "update `{$wpdb->prefix}wpda_project_page` set `page_schema_name` = %s where `page_schema_name` = %s",
1383 "update `{$wpdb->prefix}wpda_project_table` set `wpda_schema_name` = %s where `wpda_schema_name` = %s",
1384 "update `{$wpdb->prefix}wpda_media` set `media_schema_name` = %s where `media_schema_name` = %s",
1385 "update `{$wpdb->prefix}wpda_menus` set `menu_schema_name` = %s where `menu_schema_name` = %s",
1386 "update `{$wpdb->prefix}wpda_table_design` set `wpda_schema_name` = %s where `wpda_schema_name` = %s",
1387 "update `{$wpdb->prefix}wpda_table_settings` set `wpda_schema_name` = %s where `wpda_schema_name` = %s",
1388 "update `{$wpdb->prefix}wpda_app_container` set `cnt_dbs` = %s where `cnt_dbs` = %s"
1389 );
1390 foreach ( $sqls as $sql ) {
1391 $result = $wpdb->query( $wpdb->prepare( $sql, array($dbs_destination, $dbs_source) ) );
1392 $renamed += $result;
1393 if ( $debug_mode ) {
1394 $debug[] = array(
1395 'sql' => $sql,
1396 'result' => $result,
1397 );
1398 }
1399 if ( '' !== $wpdb->last_error ) {
1400 $errors[] = array(
1401 'sql' => $sql,
1402 'error' => $wpdb->last_error,
1403 );
1404 }
1405 }
1406 $sql_content = array("update `{$wpdb->prefix}wpda_app_container` set `cnt_table` = replace(`cnt_table`, '\"dbs\":\"%1s\"', '\"dbs\":\"%1s\"') where `cnt_table` like '%\"dbs\":\"%1s\"%'", "update `{$wpdb->prefix}wpda_app_container` set `cnt_form` = replace(`cnt_form`, '\"dbs\":\"%1s\"', '\"dbs\":\"%1s\"') where `cnt_form` like '%\"dbs\":\"%1s\"%'");
1407 foreach ( $sql_content as $sql ) {
1408 $result = $wpdb->query( $wpdb->prepare( $sql, array($dbs_source, $dbs_destination, $dbs_source) ) );
1409 $renamed += $result;
1410 if ( $debug_mode ) {
1411 $debug[] = array(
1412 'sql' => $sql,
1413 'result' => $result,
1414 );
1415 }
1416 if ( '' !== $wpdb->last_error ) {
1417 $errors[] = array(
1418 'sql' => $sql,
1419 'error' => $wpdb->last_error,
1420 );
1421 }
1422 }
1423 $context = array();
1424 if ( $debug_mode ) {
1425 $context['debug'] = $debug;
1426 }
1427 if ( 0 < count( $errors ) ) {
1428 $context['errors'] = $errors;
1429 return new \WP_Error('error', 'Failed renaming database', array(
1430 'status' => 401,
1431 'context' => $context,
1432 ));
1433 }
1434 return $this->WPDA_Rest_Response( sprintf( __( 'Successfully renamed %s database occurrences', 'wp-data-access' ), $renamed ), null, $context );
1435 }
1436
1437 public function app_chart_data( $request ) {
1438 $app_id = $request->get_param( 'app_id' );
1439 $search_custom = $request->get_param( 'search_custom' );
1440 $shortcode_params = $request->get_param( 'shortcode_params' );
1441 if ( !$this->main_app_access( $app_id, $msg ) ) {
1442 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1443 return $this->invalid_nonce();
1444 }
1445 return $this->unauthorized();
1446 }
1447 if ( !$this->current_user_token_valid( $request ) ) {
1448 return $this->invalid_nonce();
1449 }
1450 $app_container = WPDA_App_Container_Model::select( $app_id, 0 );
1451 if ( 1 === count( $app_container ) && null !== $app_container[0]['cnt_query'] && '' !== trim( (string) $app_container[0]['cnt_query'] ) ) {
1452 $dbs = $app_container[0]['cnt_dbs'];
1453 $query = $app_container[0]['cnt_query'];
1454 // Process shortcode and url parameters
1455 $query = $this->process_params(
1456 $query,
1457 $search_custom,
1458 null,
1459 $shortcode_params
1460 );
1461 $wpdadb = WPDADB::get_db_connection( $dbs );
1462 if ( null === $wpdadb ) {
1463 // Error connecting.
1464 return new \WP_Error('error', "Error connecting to database {$dbs}", array(
1465 'status' => 420,
1466 ));
1467 }
1468 $suppress = $wpdadb->suppress_errors( true );
1469 $chart_data = $wpdadb->get_results( $query, 'ARRAY_A' );
1470 $wpdadb->get_results( "create temporary table `wpda_chart_data_types` as {$query}", 'ARRAY_A' );
1471 $explain = $wpdadb->get_results( "desc `wpda_chart_data_types`", 'ARRAY_A' );
1472 $wpdadb->get_results( "drop temporary table `wpda_chart_data_types`", 'ARRAY_A' );
1473 $wpdadb->suppress_errors( $suppress );
1474 return array(
1475 'data' => $chart_data,
1476 'explain' => $explain,
1477 );
1478 } else {
1479 return new \WP_Error('error', $msg, array(
1480 'status' => 401,
1481 ));
1482 }
1483 }
1484
1485 public function app_lang( $request ) {
1486 if ( !$this->current_user_can_access() ) {
1487 return $this->unauthorized();
1488 }
1489 if ( !$this->current_user_token_valid( $request ) ) {
1490 return $this->invalid_nonce();
1491 }
1492 $lang = $request->get_param( 'lang' );
1493 update_option( self::WPDA_APP_DEFAULT_LANG, $lang );
1494 return $this->WPDA_Rest_Response( __( 'Successfully saved changes', 'wp-data-access' ) );
1495 }
1496
1497 public function app_meta( $request ) {
1498 $app_id = $request->get_param( 'app_id' );
1499 if ( !$this->main_app_access( $app_id, $msg ) ) {
1500 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1501 return $this->invalid_nonce();
1502 }
1503 return $this->unauthorized();
1504 }
1505 if ( !$this->current_user_token_valid( $request ) ) {
1506 return $this->invalid_nonce();
1507 }
1508 return $this->get_app_meta( $app_id );
1509 }
1510
1511 public function app_settings( $request ) {
1512 if ( !$this->current_user_can_access() ) {
1513 return $this->unauthorized();
1514 }
1515 if ( !$this->current_user_token_valid( $request ) ) {
1516 return $this->invalid_nonce();
1517 }
1518 $app_id = $request->get_param( 'app_id' );
1519 $cnt_id = $request->get_param( 'cnt_id' );
1520 $target = $request->get_param( 'target' );
1521 $settings = $request->get_param( 'settings' );
1522 $chart = $request->get_param( 'chart' );
1523 $map = $request->get_param( 'map' );
1524 $theme = $request->get_param( 'theme' );
1525 return $this->do_app_settings(
1526 $app_id,
1527 $cnt_id,
1528 $target,
1529 $settings,
1530 $chart,
1531 $map,
1532 $theme
1533 );
1534 }
1535
1536 public function app_init( $request ) {
1537 if ( !$this->current_user_can_access() ) {
1538 return $this->unauthorized();
1539 }
1540 if ( !$this->current_user_token_valid( $request ) ) {
1541 return $this->invalid_nonce();
1542 }
1543 return $this->get_app_init();
1544 }
1545
1546 public function app_list( $request ) {
1547 if ( !$this->current_user_can_access() ) {
1548 return $this->unauthorized();
1549 }
1550 if ( !$this->current_user_token_valid( $request ) ) {
1551 return $this->invalid_nonce();
1552 }
1553 return $this->get_app_list();
1554 }
1555
1556 public function app_table_meta( $request ) {
1557 $dbs = $request->get_param( 'dbs' );
1558 $tbl = $request->get_param( 'tbl' );
1559 $waa = $request->get_param( 'waa' );
1560 if ( !$this->current_user_can_access() ) {
1561 return $this->unauthorized();
1562 }
1563 if ( !$this->current_user_token_valid( $request ) ) {
1564 return $this->invalid_nonce();
1565 }
1566 $table_api = new WPDA_Table();
1567 return $this->WPDA_Rest_Response( '', $table_api->get_table_meta_data( $dbs, $tbl, $waa ) );
1568 }
1569
1570 public function app_create( $request ) {
1571 if ( !$this->current_user_can_access() ) {
1572 return $this->unauthorized();
1573 }
1574 if ( !$this->current_user_token_valid( $request ) ) {
1575 return $this->invalid_nonce();
1576 }
1577 // App details
1578 $app_name = $request->get_param( 'app_name' );
1579 $app_title = $request->get_param( 'app_title' );
1580 $app_type = $request->get_param( 'app_type' );
1581 $app_settings = $request->get_param( 'app_settings' );
1582 // App container
1583 $app_dbs = $request->get_param( 'app_dbs' );
1584 $app_tbl = $request->get_param( 'app_tbl' );
1585 $app_cls = $request->get_param( 'app_cls' );
1586 $app_table = $request->get_param( 'app_table' );
1587 $app_query = $request->get_param( 'app_query' );
1588 return $this->do_app_create(
1589 $app_name,
1590 $app_title,
1591 $app_type,
1592 $app_settings,
1593 $app_dbs,
1594 $app_tbl,
1595 $app_cls,
1596 $app_table,
1597 $app_query
1598 );
1599 }
1600
1601 public function app_createapp( $request ) {
1602 if ( !$this->current_user_can_access() ) {
1603 return $this->unauthorized();
1604 }
1605 if ( !$this->current_user_token_valid( $request ) ) {
1606 return $this->invalid_nonce();
1607 }
1608 $app_name = $request->get_param( 'app_name' );
1609 $app_title = $request->get_param( 'app_title' );
1610 $app_type = $request->get_param( 'app_type' );
1611 $app_settings = $request->get_param( 'app_settings' );
1612 $app_apps = $request->get_param( 'app_apps' );
1613 return $this->do_app_createapp(
1614 $app_name,
1615 $app_title,
1616 $app_type,
1617 $app_settings,
1618 $app_apps
1619 );
1620 }
1621
1622 public function app_remove( $request ) {
1623 if ( !$this->current_user_can_access() ) {
1624 return $this->unauthorized();
1625 }
1626 if ( !$this->current_user_token_valid( $request ) ) {
1627 return $this->invalid_nonce();
1628 }
1629 $app_id = $request->get_param( 'app_id' );
1630 return $this->do_app_remove( $app_id );
1631 }
1632
1633 public function app_save( $request ) {
1634 if ( !$this->current_user_can_access() ) {
1635 return $this->unauthorized();
1636 }
1637 if ( !$this->current_user_token_valid( $request ) ) {
1638 return $this->invalid_nonce();
1639 }
1640 // App details
1641 $app_id = $request->get_param( 'app_id' );
1642 $app_name = $request->get_param( 'app_name' );
1643 $app_title = $request->get_param( 'app_title' );
1644 $app_type = $request->get_param( 'app_type' );
1645 $app_settings = $request->get_param( 'app_settings' );
1646 $app_add_to_menu = $request->get_param( 'app_add_to_menu' );
1647 // App container
1648 $app_dbs = $request->get_param( 'app_dbs' );
1649 $app_tbl = $request->get_param( 'app_tbl' );
1650 $app_cls = $request->get_param( 'app_cls' );
1651 $app_query = $request->get_param( 'app_query' );
1652 return $this->do_app_save(
1653 $app_id,
1654 $app_name,
1655 $app_title,
1656 $app_type,
1657 $app_settings,
1658 $app_add_to_menu,
1659 $app_dbs,
1660 $app_tbl,
1661 $app_cls,
1662 $app_query
1663 );
1664 }
1665
1666 public function app_saveapp( $request ) {
1667 if ( !$this->current_user_can_access() ) {
1668 return $this->unauthorized();
1669 }
1670 if ( !$this->current_user_token_valid( $request ) ) {
1671 return $this->invalid_nonce();
1672 }
1673 $app_id = $request->get_param( 'app_id' );
1674 $app_name = $request->get_param( 'app_name' );
1675 $app_title = $request->get_param( 'app_title' );
1676 $app_type = $request->get_param( 'app_type' );
1677 $app_settings = $request->get_param( 'app_settings' );
1678 $app_add_to_menu = $request->get_param( 'app_add_to_menu' );
1679 $app_apps = $request->get_param( 'app_apps' );
1680 return $this->do_app_saveapp(
1681 $app_id,
1682 $app_name,
1683 $app_title,
1684 $app_type,
1685 $app_settings,
1686 $app_add_to_menu,
1687 $app_apps
1688 );
1689 }
1690
1691 private function do_app_settings(
1692 $app_id,
1693 $cnt_id,
1694 $target,
1695 $settings,
1696 $chart,
1697 $map,
1698 $theme
1699 ) {
1700 if ( 1 > $app_id || 1 > $cnt_id || 'table' !== $target && 'form' !== $target && 'rform' !== $target && 'theme' !== $target && 'chart' !== $target && 'map' !== $target && 'dashboard' !== $target ) {
1701 return $this->bad_request();
1702 }
1703 if ( null === $settings || '' === $settings ) {
1704 // Perform reset
1705 switch ( $target ) {
1706 case 'table':
1707 $error_msg = WPDA_App_Container_Model::update_table_settings( $cnt_id, null );
1708 if ( '' !== $error_msg ) {
1709 return new \WP_Error('error', $error_msg, array(
1710 'status' => 403,
1711 ));
1712 }
1713 break;
1714 case 'form':
1715 $error_msg = WPDA_App_Container_Model::update_form_settings( $cnt_id, null );
1716 if ( '' !== $error_msg ) {
1717 return new \WP_Error('error', $error_msg, array(
1718 'status' => 403,
1719 ));
1720 }
1721 break;
1722 case 'chart':
1723 $error_msg = WPDA_App_Container_Model::update_chart_settings( $cnt_id, null );
1724 if ( '' !== $error_msg ) {
1725 return new \WP_Error('error', $error_msg, array(
1726 'status' => 403,
1727 ));
1728 }
1729 break;
1730 case 'map':
1731 $error_msg = WPDA_App_Container_Model::update_map_settings( $cnt_id, null );
1732 if ( '' !== $error_msg ) {
1733 return new \WP_Error('error', $error_msg, array(
1734 'status' => 403,
1735 ));
1736 }
1737 break;
1738 case 'theme':
1739 $error_msg = WPDA_App_Model::update_theme( $app_id, null );
1740 if ( '' !== $error_msg ) {
1741 return new \WP_Error('error', $error_msg, array(
1742 'status' => 403,
1743 ));
1744 }
1745 break;
1746 case 'dashboard':
1747 $error_msg = WPDA_App_Container_Model::update_dashboard_settings( $app_id, null );
1748 if ( '' !== $error_msg ) {
1749 return new \WP_Error('error', $error_msg, array(
1750 'status' => 403,
1751 ));
1752 }
1753 break;
1754 default:
1755 return $this->bad_request();
1756 }
1757 return $this->WPDA_Rest_Response( __( 'Reset was successful', 'wp-data-access' ) );
1758 }
1759 if ( 'table' === $target ) {
1760 // Update table settings
1761 $error_msg = WPDA_App_Container_Model::update_table_settings( $cnt_id, $settings );
1762 if ( '' !== $error_msg ) {
1763 return new \WP_Error('error', $error_msg, array(
1764 'status' => 403,
1765 ));
1766 }
1767 // Update chart settings
1768 $error_msg = WPDA_App_Container_Model::update_chart_settings( $cnt_id, $chart );
1769 if ( '' !== $error_msg ) {
1770 return new \WP_Error('error', $error_msg, array(
1771 'status' => 403,
1772 ));
1773 }
1774 // Update map settings
1775 $error_msg = WPDA_App_Container_Model::update_map_settings( $cnt_id, $map );
1776 if ( '' !== $error_msg ) {
1777 return new \WP_Error('error', $error_msg, array(
1778 'status' => 403,
1779 ));
1780 }
1781 } else {
1782 if ( 'rform' === $target ) {
1783 // Update rform settings
1784 $error_msg = WPDA_App_Container_Model::update_rform_settings( $cnt_id, $settings );
1785 if ( '' !== $error_msg ) {
1786 return new \WP_Error('error', $error_msg, array(
1787 'status' => 403,
1788 ));
1789 }
1790 } else {
1791 if ( 'chart' === $target ) {
1792 // Update chart settings
1793 $error_msg = WPDA_App_Container_Model::update_chart_settings( $cnt_id, $settings );
1794 if ( '' !== $error_msg ) {
1795 return new \WP_Error('error', $error_msg, array(
1796 'status' => 403,
1797 ));
1798 }
1799 } else {
1800 if ( 'map' === $target ) {
1801 // Update chart settings
1802 $error_msg = WPDA_App_Container_Model::update_map_settings( $cnt_id, $settings );
1803 if ( '' !== $error_msg ) {
1804 return new \WP_Error('error', $error_msg, array(
1805 'status' => 403,
1806 ));
1807 }
1808 } else {
1809 if ( 'form' === $target ) {
1810 // Update form settings
1811 $error_msg = WPDA_App_Container_Model::update_form_settings( $cnt_id, $settings );
1812 if ( '' !== $error_msg ) {
1813 return new \WP_Error('error', $error_msg, array(
1814 'status' => 403,
1815 ));
1816 }
1817 } else {
1818 if ( 'dashboard' === $target ) {
1819 $error_msg = WPDA_App_Container_Model::update_dashboard_settings( $cnt_id, $settings );
1820 if ( '' !== $error_msg ) {
1821 return new \WP_Error('error', $error_msg, array(
1822 'status' => 403,
1823 ));
1824 }
1825 }
1826 }
1827 }
1828 }
1829 }
1830 }
1831 $error_msg = WPDA_App_Model::update_theme( $app_id, $theme );
1832 if ( '' !== $error_msg ) {
1833 return new \WP_Error('error', $error_msg, array(
1834 'status' => 403,
1835 ));
1836 }
1837 return $this->WPDA_Rest_Response( __( 'Successfully saved settings', 'wp-data-access' ) );
1838 }
1839
1840 private function do_app_remove( $app_id ) {
1841 WPDA_App_Apps_Model::delete( $app_id, true );
1842 WPDA_App_Container_Model::delete( $app_id );
1843 WPDA_App_Model::delete( $app_id );
1844 return $this->WPDA_Rest_Response( __( 'Successfully deleted app', 'wp-data-access' ) );
1845 }
1846
1847 private function do_app_create(
1848 $app_name,
1849 $app_title,
1850 $app_type,
1851 $app_settings,
1852 $app_dbs,
1853 $app_tbl,
1854 $app_cls,
1855 $app_table,
1856 $app_query
1857 ) {
1858 // Add app
1859 $insert = WPDA_App_Model::create(
1860 $app_name,
1861 $app_title,
1862 $app_type,
1863 $app_settings
1864 );
1865 if ( false !== $insert['app_id'] ) {
1866 $app_id = $insert['app_id'];
1867 // Add app container
1868 $container = WPDA_App_Container_Model::create(
1869 $app_id,
1870 $app_dbs,
1871 $app_tbl,
1872 json_encode( $app_cls ),
1873 $app_title,
1874 0,
1875 $app_table,
1876 null,
1877 $app_query
1878 );
1879 if ( false !== $container['cnt_id'] ) {
1880 // App and container successfully saved
1881 return $this->WPDA_Rest_Response( __( 'Successfully saved changes', 'wp-data-access' ) );
1882 } else {
1883 // Insert failed
1884 // Remove previously created app
1885 WPDA_App_Model::delete( $app_id );
1886 return new \WP_Error('error', $container['msg'], array(
1887 'status' => 403,
1888 ));
1889 }
1890 } else {
1891 // Insert failed
1892 return new \WP_Error('error', $insert['msg'], array(
1893 'status' => 403,
1894 ));
1895 }
1896 }
1897
1898 private function do_app_createapp(
1899 $app_name,
1900 $app_title,
1901 $app_type,
1902 $app_settings,
1903 $app_apps
1904 ) {
1905 // Add app
1906 $insert = WPDA_App_Model::create(
1907 $app_name,
1908 $app_title,
1909 $app_type,
1910 $app_settings
1911 );
1912 if ( false !== $insert['app_id'] ) {
1913 // Add apps
1914 if ( is_array( $app_apps ) ) {
1915 $app_id = $insert['app_id'];
1916 foreach ( $app_apps as $index => $app_id_detail ) {
1917 // Insert app
1918 WPDA_App_Apps_Model::create( $app_id, $app_id_detail, $index );
1919 }
1920 }
1921 // App and details successfully saved
1922 return $this->WPDA_Rest_Response( __( 'Successfully saved changes', 'wp-data-access' ) );
1923 } else {
1924 // Insert failed
1925 return new \WP_Error('error', $insert['msg'], array(
1926 'status' => 403,
1927 ));
1928 }
1929 }
1930
1931 private function get_app_init() {
1932 return $this->WPDA_Rest_Response( '', array(
1933 'roles' => $this->get_wp_roles(),
1934 'users' => $this->get_wp_users(),
1935 'lang' => get_option( self::WPDA_APP_DEFAULT_LANG ),
1936 ) );
1937 }
1938
1939 private function get_app_list() {
1940 $dataset = WPDA_App_Model::list();
1941 $context = WPDA_App_Apps_Model::list();
1942 return $this->WPDA_Rest_Response( '', $dataset, $context );
1943 }
1944
1945 private function get_relation_columns( $container ) {
1946 return null;
1947 }
1948
1949 private function reorder_details( $app_id, $cnt_id_from, $cnt_id_to ) {
1950 return $this->bad_request();
1951 }
1952
1953 private function get_app_apps_meta( $app, $apps ) {
1954 $app_id_details = array_map( function ( $e ) {
1955 if ( isset( $e['app_id_detail'] ) ) {
1956 return $e['app_id_detail'];
1957 }
1958 }, $apps );
1959 $app_titles = array();
1960 foreach ( $app_id_details as $app_id_detail ) {
1961 $app_detail = WPDA_App_Model::get_by_id( $app_id_detail );
1962 if ( isset( $app_detail[0]['app_title'] ) ) {
1963 $app_titles[$app_id_detail] = $app_detail[0]['app_title'];
1964 }
1965 }
1966 $response = array(
1967 'app' => array(
1968 'app' => $app,
1969 'container' => array(),
1970 'apps' => $app_id_details,
1971 'titles' => $app_titles,
1972 ),
1973 );
1974 $response['settings'] = $this->get_table_settings();
1975 return $this->WPDA_Rest_Response( '', $response );
1976 }
1977
1978 private function get_table_settings( $tbl = null, $dbs = null ) {
1979 $settings = new stdClass();
1980 if ( null !== $dbs && null !== $tbl ) {
1981 $settings_db = WPDA_Table_Settings_Model::query( $tbl, $dbs );
1982 if ( isset( $settings_db[0]['wpda_table_settings'] ) ) {
1983 $settings = json_decode( (string) $settings_db[0]['wpda_table_settings'] );
1984 // Remove old settings from response.
1985 unset($settings->form_labels);
1986 unset($settings->list_labels);
1987 unset($settings->custom_settings);
1988 unset($settings->search_settings);
1989 }
1990 }
1991 $settings->env = $this->get_env();
1992 global $wpdb;
1993 $settings->wp = [
1994 'roles' => $this->get_wp_roles(),
1995 'users' => $this->get_wp_users(),
1996 'home' => admin_url( 'admin.php' ),
1997 'tables' => array_values( $wpdb->tables() ),
1998 'date_format' => get_option( 'date_format' ),
1999 'time_format' => get_option( 'time_format' ),
2000 'scroll_offset' => WPDA::get_option( WPDA::OPTION_APPS_SCROLL_OFFSET ),
2001 ];
2002 return $settings;
2003 }
2004
2005 private function get_app_container_meta( $app_id, $container, $rel_tab = false ) {
2006 $app = WPDA_App_Model::get_by_id( $app_id );
2007 if ( false === $app ) {
2008 return $this->bad_request();
2009 }
2010 if ( !isset( $container[0]['cnt_dbs'], $container[0]['cnt_tbl'], $container[0]['cnt_cls'] ) ) {
2011 return $this->bad_request();
2012 }
2013 $dbs = $container[0]['cnt_dbs'];
2014 $tbl = $container[0]['cnt_tbl'];
2015 $response = array(
2016 'app' => array(
2017 'app' => $app,
2018 'container' => array_map( function ( $value ) {
2019 $show = WPDA::current_user_is_admin();
2020 if ( !$show ) {
2021 // Hide database and table name in responses for non admin users.
2022 unset($value['cnt_dbs']);
2023 unset($value['cnt_tbl']);
2024 }
2025 return $value;
2026 }, $container ),
2027 'apps' => array(),
2028 ),
2029 );
2030 $access = array(
2031 'select' => array(),
2032 'insert' => array(),
2033 'update' => array(),
2034 'delete' => array(),
2035 );
2036 $cls = WPDA_List_Columns_Cache::get_list_columns( $dbs, $tbl );
2037 $columns = $cls->get_table_columns();
2038 $columns_sorted = array();
2039 foreach ( $columns as $column ) {
2040 if ( isset( $column['column_name'] ) ) {
2041 $columns_sorted[$column['column_name']] = $column;
2042 }
2043 }
2044 $media = $this->get_media( $dbs, $tbl, $cls->get_table_columns() );
2045 $response['columns'] = $columns;
2046 $response['columns_sorted'] = $columns_sorted;
2047 $response['table_labels'] = $cls->get_table_header_labels();
2048 $response['form_labels'] = $cls->get_table_column_headers();
2049 $response['primary_key'] = $cls->get_table_primary_key();
2050 $response['access'] = $access;
2051 $response['settings'] = $this->get_table_settings( $tbl, $dbs );
2052 $response['media'] = $media['media'];
2053 $response['wp_media'] = $media['wp_media'];
2054 $table_settings = json_decode( (string) $container[0]['cnt_table'], true );
2055 if ( isset( $table_settings['table']['defaultWhere'] ) ) {
2056 $default_where = $table_settings['table']['defaultWhere'];
2057 } else {
2058 $default_where = '';
2059 }
2060 $response['table_info'] = $this->get_table_info( $dbs, $tbl, $default_where );
2061 return $this->WPDA_Rest_Response( '', $response );
2062 }
2063
2064 public function get_app_meta( $app_id ) {
2065 $app = WPDA_App_Model::get_by_id( $app_id );
2066 if ( !isset( $app[0]['app_type'] ) ) {
2067 return $this->bad_request();
2068 }
2069 if ( '5' === $app[0]['app_type'] || 5 === $app[0]['app_type'] ) {
2070 // App container
2071 $apps = WPDA_App_Apps_Model::select_all( $app_id, 0 );
2072 return $this->get_app_apps_meta( $app, $apps );
2073 } else {
2074 // Other container
2075 $container = WPDA_App_Container_Model::select( $app_id, 0 );
2076 if ( !isset( $container[0] ) ) {
2077 return $this->bad_request();
2078 }
2079 return $this->get_app_container_meta( $app_id, $container );
2080 }
2081 }
2082
2083 private function do_app_export_app( $app_id, $main_app_id ) {
2084 global $wpdb;
2085 $quotes = function ( $value ) {
2086 return str_replace( array(
2087 "'",
2088 '\\"',
2089 "\\\\t",
2090 "\\t",
2091 "\\\\n",
2092 "\\n",
2093 "\\r\\n",
2094 "\\r"
2095 ), array(
2096 "''",
2097 '\\\\"',
2098 "\\\\\\t",
2099 "\\\\t",
2100 "\\\\\\n",
2101 "\\\\n",
2102 "\\\\r\\\\n",
2103 "\\\\r"
2104 ), $value );
2105 };
2106 $app = WPDA_App_Model::get_by_id( $app_id );
2107 $app_settings = ( null === $app[0]['app_settings'] ? 'null' : "{$quotes( $app[0]['app_settings'] )}" );
2108 $app_theme = ( null === $app[0]['app_theme'] ? 'null' : "{$quotes( $app[0]['app_theme'] )}" );
2109 $app_sql = <<<SQL
2110 # Import app
2111 insert into `{wp_prefix}wpda_app`
2112 \t(`app_name`
2113 \t,`app_title`
2114 \t,`app_type`
2115 \t,`app_settings`
2116 \t,`app_theme`
2117 \t,`app_add_to_menu`
2118 \t)
2119 values
2120 \t('{$quotes( $app[0]['app_name'] )}'
2121 \t,'{$quotes( $app[0]['app_title'] )}'
2122 \t,{$app[0]['app_type']}
2123 \t,'{$app_settings}'
2124 \t,'{$app_theme}'
2125 \t,{$app[0]['app_add_to_menu']}
2126 \t);
2127
2128 SET @APP_ID = LAST_INSERT_ID();
2129 insert into `wpda_transfer_apps_{$main_app_id}`
2130 values
2131 ({$app[0]['app_id']}
2132 ,(select LAST_INSERT_ID(`app_id`) from `{wp_prefix}wpda_app` order by 1 desc limit 1)
2133 );
2134
2135
2136 SQL;
2137 $containers = WPDA_App_Container_Model::select_all( $app_id );
2138 $containers_sql = '';
2139 foreach ( $containers as $container ) {
2140 $cnt_table = ( null === $container['cnt_table'] ? 'null' : "'{$quotes( $container['cnt_table'] )}'" );
2141 $cnt_form = ( null === $container['cnt_form'] ? 'null' : "'{$quotes( $container['cnt_form'] )}'" );
2142 $cnt_relation = ( null === $container['cnt_relation'] ? 'null' : "'{$quotes( $container['cnt_relation'] )}'" );
2143 $cnt_rform = ( null === $container['cnt_rform'] ? 'null' : "'{$quotes( $container['cnt_rform'] )}'" );
2144 $cnt_chart = ( null === $container['cnt_chart'] ? 'null' : "'{$quotes( $container['cnt_chart'] )}'" );
2145 $cnt_map = ( null === $container['cnt_map'] ? 'null' : "'{$quotes( $container['cnt_map'] )}'" );
2146 $cnt_query = ( null === $container['cnt_query'] ? 'null' : "'{$quotes( $container['cnt_query'] )}'" );
2147 // Replace default WordPress database with conversion string
2148 $cnt_dbs = ( $wpdb->dbname === $container['cnt_dbs'] ? '{wp_schema}' : "{$quotes( $container['cnt_dbs'] )}" );
2149 $cnt_table = str_replace( "\"dbs\":\"{$wpdb->dbname}\"", "\"dbs\":\"{wp_schema}\"", $cnt_table );
2150 $cnt_form = str_replace( "\"dbs\":\"{$wpdb->dbname}\"", "\"dbs\":\"{wp_schema}\"", $cnt_form );
2151 $containers_sql .= <<<SQL
2152 # Import app container
2153 insert into `{wp_prefix}wpda_app_container`
2154 \t(`cnt_dbs`
2155 \t,`cnt_tbl`
2156 \t,`cnt_cls`
2157 \t,`cnt_title`
2158 \t,`app_id`
2159 \t,`cnt_seq_nr`
2160 \t,`cnt_table`
2161 \t,`cnt_form`
2162 \t,`cnt_relation`
2163 ,`cnt_rform`
2164 ,`cnt_chart`
2165 ,`cnt_map`
2166 ,`cnt_query`
2167 \t)
2168 values
2169 \t('{$cnt_dbs}'
2170 \t,'{$quotes( $container['cnt_tbl'] )}'
2171 \t,'{$quotes( $container['cnt_cls'] )}'
2172 \t,'{$quotes( $container['cnt_title'] )}'
2173 \t,@APP_ID
2174 \t,{$container['cnt_seq_nr']}
2175 \t,{$cnt_table}
2176 \t,{$cnt_form}
2177 \t,{$cnt_relation}
2178 \t,{$cnt_rform}
2179 \t,{$cnt_chart}
2180 \t,{$cnt_map}
2181 \t,{$cnt_query}
2182 \t);
2183
2184 insert into `wpda_transfer_containers_{$main_app_id}`
2185 values
2186 ({$container['cnt_id']}
2187 ,(select LAST_INSERT_ID(`cnt_id`) from `{wp_prefix}wpda_app_container` order by 1 desc limit 1)
2188 );
2189
2190
2191 SQL;
2192 }
2193 // Post update: update master container ids
2194 $containers_sql .= <<<SQL
2195 # Update app master container IDs
2196 update `{wp_prefix}wpda_app_container` as a
2197 set a.`cnt_relation` =
2198 (
2199 select replace(
2200 a.`cnt_relation`,
2201 concat('"cnt_id_master":"', b.cnt_id_old, '"'),
2202 concat('"cnt_id_master":"', b.cnt_id_new, '"')
2203 )
2204 from `wpda_transfer_containers_{$main_app_id}` as b
2205 where a.`cnt_relation` like concat('%"cnt_id_master":"', b.cnt_id_old, '"%')
2206 )
2207 where a.`app_id` = @APP_ID
2208 and a.`cnt_relation` is not null;
2209
2210
2211 SQL;
2212 $apps = WPDA_App_Apps_Model::select_all( $app_id );
2213 $apps_sql = '';
2214 foreach ( $apps as $app ) {
2215 $apps_sql .= $this->do_app_export_app( $app['app_id_detail'], $main_app_id );
2216 }
2217 foreach ( $apps as $app ) {
2218 $apps_sql .= <<<SQL
2219 # Import app relationships
2220 insert into `{wp_prefix}wpda_app_apps`
2221 \t(`app_id`
2222 \t,`app_id_detail`
2223 \t,`seq_nr`\t\t\t\t\t
2224 \t)
2225 values
2226 \t((select `app_id_new` from `wpda_transfer_apps_{$main_app_id}` where `app_id_old` = {$app['app_id']})
2227 \t,(select `app_id_new` from `wpda_transfer_apps_{$main_app_id}` where `app_id_old` = {$app['app_id_detail']})
2228 \t,{$app['seq_nr']}\t\t\t\t\t
2229 \t);
2230
2231
2232 SQL;
2233 }
2234 return $app_sql . $containers_sql . $apps_sql;
2235 }
2236
2237 private function do_app_export( $app_id ) {
2238 global $wpdb;
2239 $sql = '';
2240 $begin_sql = <<<SQL
2241 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
2242 /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
2243 /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
2244 /*!40101 SET NAMES {$wpdb->charset} */;
2245
2246 # Create temporary table
2247 CREATE TABLE `wpda_transfer_containers_{$app_id}`
2248 (cnt_id_old bigint(20) unsigned
2249 ,cnt_id_new bigint(20) unsigned
2250 );
2251
2252 CREATE TABLE `wpda_transfer_apps_{$app_id}`
2253 (app_id_old bigint(20) unsigned
2254 ,app_id_new bigint(20) unsigned
2255 );
2256
2257 SET @APP_ID = NULL;
2258
2259
2260 SQL;
2261 $sql .= $this->do_app_export_app( $app_id, $app_id );
2262 $end_sql = <<<SQL
2263 # Drop temporary table
2264 DROP TABLE `wpda_transfer_containers_{$app_id}`;
2265 DROP TABLE `wpda_transfer_apps_{$app_id}`;
2266
2267 /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
2268 /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
2269 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
2270
2271
2272 SQL;
2273 $data = array(
2274 'data' => $begin_sql . $sql . $end_sql,
2275 );
2276 return $this->WPDA_Rest_Response( __( 'App successfully exported', 'wp-data-access' ), $data );
2277 }
2278
2279 private function do_app_copy( $app_id ) {
2280 $copy = WPDA_App_Model::copy( $app_id );
2281 if ( false === $copy['app_id'] ) {
2282 return new \WP_Error('error', $copy['msg'], array(
2283 'status' => 403,
2284 ));
2285 } else {
2286 return $this->WPDA_Rest_Response( __( 'App successfully copied', 'wp-data-access' ) );
2287 }
2288 }
2289
2290 private function do_app_saveapp(
2291 $app_id,
2292 $app_name,
2293 $app_title,
2294 $app_type,
2295 $app_settings,
2296 $app_add_to_menu,
2297 $app_apps
2298 ) {
2299 $error_msg = WPDA_App_Model::update(
2300 $app_id,
2301 $app_name,
2302 $app_title,
2303 $app_type,
2304 $app_settings,
2305 $app_add_to_menu
2306 );
2307 if ( '' !== $error_msg ) {
2308 return new \WP_Error('error', $error_msg, array(
2309 'status' => 403,
2310 ));
2311 }
2312 WPDA_App_Apps_Model::update( $app_id, $app_apps );
2313 return $this->WPDA_Rest_Response( __( 'Changes successfully saved', 'wp-data-access' ) );
2314 }
2315
2316 private function do_app_save(
2317 $app_id,
2318 $app_name,
2319 $app_title,
2320 $app_type,
2321 $app_settings,
2322 $app_add_to_menu,
2323 $app_dbs,
2324 $app_tbl,
2325 $app_cls,
2326 $app_query
2327 ) {
2328 $error_msg = WPDA_App_Model::update(
2329 $app_id,
2330 $app_name,
2331 $app_title,
2332 $app_type,
2333 $app_settings,
2334 $app_add_to_menu
2335 );
2336 if ( '' !== $error_msg ) {
2337 return new \WP_Error('error', $error_msg, array(
2338 'status' => 403,
2339 ));
2340 }
2341 $error_msg = WPDA_App_Container_Model::update_master(
2342 $app_id,
2343 $app_dbs,
2344 $app_tbl,
2345 json_encode( $app_cls ),
2346 $app_query
2347 );
2348 if ( '' !== $error_msg ) {
2349 return new \WP_Error('error', $error_msg, array(
2350 'status' => 403,
2351 ));
2352 }
2353 return $this->WPDA_Rest_Response( __( 'Changes successfully saved', 'wp-data-access' ) );
2354 }
2355
2356 private function main_app_access( $app_id, &$msg = '', &$app = null ) {
2357 // Get app info
2358 $app = WPDA_App_Model::get_by_id( $app_id );
2359 if ( false === $app ) {
2360 // App not found
2361 $msg = __( 'Bad request', 'wp-data-access' );
2362 return false;
2363 }
2364 // Check access
2365 $app_settings_db = $app[0]['app_settings'];
2366 $app_settings = json_decode( (string) $app_settings_db, true );
2367 if ( !isset( $app_settings['rest_api']['authorization'], $app_settings['rest_api']['authorized_roles'], $app_settings['rest_api']['authorized_users'] ) || !is_array( $app_settings['rest_api']['authorized_roles'] ) || !is_array( $app_settings['rest_api']['authorized_users'] ) ) {
2368 // App contain no rest api settings
2369 $msg = __( 'Bad request', 'wp-data-access' );
2370 return false;
2371 }
2372 if ( !$this->current_user_can_access() && 'anonymous' !== $app_settings['rest_api']['authorization'] ) {
2373 // Check authorization
2374 // Check user role
2375 $user_roles = WPDA::get_current_user_roles();
2376 if ( !is_array( $user_roles ) || empty( array_intersect( $app_settings['rest_api']['authorized_roles'], $user_roles ) ) ) {
2377 // Check user login
2378 $user_login = WPDA::get_current_user_login();
2379 if ( !in_array( $user_login, $app_settings['rest_api']['authorized_users'] ) ) {
2380 $msg = __( 'Unauthorized', 'wp-data-access' );
2381 return false;
2382 }
2383 }
2384 }
2385 return true;
2386 }
2387
2388 public function check_app_access(
2389 $app_id,
2390 $cnt_id,
2391 $action,
2392 &$dbs,
2393 &$tbl,
2394 &$msg = '',
2395 &$settings = array()
2396 ) {
2397 if ( !$this->main_app_access( $app_id, $msg ) ) {
2398 return false;
2399 }
2400 // Get container
2401 $container = WPDA_App_Container_Model::get_container( $app_id, $cnt_id );
2402 if ( !is_array( $container ) || 0 === count( $container ) ) {
2403 // Container not found
2404 $msg = __( 'Bad request', 'wp-data-access' );
2405 return false;
2406 }
2407 if ( 'select' !== $action ) {
2408 $cnt_table = json_decode( (string) $container[0]['cnt_table'], true );
2409 if ( !isset( $cnt_table['table']['transactions'][$action] ) || false === $cnt_table['table']['transactions'][$action] ) {
2410 if ( !isset( $cnt_table['table']['bulkActions'][$action] ) || false === $cnt_table['table']['bulkActions'][$action] ) {
2411 $cnt_relation = json_decode( (string) $container[0]['cnt_relation'], true );
2412 if ( !(isset( $cnt_relation['cnt_id_master'] ) && $this->check_master_container_access( $app_id, $cnt_relation['cnt_id_master'], $action )) ) {
2413 $msg = __( 'Unauthorized', 'wp-data-access' );
2414 return false;
2415 }
2416 }
2417 }
2418 }
2419 // Return database name, table name and columns
2420 $dbs = $container[0]['cnt_dbs'];
2421 $tbl = $container[0]['cnt_tbl'];
2422 $settings = array(
2423 'columns' => json_decode( (string) $container[0]['cnt_cls'], true ),
2424 'table' => json_decode( (string) $container[0]['cnt_table'], true ),
2425 'form' => json_decode( (string) $container[0]['cnt_form'], true ),
2426 );
2427 return true;
2428 }
2429
2430 private function check_master_container_access( $app_id, $cnt_id, $action ) {
2431 $container = WPDA_App_Container_Model::get_container( $app_id, $cnt_id );
2432 if ( !is_array( $container ) || 0 === count( $container ) ) {
2433 // Container not found
2434 return false;
2435 }
2436 $cnt_table = json_decode( (string) $container[0]['cnt_table'], true );
2437 if ( !isset( $cnt_table['table']['transactions'][$action] ) || false === $cnt_table['table']['transactions'][$action] ) {
2438 $cnt_relation = json_decode( (string) $container[0]['cnt_relation'], true );
2439 if ( !(isset( $cnt_relation['cnt_id_master'] ) && $this->check_master_container_access( $app_id, $cnt_relation['cnt_id_master'], $action )) ) {
2440 return false;
2441 }
2442 }
2443 return true;
2444 }
2445
2446 private function process_params(
2447 $where,
2448 $search_custom,
2449 $search_params,
2450 $shortcode_params,
2451 $dynamic_params = array()
2452 ) {
2453 // Process $search_custom > URL parameters
2454 global $wpdb;
2455 foreach ( self::METHODS as $method ) {
2456 $offset = 0;
2457 $search = $method . '[';
2458 while ( ($pos_start = stripos( $where, $search, $offset )) !== false ) {
2459 if ( ($pos_end = stripos( $where, ']', $pos_start )) !== false ) {
2460 // Get filter
2461 $filter = substr( $where, $pos_start, $pos_end - $pos_start + 1 );
2462 // Get name
2463 $arg_name = substr( $where, $pos_start + strlen( $search ), $pos_end - $pos_start - strlen( $search ) );
2464 // Remove quotes from name
2465 if ( substr( $arg_name, 0, 1 ) === "'" && substr( $arg_name, -1 ) === "'" ) {
2466 $arg_name = substr( $arg_name, 1, -1 );
2467 }
2468 // Remove double quotes from name
2469 if ( substr( $arg_name, 0, 1 ) === '"' && substr( $arg_name, -1 ) === '"' ) {
2470 $arg_name = substr( $arg_name, 1, -1 );
2471 }
2472 // Handle GET args
2473 if ( $method === self::METHODS[0] ) {
2474 if ( isset( $search_custom['get'][$arg_name] ) ) {
2475 $arg_value = sanitize_text_field( wp_unslash( $search_custom['get'][$arg_name] ) );
2476 $where = $wpdb->prepare( substr_replace(
2477 $where,
2478 '%s',
2479 $pos_start,
2480 $pos_end - $pos_start + 1
2481 ), $arg_value );
2482 } else {
2483 $where = str_replace( $filter, 'null', $where );
2484 }
2485 }
2486 // Handle POST args
2487 if ( $method === self::METHODS[1] ) {
2488 if ( isset( $search_custom['post'][$arg_name] ) ) {
2489 $arg_value = sanitize_text_field( wp_unslash( $search_custom['post'][$arg_name] ) );
2490 $where = $wpdb->prepare( substr_replace(
2491 $where,
2492 '%s',
2493 $pos_start,
2494 $pos_end - $pos_start + 1
2495 ), $arg_value );
2496 } else {
2497 $where = str_replace( $filter, 'null', $where );
2498 }
2499 }
2500 // Handle REQUEST args
2501 if ( $method === self::METHODS[2] ) {
2502 if ( isset( $search_custom['get'][$arg_name] ) ) {
2503 $arg_value = sanitize_text_field( wp_unslash( $search_custom['get'][$arg_name] ) );
2504 $where = $wpdb->prepare( substr_replace(
2505 $where,
2506 '%s',
2507 $pos_start,
2508 $pos_end - $pos_start + 1
2509 ), $arg_value );
2510 } elseif ( isset( $search_custom['post'][$arg_name] ) ) {
2511 $arg_value = sanitize_text_field( wp_unslash( $search_custom['post'][$arg_name] ) );
2512 $where = $wpdb->prepare( substr_replace(
2513 $where,
2514 '%s',
2515 $pos_start,
2516 $pos_end - $pos_start + 1
2517 ), $arg_value );
2518 } else {
2519 $where = str_replace( $filter, 'null', $where );
2520 }
2521 }
2522 }
2523 $offset = $pos_start + 1;
2524 if ( $offset > strlen( $where ) ) {
2525 $offset = strlen( $where ) - 1;
2526 }
2527 }
2528 }
2529 // Process $search_params > shortcode parameters
2530 if ( is_array( $search_params ) && 1 === count( $search_params ) ) {
2531 $filter_field_name = $this->sanitize_db_identifier( array_keys( $search_params )[0] );
2532 $filter_field_value = sanitize_text_field( $search_params[$filter_field_name] );
2533 $filter_field_name_array = array_map( 'trim', explode( ',', $filter_field_name ) );
2534 //phpcs:ignore - 8.1 proof
2535 $filter_field_value_array = array_map( 'trim', explode( ',', $filter_field_value ) );
2536 //phpcs:ignore - 8.1 proof
2537 if ( count( $filter_field_name_array ) === count( $filter_field_value_array ) ) {
2538 //phpcs:ignore - 8.1 proof
2539 // Add filter to where clause.
2540 for ($i = 0; $i < count( $filter_field_name_array ); $i++) {
2541 // phpcs:ignore Generic.CodeAnalysis.ForLoopWithTestFunctionCall, Squiz.PHP.DisallowSizeFunctionsInLoops
2542 $where .= (( '' === $where ? '' : ' and ' )) . $wpdb->prepare(
2543 ' `%1s` like %s ',
2544 // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
2545 array($filter_field_name_array[$i], $filter_field_value_array[$i])
2546 );
2547 }
2548 }
2549 }
2550 // Substitute all shortcode parameters
2551 if ( is_array( $shortcode_params ) ) {
2552 foreach ( $shortcode_params as $column_name => $column_value ) {
2553 $occurences = substr_count( strtolower( $where ), strtolower( "shortcodeParam['{$column_name}']" ) );
2554 if ( 0 < $occurences ) {
2555 $column_values = array();
2556 for ($i = 0; $i < $occurences; $i++) {
2557 $column_values[] = sanitize_text_field( $column_value );
2558 }
2559 $where = $wpdb->prepare( str_ireplace( "shortcodeParam['{$column_name}']", '%s', $where ), $column_values );
2560 }
2561 }
2562 }
2563 // Substitute all unused shortcode parameter calls with null
2564 $offset = 0;
2565 $search = "shortcodeParam['";
2566 while ( ($pos_start = stripos( $where, $search, $offset )) !== false ) {
2567 if ( ($pos_end = stripos( $where, "']", $pos_start )) !== false ) {
2568 $shortcode_value = substr( $where, $pos_start, $pos_end - $pos_start + 2 );
2569 $where = str_ireplace( $shortcode_value, 'null', $where );
2570 }
2571 $offset = $pos_start + 4;
2572 if ( $offset > strlen( $where ) ) {
2573 $offset = strlen( $where ) - 1;
2574 }
2575 }
2576 // Substitute all dynamic parameters
2577 if ( is_array( $dynamic_params ) && 0 < count( $dynamic_params ) ) {
2578 foreach ( $dynamic_params as $column_name => $column_value ) {
2579 $where = $wpdb->prepare( str_ireplace( "{:{$column_name}}", '%s', $where ), $column_value );
2580 }
2581 }
2582 return $where;
2583 }
2584
2585 }
2586