Completed
Push — update/dialogue-focus-on-conte... ( 9f1745...fa862f )
by
unknown
80:03 queued 71:18
created

WPCOM_JSON_API_Update_Taxonomy_Endpoint   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 152
Duplicated Lines 7.89 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 12
loc 152
rs 9.1199
c 0
b 0
f 0
wmc 41
lcom 1
cbo 3

4 Methods

Rating   Name   Duplication   Size   Complexity  
A callback() 0 20 5
C update_taxonomy() 0 43 13
B delete_taxonomy() 0 30 7
C new_taxonomy() 12 48 16

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WPCOM_JSON_API_Update_Taxonomy_Endpoint often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WPCOM_JSON_API_Update_Taxonomy_Endpoint, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
4
	'description' => 'Create a new category.',
5
	'group'       => 'taxonomy',
6
	'stat'        => 'categories:new',
7
8
	'method'      => 'POST',
9
	'path'        => '/sites/%s/categories/new',
10
	'path_labels' => array(
11
		'$site' => '(int|string) Site ID or domain',
12
	),
13
14
	'request_format' => array(
15
		'name'        => '(string) Name of the category',
16
		'description' => '(string) A description of the category',
17
		'parent'      => '(int) ID of the parent category',
18
	),
19
20
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/82974409/categories/new/',
21
	'example_request_data' => array(
22
		'headers' => array(
23
			'authorization' => 'Bearer YOUR_API_TOKEN'
24
		),
25
		'body' => array(
26
			'name' => 'Puppies',
27
		)
28
	)
29
) );
30
31
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
32
	'description' => 'Create a new tag.',
33
	'group'       => 'taxonomy',
34
	'stat'        => 'tags:new',
35
36
	'method'      => 'POST',
37
	'path'        => '/sites/%s/tags/new',
38
	'path_labels' => array(
39
		'$site' => '(int|string) Site ID or domain',
40
	),
41
42
	'request_format' => array(
43
		'name'        => '(string) Name of the tag',
44
		'description' => '(string) A description of the tag',
45
	),
46
47
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/82974409/tags/new/',
48
	'example_request_data' => array(
49
		'headers' => array(
50
			'authorization' => 'Bearer YOUR_API_TOKEN'
51
		),
52
		'body' => array(
53
			'name' => 'Kitties'
54
		)
55
	)
56
) );
57
58
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
59
	'description' => 'Edit a tag.',
60
	'group'       => 'taxonomy',
61
	'stat'        => 'tags:1:POST',
62
63
	'method'      => 'POST',
64
	'path'        => '/sites/%s/tags/slug:%s',
65
	'path_labels' => array(
66
		'$site' => '(int|string) Site ID or domain',
67
		'$tag'  => '(string) The tag slug',
68
	),
69
70
	'request_format' => array(
71
		'name'        => '(string) Name of the tag',
72
		'description' => '(string) A description of the tag',
73
	),
74
75
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/82974409/tags/slug:testing-tag',
76
	'example_request_data' => array(
77
		'headers' => array(
78
			'authorization' => 'Bearer YOUR_API_TOKEN'
79
		),
80
		'body' => array(
81
			'description' => 'Kitties are awesome!'
82
		)
83
	)
84
) );
85
86
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
87
	'description' => 'Edit a category.',
88
	'group'       => 'taxonomy',
89
	'stat'        => 'categories:1:POST',
90
91
	'method'      => 'POST',
92
	'path'        => '/sites/%s/categories/slug:%s',
93
	'path_labels' => array(
94
		'$site'     => '(int|string) Site ID or domain',
95
		'$category' => '(string) The category slug',
96
	),
97
98
	'request_format' => array(
99
		'name'        => '(string) Name of the category',
100
		'description' => '(string) A description of the category',
101
		'parent'      => '(int) ID of the parent category',
102
	),
103
104
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/82974409/categories/slug:testing-category',
105
	'example_request_data' => array(
106
		'headers' => array(
107
			'authorization' => 'Bearer YOUR_API_TOKEN'
108
		),
109
		'body' => array(
110
			'description' => 'Puppies are great!'
111
		)
112
	)
113
) );
114
115
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
116
	'description' => 'Delete a category.',
117
	'group'       => 'taxonomy',
118
	'stat'        => 'categories:1:delete',
119
120
	'method'      => 'POST',
121
	'path'        => '/sites/%s/categories/slug:%s/delete',
122
	'path_labels' => array(
123
		'$site'     => '(int|string) Site ID or domain',
124
		'$category' => '(string) The category slug',
125
	),
126
	'response_format' => array(
127
		'slug'    => '(string) The slug of the deleted category',
128
		'success' => '(bool) Was the operation successful?',
129
	),
130
131
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/82974409/categories/slug:$category/delete',
132
	'example_request_data' => array(
133
		'headers' => array(
134
			'authorization' => 'Bearer YOUR_API_TOKEN'
135
		),
136
	)
137
) );
138
139
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
140
	'description' => 'Delete a tag.',
141
	'group'       => 'taxonomy',
142
	'stat'        => 'tags:1:delete',
143
144
	'method'      => 'POST',
145
	'path'        => '/sites/%s/tags/slug:%s/delete',
146
	'path_labels' => array(
147
		'$site' => '(int|string) Site ID or domain',
148
		'$tag'  => '(string) The tag slug',
149
	),
150
	'response_format' => array(
151
		'slug'    => '(string) The slug of the deleted tag',
152
		'success' => '(bool) Was the operation successful?',
153
	),
154
155
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/82974409/tags/slug:$tag/delete',
156
	'example_request_data' => array(
157
		'headers' => array(
158
			'authorization' => 'Bearer YOUR_API_TOKEN'
159
		),
160
	)
161
) );
162
163
class WPCOM_JSON_API_Update_Taxonomy_Endpoint extends WPCOM_JSON_API_Taxonomy_Endpoint {
164
	// /sites/%s/tags|categories/new    -> $blog_id
165
	// /sites/%s/tags|categories/slug:%s -> $blog_id, $taxonomy_id
166
	// /sites/%s/tags|categories/slug:%s/delete -> $blog_id, $taxonomy_id
167
	function callback( $path = '', $blog_id = 0, $object_id = 0 ) {
168
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
169
		if ( is_wp_error( $blog_id ) ) {
170
			return $blog_id;
171
		}
172
173
		if ( preg_match( '#/tags/#i', $path ) ) {
174
			$taxonomy_type = "post_tag";
175
		} else {
176
			$taxonomy_type = "category";
177
		}
178
179
		if ( $this->api->ends_with( $path, '/delete' ) ) {
180
			return $this->delete_taxonomy( $path, $blog_id, $object_id, $taxonomy_type );
181
		} elseif ( $this->api->ends_with( $path, '/new' ) ) {
182
			return $this->new_taxonomy( $path, $blog_id, $taxonomy_type );
183
		}
184
185
		return $this->update_taxonomy( $path, $blog_id, $object_id, $taxonomy_type );
186
	}
187
188
	// /sites/%s/tags|categories/new    -> $blog_id
189
	function new_taxonomy( $path, $blog_id, $taxonomy_type ) {
190
		$args  = $this->query_args();
191
		$input = $this->input();
192 View Code Duplication
		if ( !is_array( $input ) || !$input || !strlen( $input['name'] ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $input of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
193
			return new WP_Error( 'invalid_input', 'Unknown data passed', 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_input'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
194
		}
195
196
		$user = wp_get_current_user();
197 View Code Duplication
		if ( !$user || is_wp_error( $user ) || !$user->ID ) {
198
			return new WP_Error( 'authorization_required', 'An active access token must be used to manage taxonomies.', 403 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'authorization_required'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
199
		}
200
201
		$tax = get_taxonomy( $taxonomy_type );
202
		if ( !current_user_can( $tax->cap->edit_terms ) ) {
203
			return new WP_Error( 'unauthorized', 'User cannot edit taxonomy', 403 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unauthorized'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
204
		}
205
206
		if ( 'category' !== $taxonomy_type || ! isset( $input['parent'] ) )
207
			$input['parent'] = 0;
208
209 View Code Duplication
		if ( $term = get_term_by( 'name', $input['name'], $taxonomy_type ) ) {
210
			// the same name is allowed as long as the parents are different
211
			if ( $input['parent'] === $term->parent ) {
212
				return new WP_Error( 'duplicate', 'A taxonomy with that name already exists', 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'duplicate'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
213
			}
214
		}
215
216
		$data = wp_insert_term( addslashes( $input['name'] ), $taxonomy_type,
217
			array(
218
		  		'description' => isset( $input['description'] ) ? addslashes( $input['description'] ) : '',
219
		  		'parent'      => $input['parent']
220
			)
221
		);
222
223
		if ( is_wp_error( $data ) )
224
			return $data;
225
226
		$taxonomy = get_term_by( 'id', $data['term_id'], $taxonomy_type );
227
228
		$return   = $this->get_taxonomy( $taxonomy->slug, $taxonomy_type, $args['context'] );
229
		if ( !$return || is_wp_error( $return ) ) {
230
			return $return;
231
		}
232
233
		/** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
234
		do_action( 'wpcom_json_api_objects', 'taxonomies' );
235
		return $return;
236
	}
237
238
	// /sites/%s/tags|categories/slug:%s -> $blog_id, $taxonomy_id
239
	function update_taxonomy( $path, $blog_id, $object_id, $taxonomy_type ) {
240
		$taxonomy = get_term_by( 'slug', $object_id, $taxonomy_type );
241
		$tax      = get_taxonomy( $taxonomy_type );
242
		if ( !current_user_can( $tax->cap->edit_terms ) )
243
			return new WP_Error( 'unauthorized', 'User cannot edit taxonomy', 403 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unauthorized'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
244
245
		if ( !$taxonomy || is_wp_error( $taxonomy ) ) {
246
			return new WP_Error( 'unknown_taxonomy', 'Unknown taxonomy', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unknown_taxonomy'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
247
		}
248
249
		if ( false === term_exists( $object_id, $taxonomy_type ) ) {
250
			return new WP_Error( 'unknown_taxonomy', 'That taxonomy does not exist', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unknown_taxonomy'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
251
		}
252
253
		$args  = $this->query_args();
254
		$input = $this->input( false );
255
		if ( !is_array( $input ) || !$input ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $input of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
256
			return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_input'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
257
		}
258
259
		$update = array();
260
		if ( 'category' === $taxonomy_type && !empty( $input['parent'] ) )
261
			$update['parent'] = $input['parent'];
262
263
		if ( !empty( $input['description'] ) )
264
			$update['description'] = addslashes( $input['description'] );
265
266
		if ( !empty( $input['name'] ) )
267
			$update['name'] = addslashes( $input['name'] );
268
269
270
		$data     = wp_update_term( $taxonomy->term_id, $taxonomy_type, $update );
271
		$taxonomy = get_term_by( 'id', $data['term_id'], $taxonomy_type );
272
273
		$return   = $this->get_taxonomy( $taxonomy->slug, $taxonomy_type, $args['context'] );
274
		if ( !$return || is_wp_error( $return ) ) {
275
			return $return;
276
		}
277
278
		/** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
279
		do_action( 'wpcom_json_api_objects', 'taxonomies' );
280
		return $return;
281
	}
282
283
	// /sites/%s/tags|categories/%s/delete -> $blog_id, $taxonomy_id
284
	function delete_taxonomy( $path, $blog_id, $object_id, $taxonomy_type ) {
285
		$taxonomy = get_term_by( 'slug', $object_id, $taxonomy_type );
286
		$tax      = get_taxonomy( $taxonomy_type );
287
		if ( !current_user_can( $tax->cap->delete_terms ) )
288
			return new WP_Error( 'unauthorized', 'User cannot edit taxonomy', 403 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unauthorized'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
289
290
		if ( !$taxonomy || is_wp_error( $taxonomy ) ) {
291
			return new WP_Error( 'unknown_taxonomy', 'Unknown taxonomy', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unknown_taxonomy'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
292
		}
293
294
		if ( false === term_exists( $object_id, $taxonomy_type ) ) {
295
			return new WP_Error( 'unknown_taxonomy', 'That taxonomy does not exist', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unknown_taxonomy'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
296
		}
297
298
		$args  = $this->query_args();
299
		$return = $this->get_taxonomy( $taxonomy->slug, $taxonomy_type, $args['context'] );
300
		if ( !$return || is_wp_error( $return ) ) {
301
			return $return;
302
		}
303
304
		/** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
305
		do_action( 'wpcom_json_api_objects', 'taxonomies' );
306
307
		wp_delete_term( $taxonomy->term_id, $taxonomy_type );
308
309
		return array(
310
			'slug'    => (string) $taxonomy->slug,
311
			'success' => 'true',
312
		);
313
	}
314
}
315