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

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