Completed
Push — add/eta-to-sync-status ( d17f42...551096 )
by
unknown
06:17
created

Term_Relationships::get_sync_speed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
/**
14
 * Class to handle sync for term relationships.
15
 */
16
class Term_Relationships extends Module {
17
	/**
18
	 *  An estimate of how many rows per second can be synced during a full sync.
19
	 *
20
	 * @access static
21
	 *
22
	 * @var int|null Null if speed is not important in a full sync.
23
	 */
24
	static $sync_speed = 14;
25
	/**
26
	 * Max terms to return in one single query
27
	 *
28
	 * @access public
29
	 *
30
	 * @const int
31
	 */
32
	const QUERY_LIMIT = 1000;
33
34
	/**
35
	 * Max value for a signed INT in MySQL - https://dev.mysql.com/doc/refman/8.0/en/integer-types.html
36
	 *
37
	 * @access public
38
	 *
39
	 * @const int
40
	 */
41
	const MAX_INT = 2147483647;
42
43
	/**
44
	 * Sync module name.
45
	 *
46
	 * @access public
47
	 *
48
	 * @return string
49
	 */
50
	public function name() {
51
		return 'term_relationships';
52
	}
53
54
	/**
55
	 * The id field in the database.
56
	 *
57
	 * @access public
58
	 *
59
	 * @return string
60
	 */
61
	public function id_field() {
62
		return 'object_id';
63
	}
64
65
	/**
66
	 * The table in the database.
67
	 *
68
	 * @access public
69
	 *
70
	 * @return string
71
	 */
72
	public function table_name() {
73
		return 'term_relationships';
74
	}
75
76
	/**
77
	 * Initialize term relationships action listeners for full sync.
78
	 *
79
	 * @access public
80
	 *
81
	 * @param callable $callable Action handler callable.
82
	 */
83
	public function init_full_sync_listeners( $callable ) {
84
		add_action( 'jetpack_full_sync_term_relationships', $callable, 10, 2 );
85
	}
86
87
	/**
88
	 * Initialize the module in the sender.
89
	 *
90
	 * @access public
91
	 */
92
	public function init_before_send() {
93
		// Full sync.
94
		add_filter( 'jetpack_sync_before_send_jetpack_full_sync_term_relationships', array( $this, 'expand_term_relationships' ) );
95
	}
96
97
	/**
98
	 * Enqueue the term relationships actions for full sync.
99
	 *
100
	 * @access public
101
	 *
102
	 * @param array  $config Full sync configuration for this sync module.
103
	 * @param int    $max_items_to_enqueue Maximum number of items to enqueue.
104
	 * @param object $last_object_enqueued Last object enqueued.
105
	 *
106
	 * @return array Number of actions enqueued, and next module state.
107
	 * @todo This method has similarities with Automattic\Jetpack\Sync\Modules\Module::enqueue_all_ids_as_action. Refactor to keep DRY.
108
	 * @see Automattic\Jetpack\Sync\Modules\Module::enqueue_all_ids_as_action
109
	 */
110
	public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $last_object_enqueued ) {
111
		global $wpdb;
112
		$term_relationships_full_sync_item_size = Settings::get_setting( 'term_relationships_full_sync_item_size' );
113
		$limit                                  = min( $max_items_to_enqueue * $term_relationships_full_sync_item_size, self::QUERY_LIMIT );
114
		$items_enqueued_count                   = 0;
115
		$last_object_enqueued                   = $last_object_enqueued ? $last_object_enqueued : array(
116
			'object_id'        => self::MAX_INT,
117
			'term_taxonomy_id' => self::MAX_INT,
118
		);
119
120
		while ( $limit > 0 ) {
121
			/*
122
			 * SELECT object_id, term_taxonomy_id
123
			 *  FROM $wpdb->term_relationships
124
			 *  WHERE ( object_id = 11 AND term_taxonomy_id < 14 ) OR ( object_id < 11 )
125
			 *  ORDER BY object_id DESC, term_taxonomy_id DESC LIMIT 1000
126
			 */
127
			$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 );
128
			// Request term relationships in groups of N for efficiency.
129
			$objects_count = count( $objects );
130
			if ( ! count( $objects ) ) {
131
				return array( $items_enqueued_count, true );
132
			}
133
			$items                 = array_chunk( $objects, $term_relationships_full_sync_item_size );
134
			$last_object_enqueued  = $this->bulk_enqueue_full_sync_term_relationships( $items, $last_object_enqueued );
0 ignored issues
show
Bug introduced by
It seems like $last_object_enqueued can also be of type object; however, Automattic\Jetpack\Sync\...nc_term_relationships() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
135
			$items_enqueued_count += count( $items );
136
			$limit                 = min( $limit - $objects_count, self::QUERY_LIMIT );
137
		}
138
139
		// We need to do this extra check in case $max_items_to_enqueue * $term_relationships_full_sync_item_size == relationships objects left.
140
		$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 ) );
141
		if ( intval( $count ) === 0 ) {
142
			return array( $items_enqueued_count, true );
143
		}
144
145
		return array( $items_enqueued_count, $last_object_enqueued );
146
	}
147
148
	/**
149
	 * Return the initial last sent object.
150
	 *
151
	 * @return string|array initial status.
152
	 */
153
	public function get_initial_last_sent() {
154
		return array(
155
			'object_id'        => self::MAX_INT,
156
			'term_taxonomy_id' => self::MAX_INT,
157
		);
158
	}
159
160
	/**
161
	 * Given the Module Full Sync Configuration and Status return the next chunk of items to send.
162
	 *
163
	 * @param array $config This module Full Sync configuration.
164
	 * @param array $status This module Full Sync status.
165
	 * @param int   $chunk_size Chunk size.
166
	 *
167
	 * @return array|object|null
168
	 */
169
	public function get_next_chunk( $config, $status, $chunk_size ) {
170
		global $wpdb;
171
172
		return $wpdb->get_results(
173
			$wpdb->prepare(
174
				"SELECT object_id, term_taxonomy_id
175
				FROM $wpdb->term_relationships
176
				WHERE ( object_id = %d AND term_taxonomy_id < %d ) OR ( object_id < %d )
177
				ORDER BY object_id DESC, term_taxonomy_id
178
				DESC LIMIT %d",
179
				$status['last_sent']['object_id'],
180
				$status['last_sent']['term_taxonomy_id'],
181
				$status['last_sent']['object_id'],
182
				$chunk_size
183
			),
184
			ARRAY_A
185
		);
186
	}
187
188
	/**
189
	 *
190
	 * Enqueue all $items within `jetpack_full_sync_term_relationships` actions.
191
	 *
192
	 * @param array $items Groups of objects to sync.
193
	 * @param array $previous_interval_end Last item enqueued.
194
	 *
195
	 * @return array Last enqueued object.
196
	 */
197
	public function bulk_enqueue_full_sync_term_relationships( $items, $previous_interval_end ) {
198
		$listener                         = Listener::get_instance();
199
		$items_with_previous_interval_end = $this->get_chunks_with_preceding_end( $items, $previous_interval_end );
0 ignored issues
show
Documentation introduced by
$previous_interval_end is of type array, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
200
		$listener->bulk_enqueue_full_sync_actions( 'jetpack_full_sync_term_relationships', $items_with_previous_interval_end );
201
		$last_item = end( $items );
202
		return end( $last_item );
203
	}
204
205
	/**
206
	 * Retrieve an estimated number of actions that will be enqueued.
207
	 *
208
	 * @access public
209
	 *
210
	 * @param array $config Full sync configuration for this sync module.
211
	 * @return int Number of items yet to be enqueued.
212
	 */
213
	public function estimate_full_sync_actions( $config ) {
214
		global $wpdb;
215
216
		$query = "SELECT COUNT(*) FROM $wpdb->term_relationships";
217
218
		// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
219
		$count = $wpdb->get_var( $query );
220
221
		return (int) ceil( $count / Settings::get_setting( 'term_relationships_full_sync_item_size' ) );
222
	}
223
224
	/**
225
	 * Retrieve the actions that will be sent for this module during a full sync.
226
	 *
227
	 * @access public
228
	 *
229
	 * @return array Full sync actions of this module.
230
	 */
231
	public function get_full_sync_actions() {
232
		return array( 'jetpack_full_sync_term_relationships' );
233
	}
234
235
	/**
236
	 * Expand the term relationships within a hook before they are serialized and sent to the server.
237
	 *
238
	 * @access public
239
	 *
240
	 * @param array $args The hook parameters.
241
	 * @return array $args The expanded hook parameters.
242
	 */
243
	public function expand_term_relationships( $args ) {
244
		list( $term_relationships, $previous_end ) = $args;
245
246
		return array(
247
			'term_relationships' => $term_relationships,
248
			'previous_end'       => $previous_end,
249
		);
250
	}
251
252
	/**
253
	 * Gets the sync speed of a module.
254
	 *
255
	 * @access public
256
	 *
257
	 * @return int
258
	 */
259
	public function get_sync_speed() {
260
		return self::$sync_speed;
261
	}
262
}
263