Completed
Push — branch-8.sync ( b15093 )
by Jeremy
07:09
created

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