PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.40
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.40
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.40, at WPDataAccess/API/WPDA_Apps.php

2,390 lines 95.8 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 // Rename all occurrences in repository tables and apps
1292 $sqls = array(
1293 "update `{$wpdb->prefix}wpda_publisher` set `pub_schema_name` = %s where `pub_schema_name` = %s",
1294 "update `{$wpdb->prefix}wpda_project_page` set `page_schema_name` = %s where `page_schema_name` = %s",
1295 "update `{$wpdb->prefix}wpda_project_table` set `wpda_schema_name` = %s where `wpda_schema_name` = %s",
1296 "update `{$wpdb->prefix}wpda_media` set `media_schema_name` = %s where `media_schema_name` = %s",
1297 "update `{$wpdb->prefix}wpda_menus` set `menu_schema_name` = %s where `menu_schema_name` = %s",
1298 "update `{$wpdb->prefix}wpda_table_design` set `wpda_schema_name` = %s where `wpda_schema_name` = %s",
1299 "update `{$wpdb->prefix}wpda_table_settings` set `wpda_schema_name` = %s where `wpda_schema_name` = %s",
1300 "update `{$wpdb->prefix}wpda_container` set `cnt_dbs` = %s where `cnt_dbs` = %s"
1301 );
1302 foreach ( $sqls as $sql ) {
1303 $renamed += $wpdb->query( $wpdb->prepare( $sql, array($dbs_destination, $dbs_source) ) );
1304 }
1305 $sql_content = array("update `{$wpdb->prefix}wpda_container` set `cnt_table` = replace(`cnt_table`, '\"dbs\":\"%1s\"', '\"dbs\":\"%1s\"') where `cnt_table` like '%\"dbs\":\"%1s\"%'", "update `{$wpdb->prefix}wpda_container` set `cnt_form` = replace(`cnt_form`, '\"dbs\":\"%1s\"', '\"dbs\":\"%1s\"') where `cnt_form` like '%\"dbs\":\"%1s\"%'");
1306 foreach ( $sql_content as $sql ) {
1307 $renamed += $wpdb->query( $wpdb->prepare( $sql, array($dbs_source, $dbs_destination, $dbs_source) ) );
1308 }
1309 return $this->WPDA_Rest_Response( sprintf( __( 'Successfully renamed %s database occurrences', 'wp-data-access' ), $renamed ) );
1310 }
1311
1312 public function app_chart_data( $request ) {
1313 $app_id = $request->get_param( 'app_id' );
1314 $search_custom = $request->get_param( 'search_custom' );
1315 $shortcode_params = $request->get_param( 'shortcode_params' );
1316 if ( !$this->main_app_access( $app_id, $msg ) ) {
1317 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1318 return $this->invalid_nonce();
1319 }
1320 return $this->unauthorized();
1321 }
1322 if ( !$this->current_user_token_valid( $request ) ) {
1323 return $this->invalid_nonce();
1324 }
1325 $app_container = WPDA_App_Container_Model::select( $app_id, 0 );
1326 if ( 1 === count( $app_container ) && null !== $app_container[0]['cnt_query'] && '' !== trim( (string) $app_container[0]['cnt_query'] ) ) {
1327 $dbs = $app_container[0]['cnt_dbs'];
1328 $query = $app_container[0]['cnt_query'];
1329 // Process shortcode and url parameters
1330 $query = $this->process_params(
1331 $query,
1332 $search_custom,
1333 null,
1334 $shortcode_params
1335 );
1336 $wpdadb = WPDADB::get_db_connection( $dbs );
1337 if ( null === $wpdadb ) {
1338 // Error connecting.
1339 return new \WP_Error('error', "Error connecting to database {$dbs}", array(
1340 'status' => 420,
1341 ));
1342 }
1343 $suppress = $wpdadb->suppress_errors( true );
1344 $chart_data = $wpdadb->get_results( $query, 'ARRAY_A' );
1345 $wpdadb->get_results( "create temporary table `wpda_chart_data_types` as {$query}", 'ARRAY_A' );
1346 $explain = $wpdadb->get_results( "desc `wpda_chart_data_types`", 'ARRAY_A' );
1347 $wpdadb->get_results( "drop temporary table `wpda_chart_data_types`", 'ARRAY_A' );
1348 $wpdadb->suppress_errors( $suppress );
1349 return array(
1350 'data' => $chart_data,
1351 'explain' => $explain,
1352 );
1353 } else {
1354 return new \WP_Error('error', $msg, array(
1355 'status' => 401,
1356 ));
1357 }
1358 }
1359
1360 public function app_lang( $request ) {
1361 if ( !$this->current_user_can_access() ) {
1362 return $this->unauthorized();
1363 }
1364 if ( !$this->current_user_token_valid( $request ) ) {
1365 return $this->invalid_nonce();
1366 }
1367 $lang = $request->get_param( 'lang' );
1368 update_option( self::WPDA_APP_DEFAULT_LANG, $lang );
1369 return $this->WPDA_Rest_Response( __( 'Successfully saved changes', 'wp-data-access' ) );
1370 }
1371
1372 public function app_meta( $request ) {
1373 $app_id = $request->get_param( 'app_id' );
1374 if ( !$this->main_app_access( $app_id, $msg ) ) {
1375 if ( 'rest_cookie_invalid_nonce' === $msg ) {
1376 return $this->invalid_nonce();
1377 }
1378 return $this->unauthorized();
1379 }
1380 if ( !$this->current_user_token_valid( $request ) ) {
1381 return $this->invalid_nonce();
1382 }
1383 return $this->get_app_meta( $app_id );
1384 }
1385
1386 public function app_settings( $request ) {
1387 if ( !$this->current_user_can_access() ) {
1388 return $this->unauthorized();
1389 }
1390 if ( !$this->current_user_token_valid( $request ) ) {
1391 return $this->invalid_nonce();
1392 }
1393 $app_id = $request->get_param( 'app_id' );
1394 $cnt_id = $request->get_param( 'cnt_id' );
1395 $target = $request->get_param( 'target' );
1396 $settings = $request->get_param( 'settings' );
1397 $chart = $request->get_param( 'chart' );
1398 $map = $request->get_param( 'map' );
1399 $theme = $request->get_param( 'theme' );
1400 return $this->do_app_settings(
1401 $app_id,
1402 $cnt_id,
1403 $target,
1404 $settings,
1405 $chart,
1406 $map,
1407 $theme
1408 );
1409 }
1410
1411 public function app_init( $request ) {
1412 if ( !$this->current_user_can_access() ) {
1413 return $this->unauthorized();
1414 }
1415 if ( !$this->current_user_token_valid( $request ) ) {
1416 return $this->invalid_nonce();
1417 }
1418 return $this->get_app_init();
1419 }
1420
1421 public function app_list( $request ) {
1422 if ( !$this->current_user_can_access() ) {
1423 return $this->unauthorized();
1424 }
1425 if ( !$this->current_user_token_valid( $request ) ) {
1426 return $this->invalid_nonce();
1427 }
1428 return $this->get_app_list();
1429 }
1430
1431 public function app_table_meta( $request ) {
1432 $dbs = $request->get_param( 'dbs' );
1433 $tbl = $request->get_param( 'tbl' );
1434 $waa = $request->get_param( 'waa' );
1435 if ( !$this->current_user_can_access() ) {
1436 return $this->unauthorized();
1437 }
1438 if ( !$this->current_user_token_valid( $request ) ) {
1439 return $this->invalid_nonce();
1440 }
1441 $table_api = new WPDA_Table();
1442 return $this->WPDA_Rest_Response( '', $table_api->get_table_meta_data( $dbs, $tbl, $waa ) );
1443 }
1444
1445 public function app_create( $request ) {
1446 if ( !$this->current_user_can_access() ) {
1447 return $this->unauthorized();
1448 }
1449 if ( !$this->current_user_token_valid( $request ) ) {
1450 return $this->invalid_nonce();
1451 }
1452 // App details
1453 $app_name = $request->get_param( 'app_name' );
1454 $app_title = $request->get_param( 'app_title' );
1455 $app_type = $request->get_param( 'app_type' );
1456 $app_settings = $request->get_param( 'app_settings' );
1457 // App container
1458 $app_dbs = $request->get_param( 'app_dbs' );
1459 $app_tbl = $request->get_param( 'app_tbl' );
1460 $app_cls = $request->get_param( 'app_cls' );
1461 $app_table = $request->get_param( 'app_table' );
1462 $app_query = $request->get_param( 'app_query' );
1463 return $this->do_app_create(
1464 $app_name,
1465 $app_title,
1466 $app_type,
1467 $app_settings,
1468 $app_dbs,
1469 $app_tbl,
1470 $app_cls,
1471 $app_table,
1472 $app_query
1473 );
1474 }
1475
1476 public function app_createapp( $request ) {
1477 if ( !$this->current_user_can_access() ) {
1478 return $this->unauthorized();
1479 }
1480 if ( !$this->current_user_token_valid( $request ) ) {
1481 return $this->invalid_nonce();
1482 }
1483 $app_name = $request->get_param( 'app_name' );
1484 $app_title = $request->get_param( 'app_title' );
1485 $app_type = $request->get_param( 'app_type' );
1486 $app_settings = $request->get_param( 'app_settings' );
1487 $app_apps = $request->get_param( 'app_apps' );
1488 return $this->do_app_createapp(
1489 $app_name,
1490 $app_title,
1491 $app_type,
1492 $app_settings,
1493 $app_apps
1494 );
1495 }
1496
1497 public function app_remove( $request ) {
1498 if ( !$this->current_user_can_access() ) {
1499 return $this->unauthorized();
1500 }
1501 if ( !$this->current_user_token_valid( $request ) ) {
1502 return $this->invalid_nonce();
1503 }
1504 $app_id = $request->get_param( 'app_id' );
1505 return $this->do_app_remove( $app_id );
1506 }
1507
1508 public function app_save( $request ) {
1509 if ( !$this->current_user_can_access() ) {
1510 return $this->unauthorized();
1511 }
1512 if ( !$this->current_user_token_valid( $request ) ) {
1513 return $this->invalid_nonce();
1514 }
1515 // App details
1516 $app_id = $request->get_param( 'app_id' );
1517 $app_name = $request->get_param( 'app_name' );
1518 $app_title = $request->get_param( 'app_title' );
1519 $app_type = $request->get_param( 'app_type' );
1520 $app_settings = $request->get_param( 'app_settings' );
1521 $app_add_to_menu = $request->get_param( 'app_add_to_menu' );
1522 // App container
1523 $app_dbs = $request->get_param( 'app_dbs' );
1524 $app_tbl = $request->get_param( 'app_tbl' );
1525 $app_cls = $request->get_param( 'app_cls' );
1526 $app_query = $request->get_param( 'app_query' );
1527 return $this->do_app_save(
1528 $app_id,
1529 $app_name,
1530 $app_title,
1531 $app_type,
1532 $app_settings,
1533 $app_add_to_menu,
1534 $app_dbs,
1535 $app_tbl,
1536 $app_cls,
1537 $app_query
1538 );
1539 }
1540
1541 public function app_saveapp( $request ) {
1542 if ( !$this->current_user_can_access() ) {
1543 return $this->unauthorized();
1544 }
1545 if ( !$this->current_user_token_valid( $request ) ) {
1546 return $this->invalid_nonce();
1547 }
1548 $app_id = $request->get_param( 'app_id' );
1549 $app_name = $request->get_param( 'app_name' );
1550 $app_title = $request->get_param( 'app_title' );
1551 $app_type = $request->get_param( 'app_type' );
1552 $app_settings = $request->get_param( 'app_settings' );
1553 $app_add_to_menu = $request->get_param( 'app_add_to_menu' );
1554 $app_apps = $request->get_param( 'app_apps' );
1555 return $this->do_app_saveapp(
1556 $app_id,
1557 $app_name,
1558 $app_title,
1559 $app_type,
1560 $app_settings,
1561 $app_add_to_menu,
1562 $app_apps
1563 );
1564 }
1565
1566 private function do_app_settings(
1567 $app_id,
1568 $cnt_id,
1569 $target,
1570 $settings,
1571 $chart,
1572 $map,
1573 $theme
1574 ) {
1575 if ( 1 > $app_id || 1 > $cnt_id || 'table' !== $target && 'form' !== $target && 'rform' !== $target && 'theme' !== $target && 'chart' !== $target && 'map' !== $target ) {
1576 return $this->bad_request();
1577 }
1578 if ( null === $settings || '' === $settings ) {
1579 // Perform reset
1580 switch ( $target ) {
1581 case 'table':
1582 $error_msg = WPDA_App_Container_Model::update_table_settings( $cnt_id, null );
1583 if ( '' !== $error_msg ) {
1584 return new \WP_Error('error', $error_msg, array(
1585 'status' => 403,
1586 ));
1587 }
1588 break;
1589 case 'form':
1590 $error_msg = WPDA_App_Container_Model::update_form_settings( $cnt_id, null );
1591 if ( '' !== $error_msg ) {
1592 return new \WP_Error('error', $error_msg, array(
1593 'status' => 403,
1594 ));
1595 }
1596 break;
1597 case 'chart':
1598 $error_msg = WPDA_App_Container_Model::update_chart_settings( $cnt_id, null );
1599 if ( '' !== $error_msg ) {
1600 return new \WP_Error('error', $error_msg, array(
1601 'status' => 403,
1602 ));
1603 }
1604 break;
1605 case 'map':
1606 $error_msg = WPDA_App_Container_Model::update_map_settings( $cnt_id, null );
1607 if ( '' !== $error_msg ) {
1608 return new \WP_Error('error', $error_msg, array(
1609 'status' => 403,
1610 ));
1611 }
1612 break;
1613 case 'theme':
1614 $error_msg = WPDA_App_Model::update_theme( $app_id, null );
1615 if ( '' !== $error_msg ) {
1616 return new \WP_Error('error', $error_msg, array(
1617 'status' => 403,
1618 ));
1619 }
1620 break;
1621 default:
1622 return $this->bad_request();
1623 }
1624 return $this->WPDA_Rest_Response( __( 'Reset was successful', 'wp-data-access' ) );
1625 }
1626 if ( 'table' === $target ) {
1627 // Update table settings
1628 $error_msg = WPDA_App_Container_Model::update_table_settings( $cnt_id, $settings );
1629 if ( '' !== $error_msg ) {
1630 return new \WP_Error('error', $error_msg, array(
1631 'status' => 403,
1632 ));
1633 }
1634 // Update chart settings
1635 $error_msg = WPDA_App_Container_Model::update_chart_settings( $cnt_id, $chart );
1636 if ( '' !== $error_msg ) {
1637 return new \WP_Error('error', $error_msg, array(
1638 'status' => 403,
1639 ));
1640 }
1641 // Update map settings
1642 $error_msg = WPDA_App_Container_Model::update_map_settings( $cnt_id, $map );
1643 if ( '' !== $error_msg ) {
1644 return new \WP_Error('error', $error_msg, array(
1645 'status' => 403,
1646 ));
1647 }
1648 } else {
1649 if ( 'rform' === $target ) {
1650 // Update rform settings
1651 $error_msg = WPDA_App_Container_Model::update_rform_settings( $cnt_id, $settings );
1652 if ( '' !== $error_msg ) {
1653 return new \WP_Error('error', $error_msg, array(
1654 'status' => 403,
1655 ));
1656 }
1657 } else {
1658 if ( 'chart' === $target ) {
1659 // Update chart settings
1660 $error_msg = WPDA_App_Container_Model::update_chart_settings( $cnt_id, $settings );
1661 if ( '' !== $error_msg ) {
1662 return new \WP_Error('error', $error_msg, array(
1663 'status' => 403,
1664 ));
1665 }
1666 } else {
1667 if ( 'map' === $target ) {
1668 // Update chart settings
1669 $error_msg = WPDA_App_Container_Model::update_map_settings( $cnt_id, $settings );
1670 if ( '' !== $error_msg ) {
1671 return new \WP_Error('error', $error_msg, array(
1672 'status' => 403,
1673 ));
1674 }
1675 } else {
1676 if ( 'form' === $target ) {
1677 // Update form settings
1678 $error_msg = WPDA_App_Container_Model::update_form_settings( $cnt_id, $settings );
1679 if ( '' !== $error_msg ) {
1680 return new \WP_Error('error', $error_msg, array(
1681 'status' => 403,
1682 ));
1683 }
1684 }
1685 }
1686 }
1687 }
1688 }
1689 $error_msg = WPDA_App_Model::update_theme( $app_id, $theme );
1690 if ( '' !== $error_msg ) {
1691 return new \WP_Error('error', $error_msg, array(
1692 'status' => 403,
1693 ));
1694 }
1695 return $this->WPDA_Rest_Response( __( 'Successfully saved settings', 'wp-data-access' ) );
1696 }
1697
1698 private function do_app_remove( $app_id ) {
1699 WPDA_App_Apps_Model::delete( $app_id, true );
1700 WPDA_App_Container_Model::delete( $app_id );
1701 WPDA_App_Model::delete( $app_id );
1702 return $this->WPDA_Rest_Response( __( 'Successfully deleted app', 'wp-data-access' ) );
1703 }
1704
1705 private function do_app_create(
1706 $app_name,
1707 $app_title,
1708 $app_type,
1709 $app_settings,
1710 $app_dbs,
1711 $app_tbl,
1712 $app_cls,
1713 $app_table,
1714 $app_query
1715 ) {
1716 // Add app
1717 $insert = WPDA_App_Model::create(
1718 $app_name,
1719 $app_title,
1720 $app_type,
1721 $app_settings
1722 );
1723 if ( false !== $insert['app_id'] ) {
1724 $app_id = $insert['app_id'];
1725 // Add app container
1726 $container = WPDA_App_Container_Model::create(
1727 $app_id,
1728 $app_dbs,
1729 $app_tbl,
1730 json_encode( $app_cls ),
1731 $app_title,
1732 0,
1733 $app_table,
1734 null,
1735 $app_query
1736 );
1737 if ( false !== $container['cnt_id'] ) {
1738 // App and container successfully saved
1739 return $this->WPDA_Rest_Response( __( 'Successfully saved changes', 'wp-data-access' ) );
1740 } else {
1741 // Insert failed
1742 // Remove previously created app
1743 WPDA_App_Model::delete( $app_id );
1744 return new \WP_Error('error', $container['msg'], array(
1745 'status' => 403,
1746 ));
1747 }
1748 } else {
1749 // Insert failed
1750 return new \WP_Error('error', $insert['msg'], array(
1751 'status' => 403,
1752 ));
1753 }
1754 }
1755
1756 private function do_app_createapp(
1757 $app_name,
1758 $app_title,
1759 $app_type,
1760 $app_settings,
1761 $app_apps
1762 ) {
1763 // Add app
1764 $insert = WPDA_App_Model::create(
1765 $app_name,
1766 $app_title,
1767 $app_type,
1768 $app_settings
1769 );
1770 if ( false !== $insert['app_id'] ) {
1771 // Add apps
1772 if ( is_array( $app_apps ) ) {
1773 $app_id = $insert['app_id'];
1774 foreach ( $app_apps as $index => $app_id_detail ) {
1775 // Insert app
1776 WPDA_App_Apps_Model::create( $app_id, $app_id_detail, $index );
1777 }
1778 }
1779 // App and details successfully saved
1780 return $this->WPDA_Rest_Response( __( 'Successfully saved changes', 'wp-data-access' ) );
1781 } else {
1782 // Insert failed
1783 return new \WP_Error('error', $insert['msg'], array(
1784 'status' => 403,
1785 ));
1786 }
1787 }
1788
1789 private function get_app_init() {
1790 return $this->WPDA_Rest_Response( '', array(
1791 'roles' => $this->get_wp_roles(),
1792 'users' => $this->get_wp_users(),
1793 'lang' => get_option( self::WPDA_APP_DEFAULT_LANG ),
1794 ) );
1795 }
1796
1797 private function get_app_list() {
1798 $dataset = WPDA_App_Model::list();
1799 $context = WPDA_App_Apps_Model::list();
1800 return $this->WPDA_Rest_Response( '', $dataset, $context );
1801 }
1802
1803 private function get_relation_columns( $container ) {
1804 return null;
1805 }
1806
1807 private function reorder_details( $cnt_id_from, $cnt_id_to ) {
1808 return $this->bad_request();
1809 }
1810
1811 private function get_app_apps_meta( $app, $apps ) {
1812 $app_id_details = array_map( function ( $e ) {
1813 if ( isset( $e['app_id_detail'] ) ) {
1814 return $e['app_id_detail'];
1815 }
1816 }, $apps );
1817 $app_titles = array();
1818 foreach ( $app_id_details as $app_id_detail ) {
1819 $app_detail = WPDA_App_Model::get_by_id( $app_id_detail );
1820 if ( isset( $app_detail[0]['app_title'] ) ) {
1821 $app_titles[$app_id_detail] = $app_detail[0]['app_title'];
1822 }
1823 }
1824 $response = array(
1825 'app' => array(
1826 'app' => $app,
1827 'container' => array(),
1828 'apps' => $app_id_details,
1829 'titles' => $app_titles,
1830 ),
1831 );
1832 $response['settings'] = $this->get_table_settings();
1833 return $this->WPDA_Rest_Response( '', $response );
1834 }
1835
1836 private function get_table_settings( $tbl = null, $dbs = null ) {
1837 $settings = new stdClass();
1838 if ( null !== $dbs && null !== $tbl ) {
1839 $settings_db = WPDA_Table_Settings_Model::query( $tbl, $dbs );
1840 if ( isset( $settings_db[0]['wpda_table_settings'] ) ) {
1841 $settings = json_decode( (string) $settings_db[0]['wpda_table_settings'] );
1842 // Remove old settings from response.
1843 unset($settings->form_labels);
1844 unset($settings->list_labels);
1845 unset($settings->custom_settings);
1846 unset($settings->search_settings);
1847 }
1848 }
1849 $settings->env = $this->get_env();
1850 global $wpdb;
1851 $settings->wp = [
1852 'roles' => $this->get_wp_roles(),
1853 'users' => $this->get_wp_users(),
1854 'home' => admin_url( 'admin.php' ),
1855 'tables' => array_values( $wpdb->tables() ),
1856 'date_format' => get_option( 'date_format' ),
1857 'time_format' => get_option( 'time_format' ),
1858 ];
1859 return $settings;
1860 }
1861
1862 private function get_app_container_meta( $app_id, $container, $rel_tab = false ) {
1863 $app = WPDA_App_Model::get_by_id( $app_id );
1864 if ( false === $app ) {
1865 return $this->bad_request();
1866 }
1867 if ( !isset( $container[0]['cnt_dbs'], $container[0]['cnt_tbl'], $container[0]['cnt_cls'] ) ) {
1868 return $this->bad_request();
1869 }
1870 $dbs = $container[0]['cnt_dbs'];
1871 $tbl = $container[0]['cnt_tbl'];
1872 $response = array(
1873 'app' => array(
1874 'app' => $app,
1875 'container' => array_map( function ( $value ) {
1876 $show = WPDA::current_user_is_admin();
1877 if ( !$show ) {
1878 // Hide database and table name in responses for non admin users.
1879 unset($value['cnt_dbs']);
1880 unset($value['cnt_tbl']);
1881 }
1882 return $value;
1883 }, $container ),
1884 'apps' => array(),
1885 ),
1886 );
1887 $access = array(
1888 'select' => array(),
1889 'insert' => array(),
1890 'update' => array(),
1891 'delete' => array(),
1892 );
1893 $cls = WPDA_List_Columns_Cache::get_list_columns( $dbs, $tbl );
1894 $media = $this->get_media( $dbs, $tbl, $cls->get_table_columns() );
1895 $response['columns'] = $cls->get_table_columns();
1896 $response['table_labels'] = $cls->get_table_header_labels();
1897 $response['form_labels'] = $cls->get_table_column_headers();
1898 $response['primary_key'] = $cls->get_table_primary_key();
1899 $response['access'] = $access;
1900 $response['settings'] = $this->get_table_settings( $tbl, $dbs );
1901 $response['media'] = $media['media'];
1902 $response['wp_media'] = $media['wp_media'];
1903 $table_settings = json_decode( (string) $container[0]['cnt_table'], true );
1904 if ( isset( $table_settings['table']['defaultWhere'] ) ) {
1905 $default_where = $table_settings['table']['defaultWhere'];
1906 } else {
1907 $default_where = '';
1908 }
1909 $response['table_info'] = $this->get_table_info( $dbs, $tbl, $default_where );
1910 return $this->WPDA_Rest_Response( '', $response );
1911 }
1912
1913 public function get_app_meta( $app_id ) {
1914 $app = WPDA_App_Model::get_by_id( $app_id );
1915 if ( !isset( $app[0]['app_type'] ) ) {
1916 return $this->bad_request();
1917 }
1918 if ( '5' === $app[0]['app_type'] || 5 === $app[0]['app_type'] ) {
1919 // App container
1920 $apps = WPDA_App_Apps_Model::select_all( $app_id, 0 );
1921 return $this->get_app_apps_meta( $app, $apps );
1922 } else {
1923 // Other container
1924 $container = WPDA_App_Container_Model::select( $app_id, 0 );
1925 if ( !isset( $container[0] ) ) {
1926 return $this->bad_request();
1927 }
1928 return $this->get_app_container_meta( $app_id, $container );
1929 }
1930 }
1931
1932 private function do_app_export_app( $app_id, $main_app_id ) {
1933 global $wpdb;
1934 $quotes = function ( $value ) {
1935 return str_replace( array(
1936 "'",
1937 '\\"',
1938 "\\t",
1939 "\\n",
1940 "\\r\\n",
1941 "\\r"
1942 ), array(
1943 "''",
1944 '\\\\"',
1945 "\\\\t",
1946 "\\\\n",
1947 "\\\\r\\\\n",
1948 "\\\\r"
1949 ), $value );
1950 };
1951 $app = WPDA_App_Model::get_by_id( $app_id );
1952 $app_settings = ( null === $app[0]['app_settings'] ? 'null' : "{$quotes( $app[0]['app_settings'] )}" );
1953 $app_theme = ( null === $app[0]['app_theme'] ? 'null' : "{$quotes( $app[0]['app_theme'] )}" );
1954 $app_sql = <<<SQL
1955 # Import app
1956 insert into `{wp_prefix}wpda_app`
1957 \t(`app_name`
1958 \t,`app_title`
1959 \t,`app_type`
1960 \t,`app_settings`
1961 \t,`app_theme`
1962 \t,`app_add_to_menu`
1963 \t)
1964 values
1965 \t('{$quotes( $app[0]['app_name'] )}'
1966 \t,'{$quotes( $app[0]['app_title'] )}'
1967 \t,{$app[0]['app_type']}
1968 \t,'{$app_settings}'
1969 \t,'{$app_theme}'
1970 \t,{$app[0]['app_add_to_menu']}
1971 \t);
1972
1973 SET @APP_ID = LAST_INSERT_ID();
1974 insert into `wpda_transfer_apps_{$main_app_id}`
1975 values
1976 ({$app[0]['app_id']}
1977 ,(select LAST_INSERT_ID(`app_id`) from `{wp_prefix}wpda_app` order by 1 desc limit 1)
1978 );
1979
1980
1981 SQL;
1982 $containers = WPDA_App_Container_Model::select_all( $app_id );
1983 $containers_sql = '';
1984 foreach ( $containers as $container ) {
1985 $cnt_table = ( null === $container['cnt_table'] ? 'null' : "{$quotes( $container['cnt_table'] )}" );
1986 $cnt_form = ( null === $container['cnt_form'] ? 'null' : "{$quotes( $container['cnt_form'] )}" );
1987 $cnt_relation = ( null === $container['cnt_relation'] ? 'null' : "{$quotes( $container['cnt_relation'] )}" );
1988 // Replace default WordPress database with conversion string
1989 $cnt_dbs = ( $wpdb->dbname === $container['cnt_dbs'] ? '{wp_schema}' : "{$quotes( $container['cnt_dbs'] )}" );
1990 $cnt_table = str_replace( "\"dbs\":\"{$wpdb->dbname}\"", "\"dbs\":\"{wp_schema}\"", $cnt_table );
1991 $cnt_form = str_replace( "\"dbs\":\"{$wpdb->dbname}\"", "\"dbs\":\"{wp_schema}\"", $cnt_form );
1992 $containers_sql .= <<<SQL
1993 # Import app container
1994 insert into `{wp_prefix}wpda_app_container`
1995 \t(`cnt_dbs`
1996 \t,`cnt_tbl`
1997 \t,`cnt_cls`
1998 \t,`cnt_title`
1999 \t,`app_id`
2000 \t,`cnt_seq_nr`
2001 \t,`cnt_table`
2002 \t,`cnt_form`
2003 \t,`cnt_relation`
2004 \t)
2005 values
2006 \t('{$cnt_dbs}'
2007 \t,'{$quotes( $container['cnt_tbl'] )}'
2008 \t,'{$quotes( $container['cnt_cls'] )}'
2009 \t,'{$quotes( $container['cnt_title'] )}'
2010 \t,@APP_ID
2011 \t,{$container['cnt_seq_nr']}
2012 \t,'{$cnt_table}'
2013 \t,'{$cnt_form}'
2014 \t,'{$cnt_relation}'
2015 \t);
2016
2017 insert into `wpda_transfer_containers_{$main_app_id}`
2018 values
2019 ({$container['cnt_id']}
2020 ,(select LAST_INSERT_ID(`cnt_id`) from `{wp_prefix}wpda_app_container` order by 1 desc limit 1)
2021 );
2022
2023
2024 SQL;
2025 }
2026 // Post update: update master container ids
2027 $containers_sql .= <<<SQL
2028 # Update app master container IDs
2029 update `{wp_prefix}wpda_app_container` as a
2030 set a.`cnt_relation` =
2031 (
2032 select replace(
2033 a.`cnt_relation`,
2034 concat('"cnt_id_master":"', b.cnt_id_old, '"'),
2035 concat('"cnt_id_master":"', b.cnt_id_new, '"')
2036 )
2037 from `wpda_transfer_containers_{$main_app_id}` as b
2038 where a.`cnt_relation` like concat('%"cnt_id_master":"', b.cnt_id_old, '"%')
2039 )
2040 where a.`app_id` = @APP_ID
2041 and a.`cnt_relation` is not null;
2042
2043
2044 SQL;
2045 $apps = WPDA_App_Apps_Model::select_all( $app_id );
2046 $apps_sql = '';
2047 foreach ( $apps as $app ) {
2048 $apps_sql .= $this->do_app_export_app( $app['app_id_detail'], $main_app_id );
2049 }
2050 foreach ( $apps as $app ) {
2051 $apps_sql .= <<<SQL
2052 # Import app relationships
2053 insert into `{wp_prefix}wpda_app_apps`
2054 \t(`app_id`
2055 \t,`app_id_detail`
2056 \t,`seq_nr`\t\t\t\t\t
2057 \t)
2058 values
2059 \t((select `app_id_new` from `wpda_transfer_apps_{$main_app_id}` where `app_id_old` = {$app['app_id']})
2060 \t,(select `app_id_new` from `wpda_transfer_apps_{$main_app_id}` where `app_id_old` = {$app['app_id_detail']})
2061 \t,{$app['seq_nr']}\t\t\t\t\t
2062 \t);
2063
2064
2065 SQL;
2066 }
2067 return $app_sql . $containers_sql . $apps_sql;
2068 }
2069
2070 private function do_app_export( $app_id ) {
2071 global $wpdb;
2072 $sql = '';
2073 $begin_sql = <<<SQL
2074 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
2075 /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
2076 /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
2077 /*!40101 SET NAMES {$wpdb->charset} */;
2078
2079 # Create temporary table
2080 CREATE TABLE `wpda_transfer_containers_{$app_id}`
2081 (cnt_id_old bigint(20) unsigned
2082 ,cnt_id_new bigint(20) unsigned
2083 );
2084
2085 CREATE TABLE `wpda_transfer_apps_{$app_id}`
2086 (app_id_old bigint(20) unsigned
2087 ,app_id_new bigint(20) unsigned
2088 );
2089
2090 SET @APP_ID = NULL;
2091
2092
2093 SQL;
2094 $sql .= $this->do_app_export_app( $app_id, $app_id );
2095 $end_sql = <<<SQL
2096 # Drop temporary table
2097 DROP TABLE `wpda_transfer_containers_{$app_id}`;
2098 DROP TABLE `wpda_transfer_apps_{$app_id}`;
2099
2100 /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
2101 /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
2102 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
2103
2104
2105 SQL;
2106 $data = array(
2107 'data' => $begin_sql . $sql . $end_sql,
2108 );
2109 return $this->WPDA_Rest_Response( __( 'App successfully exported', 'wp-data-access' ), $data );
2110 }
2111
2112 private function do_app_copy( $app_id ) {
2113 $copy = WPDA_App_Model::copy( $app_id );
2114 if ( false === $copy['app_id'] ) {
2115 return new \WP_Error('error', $copy['msg'], array(
2116 'status' => 403,
2117 ));
2118 } else {
2119 return $this->WPDA_Rest_Response( __( 'App successfully copied', 'wp-data-access' ) );
2120 }
2121 }
2122
2123 private function do_app_saveapp(
2124 $app_id,
2125 $app_name,
2126 $app_title,
2127 $app_type,
2128 $app_settings,
2129 $app_add_to_menu,
2130 $app_apps
2131 ) {
2132 $error_msg = WPDA_App_Model::update(
2133 $app_id,
2134 $app_name,
2135 $app_title,
2136 $app_type,
2137 $app_settings,
2138 $app_add_to_menu
2139 );
2140 if ( '' !== $error_msg ) {
2141 return new \WP_Error('error', $error_msg, array(
2142 'status' => 403,
2143 ));
2144 }
2145 WPDA_App_Apps_Model::update( $app_id, $app_apps );
2146 return $this->WPDA_Rest_Response( __( 'Changes successfully saved', 'wp-data-access' ) );
2147 }
2148
2149 private function do_app_save(
2150 $app_id,
2151 $app_name,
2152 $app_title,
2153 $app_type,
2154 $app_settings,
2155 $app_add_to_menu,
2156 $app_dbs,
2157 $app_tbl,
2158 $app_cls,
2159 $app_query
2160 ) {
2161 $error_msg = WPDA_App_Model::update(
2162 $app_id,
2163 $app_name,
2164 $app_title,
2165 $app_type,
2166 $app_settings,
2167 $app_add_to_menu
2168 );
2169 if ( '' !== $error_msg ) {
2170 return new \WP_Error('error', $error_msg, array(
2171 'status' => 403,
2172 ));
2173 }
2174 $error_msg = WPDA_App_Container_Model::update_master(
2175 $app_id,
2176 $app_dbs,
2177 $app_tbl,
2178 json_encode( $app_cls ),
2179 $app_query
2180 );
2181 if ( '' !== $error_msg ) {
2182 return new \WP_Error('error', $error_msg, array(
2183 'status' => 403,
2184 ));
2185 }
2186 return $this->WPDA_Rest_Response( __( 'Changes successfully saved', 'wp-data-access' ) );
2187 }
2188
2189 private function main_app_access( $app_id, &$msg = '' ) {
2190 // Get app info
2191 $app = WPDA_App_Model::get_by_id( $app_id );
2192 if ( false === $app ) {
2193 // App not found
2194 $msg = __( 'Bad request', 'wp-data-access' );
2195 return false;
2196 }
2197 // Check access
2198 $app_settings_db = $app[0]['app_settings'];
2199 $app_settings = json_decode( (string) $app_settings_db, true );
2200 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'] ) ) {
2201 // App contain no rest api settings
2202 $msg = __( 'Bad request', 'wp-data-access' );
2203 return false;
2204 }
2205 if ( !$this->current_user_can_access() && 'anonymous' !== $app_settings['rest_api']['authorization'] ) {
2206 // Check authorization
2207 // Check user role
2208 $user_roles = WPDA::get_current_user_roles();
2209 if ( !is_array( $user_roles ) || empty( array_intersect( $app_settings['rest_api']['authorized_roles'], $user_roles ) ) ) {
2210 // Check user login
2211 $user_login = WPDA::get_current_user_login();
2212 if ( !in_array( $user_login, $app_settings['rest_api']['authorized_users'] ) ) {
2213 $msg = __( 'Unauthorized', 'wp-data-access' );
2214 return false;
2215 }
2216 }
2217 }
2218 return true;
2219 }
2220
2221 public function check_app_access(
2222 $app_id,
2223 $cnt_id,
2224 $action,
2225 &$dbs,
2226 &$tbl,
2227 &$msg = '',
2228 &$settings = array()
2229 ) {
2230 if ( !$this->main_app_access( $app_id, $msg ) ) {
2231 return false;
2232 }
2233 // Get container
2234 $container = WPDA_App_Container_Model::get_container( $cnt_id );
2235 if ( !is_array( $container ) || 0 === count( $container ) ) {
2236 // Container not found
2237 $msg = __( 'Bad request', 'wp-data-access' );
2238 return false;
2239 }
2240 if ( 'select' !== $action ) {
2241 $cnt_table = json_decode( (string) $container[0]['cnt_table'], true );
2242 if ( !isset( $cnt_table['table']['transactions'][$action] ) || false === $cnt_table['table']['transactions'][$action] ) {
2243 $cnt_relation = json_decode( (string) $container[0]['cnt_relation'], true );
2244 if ( !(isset( $cnt_relation['cnt_id_master'] ) && $this->check_master_container_access( $cnt_relation['cnt_id_master'], $action )) ) {
2245 $msg = __( 'Unauthorized', 'wp-data-access' );
2246 return false;
2247 }
2248 }
2249 }
2250 // Return database name, table name and columns
2251 $dbs = $container[0]['cnt_dbs'];
2252 $tbl = $container[0]['cnt_tbl'];
2253 $settings = array(
2254 'columns' => json_decode( (string) $container[0]['cnt_cls'], true ),
2255 'table' => json_decode( (string) $container[0]['cnt_table'], true ),
2256 'form' => json_decode( (string) $container[0]['cnt_form'], true ),
2257 );
2258 return true;
2259 }
2260
2261 private function check_master_container_access( $cnt_id, $action ) {
2262 $container = WPDA_App_Container_Model::get_container( $cnt_id );
2263 if ( !is_array( $container ) || 0 === count( $container ) ) {
2264 // Container not found
2265 return false;
2266 }
2267 $cnt_table = json_decode( (string) $container[0]['cnt_table'], true );
2268 if ( !isset( $cnt_table['table']['transactions'][$action] ) || false === $cnt_table['table']['transactions'][$action] ) {
2269 $cnt_relation = json_decode( (string) $container[0]['cnt_relation'], true );
2270 if ( !(isset( $cnt_relation['cnt_id_master'] ) && $this->check_master_container_access( $cnt_relation['cnt_id_master'], $action )) ) {
2271 return false;
2272 }
2273 }
2274 return true;
2275 }
2276
2277 private function process_params(
2278 $where,
2279 $search_custom,
2280 $search_params,
2281 $shortcode_params
2282 ) {
2283 // Process $search_custom > URL parameters
2284 global $wpdb;
2285 foreach ( self::METHODS as $method ) {
2286 $offset = 0;
2287 $search = $method . '[';
2288 while ( ($pos_start = stripos( $where, $search, $offset )) !== false ) {
2289 if ( ($pos_end = stripos( $where, ']', $pos_start )) !== false ) {
2290 // Get filter
2291 $filter = substr( $where, $pos_start, $pos_end - $pos_start + 1 );
2292 // Get name
2293 $arg_name = substr( $where, $pos_start + strlen( $search ), $pos_end - $pos_start - strlen( $search ) );
2294 // Remove quotes from name
2295 if ( substr( $arg_name, 0, 1 ) === "'" && substr( $arg_name, -1 ) === "'" ) {
2296 $arg_name = substr( $arg_name, 1, -1 );
2297 }
2298 // Remove double quotes from name
2299 if ( substr( $arg_name, 0, 1 ) === '"' && substr( $arg_name, -1 ) === '"' ) {
2300 $arg_name = substr( $arg_name, 1, -1 );
2301 }
2302 // Handle GET args
2303 if ( $method === self::METHODS[0] || $method === self::METHODS[2] ) {
2304 if ( isset( $search_custom['get'][$arg_name] ) ) {
2305 $arg_value = sanitize_text_field( wp_unslash( $search_custom['get'][$arg_name] ) );
2306 $where = $wpdb->prepare( substr_replace(
2307 $where,
2308 '%s',
2309 $pos_start,
2310 $pos_end - $pos_start + 1
2311 ), $arg_value );
2312 } else {
2313 if ( $method === self::METHODS[0] ) {
2314 $where = str_replace( $filter, 'null', $where );
2315 }
2316 }
2317 }
2318 // Handle POST args
2319 if ( $method === self::METHODS[1] || $method === self::METHODS[2] ) {
2320 if ( isset( $search_custom['post'][$arg_name] ) ) {
2321 $arg_value = sanitize_text_field( wp_unslash( $search_custom['post'][$arg_name] ) );
2322 $where = $wpdb->prepare( substr_replace(
2323 $where,
2324 '%s',
2325 $pos_start,
2326 $pos_end - $pos_start + 1
2327 ), $arg_value );
2328 } else {
2329 $where = str_replace( $filter, 'null', $where );
2330 }
2331 }
2332 }
2333 $offset = $pos_start + 6;
2334 if ( $offset > strlen( $where ) ) {
2335 $offset = strlen( $where ) - 1;
2336 }
2337 }
2338 }
2339 // Process $search_params > shortcode parameters
2340 if ( is_array( $search_params ) && 1 === count( $search_params ) ) {
2341 $filter_field_name = $this->sanitize_db_identifier( array_keys( $search_params )[0] );
2342 $filter_field_value = sanitize_text_field( $search_params[$filter_field_name] );
2343 $filter_field_name_array = array_map( 'trim', explode( ',', $filter_field_name ) );
2344 //phpcs:ignore - 8.1 proof
2345 $filter_field_value_array = array_map( 'trim', explode( ',', $filter_field_value ) );
2346 //phpcs:ignore - 8.1 proof
2347 if ( count( $filter_field_name_array ) === count( $filter_field_value_array ) ) {
2348 //phpcs:ignore - 8.1 proof
2349 // Add filter to where clause.
2350 for ($i = 0; $i < count( $filter_field_name_array ); $i++) {
2351 // phpcs:ignore Generic.CodeAnalysis.ForLoopWithTestFunctionCall, Squiz.PHP.DisallowSizeFunctionsInLoops
2352 $where .= (( '' === $where ? '' : ' and ' )) . $wpdb->prepare(
2353 ' `%1s` like %s ',
2354 // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
2355 array($filter_field_name_array[$i], $filter_field_value_array[$i])
2356 );
2357 }
2358 }
2359 }
2360 // Substitute all shortcode parameters
2361 if ( is_array( $shortcode_params ) ) {
2362 foreach ( $shortcode_params as $column_name => $column_value ) {
2363 $occurences = substr_count( strtolower( $where ), strtolower( "shortcodeParam['{$column_name}']" ) );
2364 if ( 0 < $occurences ) {
2365 $column_values = array();
2366 for ($i = 0; $i < $occurences; $i++) {
2367 $column_values[] = sanitize_text_field( $column_value );
2368 }
2369 $where = $wpdb->prepare( str_ireplace( "shortcodeParam['{$column_name}']", '%s', $where ), $column_values );
2370 }
2371 }
2372 }
2373 // Substitute all unused shortcode parameter calls with null
2374 $offset = 0;
2375 $search = "shortcodeParam['";
2376 while ( ($pos_start = stripos( $where, $search, $offset )) !== false ) {
2377 if ( ($pos_end = stripos( $where, "']", $pos_start )) !== false ) {
2378 $shortcode_value = substr( $where, $pos_start, $pos_end - $pos_start + 2 );
2379 $where = str_ireplace( $shortcode_value, 'null', $where );
2380 }
2381 $offset = $pos_start + 4;
2382 if ( $offset > strlen( $where ) ) {
2383 $offset = strlen( $where ) - 1;
2384 }
2385 }
2386 return $where;
2387 }
2388
2389 }
2390