PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.41
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.41
5.5.84 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 All 160 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.41, at WPDataAccess/API/WPDA_Apps.php

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