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

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

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