Completed
Push — renovate/slack-web-api-5.x ( f1014a...4f2b74 )
by
unknown
30:35 queued 23:31
created

Terms::init_before_send()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Terms sync module.
4
 *
5
 * @package automattic/jetpack-sync
6
 */
7
8
namespace Automattic\Jetpack\Sync\Modules;
9
10
use Automattic\Jetpack\Sync\Defaults;
11
use Automattic\Jetpack\Sync\Settings;
12
13
/**
14
 * Class to handle sync for terms.
15
 */
16
class Terms extends Module {
17
18
	/**
19
	 * Sync module name.
20
	 *
21
	 * @access public
22
	 *
23
	 * @return string
24
	 */
25
	public function name() {
26
		return 'terms';
27
	}
28
29
	/**
30
	 * The id field in the database.
31
	 *
32
	 * @access public
33
	 *
34
	 * @return string
35
	 */
36
	public function id_field() {
37
		return 'term_id';
38
	}
39
40
	/**
41
	 * The table in the database.
42
	 *
43
	 * @access public
44
	 *
45
	 * @return string
46
	 */
47
	public function table_name() {
48
		return 'term_taxonomy';
49
	}
50
51
	/**
52
	 * Allows WordPress.com servers to retrieve term-related objects via the sync API.
53
	 *
54
	 * @param string $object_type The type of object.
55
	 * @param int    $id          The id of the object.
56
	 *
57
	 * @return bool|object A WP_Term object, or a row from term_taxonomy table depending on object type.
58
	 */
59
	public function get_object_by_id( $object_type, $id ) {
60
		global $wpdb;
61
		$object = false;
62
		if ( 'term' === $object_type ) {
63
			$object = get_term( intval( $id ) );
64
65 View Code Duplication
			if ( is_wp_error( $object ) && $object->get_error_code() === 'invalid_taxonomy' ) {
66
				// Fetch raw term.
67
				$columns = implode( ', ', array_unique( array_merge( Defaults::$default_term_checksum_columns, array( 'term_group' ) ) ) );
68
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
69
				$object = $wpdb->get_row( $wpdb->prepare( "SELECT $columns FROM $wpdb->terms WHERE term_id = %d", $id ) );
70
			}
71
		}
72
73 View Code Duplication
		if ( 'term_taxonomy' === $object_type ) {
74
			$columns = implode( ', ', array_unique( array_merge( Defaults::$default_term_taxonomy_checksum_columns, array( 'description' ) ) ) );
75
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
76
			$object = $wpdb->get_row( $wpdb->prepare( "SELECT $columns FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $id ) );
77
		}
78
79
		if ( 'term_relationships' === $object_type ) {
80
			$columns = implode( ', ', Defaults::$default_term_relationships_checksum_columns );
81
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
82
			$objects = $wpdb->get_results( $wpdb->prepare( "SELECT $columns FROM $wpdb->term_relationships WHERE object_id = %d", $id ) );
83
			$object  = (object) array(
84
				'object_id'     => $id,
85
				'relationships' => array_map( array( $this, 'expand_terms_for_relationship' ), $objects ),
86
			);
87
		}
88
89
		return $object ? $object : false;
90
	}
91
92
	/**
93
	 * Initialize terms action listeners.
94
	 *
95
	 * @access public
96
	 *
97
	 * @param callable $callable Action handler callable.
98
	 */
99
	public function init_listeners( $callable ) {
100
		add_action( 'created_term', array( $this, 'save_term_handler' ), 10, 3 );
101
		add_action( 'edited_term', array( $this, 'save_term_handler' ), 10, 3 );
102
		add_action( 'jetpack_sync_save_term', $callable );
103
		add_action( 'jetpack_sync_add_term', $callable );
104
		add_action( 'delete_term', $callable, 10, 4 );
105
		add_action( 'set_object_terms', $callable, 10, 6 );
106
		add_action( 'deleted_term_relationships', $callable, 10, 2 );
107
		add_filter( 'jetpack_sync_before_enqueue_jetpack_sync_save_term', array( $this, 'filter_blacklisted_taxonomies' ) );
108
		add_filter( 'jetpack_sync_before_enqueue_jetpack_sync_add_term', array( $this, 'filter_blacklisted_taxonomies' ) );
109
	}
110
111
	/**
112
	 * Initialize terms action listeners for full sync.
113
	 *
114
	 * @access public
115
	 *
116
	 * @param callable $callable Action handler callable.
117
	 */
118
	public function init_full_sync_listeners( $callable ) {
119
		add_action( 'jetpack_full_sync_terms', $callable, 10, 2 );
120
	}
121
122
	/**
123
	 * Initialize the module in the sender.
124
	 *
125
	 * @access public
126
	 */
127
	public function init_before_send() {
128
		// Full sync.
129
		add_filter( 'jetpack_sync_before_send_jetpack_full_sync_terms', array( $this, 'expand_term_taxonomy_id' ) );
130
	}
131
132
	/**
133
	 * Enqueue the terms actions for full sync.
134
	 *
135
	 * @access public
136
	 *
137
	 * @param array   $config               Full sync configuration for this sync module.
138
	 * @param int     $max_items_to_enqueue Maximum number of items to enqueue.
139
	 * @param boolean $state                True if full sync has finished enqueueing this module, false otherwise.
140
	 * @return array Number of actions enqueued, and next module state.
141
	 */
142
	public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) {
143
		global $wpdb;
144
		return $this->enqueue_all_ids_as_action( 'jetpack_full_sync_terms', $wpdb->term_taxonomy, 'term_taxonomy_id', $this->get_where_sql( $config ), $max_items_to_enqueue, $state );
145
	}
146
147
	/**
148
	 * Retrieve the WHERE SQL clause based on the module config.
149
	 *
150
	 * @access public
151
	 *
152
	 * @param array $config Full sync configuration for this sync module.
153
	 * @return string WHERE SQL clause, or `null` if no comments are specified in the module config.
154
	 */
155 View Code Duplication
	public function get_where_sql( $config ) {
156
		$where_sql = Settings::get_blacklisted_taxonomies_sql();
157
158
		if ( is_array( $config ) ) {
159
			$where_sql .= ' AND term_taxonomy_id IN (' . implode( ',', array_map( 'intval', $config ) ) . ')';
160
		}
161
162
		return $where_sql;
163
	}
164
165
	/**
166
	 * Retrieve an estimated number of actions that will be enqueued.
167
	 *
168
	 * @access public
169
	 *
170
	 * @param array $config Full sync configuration for this sync module.
171
	 * @return int Number of items yet to be enqueued.
172
	 */
173 View Code Duplication
	public function estimate_full_sync_actions( $config ) {
174
		global $wpdb;
175
176
		$query = "SELECT count(*) FROM $wpdb->term_taxonomy";
177
178
		$where_sql = $this->get_where_sql( $config );
179
		if ( $where_sql ) {
180
			$query .= ' WHERE ' . $where_sql;
181
		}
182
183
		// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
184
		$count = $wpdb->get_var( $query );
185
186
		return (int) ceil( $count / self::ARRAY_CHUNK_SIZE );
187
	}
188
189
	/**
190
	 * Retrieve the actions that will be sent for this module during a full sync.
191
	 *
192
	 * @access public
193
	 *
194
	 * @return array Full sync actions of this module.
195
	 */
196
	public function get_full_sync_actions() {
197
		return array( 'jetpack_full_sync_terms' );
198
	}
199
200
	/**
201
	 * Handler for creating and updating terms.
202
	 *
203
	 * @access public
204
	 *
205
	 * @param int    $term_id  Term ID.
206
	 * @param int    $tt_id    Term taxonomy ID.
207
	 * @param string $taxonomy Taxonomy slug.
208
	 */
209
	public function save_term_handler( $term_id, $tt_id, $taxonomy ) {
210
		if ( class_exists( '\\WP_Term' ) ) {
211
			$term_object = \WP_Term::get_instance( $term_id, $taxonomy );
212
		} else {
213
			$term_object = get_term_by( 'id', $term_id, $taxonomy );
214
		}
215
216
		$current_filter = current_filter();
217
218
		if ( 'created_term' === $current_filter ) {
219
			/**
220
			 * Fires when the client needs to add a new term
221
			 *
222
			 * @since 5.0.0
223
			 *
224
			 * @param object the Term object
225
			 */
226
			do_action( 'jetpack_sync_add_term', $term_object );
227
			return;
228
		}
229
230
		/**
231
		 * Fires when the client needs to update a term
232
		 *
233
		 * @since 4.2.0
234
		 *
235
		 * @param object the Term object
236
		 */
237
		do_action( 'jetpack_sync_save_term', $term_object );
238
	}
239
240
	/**
241
	 * Filter blacklisted taxonomies.
242
	 *
243
	 * @access public
244
	 *
245
	 * @param array $args Hook args.
246
	 * @return array|boolean False if not whitelisted, the original hook args otherwise.
247
	 */
248
	public function filter_blacklisted_taxonomies( $args ) {
249
		$term = $args[0];
250
251
		if ( in_array( $term->taxonomy, Settings::get_setting( 'taxonomies_blacklist' ), true ) ) {
252
			return false;
253
		}
254
255
		return $args;
256
	}
257
258
	/**
259
	 * Expand the term taxonomy IDs to terms within a hook before they are serialized and sent to the server.
260
	 *
261
	 * @access public
262
	 *
263
	 * @param array $args The hook parameters.
264
	 * @return array $args The expanded hook parameters.
265
	 */
266
	public function expand_term_taxonomy_id( $args ) {
267
		list( $term_taxonomy_ids,  $previous_end ) = $args;
268
269
		return array(
270
			'terms'        => get_terms(
271
				array(
272
					'hide_empty'       => false,
273
					'term_taxonomy_id' => $term_taxonomy_ids,
274
					'orderby'          => 'term_taxonomy_id',
275
					'order'            => 'DESC',
276
				)
277
			),
278
			'previous_end' => $previous_end,
279
		);
280
	}
281
282
	/**
283
	 * Gets a term object based on a given row from the term_relationships database table.
284
	 *
285
	 * @access public
286
	 *
287
	 * @param object $relationship A row object from the term_relationships table.
288
	 * @return object|bool A term object, or false if term taxonomy doesn't exist.
289
	 */
290
	public function expand_terms_for_relationship( $relationship ) {
291
		return get_term_by( 'term_taxonomy_id', $relationship->term_taxonomy_id );
292
	}
293
294
}
295