Completed
Push — 2.x ( e88784...f57756 )
by Scott Kingsley
25:22 queued 17:24
created

PodsRESTHandlers::write_handler()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 17
rs 9.4286
cc 3
eloc 8
nc 2
nop 3
1
<?php
2
/**
3
 * Class PodsRESTHandlers
4
 *
5
 * Handlers for reading and writing Pods fields via REST API
6
 *
7
 * @package Pods
8
 * @since   2.5.6
9
 */
10
class PodsRESTHandlers {
11
12
	/**
13
	 * Holds a Pods object to avoid extra DB queries
14
	 *
15
	 * @since 2.5.6
16
	 *
17
	 * @var Pods
18
	 */
19
	private static $pod;
20
21
	/**
22
	 * Get Pod object
23
	 *
24
	 * @since 2.5.6
25
	 *
26
	 * @param $pod_name
27
	 * @param $id
28
	 *
29
	 * @return bool|Pods
30
	 */
31
	protected static function get_pod( $pod_name, $id ) {
32
33
		if ( ! self::$pod || self::$pod->pod != $pod_name ) {
34
			self::$pod = pods( $pod_name, $id, true );
35
		}
36
37
		if ( self::$pod && self::$pod->id != $id ) {
38
			self::$pod->fetch( $id );
39
		}
40
41
		return self::$pod;
42
43
	}
44
45
	/**
46
	 * Handler for getting custom field data.
47
	 *
48
	 * @since 2.5.6
49
	 *
50
	 * @param array           $object     The object from the response
51
	 * @param string          $field_name Name of field
52
	 * @param WP_REST_Request $request    Current request
53
	 *
54
	 * @return mixed
55
	 */
56
	public static function get_handler( $object, $field_name, $request ) {
57
58
		$pod_name = pods_v( 'type', $object );
59
		$id       = pods_v( 'id', $object );
60
		$pod      = self::get_pod( $pod_name, $id );
61
		if ( $pod && PodsRESTFields::field_allowed_to_extend( $field_name, $pod, 'read' ) ) {
62
			$params     = null;
63
			$field_data = $pod->fields( $field_name );
64
			if ( 'pick' == pods_v( 'type', $field_data ) ) {
65
				$output_type = pods_v( 'rest_pick_response', $field_data['options'], 'array' );
66
				if ( 'array' == $output_type ) {
67
68
					$related_pod = $pod->field( $field_name, array( 'output' => 'pod' ) );
69
					$fields      = $related_pod->fields();
70
					$fields      = array_keys( $fields );
71
					if ( isset( $related_pod->pod_data['object_fields'] ) && ! empty( $related_pod->pod_data['object_fields'] ) ) {
72
						$fields = array_merge( $fields, array_keys( $related_pod->pod_data['object_fields'] ) );
73
					}
74
75
					/**
76
					 * What fields to show in a related field REST response.
77
					 *
78
					 * @since 0.0.1
79
					 *
80
					 * @param array                  $fields     The fields to show
81
					 * @param string                 $field_name The name of the field
82
					 * @param object|Pods            $pod        The Pods object for Pod relationship is from.
83
					 * @param object|Pods            $pod        The Pods object for Pod relationship is to.
84
					 * @param int                    $id         Current item ID
85
					 * @param object|WP_REST_Request Current     request object.
86
					 */
87
					$fields = apply_filters( 'pods_rest_api_fields_for_relationship_response', $fields, $field_name, $pod, $related_pod, $id, $request );
88
89
					$depth = pods_v( 'rest_pick_depth', $field_data['options'], 2 );
90
91
					/**
92
					 * What depth to use for a related field REST response.
93
					 *
94
					 * @since 0.0.1
95
					 *
96
					 * @param array                  $depth      The depth.
97
					 * @param string                 $field_name The name of the field
98
					 * @param object|Pods            $pod        The Pods object for Pod relationship is from.
99
					 * @param object|Pods            $pod        The Pods object for Pod relationship is to.
100
					 * @param int                    $id         Current item ID
101
					 * @param object|WP_REST_Request Current     request object.
102
					 */
103
					$depth = apply_filters( 'pods_rest_api_depth_for_relationship_response', $depth, $field_name, $pod, $related_pod, $id, $request );
104
105
					$params = array(
106
						'fields' => $fields,
107
						'depth'  => $depth
108
109
					);
110
111
					$data = $pod->api->export_pod_item( $related_pod, $params );
112
113
					return $data;
114
115
				}
116
117
				$params           = array();
118
				$params['output'] = $output_type;
119
			}
120
121
			return $pod->field( $field_name, $params );
122
123
		}
124
125
		return false;
126
127
	}
128
129
	/**
130
	 * Handler for updating custom field data.
131
	 *
132
	 * @since 2.5.6
133
	 *
134
	 * @param mixed  $value      Value to write
135
	 * @param object $object     The object from the response
136
	 * @param string $field_name Name of field
137
	 *
138
	 * @return bool|int
139
	 */
140
	public function write_handler( $value, $object, $field_name ) {
141
142
		$pod_name = pods_v( 'type', $object );
143
144
		$id = pods_v( 'id', $object );
145
146
		$pod = self::get_pod( $pod_name, $id );
147
148
		if ( $pod && PodsRESTFields::field_allowed_to_extend( $field_name, $pod, 'write' ) ) {
149
			$pod->save( $field_name, $value, $id );
150
151
			return $pod->field( $field_name );
152
		}
153
154
		return false;
155
156
	}
157
158
	/**
159
	 * Add REST API support to a post type
160
	 *
161
	 * @since 2.5.6
162
	 *
163
	 * @param string     $post_type_name Name of post type
164
	 * @param bool|false $rest_base      Optional. Base url segment. If not set, post type name is used
165
	 * @param string     $controller     Optional, controller class for route. If not set "WP_REST_Posts_Controller" is
166
	 *                                   used.
167
	 */
168 View Code Duplication
	public static function post_type_rest_support( $post_type_name, $rest_base = false, $controller = 'WP_REST_Posts_Controller' ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
169
170
		global $wp_post_types;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
171
172
		if ( isset( $wp_post_types[ $post_type_name ] ) ) {
173
			if ( ! $rest_base ) {
174
				$rest_base = $post_type_name;
175
			}
176
177
			$wp_post_types[ $post_type_name ]->show_in_rest          = true;
178
			$wp_post_types[ $post_type_name ]->rest_base             = $rest_base;
179
			$wp_post_types[ $post_type_name ]->rest_controller_class = $controller;
180
		}
181
182
	}
183
184
	/**
185
	 * Add REST API support to an already registered taxonomy.
186
	 *
187
	 * @since 2.5.6
188
	 *
189
	 * @param string     $taxonomy_name Taxonomy name.
190
	 * @param bool|false $rest_base     Optional. Base url segment. If not set, taxonomy name is used.
191
	 * @param string     $controller    Optional, controller class for route. If not set "WP_REST_Terms_Controller" is
192
	 *                                  used.
193
	 */
194 View Code Duplication
	public static function taxonomy_rest_support( $taxonomy_name, $rest_base = false, $controller = 'WP_REST_Terms_Controller' ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
195
196
		global $wp_taxonomies;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
197
198
		if ( isset( $wp_taxonomies[ $taxonomy_name ] ) ) {
199
			if ( ! $rest_base ) {
200
				$rest_base = $taxonomy_name;
201
			}
202
203
			$wp_taxonomies[ $taxonomy_name ]->show_in_rest          = true;
204
			$wp_taxonomies[ $taxonomy_name ]->rest_base             = $rest_base;
205
			$wp_taxonomies[ $taxonomy_name ]->rest_controller_class = $controller;
206
		}
207
208
	}
209
210
	/**
211
	 * Check if a Pod supports extending core REST response.
212
	 *
213
	 * @since 2.5.6
214
	 *
215
	 * @param array|Pods $pod Pod object or the pod_data array
216
	 *
217
	 * @return bool
218
	 */
219
	public static function pod_extends_core_route( $pod ) {
220
221
	    $enabled = false;
222
223
	    if ( is_object( $pod ) ) {
224
	        $pod = $pod->pod_data;
225
	    }
226
227
	    if ( is_array( $pod ) ) {
228
	        $enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
229
	    }
230
231
	    return $enabled;
232
233
	}
234
235
}