← All changes
|
jetpack_vendor/automattic/jetpack-sync/src/class-replicastore.php
+61
-72
13.7.2
→
16.3-beta
View file →
| @@ -12,8 +12,12 @@ | ||
| 12 | 12 | use Automattic\Jetpack\Sync\Replicastore\Table_Checksum_Users; |
| 13 | 13 | use Exception; |
| 14 | 14 | use WP_Error; |
| 15 | 15 | |
| 16 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 17 | + exit( 0 ); | |
| 18 | +} | |
| 19 | + | |
| 16 | 20 | /** |
| 17 | 21 | * An implementation of Replicastore Interface which returns data stored in a WordPress.org DB. |
| 18 | 22 | * This is useful to compare values in the local WP DB to values in the synced replica store |
| 19 | 23 | */ |
| @@ -722,8 +726,47 @@ | ||
| 722 | 726 | } |
| 723 | 727 | } |
| 724 | 728 | |
| 725 | 729 | /** |
| 730 | + * Delete metadata with a certain key and value for all objects. | |
| 731 | + * | |
| 732 | + * @access public | |
| 733 | + * | |
| 734 | + * @param string $type Meta type. | |
| 735 | + * @param string $meta_key Meta key. | |
| 736 | + * @param mixed $meta_value Meta value to match. | |
| 737 | + */ | |
| 738 | + public function delete_metadata_by_key_value( $type, $meta_key, $meta_value ) { | |
| 739 | + global $wpdb; | |
| 740 | + | |
| 741 | + $table = _get_meta_table( $type ); | |
| 742 | + if ( ! $table ) { | |
| 743 | + return false; | |
| 744 | + } | |
| 745 | + | |
| 746 | + if ( '' === $meta_value || null === $meta_value || false === $meta_value ) { | |
| 747 | + return false; | |
| 748 | + } | |
| 749 | + | |
| 750 | + $column = sanitize_key( $type . '_id' ); | |
| 751 | + $meta_value = maybe_serialize( $meta_value ); | |
| 752 | + | |
| 753 | + $object_ids = $wpdb->get_col( $wpdb->prepare( 'SELECT DISTINCT %i FROM %i WHERE meta_key = %s AND meta_value = %s', $column, $table, $meta_key, $meta_value ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Direct replica query is needed to identify caches invalidated below. | |
| 754 | + $wpdb->delete( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Direct replica mutation. | |
| 755 | + $table, | |
| 756 | + array( | |
| 757 | + 'meta_key' => $meta_key, | |
| 758 | + 'meta_value' => $meta_value, | |
| 759 | + ), | |
| 760 | + array( '%s', '%s' ) | |
| 761 | + ); | |
| 762 | + | |
| 763 | + foreach ( $object_ids as $object_id ) { | |
| 764 | + wp_cache_delete( $object_id, $type . '_meta' ); | |
| 765 | + } | |
| 766 | + } | |
| 767 | + | |
| 768 | + /** | |
| 726 | 769 | * Retrieve value of a constant based on the constant name. |
| 727 | 770 | * |
| 728 | 771 | * We explicitly return null instead of false if the constant doesn't exist. |
| 729 | 772 | * |
| @@ -1182,85 +1225,28 @@ | ||
| 1182 | 1225 | * |
| 1183 | 1226 | * @return array Checksums. |
| 1184 | 1227 | */ |
| 1185 | 1228 | public function checksum_all( $perform_text_conversion = false ) { |
| 1186 | - $post_checksum = $this->checksum_histogram( 'posts', null, null, null, null, true, '', false, false, $perform_text_conversion ); | |
| 1187 | - $comments_checksum = $this->checksum_histogram( 'comments', null, null, null, null, true, '', false, false, $perform_text_conversion ); | |
| 1188 | - $post_meta_checksum = $this->checksum_histogram( 'postmeta', null, null, null, null, true, '', false, false, $perform_text_conversion ); | |
| 1189 | - $comment_meta_checksum = $this->checksum_histogram( 'commentmeta', null, null, null, null, true, '', false, false, $perform_text_conversion ); | |
| 1190 | - $terms_checksum = $this->checksum_histogram( 'terms', null, null, null, null, true, '', false, false, $perform_text_conversion ); | |
| 1191 | - $term_relationships_checksum = $this->checksum_histogram( 'term_relationships', null, null, null, null, true, '', false, false, $perform_text_conversion ); | |
| 1192 | - $term_taxonomy_checksum = $this->checksum_histogram( 'term_taxonomy', null, null, null, null, true, '', false, false, $perform_text_conversion ); | |
| 1229 | + $all_checksum_tables = Table_Checksum::get_allowed_tables(); | |
| 1193 | 1230 | |
| 1194 | - $result = array( | |
| 1195 | - 'posts' => $this->summarize_checksum_histogram( $post_checksum ), | |
| 1196 | - 'comments' => $this->summarize_checksum_histogram( $comments_checksum ), | |
| 1197 | - 'post_meta' => $this->summarize_checksum_histogram( $post_meta_checksum ), | |
| 1198 | - 'comment_meta' => $this->summarize_checksum_histogram( $comment_meta_checksum ), | |
| 1199 | - 'terms' => $this->summarize_checksum_histogram( $terms_checksum ), | |
| 1200 | - 'term_relationships' => $this->summarize_checksum_histogram( $term_relationships_checksum ), | |
| 1201 | - 'term_taxonomy' => $this->summarize_checksum_histogram( $term_taxonomy_checksum ), | |
| 1202 | - ); | |
| 1231 | + unset( $all_checksum_tables['users'] ); // Handled separately - TODO. | |
| 1232 | + unset( $all_checksum_tables['usermeta'] ); // Handled separately - TODO. | |
| 1233 | + unset( $all_checksum_tables['termmeta'] ); // Handled separately - TODO. | |
| 1234 | + unset( $all_checksum_tables['links'] ); // Not supported yet. Consider removing from default config. | |
| 1235 | + unset( $all_checksum_tables['options'] ); // Not supported yet. Consider removing from default config. | |
| 1203 | 1236 | |
| 1204 | - /** | |
| 1205 | - * WooCommerce tables | |
| 1206 | - */ | |
| 1237 | + $all_checksum_tables = array_unique( array_keys( $all_checksum_tables ) ); | |
| 1207 | 1238 | |
| 1208 | - /** | |
| 1209 | - * On WordPress.com, we can't directly check if the site has support for WooCommerce. | |
| 1210 | - * Having the option to override the functionality here helps with syncing WooCommerce tables. | |
| 1211 | - * | |
| 1212 | - * @since 10.1 | |
| 1213 | - * | |
| 1214 | - * @param bool If we should we force-enable WooCommerce tables support. | |
| 1215 | - */ | |
| 1216 | - $force_woocommerce_support = apply_filters( 'jetpack_table_checksum_force_enable_woocommerce', false ); | |
| 1239 | + $result = array(); | |
| 1217 | 1240 | |
| 1218 | - if ( $force_woocommerce_support || class_exists( 'WooCommerce' ) ) { | |
| 1219 | - /** | |
| 1220 | - * Guard in Try/Catch as it's possible for the WooCommerce class to exist, but | |
| 1221 | - * the tables to not. If we don't do this, the response will be just the exception, without | |
| 1222 | - * returning any valid data. This will prevent us from ever performing a checksum/fix | |
| 1223 | - * for sites like this. | |
| 1224 | - * It's better to just skip the tables in the response, instead of completely failing. | |
| 1225 | - */ | |
| 1226 | - | |
| 1241 | + foreach ( $all_checksum_tables as $table ) { | |
| 1242 | + $result_key = in_array( $table, array( 'postmeta', 'commentmeta' ), true ) ? str_replace( 'meta', '_meta', $table ) : $table; | |
| 1227 | 1243 | try { |
| 1228 | - $woocommerce_order_items_checksum = $this->checksum_histogram( 'woocommerce_order_items' ); | |
| 1229 | - $result['woocommerce_order_items'] = $this->summarize_checksum_histogram( $woocommerce_order_items_checksum ); | |
| 1244 | + $checksum = $this->checksum_histogram( $table, null, null, null, null, true, '', false, false, $perform_text_conversion ); | |
| 1245 | + $result[ $result_key ] = $this->summarize_checksum_histogram( $checksum ); | |
| 1230 | 1246 | } catch ( Exception $ex ) { |
| 1231 | - $result['woocommerce_order_items'] = null; | |
| 1247 | + $result[ $result_key ] = null; | |
| 1232 | 1248 | } |
| 1233 | - | |
| 1234 | - try { | |
| 1235 | - $woocommerce_order_itemmeta_checksum = $this->checksum_histogram( 'woocommerce_order_itemmeta' ); | |
| 1236 | - $result['woocommerce_order_itemmeta'] = $this->summarize_checksum_histogram( $woocommerce_order_itemmeta_checksum ); | |
| 1237 | - } catch ( Exception $ex ) { | |
| 1238 | - $result['woocommerce_order_itemmeta'] = null; | |
| 1239 | - } | |
| 1240 | - | |
| 1241 | - if ( Table_Checksum::enable_woocommerce_hpos_tables() ) { | |
| 1242 | - try { | |
| 1243 | - $woocommerce_hpos_orders_checksum = $this->checksum_histogram( 'wc_orders' ); | |
| 1244 | - $result['wc_orders'] = $this->summarize_checksum_histogram( $woocommerce_hpos_orders_checksum ); | |
| 1245 | - } catch ( Exception $ex ) { | |
| 1246 | - $result['wc_orders'] = null; | |
| 1247 | - } | |
| 1248 | - | |
| 1249 | - try { | |
| 1250 | - $woocommerce_hpos_order_addresses_checksum = $this->checksum_histogram( 'wc_order_addresses' ); | |
| 1251 | - $result['wc_order_addresses'] = $this->summarize_checksum_histogram( $woocommerce_hpos_order_addresses_checksum ); | |
| 1252 | - } catch ( Exception $ex ) { | |
| 1253 | - $result['wc_order_addresses'] = null; | |
| 1254 | - } | |
| 1255 | - | |
| 1256 | - try { | |
| 1257 | - $woocommerce_hpos_order_operational_data_checksum = $this->checksum_histogram( 'wc_order_operational_data' ); | |
| 1258 | - $result['wc_order_operational_data'] = $this->summarize_checksum_histogram( $woocommerce_hpos_order_operational_data_checksum ); | |
| 1259 | - } catch ( Exception $ex ) { | |
| 1260 | - $result['wc_order_operational_data'] = null; | |
| 1261 | - } | |
| 1262 | - } | |
| 1263 | 1249 | } |
| 1264 | 1250 | |
| 1265 | 1251 | return $result; |
| 1266 | 1252 | } |
| @@ -1345,9 +1331,9 @@ | ||
| 1345 | 1331 | |
| 1346 | 1332 | try { |
| 1347 | 1333 | $range_edges = $checksum_table->get_range_edges( $start_id, $end_id ); |
| 1348 | 1334 | } catch ( Exception $ex ) { |
| 1349 | - return new WP_Error( 'invalid_range_edges', '[' . $start_id . '-' . $end_id . ']: ' . $ex->getMessage() ); | |
| 1335 | + return new WP_Error( 'invalid_range_edges', '[' . ( $start_id ?? 'null' ) . '-' . ( $end_id ?? 'null' ) . ']: ' . $ex->getMessage() ); | |
| 1350 | 1336 | } |
| 1351 | 1337 | |
| 1352 | 1338 | if ( $only_range_edges ) { |
| 1353 | 1339 | return $range_edges; |
| @@ -1391,9 +1377,12 @@ | ||
| 1391 | 1377 | $histogram[ $ids_range['min_range'] ] = $batch_checksum; |
| 1392 | 1378 | } else { |
| 1393 | 1379 | $histogram[ "{$ids_range[ 'min_range' ]}-{$ids_range[ 'max_range' ]}" ] = $batch_checksum; |
| 1394 | 1380 | } |
| 1395 | - | |
| 1381 | + // If ids_range['max_range'] is PHP_INT_MAX, we've reached the end of the table. Edge case causing the loop to never end. | |
| 1382 | + if ( PHP_INT_MAX === (int) $ids_range['max_range'] ) { | |
| 1383 | + break; | |
| 1384 | + } | |
| 1396 | 1385 | $previous_max_id = $ids_range['max_range'] + 1; |
| 1397 | 1386 | // If we've reached the max_range lets bail out. |
| 1398 | 1387 | if ( $previous_max_id > $range_edges['max_range'] ) { |
| 1399 | 1388 | break; |