PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
jetpack / jetpack_vendor / automattic / jetpack-sync / src / modules / class-term-relationships.php

class-term-relationships.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-a.7, at jetpack_vendor/automattic/jetpack-sync/src/modules/class-term-relationships.php

285 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Term relationships sync module.
4 *
5 * @package automattic/jetpack-sync
6 */
7
8 namespace Automattic\Jetpack\Sync\Modules;
9
10 use Automattic\Jetpack\Sync\Listener;
11 use Automattic\Jetpack\Sync\Settings;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit( 0 );
15 }
16
17 /**
18 * Class to handle sync for term relationships.
19 */
20 class Term_Relationships extends Module {
21
22 /**
23 * Max terms to return in one single query
24 *
25 * @access public
26 *
27 * @const int
28 */
29 const QUERY_LIMIT = 1000;
30
31 /**
32 * Max value for a signed INT in MySQL - https://dev.mysql.com/doc/refman/8.0/en/integer-types.html
33 *
34 * @access public
35 *
36 * @const int
37 */
38 const MAX_INT = 2147483647;
39
40 /**
41 * Sync module name.
42 *
43 * @access public
44 *
45 * @return string
46 */
47 public function name() {
48 return 'term_relationships';
49 }
50
51 /**
52 * The id field in the database.
53 *
54 * @access public
55 *
56 * @return string
57 */
58 public function id_field() {
59 return 'object_id';
60 }
61
62 /**
63 * The table name.
64 *
65 * @access public
66 *
67 * @return string
68 * @deprecated since 3.11.0 Use table() instead.
69 */
70 public function table_name() {
71 _deprecated_function( __METHOD__, '3.11.0', 'Automattic\\Jetpack\\Sync\\Term_Relationships->table' );
72 return 'term_relationships';
73 }
74
75 /**
76 * The table in the database with the prefix.
77 *
78 * @access public
79 *
80 * @return string|bool
81 */
82 public function table() {
83 global $wpdb;
84 return $wpdb->term_relationships;
85 }
86
87 /**
88 * Initialize term relationships action listeners for full sync.
89 *
90 * @access public
91 *
92 * @param callable $callable Action handler callable.
93 */
94 public function init_full_sync_listeners( $callable ) {
95 add_action( 'jetpack_full_sync_term_relationships', $callable, 10, 2 );
96 }
97
98 /**
99 * Initialize the module in the sender.
100 *
101 * @access public
102 */
103 public function init_before_send() {
104 // Full sync.
105 add_filter( 'jetpack_sync_before_send_jetpack_full_sync_term_relationships', array( $this, 'expand_term_relationships' ) );
106 }
107
108 /**
109 * Enqueue the term relationships actions for full sync.
110 *
111 * @access public
112 *
113 * @param array $config Full sync configuration for this sync module.
114 * @param int $max_items_to_enqueue Maximum number of items to enqueue.
115 * @param object $last_object_enqueued Last object enqueued.
116 *
117 * @return array Number of actions enqueued, and next module state.
118 * @todo This method has similarities with Automattic\Jetpack\Sync\Modules\Module::enqueue_all_ids_as_action. Refactor to keep DRY.
119 * @see Automattic\Jetpack\Sync\Modules\Module::enqueue_all_ids_as_action
120 */
121 public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $last_object_enqueued ) {
122 global $wpdb;
123 $term_relationships_full_sync_item_size = Settings::get_setting( 'term_relationships_full_sync_item_size' );
124 $limit = min( $max_items_to_enqueue * $term_relationships_full_sync_item_size, self::QUERY_LIMIT );
125 $items_enqueued_count = 0;
126 $last_object_enqueued = $last_object_enqueued ? $last_object_enqueued : array(
127 'object_id' => self::MAX_INT,
128 'term_taxonomy_id' => self::MAX_INT,
129 );
130
131 while ( $limit > 0 ) {
132 /*
133 * SELECT object_id, term_taxonomy_id
134 * FROM $wpdb->term_relationships
135 * WHERE ( object_id = 11 AND term_taxonomy_id < 14 ) OR ( object_id < 11 )
136 * ORDER BY object_id DESC, term_taxonomy_id DESC LIMIT 1000
137 */
138 $objects = $wpdb->get_results( $wpdb->prepare( "SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships WHERE ( object_id = %d AND term_taxonomy_id < %d ) OR ( object_id < %d ) ORDER BY object_id DESC, term_taxonomy_id DESC LIMIT %d", $last_object_enqueued['object_id'], $last_object_enqueued['term_taxonomy_id'], $last_object_enqueued['object_id'], $limit ), ARRAY_A );
139 // Request term relationships in groups of N for efficiency.
140 if ( ! is_countable( $objects ) || count( $objects ) === 0 ) {
141 return array( $items_enqueued_count, true );
142 }
143 $objects_count = count( $objects );
144 $items = array_chunk( $objects, $term_relationships_full_sync_item_size );
145 $last_object_enqueued = $this->bulk_enqueue_full_sync_term_relationships( $items, $last_object_enqueued );
146 $items_enqueued_count += count( $items );
147 $limit = min( $limit - $objects_count, self::QUERY_LIMIT );
148 }
149
150 // We need to do this extra check in case $max_items_to_enqueue * $term_relationships_full_sync_item_size == relationships objects left.
151 $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE ( object_id = %d AND term_taxonomy_id < %d ) OR ( object_id < %d ) ORDER BY object_id DESC, term_taxonomy_id DESC LIMIT %d", $last_object_enqueued['object_id'], $last_object_enqueued['term_taxonomy_id'], $last_object_enqueued['object_id'], 1 ) );
152 if ( 0 === (int) $count ) {
153 return array( $items_enqueued_count, true );
154 }
155
156 return array( $items_enqueued_count, $last_object_enqueued );
157 }
158
159 /**
160 * Return the initial last sent object.
161 *
162 * @return string|array initial status.
163 */
164 public function get_initial_last_sent() {
165 return array(
166 'object_id' => self::MAX_INT,
167 'term_taxonomy_id' => self::MAX_INT,
168 );
169 }
170
171 /**
172 * Given the Module Full Sync Configuration and Status return the next chunk of items to send.
173 *
174 * @param array $config This module Full Sync configuration.
175 * @param array $status This module Full Sync status.
176 * @param int $chunk_size Chunk size.
177 *
178 * @return array|object|null
179 */
180 public function get_next_chunk( $config, $status, $chunk_size ) {
181 global $wpdb;
182
183 return $wpdb->get_results(
184 $wpdb->prepare(
185 "SELECT tr.object_id, tr.term_taxonomy_id
186 FROM $wpdb->term_relationships tr INNER JOIN $wpdb->term_taxonomy tt
187 ON tr.term_taxonomy_id=tt.term_taxonomy_id
188 WHERE " .
189 Settings::get_whitelisted_taxonomies_sql() // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
190 . ' AND ( ( tr.object_id = %d AND tr.term_taxonomy_id < %d ) OR ( tr.object_id < %d ) )
191 ORDER BY tr.object_id DESC, tr.term_taxonomy_id
192 DESC LIMIT %d',
193 $status['last_sent']['object_id'],
194 $status['last_sent']['term_taxonomy_id'],
195 $status['last_sent']['object_id'],
196 $chunk_size
197 ),
198 ARRAY_A
199 );
200 }
201
202 /**
203 * Return last_item to send for Module Full Sync Configuration.
204 *
205 * @param array $config This module Full Sync configuration.
206 *
207 * @return array|object|null
208 */
209 public function get_last_item( $config ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
210 global $wpdb;
211 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
212 return $wpdb->get_results(
213 "SELECT object_id, term_taxonomy_id
214 FROM $wpdb->term_relationships
215 ORDER BY object_id , term_taxonomy_id
216 LIMIT 1",
217 ARRAY_A
218 );
219 }
220
221 /**
222 *
223 * Enqueue all $items within `jetpack_full_sync_term_relationships` actions.
224 *
225 * @param array $items Groups of objects to sync.
226 * @param array $previous_interval_end Last item enqueued.
227 *
228 * @return array Last enqueued object.
229 */
230 public function bulk_enqueue_full_sync_term_relationships( $items, $previous_interval_end ) {
231 $listener = Listener::get_instance();
232 $items_with_previous_interval_end = $this->get_chunks_with_preceding_end( $items, $previous_interval_end );
233 $listener->bulk_enqueue_full_sync_actions( 'jetpack_full_sync_term_relationships', $items_with_previous_interval_end );
234 $last_item = end( $items );
235 return end( $last_item );
236 }
237
238 /**
239 * Retrieve an estimated number of actions that will be enqueued.
240 *
241 * @access public
242 *
243 * @param array $config Full sync configuration for this sync module.
244 * @return int Number of items yet to be enqueued.
245 */
246 public function estimate_full_sync_actions( $config ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
247 global $wpdb;
248
249 $query = "SELECT COUNT(*) FROM $wpdb->term_relationships";
250
251 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
252 $count = (int) $wpdb->get_var( $query );
253
254 return (int) ceil( $count / Settings::get_setting( 'term_relationships_full_sync_item_size' ) );
255 }
256
257 /**
258 * Retrieve the actions that will be sent for this module during a full sync.
259 *
260 * @access public
261 *
262 * @return array Full sync actions of this module.
263 */
264 public function get_full_sync_actions() {
265 return array( 'jetpack_full_sync_term_relationships' );
266 }
267
268 /**
269 * Expand the term relationships within a hook before they are serialized and sent to the server.
270 *
271 * @access public
272 *
273 * @param array $args The hook parameters.
274 * @return array $args The expanded hook parameters.
275 */
276 public function expand_term_relationships( $args ) {
277 list( $term_relationships, $previous_end ) = $args;
278
279 return array(
280 'term_relationships' => $term_relationships,
281 'previous_end' => $previous_end,
282 );
283 }
284 }
285