base_prefix ) && ! Staged_Replace::is_staging_table( $table ); } /** * Capability check. */ public static function can_manage(): bool { return current_user_can( self::required_cap() ); } /** * REST permission callback. * * Accepts the nonce from `X-WP-Nonce` (standard browser fetch) or `_wpnonce` * query string (required for EventSource / SSE which cannot set custom headers). * * @param WP_REST_Request $request REST request. * @return true|WP_Error */ public static function rest_permission( WP_REST_Request $request ) { if ( ! self::can_manage() ) { return new WP_Error( 'spinxqm_forbidden', __( 'Insufficient permissions.', 'spinx-quick-migrate' ), array( 'status' => 403 ) ); } $nonce = (string) $request->get_header( 'x_wp_nonce' ); if ( '' === $nonce ) { $nonce = (string) $request->get_param( '_wpnonce' ); } if ( '' === $nonce || ! wp_verify_nonce( $nonce, 'wp_rest' ) ) { return new WP_Error( 'spinxqm_bad_nonce', __( 'Invalid REST nonce.', 'spinx-quick-migrate' ), array( 'status' => 403 ) ); } return true; } /** * Sanitize table names and validate against real tables. * * @param array $requested Requested table names. * @return array Valid table names belonging to this install. */ public static function sanitize_tables( array $requested ): array { global $wpdb; $all = $wpdb->get_col( 'SHOW TABLES' ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Validate requested tables against the LIVE table list; static query that must not be cached. if ( ! is_array( $all ) ) { $all = array(); } $allow = array_fill_keys( $all, true ); $out = array(); foreach ( $requested as $table ) { $table = sanitize_text_field( (string) $table ); if ( isset( $allow[ $table ] ) && self::is_install_table( $table ) ) { $out[] = $table; } } return array_values( array_unique( $out ) ); } /** * Sanitize bool-like value. * * @param mixed $value Value to interpret as a boolean. * @return bool */ public static function bool( $value ): bool { return filter_var( $value, FILTER_VALIDATE_BOOLEAN ); } }