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

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