Completed
Push — fix/full-sync-term-relationshi... ( 87ecdb...fb06c0 )
by
unknown
06:37
created

bulk_enqueue_full_sync_term_relationships()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 5
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
	 * Sync module name.
29
	 *
30
	 * @access public
31
	 *
32
	 * @return string
33
	 */
34
	public function name() {
35
		return 'term_relationships';
36
	}
37
38
	/**
39
	 * The id field in the database.
40
	 *
41
	 * @access public
42
	 *
43
	 * @return string
44
	 */
45
	public function id_field() {
46
		return 'object_id';
47
	}
48
49
	/**
50
	 * The table in the database.
51
	 *
52
	 * @access public
53
	 *
54
	 * @return string
55
	 */
56
	public function table_name() {
57
		return 'term_relationships';
58
	}
59
60
	/**
61
	 * Initialize term relationships action listeners for full sync.
62
	 *
63
	 * @access public
64
	 *
65
	 * @param callable $callable Action handler callable.
66
	 */
67
	public function init_full_sync_listeners( $callable ) {
68
		add_action( 'jetpack_full_sync_term_relationships', $callable, 10, 2 );
69
	}
70
71
	/**
72
	 * Initialize the module in the sender.
73
	 *
74
	 * @access public
75
	 */
76
	public function init_before_send() {
77
		// Full sync.
78
		add_filter( 'jetpack_sync_before_send_jetpack_full_sync_term_relationships', array( $this, 'expand_term_relationships' ) );
79
	}
80
81
	/**
82
	 * Enqueue the term relationships actions for full sync.
83
	 *
84
	 * @access public
85
	 *
86
	 * @todo This method has similarities with Automattic\Jetpack\Sync\Modules\Module::enqueue_all_ids_as_action. Refactor to keep DRY.
87
	 * @see Automattic\Jetpack\Sync\Modules\Module::enqueue_all_ids_as_action
88
	 *
89
	 * @param array   $config               Full sync configuration for this sync module.
90
	 * @param int     $max_items_to_enqueue Maximum number of items to enqueue.
91
	 * @param boolean $state                True if full sync has finished enqueueing this module, false otherwise.
92
	 * @return array Number of actions enqueued, and next module state.
93
	 */
94
	public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) {
95
		global $wpdb;
96
		$term_relationships_batch_size = Settings::get_setting( 'term_relationships_batch_size' );
97
		$items_per_page                = min( $max_items_to_enqueue * $term_relationships_batch_size, self::QUERY_LIMIT );
98
		$chunk_count                   = 0;
99
		$previous_interval_end         = $state ? $state : array(
100
			'object_id'        => '~0',
101
			'term_taxonomy_id' => '~0',
102
		);
103
104
		// Count down from max_id to min_id so we get term relationships for the newest posts and terms first.
105
		// phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
106
		while ( $ids = $wpdb->get_results( "SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships WHERE ( object_id = {$previous_interval_end['object_id']} AND term_taxonomy_id < {$previous_interval_end['term_taxonomy_id']} ) OR ( object_id < {$previous_interval_end['object_id']} ) ORDER BY object_id DESC, term_taxonomy_id DESC LIMIT {$items_per_page}", ARRAY_A ) ) {
107
			// Request term relationships in groups of N for efficiency.
108
			$items                 = array_chunk( $ids, $term_relationships_batch_size );
109
			$remaining_items_count = $max_items_to_enqueue - $chunk_count;
110
111
			// If we hit our row limit, process and return.
112
			if ( $chunk_count + count( $items ) >= $max_items_to_enqueue ) {
113
				$items = array_slice( $items, 0, $remaining_items_count );
114
				$this->bulk_enqueue_full_sync_term_relationships( $items, $previous_interval_end );
115
				$last_chunk = end( $items );
116
				return array( $max_items_to_enqueue, end( $last_chunk ) );
117
			}
118
			$this->bulk_enqueue_full_sync_term_relationships( $items, $previous_interval_end );
119
120
			$chunk_count += count( $items );
121
			// The $ids are ordered in descending order.
122
			$previous_interval_end = end( $ids );
123
			$items_per_page        = min( $remaining_items_count * $term_relationships_batch_size, self::QUERY_LIMIT );
124
		}
125
126
		return array( $chunk_count, true );
127
	}
128
129
	/**
130
	 *
131
	 * Enqueue all $items within `jetpack_full_sync_term_relationships` actions.
132
	 *
133
	 * @param array $items Groups of objects to sync.
134
	 * @param array $previous_interval_end Last item enqueued.
135
	 */
136
	public function bulk_enqueue_full_sync_term_relationships( $items, $previous_interval_end ) {
137
		$listener                         = Listener::get_instance();
138
		$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...
139
		$listener->bulk_enqueue_full_sync_actions( 'jetpack_full_sync_term_relationships', $items_with_previous_interval_end );
140
	}
141
142
	/**
143
	 * Retrieve an estimated number of actions that will be enqueued.
144
	 *
145
	 * @access public
146
	 *
147
	 * @param array $config Full sync configuration for this sync module.
148
	 * @return int Number of items yet to be enqueued.
149
	 */
150
	public function estimate_full_sync_actions( $config ) {
151
		global $wpdb;
152
153
		$query = "SELECT COUNT(*) FROM $wpdb->term_relationships";
154
155
		// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
156
		$count = $wpdb->get_var( $query );
157
158
		return (int) ceil( $count / Settings::get_setting( 'term_relationships_batch_size' ) );
159
	}
160
161
	/**
162
	 * Retrieve the actions that will be sent for this module during a full sync.
163
	 *
164
	 * @access public
165
	 *
166
	 * @return array Full sync actions of this module.
167
	 */
168
	public function get_full_sync_actions() {
169
		return array( 'jetpack_full_sync_term_relationships' );
170
	}
171
172
	/**
173
	 * Expand the term relationships within a hook before they are serialized and sent to the server.
174
	 *
175
	 * @access public
176
	 *
177
	 * @param array $args The hook parameters.
178
	 * @return array $args The expanded hook parameters.
179
	 */
180
	public function expand_term_relationships( $args ) {
181
		list( $term_relationships, $previous_end ) = $args;
182
183
		return array(
184
			'term_relationships' => $term_relationships,
185
			'previous_end'       => $previous_end,
186
		);
187
	}
188
}
189