Completed
Push — add/stats-package ( c3aabb...99d182 )
by
unknown
148:14 queued 140:08
created

WPCOM_JSON_API_Site_User_Endpoint   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 122
Duplicated Lines 9.84 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 12
loc 122
rs 9.84
c 0
b 0
f 0
wmc 32
lcom 1
cbo 3

3 Methods

Rating   Name   Duplication   Size   Complexity  
B callback() 0 32 9
D update_user() 3 54 19
A get_user() 9 9 4

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
new WPCOM_JSON_API_Site_User_Endpoint( array(
4
	'description' => 'Get details of a user of a site by ID.',
5
	'group'       => '__do_not_document', //'users'
6
	'stat'        => 'sites:1:user',
7
	'method'      => 'GET',
8
	'path'        => '/sites/%s/users/%d',
9
	'path_labels' => array(
10
		'$site'    => '(int|string) Site ID or domain',
11
		'$user_id' => '(int) User ID',
12
	),
13
	'response_format' => WPCOM_JSON_API_Site_User_Endpoint::$user_format,
14
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/30434183/user/23',
15
	'example_request_data' => array(
16
		'headers' => array(
17
			'authorization' => 'Bearer YOUR_API_TOKEN'
18
		),
19
	),
20
	'example_response'     => '{
21
		"ID": 18342963,
22
		"login": "binarysmash",
23
		"email": false,
24
		"name": "binarysmash",
25
		"URL": "http:\/\/binarysmash.wordpress.com",
26
		"avatar_URL": "http:\/\/0.gravatar.com\/avatar\/a178ebb1731d432338e6bb0158720fcc?s=96&d=identicon&r=G",
27
		"profile_URL": "http:\/\/en.gravatar.com\/binarysmash",
28
		"roles": [ "administrator" ]
29
	}'
30
) );
31
32
new WPCOM_JSON_API_Site_User_Endpoint( array(
33
	'description' => 'Get details of a user of a site by login.',
34
	'group'       => 'users',
35
	'stat'        => 'sites:1:user',
36
	'method'      => 'GET',
37
	'path'        => '/sites/%s/users/login:%s',
38
	'path_labels' => array(
39
		'$site'    => '(int|string) The site ID or domain.',
40
		'$user_id' => '(string) The user\'s login.',
41
	),
42
	'response_format' => WPCOM_JSON_API_Site_User_Endpoint::$user_format,
43
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/30434183/user/login:binarysmash',
44
	'example_request_data' => array(
45
		'headers' => array(
46
			'authorization' => 'Bearer YOUR_API_TOKEN'
47
		),
48
	),
49
	'example_response'     => '{
50
		"ID": 18342963,
51
		"login": "binarysmash",
52
		"email": false,
53
		"name": "binarysmash",
54
		"URL": "http:\/\/binarysmash.wordpress.com",
55
		"avatar_URL": "http:\/\/0.gravatar.com\/avatar\/a178ebb1731d432338e6bb0158720fcc?s=96&d=identicon&r=G",
56
		"profile_URL": "http:\/\/en.gravatar.com\/binarysmash",
57
		"roles": [ "administrator" ]
58
	}'
59
) );
60
61
new WPCOM_JSON_API_Site_User_Endpoint( array(
62
	'description' => 'Update details of a user of a site.',
63
	'group'       => 'users',
64
	'stat'        => 'sites:1:user',
65
	'method'      => 'POST',
66
	'path'        => '/sites/%s/users/%d',
67
	'path_labels' => array(
68
		'$site'    => '(int|string) The site ID or domain.',
69
		'$user_id' => '(int) The user\'s ID.',
70
	),
71
	'request_format'  => WPCOM_JSON_API_Site_User_Endpoint::$user_format,
72
	'response_format' => WPCOM_JSON_API_Site_User_Endpoint::$user_format,
73
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/30434183/user/23',
74
	'example_request_data' => array(
75
		'headers' => array(
76
			'authorization' => 'Bearer YOUR_API_TOKEN'
77
		),
78
		'body' => array(
79
			'roles' => array(
80
				array(
81
					'administrator',
82
				)
83
			),
84
			'first_name' => 'Rocco',
85
			'last_name' => 'Tripaldi',
86
		)
87
	),
88
	'example_response'     => '{
89
		"ID": 18342963,
90
		"login": "binarysmash",
91
		"email": false,
92
		"name": "binarysmash",
93
		"URL": "http:\/\/binarysmash.wordpress.com",
94
		"avatar_URL": "http:\/\/0.gravatar.com\/avatar\/a178ebb1731d432338e6bb0158720fcc?s=96&d=identicon&r=G",
95
		"profile_URL": "http:\/\/en.gravatar.com\/binarysmash",
96
		"roles": [ "administrator" ]
97
	}'
98
) );
99
100
class WPCOM_JSON_API_Site_User_Endpoint extends WPCOM_JSON_API_Endpoint {
101
102
	public static $user_format = array(
103
		'ID'           => '(int) The ID of the user',
104
		'login'        => '(string) The login username of the user',
105
		'email'        => '(string) The email of the user',
106
		'name'         => '(string) The name to display for the user',
107
		'first_name'   => '(string) The first name of the user',
108
		'last_name'    => '(string) The last name of the user',
109
		'nice_name'    => '(string) The nice_name to display for the user',
110
		'URL'          => '(string) The primary blog of the user',
111
		'avatar_URL'   => '(url) Gravatar image URL',
112
		'profile_URL'  => '(url) Gravatar Profile URL',
113
		'site_ID'      => '(int) ID of the user\'s primary blog',
114
		'roles'        => '(array|string) The role or roles of the user',
115
	);
116
117
	// /sites/%s/users/%d -> $blog_id, $user_id
118
	function callback( $path = '', $blog_id = 0, $user_id = 0 ) {
119
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
120
		if ( is_wp_error( $blog_id ) ) {
121
			return $blog_id;
122
		}
123
		if ( ! current_user_can_for_blog( $blog_id, 'list_users' ) ) {
124
			return new WP_Error( 'unauthorized', 'User cannot view users for specified site', 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...
125
		}
126
127
		// Get the user by ID or login
128
		$get_by = false !== strpos( $path, '/users/login:' ) ? 'login' : 'id';
129
		$user = get_user_by( $get_by, $user_id );
130
131
		if ( ! $user ) {
132
			return new WP_Error( 'unknown_user', 'Unknown user', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unknown_user'.

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...
133
		}
134
135
		if ( ! is_user_member_of_blog( $user->ID, $blog_id ) ) {
136
			return new WP_Error( 'unknown_user_for_site', 'Unknown user for site', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unknown_user_for_site'.

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...
137
		}
138
139
		if ( 'GET' === $this->api->method ) {
140
			return $this->get_user( $user->ID );
141
		} else if ( 'POST' === $this->api->method ) {
142
			if ( ! current_user_can_for_blog( $blog_id, 'promote_users' ) ) {
143
				return new WP_Error( 'unauthorized_no_promote_cap', 'User cannot promote users for specified site', 403 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unauthorized_no_promote_cap'.

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...
144
			}
145
			return $this->update_user( $user_id, $blog_id );
146
		} else {
147
			return new WP_Error( 'bad_request', 'An unsupported request method was used.' );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'bad_request'.

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...
148
		}
149
	}
150
151 View Code Duplication
	public function get_user( $user_id ) {
152
		$the_user = $this->get_author( $user_id, true );
153
		if ( $the_user && ! is_wp_error( $the_user ) ) {
154
			$userdata = get_userdata( $user_id );
155
			$the_user->roles = ! is_wp_error( $userdata ) ? array_values( $userdata->roles ) : array();
156
		}
157
158
		return $the_user;
159
	}
160
161
	/**
162
	 * Updates user data
163
	 *
164
	 * @return array
165
	 */
166
	public function update_user( $user_id, $blog_id ) {
167
		$input = $this->input();
168
		$user['ID'] = $user_id;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$user was never initialized. Although not strictly required by PHP, it is generally a good practice to add $user = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
169
		$is_wpcom = defined( 'IS_WPCOM' ) && IS_WPCOM;
170
171
		if ( get_current_user_id() == $user_id && isset( $input['roles'] ) ) {
172
			return new WP_Error( 'unauthorized', 'You cannot change your own role', 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...
173
		}
174
175
		if ( $is_wpcom && $user_id !== get_current_user_id() && $user_id == wpcom_get_blog_owner( $blog_id ) ) {
176
			return new WP_Error( 'unauthorized_edit_owner', 'Current user can not edit blog owner', 403 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'unauthorized_edit_owner'.

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...
177
		}
178
179
		if ( ! $is_wpcom ) {
180
			foreach ( $input as $key => $value ) {
181
				if ( ! is_array( $value ) ) {
182
					$value = trim( $value );
183
				}
184
				$value = wp_unslash( $value );
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array; however, wp_unslash() does only seem to accept string|array<integer,string>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
185
				switch ( $key ) {
186
					case 'first_name':
187
					case 'last_name':
188
						$user[ $key ] = $value;
189
						break;
190
					case 'display_name':
191
					case 'name':
192
						$user[ 'display_name' ] = $value;
193
						break;
194
				}
195
			}
196
		}
197
198
		if ( isset( $input[ 'roles' ] ) ) {
199
			// For now, we only use the first role in the array.
200
			if ( is_array( $input['roles'] ) ) {
201
				$user['role'] = $input['roles'][0];
202
			} else if ( is_string( $input['roles'] ) ) {
203
				$user['role'] = $input['roles'];
204
			} else {
205
				return new WP_Error( 'invalid_input', __( 'The roles property must be a string or an array.', 'jetpack' ), 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...
206
			}
207
208
			$editable_roles = array_keys( get_editable_roles() );
209 View Code Duplication
			if ( ! in_array( $user['role'], $editable_roles ) ) {
210
				return new WP_Error( 'invalid_input', sprintf( __( '%s is not a valid role.', 'jetpack' ), $editable_roles ), 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...
211
			}
212
		}
213
214
		$result = wp_update_user( $user );
215
		if ( is_wp_error( $result ) ) {
216
			return $result;
217
		}
218
		return $this->get_user( $user_id );
219
	}
220
221
}
222