Completed
Push — add/publicize-rest-api-2 ( cce80d...9e6c62 )
by
unknown
120:19 queued 60:15
created

WPCOM_REST_API_V2_Field_Controller::validate()   D

Complexity

Conditions 18
Paths 17

Size

Total Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
nc 17
nop 2
dl 0
loc 57
rs 4.8666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @todo - nicer API for array values
5
 */
6
abstract class WPCOM_REST_API_V2_Field_Controller {
7
	protected $object_type;
8
	protected $field_name;
9
10
	public function __construct() {
11
		if ( ! $this->object_type ) {
12
			/* translators: %s: object_type */
13
	                _doing_it_wrong( 'WPCOM_REST_API_V2_Field_Controller::$object_type', sprintf( __( "Property '%s' must be overridden.", 'jetpack' ), 'object_type' ), 'Jetpack 6.8' );
14
			return;
15
		}
16
17
		if ( ! $this->field_name ) {
18
			/* translators: %s: field_name */
19
	                _doing_it_wrong( 'WPCOM_REST_API_V2_Field_Controller::$field_name', sprintf( __( "Property '%s' must be overridden.", 'jetpack' ), 'field_name' ), 'Jetpack 6.8' );
20
			return;
21
		}
22
23
		register_rest_field( 'post', 'jetpack_publicize_connections', array(
24
			'get_callback' => array( $this, 'get_for_response' ),
25
			'update_callback' => array( $this, 'update_from_request' ),
26
			'schema' => $this->get_schema(),
27
		) );
28
	}
29
30
	function prepare_for_response( $value, $request ) {
31
		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
32
		$schema = $this->get_schema();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $schema is correct as $this->get_schema() (which targets WPCOM_REST_API_V2_Field_Controller::get_schema()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
33
34
		$validated = $this->validate( $value, $schema );
35
		return $this->filter_response_by_context( $validated, $schema, $context );
36
	}
37
38
	public function get_for_response( $object_data, $field_name, $request, $object_type ) {
39
		$permission_check = $this->get_permission_check( $request );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $permission_check is correct as $this->get_permission_check($request) (which targets WPCOM_REST_API_V2_Field_...:get_permission_check()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
40
41
		if ( ! $permission_check || is_wp_error( $permission_check ) ) {
42
			return;
43
		}
44
45
		$value = $this->get( $object_data, $request );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $value is correct as $this->get($object_data, $request) (which targets WPCOM_REST_API_V2_Field_Controller::get()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
46
47
		return $this->prepare_for_response( $value, $request );
48
	}
49
50
	public function update_from_request( $value, $object_data, $field_name, $request, $object_type ) {
51
		$permission_check = $this->update_permission_check( $value, $request );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $permission_check is correct as $this->update_permission_check($value, $request) (which targets WPCOM_REST_API_V2_Field_...date_permission_check()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
52
53
		if ( ! $permission_check ) {
54
			return;
55
		}
56
57
		if ( is_wp_error( $permission_check ) ) {
58
			return $permission_check;
59
		}
60
61
		$new_value = $this->update( $value, $object_data, $request );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $new_value is correct as $this->update($value, $object_data, $request) (which targets WPCOM_REST_API_V2_Field_Controller::update()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
62
63
		$this->prepare_for_response( $new_value, $request );
64
	}
65
66
	public function get_permission_check( $request ) {
67
		/* translators: %s: get_permission_check() */
68
                _doing_it_wrong( 'WPCOM_REST_API_V2_Field_Controller::get_permission_check', sprintf( __( "Method '%s' must be overridden." ), __METHOD__ ), 'Jetpack 6.8' );
69
	}
70
71
	public function get( $object_data, $request ) {
72
		/* translators: %s: get() */
73
                _doing_it_wrong( 'WPCOM_REST_API_V2_Field_Controller::get', sprintf( __( "Method '%s' must be overridden." ), __METHOD__ ), 'Jetpack 6.8' );
74
	}
75
76
	public function update_permission_check( $value, $request ) {
77
		/* translators: %s: update_permission_check() */
78
                _doing_it_wrong( 'WPCOM_REST_API_V2_Field_Controller::update_permission_check', sprintf( __( "Method '%s' must be overridden." ), __METHOD__ ), 'Jetpack 6.8' );
79
	}
80
81
	public function update( $value, $object_data, $request ) {
82
		/* translators: %s: update() */
83
                _doing_it_wrong( 'WPCOM_REST_API_V2_Field_Controller::update', sprintf( __( "Method '%s' must be overridden." ), __METHOD__ ), 'Jetpack 6.8' );
84
	}
85
86
	public function get_schema() {
87
		/* translators: %s: get_schema() */
88
                _doing_it_wrong( 'WPCOM_REST_API_V2_Field_Controller::get_schema', sprintf( __( "Method '%s' must be overridden." ), __METHOD__ ), 'Jetpack 6.8' );
89
	}
90
91
	public function validate( $value, $schema ) {
92
		switch ( $schema['type'] ) {
93
		case 'integer' :
94
			return (int) $value;
95
		case 'number' :
96
			return (float) $value;
97
		case 'string' :
98
			return (string) $value;
99
		case 'boolean' :
100
			return (bool) $value;
101
		case 'null' :
102
			return null;
103
		case 'array' :
104
			$value = (array) $value;
105
			if ( ! isset( $schema['items'] ) ) {
106
				return $value;				
107
			}
108
109
			$keys = array_keys( $value );
110
111
			if ( isset( $schema['items'][0] ) ) {
112
				// tuple
113
				$items = array_map( array( $this, 'validate' ), $value, $schema['items'] );
114
			} else {
115
				// list
116
				$items = array_map( array( $this, 'validate' ), $value, array_fill( 0, count( $keys ), $schema['items'] ) );
117
			}
118
119
			return array_combine( $keys, $items );
120
		case 'object' :
121
			$value = is_object( $value ) ? get_object_vars( $value ) : (array) $value;
122
			$output = array();
123
124
			if ( isset( $schema['properties'] ) ) {
125
				foreach ( $schema['properties'] as $field_name => $field_schema ) {
126
					if ( isset( $value[$field_name] ) ) {
127
						$output[$field_name] = $this->validate( $value[$field_name], $field_schema );
128
						unset( $value[$field_name] );
129
					}
130
				}
131
			}
132
133
			if ( isset( $schema['patternProperties'] ) ) {
134
				foreach ( $value as $field_name => $field_value ) {
135
					foreach ( $schema['patternProperties'] as $pattern => $pattern_schema ) {
136
						if ( preg_match( "/$pattern/", $field_name ) ) {
137
							$value[$field_name] = $this->validate( $field_value, $pattern_schema );
138
						}
139
					}
140
				}
141
			}
142
143
			$output += $value;
144
145
			return $output;
146
		}
147
	}
148
149
	function filter_response_by_context( $value, $schema, $context ) {
150
		if ( empty( $schema['context'] ) ) {
151
			return $value;
152
		}
153
154
		if ( ! in_array( $context, $schema['context'], true ) ) {
155
			// The Core REST API code will remove the root
156
			// property if the cotext doesn't match
157
			// For sub-properties, we filter them out later
158
			// using this hack.
159
			return new WP_Error( '__wrong-context__' );
160
		}
161
162
		switch ( $schema['type'] ) {
163
		case 'integer' :
164
		case 'number' :
165
		case 'string' :
166
		case 'boolean' :
167
		case 'null' :
168
			return $value;
169
		case 'array' :
170
			if ( ! isset( $schema['items'] ) ) {
171
				return $value;				
172
			}
173
174
			$keys = array_keys( $value );
175
176
			if ( isset( $schema['items'][0] ) ) {
177
				// tuple
178
				$items = array_map(
179
					array( $this, 'filter_response_by_context' ),
180
					$value,
181
					$schema['items'],
182
					array_fill( 0, count( $keys ), $context )
183
				);
184
185
				// It doesn't make sense for tuples to have one item with one context and another with another.
186
				// Instead, we depend on the context details for the propertie one level up.
187
				// (We still do the array_map above, though, so that sub-properties of the tuple's items will
188
				// have their contexts processed.)
189
				return array_combine( $keys, $items );
190
			}
191
192
			// else: list
193
			$items = array_map(
194
				array( $this, 'filter_response_by_context' ),
195
				$value,
196
				array_fill( 0, count( $keys ), $schema['items'] ),
197
				array_fill( 0, count( $keys ), $context )
198
			);
199
200
			$value = array_combine( $keys, $items );
201
202
			foreach ( $value as $key => $item ) {
203
				if ( is_wp_error( $item ) && '__wrong-context__' === $item->get_error_code() ) {
204
					unset( $value[$key] );
205
				}
206
			}
207
208
			return $value;
209
		case 'object' :
210
			$output = array();
211
212
			if ( isset( $schema['properties'] ) ) {
213
				foreach ( $value as $field_name => $field_value ) {
214
					if ( isset( $schema['properties'][$field_name] ) ) {
215
						$field_value = $this->filter_response_by_context( $field_value, $schema['properties'][$field_name], $context );
216
						if ( ! is_wp_error( $field_value ) || '__wrong-context__' !== $field_value->get_error_code() ) {
217
							$output[$field_name] = $field_value;
218
						}
219
						unset( $value[$field_name] );
220
					}
221
				}
222
			}
223
224
			if ( isset( $schema['patternProperties'] ) ) {
225
				foreach ( $schema['patternProperties'] as $pattern => $pattern_schema ) {
226
					foreach ( $value as $field_name => $field_value ) {
227
						if ( preg_match( "/$pattern/", $field_name ) ) {
228
							$field_value = $this->filter_response_by_context( $field_value, $pattern_schema, $context );
229
							if ( is_wp_error( $field_value ) && '__wrong-context__' === $field_value->get_error_code() ) {
230
								unset( $value[$field_name] );
231
							} else {
232
								$value[$field_name] = $field_value;
233
							}
234
						}
235
					}
236
				}
237
			}
238
239
			$output += $value;
240
241
			return (object) $output;
242
		}
243
	}
244
}
245