Completed
Push — add/user-authentication ( 651ac4...684086 )
by
unknown
26:10 queued 18:04
created

Terms   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 285
Duplicated Lines 12.28 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

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

15 Methods

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