Completed
Push — update/sync-histogram-term-rel... ( 60c21f...4db924 )
by
unknown
15:15 queued 08:03
created

Terms   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 263
Duplicated Lines 13.31 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

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

14 Methods

Rating   Name   Duplication   Size   Complexity  
A name() 0 3 1
B get_object_by_id() 11 22 6
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

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