Completed
Push — renovate/jest-monorepo ( bd2eaf...d289c3 )
by
unknown
44:07 queued 37:28
created

Terms::table_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
 * 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
	 * Whitelist for taxonomies we want to sync.
19
	 *
20
	 * @access private
21
	 *
22
	 * @var array
23
	 */
24
	private $taxonomy_whitelist;
25
26
	/**
27
	 * Sync module name.
28
	 *
29
	 * @access public
30
	 *
31
	 * @return string
32
	 */
33
	public function name() {
34
		return 'terms';
35
	}
36
37
	/**
38
	 * The id field in the database.
39
	 *
40
	 * @access public
41
	 *
42
	 * @return string
43
	 */
44
	public function id_field() {
45
		return 'term_id';
46
	}
47
48
	/**
49
	 * The table in the database.
50
	 *
51
	 * @access public
52
	 *
53
	 * @return string
54
	 */
55
	public function table_name() {
56
		return 'terms';
57
	}
58
59
	/**
60
	 * Allows WordPress.com servers to retrieve term-related objects via the sync API.
61
	 *
62
	 * @param string $object_type The type of object.
63
	 * @param int    $id          The id of the object.
64
	 *
65
	 * @return bool|object A WP_Term object, or a row from term_taxonomy table depending on object type.
66
	 */
67
	public function get_object_by_id( $object_type, $id ) {
68
		global $wpdb;
69
		$object = false;
70
		if ( 'term' === $object_type ) {
71
			$object = get_term( intval( $id ) );
72
73 View Code Duplication
			if ( is_wp_error( $object ) && $object->get_error_code() === 'invalid_taxonomy' ) {
74
				// Fetch raw term.
75
				$columns = implode( ', ', array_unique( array_merge( Defaults::$default_term_checksum_columns, array( 'term_group' ) ) ) );
0 ignored issues
show
Bug introduced by
The property default_term_checksum_columns cannot be accessed from this context as it is declared private in class Automattic\Jetpack\Sync\Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
76
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
77
				$object = $wpdb->get_row( $wpdb->prepare( "SELECT $columns FROM $wpdb->terms WHERE term_id = %d", $id ) );
78
			}
79
		}
80
81 View Code Duplication
		if ( 'term_taxonomy' === $object_type ) {
82
			$columns = implode( ', ', array_unique( array_merge( Defaults::$default_term_taxonomy_checksum_columns, array( 'description' ) ) ) );
0 ignored issues
show
Bug introduced by
The property default_term_taxonomy_checksum_columns cannot be accessed from this context as it is declared private in class Automattic\Jetpack\Sync\Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
83
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
84
			$object = $wpdb->get_row( $wpdb->prepare( "SELECT $columns FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $id ) );
85
		}
86
87
		if ( 'term_relationships' === $object_type ) {
88
			$columns = implode( ', ', Defaults::$default_term_relationships_checksum_columns );
0 ignored issues
show
Bug introduced by
The property default_term_relationships_checksum_columns cannot be accessed from this context as it is declared private in class Automattic\Jetpack\Sync\Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
89
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
90
			$objects = $wpdb->get_results( $wpdb->prepare( "SELECT $columns FROM $wpdb->term_relationships WHERE object_id = %d", $id ) );
91
			$object  = (object) array(
92
				'object_id'     => $id,
93
				'relationships' => array_map( array( $this, 'expand_terms_for_relationship' ), $objects ),
94
			);
95
		}
96
97
		return $object ? $object : false;
98
	}
99
100
	/**
101
	 * Initialize terms action listeners.
102
	 *
103
	 * @access public
104
	 *
105
	 * @param callable $callable Action handler callable.
106
	 */
107
	public function init_listeners( $callable ) {
108
		add_action( 'created_term', array( $this, 'save_term_handler' ), 10, 3 );
109
		add_action( 'edited_term', array( $this, 'save_term_handler' ), 10, 3 );
110
		add_action( 'jetpack_sync_save_term', $callable );
111
		add_action( 'jetpack_sync_add_term', $callable );
112
		add_action( 'delete_term', $callable, 10, 4 );
113
		add_action( 'set_object_terms', $callable, 10, 6 );
114
		add_action( 'deleted_term_relationships', $callable, 10, 2 );
115
		add_filter( 'jetpack_sync_before_enqueue_jetpack_sync_save_term', array( $this, 'filter_blacklisted_taxonomies' ) );
116
		add_filter( 'jetpack_sync_before_enqueue_jetpack_sync_add_term', array( $this, 'filter_blacklisted_taxonomies' ) );
117
	}
118
119
	/**
120
	 * Initialize terms action listeners for full sync.
121
	 *
122
	 * @access public
123
	 *
124
	 * @param callable $callable Action handler callable.
125
	 */
126
	public function init_full_sync_listeners( $callable ) {
127
		add_action( 'jetpack_full_sync_terms', $callable, 10, 2 );
128
	}
129
130
	/**
131
	 * Initialize the module in the sender.
132
	 *
133
	 * @access public
134
	 */
135
	public function init_before_send() {
136
		// Full sync.
137
		add_filter( 'jetpack_sync_before_send_jetpack_full_sync_terms', array( $this, 'expand_term_taxonomy_id' ) );
138
	}
139
140
	/**
141
	 * Enqueue the terms actions for full sync.
142
	 *
143
	 * @access public
144
	 *
145
	 * @param array   $config               Full sync configuration for this sync module.
146
	 * @param int     $max_items_to_enqueue Maximum number of items to enqueue.
147
	 * @param boolean $state                True if full sync has finished enqueueing this module, false otherwise.
148
	 * @return array Number of actions enqueued, and next module state.
149
	 */
150
	public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) {
151
		global $wpdb;
152
		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 );
153
	}
154
155
	/**
156
	 * Retrieve the WHERE SQL clause based on the module config.
157
	 *
158
	 * @access public
159
	 *
160
	 * @param array $config Full sync configuration for this sync module.
161
	 * @return string WHERE SQL clause, or `null` if no comments are specified in the module config.
162
	 */
163 View Code Duplication
	public function get_where_sql( $config ) {
164
		$where_sql = Settings::get_blacklisted_taxonomies_sql();
165
166
		if ( is_array( $config ) ) {
167
			$where_sql .= ' AND term_taxonomy_id IN (' . implode( ',', array_map( 'intval', $config ) ) . ')';
168
		}
169
170
		return $where_sql;
171
	}
172
173
	/**
174
	 * Retrieve an estimated number of actions that will be enqueued.
175
	 *
176
	 * @access public
177
	 *
178
	 * @param array $config Full sync configuration for this sync module.
179
	 * @return int Number of items yet to be enqueued.
180
	 */
181 View Code Duplication
	public function estimate_full_sync_actions( $config ) {
182
		global $wpdb;
183
184
		$query = "SELECT count(*) FROM $wpdb->term_taxonomy";
185
186
		$where_sql = $this->get_where_sql( $config );
187
		if ( $where_sql ) {
188
			$query .= ' WHERE ' . $where_sql;
189
		}
190
191
		// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
192
		$count = $wpdb->get_var( $query );
193
194
		return (int) ceil( $count / self::ARRAY_CHUNK_SIZE );
195
	}
196
197
	/**
198
	 * Retrieve the actions that will be sent for this module during a full sync.
199
	 *
200
	 * @access public
201
	 *
202
	 * @return array Full sync actions of this module.
203
	 */
204
	public function get_full_sync_actions() {
205
		return array( 'jetpack_full_sync_terms' );
206
	}
207
208
	/**
209
	 * Handler for creating and updating terms.
210
	 *
211
	 * @access public
212
	 *
213
	 * @param int    $term_id  Term ID.
214
	 * @param int    $tt_id    Term taxonomy ID.
215
	 * @param string $taxonomy Taxonomy slug.
216
	 */
217
	public function save_term_handler( $term_id, $tt_id, $taxonomy ) {
218
		if ( class_exists( '\\WP_Term' ) ) {
219
			$term_object = \WP_Term::get_instance( $term_id, $taxonomy );
220
		} else {
221
			$term_object = get_term_by( 'id', $term_id, $taxonomy );
222
		}
223
224
		$current_filter = current_filter();
225
226
		if ( 'created_term' === $current_filter ) {
227
			/**
228
			 * Fires when the client needs to add a new term
229
			 *
230
			 * @since 5.0.0
231
			 *
232
			 * @param object the Term object
233
			 */
234
			do_action( 'jetpack_sync_add_term', $term_object );
235
			return;
236
		}
237
238
		/**
239
		 * Fires when the client needs to update a term
240
		 *
241
		 * @since 4.2.0
242
		 *
243
		 * @param object the Term object
244
		 */
245
		do_action( 'jetpack_sync_save_term', $term_object );
246
	}
247
248
	/**
249
	 * Filter blacklisted taxonomies.
250
	 *
251
	 * @access public
252
	 *
253
	 * @param array $args Hook args.
254
	 * @return array|boolean False if not whitelisted, the original hook args otherwise.
255
	 */
256
	public function filter_blacklisted_taxonomies( $args ) {
257
		$term = $args[0];
258
259
		if ( in_array( $term->taxonomy, Settings::get_setting( 'taxonomies_blacklist' ), true ) ) {
260
			return false;
261
		}
262
263
		return $args;
264
	}
265
266
	/**
267
	 * Set the taxonomy whitelist.
268
	 *
269
	 * @access public
270
	 *
271
	 * @param array $taxonomies The new taxonomyy whitelist.
272
	 */
273
	public function set_taxonomy_whitelist( $taxonomies ) {
274
		$this->taxonomy_whitelist = $taxonomies;
275
	}
276
277
	/**
278
	 * Set module defaults.
279
	 * Define the taxonomy whitelist to be the default one.
280
	 *
281
	 * @access public
282
	 */
283
	public function set_defaults() {
284
		$this->taxonomy_whitelist = Defaults::$default_taxonomy_whitelist;
0 ignored issues
show
Bug introduced by
The property default_taxonomy_whitelist cannot be accessed from this context as it is declared private in class Automattic\Jetpack\Sync\Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
285
	}
286
287
	/**
288
	 * Expand the term taxonomy IDs to terms within a hook before they are serialized and sent to the server.
289
	 *
290
	 * @access public
291
	 *
292
	 * @param array $args The hook parameters.
293
	 * @return array $args The expanded hook parameters.
294
	 */
295
	public function expand_term_taxonomy_id( $args ) {
296
		list( $term_taxonomy_ids,  $previous_end ) = $args;
297
298
		return array(
299
			'terms'        => get_terms(
300
				array(
301
					'hide_empty'       => false,
302
					'term_taxonomy_id' => $term_taxonomy_ids,
303
					'orderby'          => 'term_taxonomy_id',
304
					'order'            => 'DESC',
305
				)
306
			),
307
			'previous_end' => $previous_end,
308
		);
309
	}
310
311
	/**
312
	 * Gets a term object based on a given row from the term_relationships database table.
313
	 *
314
	 * @access public
315
	 *
316
	 * @param object $relationship A row object from the term_relationships table.
317
	 * @return object|bool A term object, or false if term taxonomy doesn't exist.
318
	 */
319
	public function expand_terms_for_relationship( $relationship ) {
320
		return get_term_by( 'term_taxonomy_id', $relationship->term_taxonomy_id );
321
	}
322
}
323