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

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