Completed
Push — add/script-update-package-vers... ( 38150b...f5f944 )
by
unknown
06:18
created

Terms   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 307
Duplicated Lines 11.4 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 0
Metric Value
dl 35
loc 307
rs 10
c 0
b 0
f 0
wmc 28
lcom 2
cbo 3

17 Methods

Rating   Name   Duplication   Size   Complexity  
A name() 0 3 1
A id_field() 0 3 1
A table_name() 0 3 1
B get_object_by_id() 11 32 7
A init_listeners() 0 11 1
A init_full_sync_listeners() 0 3 1
A init_before_send() 0 4 1
A enqueue_full_sync_actions() 0 4 1
A get_where_sql() 9 9 2
A estimate_full_sync_actions() 15 15 2
A get_full_sync_actions() 0 3 1
A save_term_handler() 0 30 3
A filter_blacklisted_taxonomies() 0 9 2
A set_taxonomy_whitelist() 0 3 1
A set_defaults() 0 3 1
A expand_term_taxonomy_id() 0 15 1
A expand_terms_for_relationship() 0 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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' ) ) ) );
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' ) ) ) );
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 );
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;
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