PluginProbe
WP Data Access – App Builder for Tables, Forms, Dashboards, Charts & Maps / 5.5.87
WP Data Access – App Builder for Tables, Forms, Dashboards, Charts & Maps v5.5.87
5.5.87 5.5.85 5.5.84 5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 All 162 releases
← All changes | WPDataAccess/API/WPDA_Apps.php +120 -3 5.5.82 → 5.5.87 View file →
@@ -280,9 +280,13 @@
280 280 'map' => array(
281 281 'required' => false,
282 282 'type' => 'string',
283 283 'description' => __( 'Map settings - JSON string', 'wp-data-access' ),
284 - 'sanitize_callback' => 'wp_kses_post',
284 + 'sanitize_callback' => function ( $param ) {
285 + $sanitized_settings = $this->sanitize_settings( json_decode( (string) $param, true ) );
286 + // Save sanitized JSON as string
287 + return json_encode( $sanitized_settings );
288 + },
285 289 'validate_callback' => 'rest_validate_request_arg',
286 290 ),
287 291 'chart' => array(
288 292 'required' => false,
@@ -514,8 +518,15 @@
514 518 'permission_callback' => '__return_true',
515 519 'args' => array(
516 520 'dbs_source' => $this->get_param( 'dbs' ),
517 521 'dbs_destination' => $this->get_param( 'dbs' ),
522 + 'appDbId' => array(
523 + 'required' => false,
524 + 'type' => 'integer',
525 + 'description' => __( 'App Id', 'wp-data-access' ),
526 + 'sanitize_callback' => 'absint',
527 + 'validate_callback' => 'rest_validate_request_arg',
528 + ),
518 529 ),
519 530 ) );
520 531 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/lang/get', array(
521 532 'methods' => array('POST'),
@@ -564,8 +575,24 @@
564 575 'validate_callback' => 'rest_validate_request_arg',
565 576 ),
566 577 ),
567 578 ) );
579 + register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/proxy', array(
580 + 'methods' => array('GET'),
581 + 'callback' => array($this, 'app_proxy'),
582 + 'permission_callback' => '__return_true',
583 + 'args' => array(
584 + 'app_id' => $this->get_param( 'app_id' ),
585 + 'cnt_id' => $this->get_param( 'cnt_id' ),
586 + 'url' => array(
587 + 'required' => true,
588 + 'type' => 'string',
589 + 'description' => __( 'URL', 'wp-data-access' ),
590 + 'sanitize_callback' => 'sanitize_text_field',
591 + 'validate_callback' => 'rest_validate_request_arg',
592 + ),
593 + ),
594 + ) );
568 595 // PWA
569 596 register_rest_route( WPDA_API::WPDA_NAMESPACE, 'app/pwa/get', array(
570 597 'methods' => array('POST'),
571 598 'callback' => array($this, 'app_wpa_get'),
@@ -625,8 +652,24 @@
625 652 ),
626 653 ) );
627 654 }
628 655
656 + public function app_proxy( $request ) {
657 + wp_die();
658 + }
659 +
660 + private function detect_image_mime( $body ) {
661 + return null;
662 + }
663 +
664 + private function is_safe_remote_url( $url, $allowed_hosts ) {
665 + return false;
666 + }
667 +
668 + private function is_public_ip( $ip ) {
669 + return false;
670 + }
671 +
629 672 public function app_download( $request ) {
630 673 return $this->WPDA_Rest_Response( 'OK' );
631 674 }
632 675
@@ -1472,8 +1515,68 @@
1472 1515 $renamed = 0;
1473 1516 $debug_mode = 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_DEBUG );
1474 1517 $debug = array();
1475 1518 $errors = array();
1519 + if ( $request->get_param( 'appDbId' ) ) {
1520 + // Update app only
1521 + $appDbId = $request->get_param( 'appDbId' );
1522 + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- plugin table
1523 + $sql = $wpdb->prepare( "update `{$wpdb->prefix}wpda_app_container` set `cnt_dbs` = %s where `cnt_dbs` = %s and app_id = %d", array($dbs_destination, $dbs_source, $appDbId) );
1524 + $result = $wpdb->query( $sql );
1525 + // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
1526 + $renamed += $result;
1527 + if ( $debug_mode ) {
1528 + $debug[] = array(
1529 + 'sql' => $sql,
1530 + 'result' => $result,
1531 + );
1532 + }
1533 + if ( '' !== $wpdb->last_error ) {
1534 + $errors[] = array(
1535 + 'sql' => $sql,
1536 + 'error' => $wpdb->last_error,
1537 + );
1538 + }
1539 + $sql_content = array("update `{$wpdb->prefix}wpda_app_container` set `cnt_table` = replace(`cnt_table`, '\"dbs\":\"%1s\"', '\"dbs\":\"%1s\"') where `cnt_table` like '%\"dbs\":\"%1s\"%' and app_id = %d", "update `{$wpdb->prefix}wpda_app_container` set `cnt_form` = replace(`cnt_form`, '\"dbs\":\"%1s\"', '\"dbs\":\"%1s\"') where `cnt_form` like '%\"dbs\":\"%1s\"%' and app_id = %d");
1540 + foreach ( $sql_content as $sql ) {
1541 + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- plugin table
1542 + $result = $wpdb->query( $wpdb->prepare( $sql, array(
1543 + $dbs_source,
1544 + $dbs_destination,
1545 + $dbs_source,
1546 + $appDbId
1547 + ) ) );
1548 + $renamed += $result;
1549 + if ( $debug_mode ) {
1550 + $debug[] = array(
1551 + 'sql' => $sql,
1552 + 'result' => $result,
1553 + );
1554 + }
1555 + if ( '' !== $wpdb->last_error ) {
1556 + $errors[] = array(
1557 + 'sql' => $sql,
1558 + 'error' => $wpdb->last_error,
1559 + );
1560 + }
1561 + }
1562 + $context = array();
1563 + if ( $debug_mode ) {
1564 + $context['debug'] = $debug;
1565 + }
1566 + if ( 0 < count( $errors ) ) {
1567 + $context['errors'] = $errors;
1568 + return new \WP_Error('error', 'Failed renaming database', array(
1569 + 'status' => 401,
1570 + 'context' => $context,
1571 + ));
1572 + }
1573 + return $this->WPDA_Rest_Response( sprintf(
1574 + /* translators: %s = number of database substitutions */
1575 + __( 'Successfully renamed %s database occurrences', 'wp-data-access' ),
1576 + $renamed
1577 + ), null, $context );
1578 + }
1476 1579 // Rename all occurrences in repository tables and apps
1477 1580 $sqls = array(
1478 1581 "update `{$wpdb->prefix}wpda_publisher` set `pub_schema_name` = %s where `pub_schema_name` = %s",
1479 1582 "update `{$wpdb->prefix}wpda_project_page` set `page_schema_name` = %s where `page_schema_name` = %s",
@@ -2220,8 +2323,17 @@
2220 2323 return $this->get_app_container_meta( $app_id, $container );
2221 2324 }
2222 2325 }
2223 2326
2327 + private function escapeUnicodeForExport( $str ) {
2328 + if ( empty( $str ) ) {
2329 + return $str;
2330 + }
2331 + return preg_replace_callback( '/\\\\(u[0-9a-fA-F]{4})/', function ( $matches ) {
2332 + return '\\\\' . $matches[1];
2333 + }, $str );
2334 + }
2335 +
2224 2336 private function do_app_export_app( $app_id, $main_app_id ) {
2225 2337 global $wpdb;
2226 2338 $quotes = function ( $value ) {
2227 2339 return str_replace( array(
@@ -2231,9 +2343,10 @@
2231 2343 "\\t",
2232 2344 "\\\\n",
2233 2345 "\\n",
2234 2346 "\\r\\n",
2235 - "\\r"
2347 + "\\r",
2348 + "\\d"
2236 2349 ), array(
2237 2350 "''",
2238 2351 '\\\\"',
2239 2352 "\\\\\\t",
@@ -2240,9 +2353,10 @@
2240 2353 "\\\\t",
2241 2354 "\\\\\\n",
2242 2355 "\\\\n",
2243 2356 "\\\\r\\\\n",
2244 - "\\\\r"
2357 + "\\\\r",
2358 + "\\\\\\\\\\d"
2245 2359 ), $value );
2246 2360 };
2247 2361 $app = WPDA_App_Model::get_by_id( $app_id );
2248 2362 $app_settings = ( null === $app[0]['app_settings'] ? 'null' : "{$quotes( $app[0]['app_settings'] )}" );
@@ -2289,8 +2403,11 @@
2289 2403 // Replace default WordPress database with conversion string
2290 2404 $cnt_dbs = ( $wpdb->dbname === $container['cnt_dbs'] ? '{wp_schema}' : "{$quotes( $container['cnt_dbs'] )}" );
2291 2405 $cnt_table = str_replace( "\"dbs\":\"{$wpdb->dbname}\"", "\"dbs\":\"{wp_schema}\"", $cnt_table );
2292 2406 $cnt_form = str_replace( "\"dbs\":\"{$wpdb->dbname}\"", "\"dbs\":\"{wp_schema}\"", $cnt_form );
2407 + // Replace Unicode characters
2408 + $cnt_table = $this->escapeUnicodeForExport( $cnt_table );
2409 + $cnt_form = $this->escapeUnicodeForExport( $cnt_form );
2293 2410 // phpcs:ignore PluginCheck.CodeAnalysis.Heredoc.NotAllowed
2294 2411 $containers_sql .= <<<SQL
2295 2412 # Import app container
2296 2413 insert into `{wp_prefix}wpda_app_container`