| @@ -60,8 +60,25 @@ | ||
| 60 | 60 | 'row_count' => $this->get_param( 'row_count' ), |
| 61 | 61 | 'row_count_estimate' => $this->get_param( 'row_count_estimate' ), |
| 62 | 62 | 'media' => $this->get_param( 'media' ), |
| 63 | 63 | 'client_side' => $this->get_param( 'client_side' ), |
| 64 | + 'global_search' => array( | |
| 65 | + 'required' => false, | |
| 66 | + 'type' => 'mixed', | |
| 67 | + 'description' => __( 'Global search', 'wp-data-access' ), | |
| 68 | + 'sanitize_callback' => function ( $param ) { | |
| 69 | + $global_search = array(); | |
| 70 | + foreach ( $param as $key => $value ) { | |
| 71 | + if ( $key === 's' || $key === 'c' ) { | |
| 72 | + $global_search[sanitize_text_field( wp_unslash( $key ) )] = sanitize_text_field( wp_unslash( $value ) ); | |
| 73 | + } | |
| 74 | + } | |
| 75 | + return $global_search; | |
| 76 | + }, | |
| 77 | + 'validate_callback' => function ( $param ) { | |
| 78 | + return is_array( $param ) && isset( $param['s'], $param['c'] ); | |
| 79 | + }, | |
| 80 | + ), | |
| 64 | 81 | ), |
| 65 | 82 | ) ); |
| 66 | 83 | register_rest_route( WPDA_API::WPDA_NAMESPACE, 'table/get', array( |
| 67 | 84 | 'methods' => array('GET', 'POST'), |
| @@ -119,9 +136,9 @@ | ||
| 119 | 136 | |
| 120 | 137 | /** |
| 121 | 138 | * Get table meta info. |
| 122 | 139 | * |
| 123 | - * @param WP_REST_Request $request Rest API request. | |
| 140 | + * @param \WP_REST_Request $request Rest API request. | |
| 124 | 141 | * @return \WP_Error|\WP_REST_Response |
| 125 | 142 | */ |
| 126 | 143 | public function table_meta( $request ) { |
| 127 | 144 | $dbs = $request->get_param( 'dbs' ); |
| @@ -148,9 +165,9 @@ | ||
| 148 | 165 | |
| 149 | 166 | /** |
| 150 | 167 | * Database table query using the full primary key. Must return exactly one row. |
| 151 | 168 | * |
| 152 | - * @param WP_REST_Request $request Rest API request. | |
| 169 | + * @param \WP_REST_Request $request Rest API request. | |
| 153 | 170 | * @return \WP_Error|\WP_REST_Response |
| 154 | 171 | */ |
| 155 | 172 | public function table_get( $request ) { |
| 156 | 173 | $dbs = $request->get_param( 'dbs' ); |
| @@ -183,9 +200,9 @@ | ||
| 183 | 200 | |
| 184 | 201 | /** |
| 185 | 202 | * Insert one row. |
| 186 | 203 | * |
| 187 | - * @param WP_REST_Request $request Rest API request. | |
| 204 | + * @param \WP_REST_Request $request Rest API request. | |
| 188 | 205 | * @return \WP_Error|\WP_REST_Response |
| 189 | 206 | */ |
| 190 | 207 | public function table_insert( $request ) { |
| 191 | 208 | $dbs = $request->get_param( 'dbs' ); |
| @@ -212,9 +229,9 @@ | ||
| 212 | 229 | |
| 213 | 230 | /** |
| 214 | 231 | * Update uses primary key. Must return exactly one row. |
| 215 | 232 | * |
| 216 | - * @param WP_REST_Request $request Rest API request. | |
| 233 | + * @param \WP_REST_Request $request Rest API request. | |
| 217 | 234 | * @return \WP_Error|\WP_REST_Response |
| 218 | 235 | */ |
| 219 | 236 | public function table_update( $request ) { |
| 220 | 237 | $dbs = $request->get_param( 'dbs' ); |
| @@ -247,9 +264,9 @@ | ||
| 247 | 264 | |
| 248 | 265 | /** |
| 249 | 266 | * Delete uses primary key. Must return exactly one row. |
| 250 | 267 | * |
| 251 | - * @param WP_REST_Request $request Rest API request. | |
| 268 | + * @param \WP_REST_Request $request Rest API request. | |
| 252 | 269 | * @return \WP_Error|\WP_REST_Response |
| 253 | 270 | */ |
| 254 | 271 | public function table_delete( $request ) { |
| 255 | 272 | $dbs = $request->get_param( 'dbs' ); |
| @@ -276,12 +293,13 @@ | ||
| 276 | 293 | |
| 277 | 294 | /** |
| 278 | 295 | * Database table query to populate a list of values for a specific table/column. |
| 279 | 296 | * |
| 280 | - * @param WP_REST_Request $request Rest API request. | |
| 297 | + * @param \WP_REST_Request $request Rest API request. | |
| 281 | 298 | * @return \WP_Error|\WP_REST_Response |
| 282 | 299 | */ |
| 283 | 300 | public function table_lov( $request ) { |
| 301 | + return null; | |
| 284 | 302 | } |
| 285 | 303 | |
| 286 | 304 | /** |
| 287 | 305 | * Database table query. |
| @@ -287,9 +305,9 @@ | ||
| 287 | 305 | * Database table query. |
| 288 | 306 | * |
| 289 | 307 | * Supports: searching, ordering and pagination. |
| 290 | 308 | * |
| 291 | - * @param WP_REST_Request $request Rest API request. | |
| 309 | + * @param \WP_REST_Request $request Rest API request. | |
| 292 | 310 | * @return \WP_Error|\WP_REST_Response |
| 293 | 311 | */ |
| 294 | 312 | public function table_select( $request ) { |
| 295 | 313 | $dbs = $request->get_param( 'dbs' ); |
| @@ -305,8 +323,9 @@ | ||
| 305 | 323 | $row_count = $request->get_param( 'row_count' ); |
| 306 | 324 | $row_count_estimate = $request->get_param( 'row_count_estimate' ); |
| 307 | 325 | $media = $request->get_param( 'media' ); |
| 308 | 326 | $client_side = '1' === $request->get_param( 'client_side' ); |
| 327 | + $global_search = $request->get_param( 'global_search' ); | |
| 309 | 328 | if ( $this->check_table_access( |
| 310 | 329 | $dbs, |
| 311 | 330 | $tbl, |
| 312 | 331 | $request, |
| @@ -331,9 +350,12 @@ | ||
| 331 | 350 | array(), |
| 332 | 351 | array(), |
| 333 | 352 | array(), |
| 334 | 353 | $search_data_types, |
| 335 | - $client_side | |
| 354 | + $client_side, | |
| 355 | + array(), | |
| 356 | + array(), | |
| 357 | + $global_search | |
| 336 | 358 | ); |
| 337 | 359 | } else { |
| 338 | 360 | if ( 'rest_cookie_invalid_nonce' === $msg ) { |
| 339 | 361 | return $this->invalid_nonce(); |
| @@ -370,8 +392,9 @@ | ||
| 370 | 392 | $md = array(), |
| 371 | 393 | $m2m_relationship = array(), |
| 372 | 394 | $search_data_types = array() |
| 373 | 395 | ) { |
| 396 | + return null; | |
| 374 | 397 | } |
| 375 | 398 | |
| 376 | 399 | public function lookup( |
| 377 | 400 | $dbs, |
| @@ -412,10 +435,21 @@ | ||
| 412 | 435 | } |
| 413 | 436 | } |
| 414 | 437 | $dynamic_where = array(); |
| 415 | 438 | if ( is_array( $column_dynamic_values ) && 0 < count( $column_dynamic_values ) ) { |
| 439 | + $dynamic_allowed = array(); | |
| 440 | + $dynamic_table = WPDA_List_Columns_Cache::get_list_columns( $dbs, $tbl ); | |
| 441 | + $dynamic_columns = $dynamic_table->get_table_columns(); | |
| 442 | + foreach ( $dynamic_columns as $column ) { | |
| 443 | + if ( isset( $column['column_name'] ) ) { | |
| 444 | + $dynamic_allowed[] = $column['column_name']; | |
| 445 | + } | |
| 446 | + } | |
| 416 | 447 | foreach ( $column_dynamic_values as $key => $value ) { |
| 417 | - $dynamic_where[] = $wpdadb->prepare( " `{$key}` = %s ", $value ); | |
| 448 | + if ( !in_array( $key, $dynamic_allowed, true ) ) { | |
| 449 | + continue; | |
| 450 | + } | |
| 451 | + $dynamic_where[] = $wpdadb->prepare( " %i = %s ", array($key, $value) ); | |
| 418 | 452 | } |
| 419 | 453 | $where .= (( '' === $where ? ' where ' : ' and ' )) . ' (' . implode( ' and ', $dynamic_where ) . ') '; |
| 420 | 454 | } |
| 421 | 455 | $column_count = ( '' === $subquery ? '' : ", stats.total_rows as 'count'" ); |
| @@ -486,9 +520,10 @@ | ||
| 486 | 520 | $tbl, |
| 487 | 521 | $primary_key, |
| 488 | 522 | $media_columns = array(), |
| 489 | 523 | $column_names = array(), |
| 490 | - $default_where = '' | |
| 524 | + $default_where = '', | |
| 525 | + $docs = array() | |
| 491 | 526 | ) { |
| 492 | 527 | $wpdadb = WPDADB::get_db_connection( $dbs ); |
| 493 | 528 | if ( null === $wpdadb ) { |
| 494 | 529 | // Error connecting. |
| @@ -516,10 +551,12 @@ | ||
| 516 | 551 | // Prepare selected column list |
| 517 | 552 | $columns_selected = array(); |
| 518 | 553 | $search_data_types = array(); |
| 519 | 554 | foreach ( $table_columns as $table_column ) { |
| 520 | - $columns_selected[$table_column['column_name']] = true; | |
| 521 | - $search_data_types[$table_column['column_name']] = $table_column['data_type']; | |
| 555 | + if ( isset( $table_column['column_name'], $table_column['data_type'] ) && (in_array( $table_column['column_name'], $column_names ) || empty( $column_names )) ) { | |
| 556 | + $columns_selected[$table_column['column_name']] = true; | |
| 557 | + $search_data_types[$table_column['column_name']] = $table_column['data_type']; | |
| 558 | + } | |
| 522 | 559 | } |
| 523 | 560 | $selected_columns = $this->get_selected_columns( $columns_selected, $search_data_types ); |
| 524 | 561 | $sql = $wpdadb->prepare( "\n select {$selected_columns}\n from `%1s`\n {$where}\n ", array($tbl) ); |
| 525 | 562 | $dataset = $wpdadb->get_results( $sql, 'ARRAY_A' ); |
| @@ -551,8 +588,9 @@ | ||
| 551 | 588 | } |
| 552 | 589 | } |
| 553 | 590 | } |
| 554 | 591 | $context = array(); |
| 592 | + // Add media | |
| 555 | 593 | $context['media'] = $media; |
| 556 | 594 | if ( isset( $debug['debug'] ) && 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_DEBUG ) ) { |
| 557 | 595 | $context['debug'] = $debug['debug']; |
| 558 | 596 | } |
| @@ -773,8 +811,9 @@ | ||
| 773 | 811 | return $sql; |
| 774 | 812 | } |
| 775 | 813 | |
| 776 | 814 | private function get_md( $md, $wpdadb, $m2m_relationship ) { |
| 815 | + return null; | |
| 777 | 816 | } |
| 778 | 817 | |
| 779 | 818 | private function get_global_filter( |
| 780 | 819 | $wpdadb, |
| @@ -816,8 +855,9 @@ | ||
| 816 | 855 | $lookups, |
| 817 | 856 | $m2m_relationship, |
| 818 | 857 | $search_data_types |
| 819 | 858 | ) { |
| 859 | + return null; | |
| 820 | 860 | } |
| 821 | 861 | |
| 822 | 862 | private function get_where( |
| 823 | 863 | $wpdadb, |
| @@ -876,8 +916,12 @@ | ||
| 876 | 916 | if ( !is_array( $column_names ) ) { |
| 877 | 917 | return '*'; |
| 878 | 918 | // select all columns |
| 879 | 919 | } |
| 920 | + if ( 0 === count( $column_names ) ) { | |
| 921 | + return '*'; | |
| 922 | + // select all columns | |
| 923 | + } | |
| 880 | 924 | // Check for geo columns |
| 881 | 925 | $geometryColumns = array(); |
| 882 | 926 | if ( is_array( $search_data_types ) ) { |
| 883 | 927 | foreach ( $search_data_types as $column_name => $search_data_type ) { |
| @@ -934,9 +978,11 @@ | ||
| 934 | 978 | $md = array(), |
| 935 | 979 | $m2m_relationship = array(), |
| 936 | 980 | $search_data_types = array(), |
| 937 | 981 | $client_side = false, |
| 938 | - $geo_radius = array() | |
| 982 | + $geo_radius = array(), | |
| 983 | + $docs = array(), | |
| 984 | + $search_global = null | |
| 939 | 985 | ) { |
| 940 | 986 | $wpdadb = WPDADB::get_db_connection( $dbs ); |
| 941 | 987 | if ( null === $wpdadb ) { |
| 942 | 988 | // Error connecting. |
| @@ -956,10 +1002,31 @@ | ||
| 956 | 1002 | $lookups, |
| 957 | 1003 | $search_columns, |
| 958 | 1004 | $search_column_fns, |
| 959 | 1005 | $search_data_types, |
| 960 | - $geo_radius | |
| 1006 | + $geo_radius, | |
| 1007 | + 'and' | |
| 961 | 1008 | ); |
| 1009 | + if ( $this->current_user_can_access() && isset( $search_global['s'], $search_global['c'] ) ) { | |
| 1010 | + // Perform global search (admins only) | |
| 1011 | + // ??? | |
| 1012 | + $wpda_list_columns = WPDA_List_Columns_Cache::get_list_columns( $dbs, $tbl ); | |
| 1013 | + $table_columns = $wpda_list_columns->get_table_columns(); | |
| 1014 | + $where_global = WPDA::construct_where_clause( | |
| 1015 | + $dbs, | |
| 1016 | + $tbl, | |
| 1017 | + $table_columns, | |
| 1018 | + $search_global['s'], | |
| 1019 | + 'false' !== $search_global['c'] | |
| 1020 | + ); | |
| 1021 | + if ( trim( $where_global ) !== '' ) { | |
| 1022 | + if ( '' !== trim( $where ) && 'where' !== strtolower( substr( trim( $where ), 0, 5 ) ) ) { | |
| 1023 | + $where .= " and {$where_global} "; | |
| 1024 | + } else { | |
| 1025 | + $where .= " where {$where_global} "; | |
| 1026 | + } | |
| 1027 | + } | |
| 1028 | + } | |
| 962 | 1029 | // Build order by. |
| 963 | 1030 | $sqlorder = ''; |
| 964 | 1031 | if ( is_array( $sorting ) && 0 < count( $sorting ) ) { |
| 965 | 1032 | foreach ( $sorting as $sort ) { |
| @@ -1131,8 +1198,9 @@ | ||
| 1131 | 1198 | $search_value, |
| 1132 | 1199 | $m2m_relationship = array(), |
| 1133 | 1200 | $search_data_types = array() |
| 1134 | 1201 | ) { |
| 1202 | + return null; | |
| 1135 | 1203 | } |
| 1136 | 1204 | |
| 1137 | 1205 | public static function add_condition( $where_lines, $operand = 'and' ) { |
| 1138 | 1206 | if ( 0 < count( array_filter( $where_lines ) ) ) { |
| @@ -1148,9 +1216,9 @@ | ||
| 1148 | 1216 | * |
| 1149 | 1217 | * @param string $dbs Database schema name. |
| 1150 | 1218 | * @param string $tbl Database table name. |
| 1151 | 1219 | * @param string $waa With admin actions. |
| 1152 | - * @return array\object | |
| 1220 | + * @return array | object | |
| 1153 | 1221 | */ |
| 1154 | 1222 | public function get_table_meta_data( $dbs, $tbl, $waa ) { |
| 1155 | 1223 | $sql_create_table = ''; |
| 1156 | 1224 | if ( WPDA::current_user_is_admin() ) { |
| @@ -1212,8 +1280,9 @@ | ||
| 1212 | 1280 | 'refresh' => $wp_nonce_refresh, |
| 1213 | 1281 | 'connect' => $connect, |
| 1214 | 1282 | 'copyinprogress' => WPDA_Actions::copy_in_progress(), |
| 1215 | 1283 | 'scroll_offset' => WPDA::get_option( WPDA::OPTION_APPS_SCROLL_OFFSET ), |
| 1284 | + 'upload' => @ini_get( 'upload_max_filesize' ), | |
| 1216 | 1285 | ]; |
| 1217 | 1286 | if ( true === $waa ) { |
| 1218 | 1287 | $settings->wp['aonce'] = implode( '-', array( |
| 1219 | 1288 | wp_create_nonce( 'wpda-export-' . json_encode( $tbl ) ), |
| @@ -1285,9 +1354,9 @@ | ||
| 1285 | 1354 | if ( isset( $table[$action]['authorized_users'] ) && is_array( $table[$action]['authorized_users'] ) && 0 < count( $table[$action]['authorized_users'] ) && in_array( (string) $this->get_user_login(), $table[$action]['authorized_users'] ) ) { |
| 1286 | 1355 | return $table[$action]['methods']; |
| 1287 | 1356 | } |
| 1288 | 1357 | // Check authorized roles |
| 1289 | - if ( isset( $table[$action]['authorized_roles'] ) && is_array( $table[$action]['authorized_roles'] ) && 0 < count( $table[$action]['authorized_roles'] ) && 0 < count( array_intersect( $this->get_user_roles(), $table[$action]['authorized_roles'] ) ) ) { | |
| 1358 | + if ( isset( $table[$action]['authorized_roles'] ) && is_array( $table[$action]['authorized_roles'] ) && 0 < count( $table[$action]['authorized_roles'] ) && 0 < count( array_intersect( ( is_array( $this->get_user_roles() ) ? $this->get_user_roles() : array() ), $table[$action]['authorized_roles'] ) ) ) { | |
| 1290 | 1359 | return $table[$action]['methods']; |
| 1291 | 1360 | } |
| 1292 | 1361 | } |
| 1293 | 1362 | } |
| @@ -1298,9 +1367,9 @@ | ||
| 1298 | 1367 | * Check if access is grant for requested database/table. |
| 1299 | 1368 | * |
| 1300 | 1369 | * @param string $dbs Remote or local database connection string. |
| 1301 | 1370 | * @param string $tbl Database table name. |
| 1302 | - * @param onject $request Request object. | |
| 1371 | + * @param object $request Request object. | |
| 1303 | 1372 | * @param string $action Possible values: select, insert, update, delete. |
| 1304 | 1373 | * @return bool |
| 1305 | 1374 | */ |
| 1306 | 1375 | private function check_table_access( |
| @@ -1325,9 +1394,9 @@ | ||
| 1325 | 1394 | $msg = __( 'Unauthorized', 'wp-data-access' ); |
| 1326 | 1395 | return false; |
| 1327 | 1396 | } else { |
| 1328 | 1397 | if ( !in_array( $request->get_method(), $tables[$dbs][$tbl][$action]['methods'] ) ) { |
| 1329 | - //phpcs:ignore - 8.1 proof | |
| 1398 | + // phpcs:ignore -- 8.1 proof | |
| 1330 | 1399 | $msg = __( 'Unauthorized', 'wp-data-access' ); |
| 1331 | 1400 | return false; |
| 1332 | 1401 | } |
| 1333 | 1402 | } |