Passed
Branch master (50908e)
by Stiofan
07:01
created
includes/api/class-wpinv-rest-items-controller.php 1 patch
Indentation   +987 added lines, -987 removed lines patch added patch discarded remove patch
@@ -20,91 +20,91 @@  discard block
 block discarded – undo
20 20
 class WPInv_REST_Items_Controller extends WP_REST_Posts_Controller {
21 21
 
22 22
     /**
23
-	 * Post type.
24
-	 *
25
-	 * @var string
26
-	 */
27
-	protected $post_type = 'wpi_item';
23
+     * Post type.
24
+     *
25
+     * @var string
26
+     */
27
+    protected $post_type = 'wpi_item';
28 28
 	
29
-	/**
30
-	 * Cached results of get_item_schema.
31
-	 *
32
-	 * @since 1.0.13
33
-	 * @var array
34
-	 */
35
-	protected $schema;
29
+    /**
30
+     * Cached results of get_item_schema.
31
+     *
32
+     * @since 1.0.13
33
+     * @var array
34
+     */
35
+    protected $schema;
36 36
 
37 37
     /**
38
-	 * Constructor.
39
-	 *
40
-	 * @since 1.0.13
41
-	 *
42
-	 * @param string $namespace Api Namespace
43
-	 */
44
-	public function __construct( $namespace ) {
38
+     * Constructor.
39
+     *
40
+     * @since 1.0.13
41
+     *
42
+     * @param string $namespace Api Namespace
43
+     */
44
+    public function __construct( $namespace ) {
45 45
         
46 46
         // Set api namespace...
47
-		$this->namespace = $namespace;
47
+        $this->namespace = $namespace;
48 48
 
49 49
         // ... and the rest base
50 50
         $this->rest_base = 'items';
51 51
 		
52 52
     }
53 53
 	
54
-	/**
55
-	 * Registers the routes for the objects of the controller.
56
-	 *
57
-	 * @since 1.0.13
58
-	 *
59
-	 * @see register_rest_route()
60
-	 */
61
-	public function register_routes() {
62
-
63
-		parent::register_routes();
64
-
65
-		register_rest_route(
66
-			$this->namespace,
67
-			'/' . $this->rest_base . '/item-types',
68
-			array(
69
-				array(
70
-					'methods'             => WP_REST_Server::READABLE,
71
-					'callback'            => array( $this, 'get_item_types' ),
72
-				),
73
-			)
74
-		);
75
-
76
-	}
54
+    /**
55
+     * Registers the routes for the objects of the controller.
56
+     *
57
+     * @since 1.0.13
58
+     *
59
+     * @see register_rest_route()
60
+     */
61
+    public function register_routes() {
62
+
63
+        parent::register_routes();
64
+
65
+        register_rest_route(
66
+            $this->namespace,
67
+            '/' . $this->rest_base . '/item-types',
68
+            array(
69
+                array(
70
+                    'methods'             => WP_REST_Server::READABLE,
71
+                    'callback'            => array( $this, 'get_item_types' ),
72
+                ),
73
+            )
74
+        );
75
+
76
+    }
77 77
 
78 78
     /**
79
-	 * Checks if a given request has access to read items.
79
+     * Checks if a given request has access to read items.
80 80
      * 
81
-	 *
82
-	 * @since 1.0.13
83
-	 *
84
-	 * @param WP_REST_Request $request Full details about the request.
85
-	 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
86
-	 */
87
-	public function get_items_permissions_check( $request ) {
81
+     *
82
+     * @since 1.0.13
83
+     *
84
+     * @param WP_REST_Request $request Full details about the request.
85
+     * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
86
+     */
87
+    public function get_items_permissions_check( $request ) {
88 88
 	
89
-		if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
90
-			return true;
91
-		}
89
+        if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
90
+            return true;
91
+        }
92 92
 
93
-		return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view invoice items.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
93
+        return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view invoice items.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
94 94
 
95 95
     }
96 96
     
97 97
     /**
98
-	 * Retrieves a collection of invoice items.
99
-	 *
100
-	 * @since 1.0.13
101
-	 *
102
-	 * @param WP_REST_Request $request Full details about the request.
103
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
104
-	 */
105
-	public function get_items( $request ) {
98
+     * Retrieves a collection of invoice items.
99
+     *
100
+     * @since 1.0.13
101
+     *
102
+     * @param WP_REST_Request $request Full details about the request.
103
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
104
+     */
105
+    public function get_items( $request ) {
106 106
 		
107
-		// Retrieve the list of registered item query parameters.
107
+        // Retrieve the list of registered item query parameters.
108 108
         $registered = $this->get_collection_params();
109 109
         
110 110
         $args       = array();
@@ -117,54 +117,54 @@  discard block
 block discarded – undo
117 117
 
118 118
         }
119 119
 
120
-		/**
121
-		 * Filters the wpinv_get_items arguments for items rest requests.
122
-		 *
123
-		 *
124
-		 * @since 1.0.13
125
-		 *
126
-		 *
127
-		 * @param array           $args    Key value array of query var to query value.
128
-		 * @param WP_REST_Request $request The request used.
129
-		 */
120
+        /**
121
+         * Filters the wpinv_get_items arguments for items rest requests.
122
+         *
123
+         *
124
+         * @since 1.0.13
125
+         *
126
+         *
127
+         * @param array           $args    Key value array of query var to query value.
128
+         * @param WP_REST_Request $request The request used.
129
+         */
130 130
         $args       = apply_filters( "wpinv_rest_get_items_arguments", $args, $request, $this );
131 131
 		
132
-		// Special args
133
-		$args[ 'return' ]   = 'objects';
134
-		$args[ 'paginate' ] = true;
132
+        // Special args
133
+        $args[ 'return' ]   = 'objects';
134
+        $args[ 'paginate' ] = true;
135 135
 
136 136
         // Run the query.
137
-		$query = wpinv_get_all_items( $args );
137
+        $query = wpinv_get_all_items( $args );
138 138
 		
139
-		// Prepare the retrieved items
140
-		$items = array();
141
-		foreach( $query->items as $item ) {
142
-
143
-			if ( ! $this->check_read_permission( $item ) ) {
144
-				continue;
145
-			}
146
-
147
-			$data       = $this->prepare_item_for_response( $item, $request );
148
-			$items[]    = $this->prepare_response_for_collection( $data );
149
-
150
-		}
151
-
152
-		// Prepare the response.
153
-		$response = rest_ensure_response( $items );
154
-		$response->header( 'X-WP-Total', (int) $query->total );
155
-		$response->header( 'X-WP-TotalPages', (int) $query->max_num_pages );
156
-
157
-		/**
158
-		 * Filters the responses for item requests.
159
-		 *
160
-		 *
161
-		 * @since 1.0.13
162
-		 *
163
-		 *
164
-		 * @param arrWP_REST_Response $response    Response object.
165
-		 * @param WP_REST_Request     $request The request used.
139
+        // Prepare the retrieved items
140
+        $items = array();
141
+        foreach( $query->items as $item ) {
142
+
143
+            if ( ! $this->check_read_permission( $item ) ) {
144
+                continue;
145
+            }
146
+
147
+            $data       = $this->prepare_item_for_response( $item, $request );
148
+            $items[]    = $this->prepare_response_for_collection( $data );
149
+
150
+        }
151
+
152
+        // Prepare the response.
153
+        $response = rest_ensure_response( $items );
154
+        $response->header( 'X-WP-Total', (int) $query->total );
155
+        $response->header( 'X-WP-TotalPages', (int) $query->max_num_pages );
156
+
157
+        /**
158
+         * Filters the responses for item requests.
159
+         *
160
+         *
161
+         * @since 1.0.13
162
+         *
163
+         *
164
+         * @param arrWP_REST_Response $response    Response object.
165
+         * @param WP_REST_Request     $request The request used.
166 166
          * @param array               $args Array of args used to retrieve the items
167
-		 */
167
+         */
168 168
         $response       = apply_filters( "wpinv_rest_items_response", $response, $request, $args );
169 169
 
170 170
         return rest_ensure_response( $response );
@@ -172,25 +172,25 @@  discard block
 block discarded – undo
172 172
     }
173 173
 
174 174
     /**
175
-	 * Get the post, if the ID is valid.
176
-	 *
177
-	 * @since 1.0.13
178
-	 *
179
-	 * @param int $item_id Supplied ID.
180
-	 * @return WPInv_Item|WP_Error Item object if ID is valid, WP_Error otherwise.
181
-	 */
182
-	protected function get_post( $item_id ) {
175
+     * Get the post, if the ID is valid.
176
+     *
177
+     * @since 1.0.13
178
+     *
179
+     * @param int $item_id Supplied ID.
180
+     * @return WPInv_Item|WP_Error Item object if ID is valid, WP_Error otherwise.
181
+     */
182
+    protected function get_post( $item_id ) {
183 183
 		
184
-		$error     = new WP_Error( 'rest_item_invalid_id', __( 'Invalid item ID.', 'invoicing' ), array( 'status' => 404 ) );
184
+        $error     = new WP_Error( 'rest_item_invalid_id', __( 'Invalid item ID.', 'invoicing' ), array( 'status' => 404 ) );
185 185
 
186 186
         // Ids start from 1
187 187
         if ( (int) $item_id <= 0 ) {
188
-			return $error;
189
-		}
188
+            return $error;
189
+        }
190 190
 
191
-		$item = wpinv_get_item_by( 'id', (int) $item_id );
192
-		if ( empty( $item ) ) {
193
-			return $error;
191
+        $item = wpinv_get_item_by( 'id', (int) $item_id );
192
+        if ( empty( $item ) ) {
193
+            return $error;
194 194
         }
195 195
 
196 196
         return $item;
@@ -198,27 +198,27 @@  discard block
 block discarded – undo
198 198
     }
199 199
 
200 200
     /**
201
-	 * Checks if a given request has access to read an invoice item.
202
-	 *
203
-	 * @since 1.0.13
204
-	 *
205
-	 * @param WP_REST_Request $request Full details about the request.
206
-	 * @return bool|WP_Error True if the request has read access for the invoice item, WP_Error object otherwise.
207
-	 */
208
-	public function get_item_permissions_check( $request ) {
201
+     * Checks if a given request has access to read an invoice item.
202
+     *
203
+     * @since 1.0.13
204
+     *
205
+     * @param WP_REST_Request $request Full details about the request.
206
+     * @return bool|WP_Error True if the request has read access for the invoice item, WP_Error object otherwise.
207
+     */
208
+    public function get_item_permissions_check( $request ) {
209 209
 
210 210
         // Retrieve the item object.
211 211
         $item = $this->get_post( $request['id'] );
212 212
         
213 213
         // Ensure it is valid.
214
-		if ( is_wp_error( $item ) ) {
215
-			return $item;
216
-		}
214
+        if ( is_wp_error( $item ) ) {
215
+            return $item;
216
+        }
217 217
 
218
-		$post_type = get_post_type_object( $this->post_type );
218
+        $post_type = get_post_type_object( $this->post_type );
219 219
 
220
-		if ( ! current_user_can(  $post_type->cap->read_post, $item->ID  ) ) {
221
-			return new WP_Error( 
220
+        if ( ! current_user_can(  $post_type->cap->read_post, $item->ID  ) ) {
221
+            return new WP_Error( 
222 222
                 'rest_cannot_edit', 
223 223
                 __( 'Sorry, you are not allowed to view this item.', 'invoicing' ), 
224 224
                 array( 
@@ -227,61 +227,61 @@  discard block
 block discarded – undo
227 227
             );
228 228
         }
229 229
 
230
-		return $this->check_read_permission( $item );
230
+        return $this->check_read_permission( $item );
231 231
     }
232 232
     
233 233
     /**
234
-	 * Checks if an item can be read.
235
-	 * 
236
-	 * An item can be read by site admins.
237
-	 *
238
-	 *
239
-	 * @since 1.0.13
240
-	 *
241
-	 * @param WPInv_Item $item WPInv_Item object.
242
-	 * @return bool Whether the post can be read.
243
-	 */
244
-	public function check_read_permission( $item ) {
245
-
246
-		// An item can be read by an admin...
247
-		if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
248
-			return true;
249
-		}
250
-
251
-		return false;
234
+     * Checks if an item can be read.
235
+     * 
236
+     * An item can be read by site admins.
237
+     *
238
+     *
239
+     * @since 1.0.13
240
+     *
241
+     * @param WPInv_Item $item WPInv_Item object.
242
+     * @return bool Whether the post can be read.
243
+     */
244
+    public function check_read_permission( $item ) {
245
+
246
+        // An item can be read by an admin...
247
+        if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
248
+            return true;
249
+        }
250
+
251
+        return false;
252 252
     }
253 253
     
254 254
     /**
255
-	 * Retrieves a single invoice item.
256
-	 *
257
-	 * @since 1.0.13
258
-	 *
259
-	 * @param WP_REST_Request $request Full details about the request.
260
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
261
-	 */
262
-	public function get_item( $request ) {
255
+     * Retrieves a single invoice item.
256
+     *
257
+     * @since 1.0.13
258
+     *
259
+     * @param WP_REST_Request $request Full details about the request.
260
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
261
+     */
262
+    public function get_item( $request ) {
263 263
 
264 264
         // Fetch the item.
265 265
         $item = $this->get_post( $request['id'] );
266 266
         
267 267
         // Abort early if it does not exist
268
-		if ( is_wp_error( $item ) ) {
269
-			return $item;
270
-		}
271
-
272
-		// Prepare the response
273
-		$response = $this->prepare_item_for_response( $item, $request );
274
-
275
-		/**
276
-		 * Filters the responses for single invoice item requests.
277
-		 *
278
-		 *
279
-		 * @since 1.0.13
280
-		 * @var WP_HTTP_Response
281
-		 *
282
-		 * @param WP_HTTP_Response $response Response.
283
-		 * @param WP_REST_Request  $request The request used.
284
-		 */
268
+        if ( is_wp_error( $item ) ) {
269
+            return $item;
270
+        }
271
+
272
+        // Prepare the response
273
+        $response = $this->prepare_item_for_response( $item, $request );
274
+
275
+        /**
276
+         * Filters the responses for single invoice item requests.
277
+         *
278
+         *
279
+         * @since 1.0.13
280
+         * @var WP_HTTP_Response
281
+         *
282
+         * @param WP_HTTP_Response $response Response.
283
+         * @param WP_REST_Request  $request The request used.
284
+         */
285 285
         $response       = apply_filters( "wpinv_rest_get_item_response", $response, $request );
286 286
 
287 287
         return rest_ensure_response( $response );
@@ -289,26 +289,26 @@  discard block
 block discarded – undo
289 289
     }
290 290
     
291 291
     /**
292
-	 * Checks if a given request has access to create an invoice item.
293
-	 *
294
-	 * @since 1.0.13
295
-	 *
296
-	 * @param WP_REST_Request $request Full details about the request.
297
-	 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
298
-	 */
299
-	public function create_item_permissions_check( $request ) {
292
+     * Checks if a given request has access to create an invoice item.
293
+     *
294
+     * @since 1.0.13
295
+     *
296
+     * @param WP_REST_Request $request Full details about the request.
297
+     * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
298
+     */
299
+    public function create_item_permissions_check( $request ) {
300 300
 	
301
-		if ( ! empty( $request['id'] ) ) {
302
-			return new WP_Error( 'rest_item_exists', __( 'Cannot create existing item.', 'invoicing' ), array( 'status' => 400 ) );
303
-		}
301
+        if ( ! empty( $request['id'] ) ) {
302
+            return new WP_Error( 'rest_item_exists', __( 'Cannot create existing item.', 'invoicing' ), array( 'status' => 400 ) );
303
+        }
304 304
 
305
-		if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
306
-			return true;
307
-		}
305
+        if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
306
+            return true;
307
+        }
308 308
 
309
-		$post_type = get_post_type_object( $this->post_type );
310
-		if ( ! current_user_can( $post_type->cap->create_posts ) ) {
311
-			return new WP_Error( 
309
+        $post_type = get_post_type_object( $this->post_type );
310
+        if ( ! current_user_can( $post_type->cap->create_posts ) ) {
311
+            return new WP_Error( 
312 312
                 'rest_cannot_create', 
313 313
                 __( 'Sorry, you are not allowed to create invoice items as this user.', 'invoicing' ), 
314 314
                 array( 
@@ -317,253 +317,253 @@  discard block
 block discarded – undo
317 317
             );
318 318
         }
319 319
 
320
-		return true;
320
+        return true;
321 321
     }
322 322
     
323 323
     /**
324
-	 * Creates a single invoice item.
325
-	 *
326
-	 * @since 1.0.13
327
-	 *
328
-	 * @param WP_REST_Request $request Full details about the request.
329
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
330
-	 */
331
-	public function create_item( $request ) {
332
-
333
-		if ( ! empty( $request['id'] ) ) {
334
-			return new WP_Error( 'rest_item_exists', __( 'Cannot create existing invoice item.', 'invoicing' ), array( 'status' => 400 ) );
335
-		}
324
+     * Creates a single invoice item.
325
+     *
326
+     * @since 1.0.13
327
+     *
328
+     * @param WP_REST_Request $request Full details about the request.
329
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
330
+     */
331
+    public function create_item( $request ) {
332
+
333
+        if ( ! empty( $request['id'] ) ) {
334
+            return new WP_Error( 'rest_item_exists', __( 'Cannot create existing invoice item.', 'invoicing' ), array( 'status' => 400 ) );
335
+        }
336 336
 
337
-		$request->set_param( 'context', 'edit' );
337
+        $request->set_param( 'context', 'edit' );
338 338
 
339
-		// Prepare the updated data.
340
-		$item_data = $this->prepare_item_for_database( $request );
339
+        // Prepare the updated data.
340
+        $item_data = $this->prepare_item_for_database( $request );
341 341
 
342
-		if ( is_wp_error( $item_data ) ) {
343
-			return $item_data;
344
-		}
342
+        if ( is_wp_error( $item_data ) ) {
343
+            return $item_data;
344
+        }
345 345
 
346
-		// Try creating the item.
346
+        // Try creating the item.
347 347
         $item = wpinv_create_item( $item_data, true );
348 348
 
349
-		if ( is_wp_error( $item ) ) {
349
+        if ( is_wp_error( $item ) ) {
350 350
             return $item;
351
-		}
352
-
353
-		// Prepare the response
354
-		$response = $this->prepare_item_for_response( $item, $request );
355
-
356
-		/**
357
-		 * Fires after a single invoice item is created or updated via the REST API.
358
-		 *
359
-		 * @since 1.0.13
360
-		 *
361
-		 * @param WPinv_Item   $item  Inserted or updated item object.
362
-		 * @param WP_REST_Request $request  Request object.
363
-		 * @param bool            $creating True when creating a post, false when updating.
364
-		 */
365
-		do_action( "wpinv_rest_insert_item", $item, $request, true );
366
-
367
-		/**
368
-		 * Filters the responses for creating single item requests.
369
-		 *
370
-		 *
371
-		 * @since 1.0.13
372
-		 *
373
-		 *
374
-		 * @param array           $item_data Invoice properties.
375
-		 * @param WP_REST_Request $request The request used.
376
-		 */
351
+        }
352
+
353
+        // Prepare the response
354
+        $response = $this->prepare_item_for_response( $item, $request );
355
+
356
+        /**
357
+         * Fires after a single invoice item is created or updated via the REST API.
358
+         *
359
+         * @since 1.0.13
360
+         *
361
+         * @param WPinv_Item   $item  Inserted or updated item object.
362
+         * @param WP_REST_Request $request  Request object.
363
+         * @param bool            $creating True when creating a post, false when updating.
364
+         */
365
+        do_action( "wpinv_rest_insert_item", $item, $request, true );
366
+
367
+        /**
368
+         * Filters the responses for creating single item requests.
369
+         *
370
+         *
371
+         * @since 1.0.13
372
+         *
373
+         *
374
+         * @param array           $item_data Invoice properties.
375
+         * @param WP_REST_Request $request The request used.
376
+         */
377 377
         $response       = apply_filters( "wpinv_rest_create_item_response", $response, $request );
378 378
 
379 379
         return rest_ensure_response( $response );
380
-	}
381
-
382
-	/**
383
-	 * Checks if a given request has access to update an item.
384
-	 *
385
-	 * @since 1.0.13
386
-	 *
387
-	 * @param WP_REST_Request $request Full details about the request.
388
-	 * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
389
-	 */
390
-	public function update_item_permissions_check( $request ) {
391
-
392
-		// Retrieve the item.
393
-		$item = $this->get_post( $request['id'] );
394
-		if ( is_wp_error( $item ) ) {
395
-			return $item;
396
-		}
397
-
398
-		if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
399
-			return true;
400
-		}
401
-
402
-		return new WP_Error( 
403
-			'rest_cannot_edit', 
404
-			__( 'Sorry, you are not allowed to update this item.', 'invoicing' ), 
405
-			array( 
406
-				'status' => rest_authorization_required_code(),
407
-			)
408
-		);
409
-
410
-	}
411
-
412
-	/**
413
-	 * Updates a single item.
414
-	 *
415
-	 * @since 1.0.13
416
-	 *
417
-	 * @param WP_REST_Request $request Full details about the request.
418
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
419
-	 */
420
-	public function update_item( $request ) {
380
+    }
381
+
382
+    /**
383
+     * Checks if a given request has access to update an item.
384
+     *
385
+     * @since 1.0.13
386
+     *
387
+     * @param WP_REST_Request $request Full details about the request.
388
+     * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
389
+     */
390
+    public function update_item_permissions_check( $request ) {
391
+
392
+        // Retrieve the item.
393
+        $item = $this->get_post( $request['id'] );
394
+        if ( is_wp_error( $item ) ) {
395
+            return $item;
396
+        }
397
+
398
+        if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
399
+            return true;
400
+        }
401
+
402
+        return new WP_Error( 
403
+            'rest_cannot_edit', 
404
+            __( 'Sorry, you are not allowed to update this item.', 'invoicing' ), 
405
+            array( 
406
+                'status' => rest_authorization_required_code(),
407
+            )
408
+        );
409
+
410
+    }
411
+
412
+    /**
413
+     * Updates a single item.
414
+     *
415
+     * @since 1.0.13
416
+     *
417
+     * @param WP_REST_Request $request Full details about the request.
418
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
419
+     */
420
+    public function update_item( $request ) {
421 421
 		
422
-		// Ensure the item exists.
422
+        // Ensure the item exists.
423 423
         $valid_check = $this->get_post( $request['id'] );
424 424
         
425 425
         // Abort early if it does not exist
426
-		if ( is_wp_error( $valid_check ) ) {
427
-			return $valid_check;
428
-		}
426
+        if ( is_wp_error( $valid_check ) ) {
427
+            return $valid_check;
428
+        }
429 429
 
430
-		$request->set_param( 'context', 'edit' );
430
+        $request->set_param( 'context', 'edit' );
431 431
 
432
-		// Prepare the updated data.
433
-		$data_to_update = $this->prepare_item_for_database( $request );
432
+        // Prepare the updated data.
433
+        $data_to_update = $this->prepare_item_for_database( $request );
434 434
 
435
-		if ( is_wp_error( $data_to_update ) ) {
436
-			return $data_to_update;
437
-		}
435
+        if ( is_wp_error( $data_to_update ) ) {
436
+            return $data_to_update;
437
+        }
438 438
 
439
-		// Abort if no item data is provided
439
+        // Abort if no item data is provided
440 440
         if( empty( $data_to_update ) ) {
441 441
             return new WP_Error( 'missing_data', __( 'An update request cannot be empty.', 'invoicing' ) );
442 442
         }
443 443
 
444
-		// Include the item ID
445
-		$data_to_update['ID'] = $request['id'];
446
-
447
-		// Update the item
448
-		$updated_item = wpinv_update_item( $data_to_update, true );
449
-
450
-		// Incase the update operation failed...
451
-		if ( is_wp_error( $updated_item ) ) {
452
-			return $updated_item;
453
-		}
454
-
455
-		// Prepare the response
456
-		$response = $this->prepare_item_for_response( $updated_item, $request );
457
-
458
-		/** This action is documented in includes/class-wpinv-rest-item-controller.php */
459
-		do_action( "wpinv_rest_insert_item", $updated_item, $request, false );
460
-
461
-		/**
462
-		 * Filters the responses for updating single item requests.
463
-		 *
464
-		 *
465
-		 * @since 1.0.13
466
-		 *
467
-		 *
468
-		 * @param array           $item_data Item properties.
469
-		 * @param WP_REST_Request $request The request used.
470
-		 */
444
+        // Include the item ID
445
+        $data_to_update['ID'] = $request['id'];
446
+
447
+        // Update the item
448
+        $updated_item = wpinv_update_item( $data_to_update, true );
449
+
450
+        // Incase the update operation failed...
451
+        if ( is_wp_error( $updated_item ) ) {
452
+            return $updated_item;
453
+        }
454
+
455
+        // Prepare the response
456
+        $response = $this->prepare_item_for_response( $updated_item, $request );
457
+
458
+        /** This action is documented in includes/class-wpinv-rest-item-controller.php */
459
+        do_action( "wpinv_rest_insert_item", $updated_item, $request, false );
460
+
461
+        /**
462
+         * Filters the responses for updating single item requests.
463
+         *
464
+         *
465
+         * @since 1.0.13
466
+         *
467
+         *
468
+         * @param array           $item_data Item properties.
469
+         * @param WP_REST_Request $request The request used.
470
+         */
471 471
         $response       = apply_filters( "wpinv_rest_update_item_response", $response,  $data_to_update, $request );
472 472
 
473 473
         return rest_ensure_response( $response );
474
-	}
475
-
476
-	/**
477
-	 * Checks if a given request has access to delete an item.
478
-	 *
479
-	 * @since 1.0.13
480
-	 *
481
-	 * @param WP_REST_Request $request Full details about the request.
482
-	 * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
483
-	 */
484
-	public function delete_item_permissions_check( $request ) {
485
-
486
-		// Retrieve the item.
487
-		$item = $this->get_post( $request['id'] );
488
-		if ( is_wp_error( $item ) ) {
489
-			return $item;
490
-		}
491
-
492
-		// 
493
-
494
-		// Ensure the current user can delete the item
495
-		if (! wpinv_can_delete_item( $request['id'] ) ) {
496
-			return new WP_Error( 
474
+    }
475
+
476
+    /**
477
+     * Checks if a given request has access to delete an item.
478
+     *
479
+     * @since 1.0.13
480
+     *
481
+     * @param WP_REST_Request $request Full details about the request.
482
+     * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
483
+     */
484
+    public function delete_item_permissions_check( $request ) {
485
+
486
+        // Retrieve the item.
487
+        $item = $this->get_post( $request['id'] );
488
+        if ( is_wp_error( $item ) ) {
489
+            return $item;
490
+        }
491
+
492
+        // 
493
+
494
+        // Ensure the current user can delete the item
495
+        if (! wpinv_can_delete_item( $request['id'] ) ) {
496
+            return new WP_Error( 
497 497
                 'rest_cannot_delete', 
498 498
                 __( 'Sorry, you are not allowed to delete this item.', 'invoicing' ), 
499 499
                 array( 
500 500
                     'status' => rest_authorization_required_code(),
501 501
                 )
502 502
             );
503
-		}
504
-
505
-		return true;
506
-	}
507
-
508
-	/**
509
-	 * Deletes a single item.
510
-	 *
511
-	 * @since 1.0.13
512
-	 *
513
-	 * @param WP_REST_Request $request Full details about the request.
514
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
515
-	 */
516
-	public function delete_item( $request ) {
503
+        }
504
+
505
+        return true;
506
+    }
507
+
508
+    /**
509
+     * Deletes a single item.
510
+     *
511
+     * @since 1.0.13
512
+     *
513
+     * @param WP_REST_Request $request Full details about the request.
514
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
515
+     */
516
+    public function delete_item( $request ) {
517 517
 		
518
-		// Retrieve the item.
519
-		$item = $this->get_post( $request['id'] );
520
-		if ( is_wp_error( $item ) ) {
521
-			return $item;
522
-		}
518
+        // Retrieve the item.
519
+        $item = $this->get_post( $request['id'] );
520
+        if ( is_wp_error( $item ) ) {
521
+            return $item;
522
+        }
523 523
 
524
-		$request->set_param( 'context', 'edit' );
524
+        $request->set_param( 'context', 'edit' );
525 525
 
526
-		// Prepare the item id
527
-		$id    = $item->ID;
526
+        // Prepare the item id
527
+        $id    = $item->ID;
528 528
 
529
-		// Prepare the response
530
-		$response = $this->prepare_item_for_response( $item, $request );
529
+        // Prepare the response
530
+        $response = $this->prepare_item_for_response( $item, $request );
531 531
 
532
-		// Check if the user wants to bypass the trash...
533
-		$force_delete = (bool) $request['force'];
532
+        // Check if the user wants to bypass the trash...
533
+        $force_delete = (bool) $request['force'];
534 534
 
535
-		// Try deleting the item.
536
-		$deleted = wp_delete_post( $id, $force_delete );
535
+        // Try deleting the item.
536
+        $deleted = wp_delete_post( $id, $force_delete );
537 537
 
538
-		// Abort early if we can't delete the item.
539
-		if ( ! $deleted ) {
540
-			return new WP_Error( 'rest_cannot_delete', __( 'The item cannot be deleted.', 'invoicing' ), array( 'status' => 500 ) );
541
-		}
538
+        // Abort early if we can't delete the item.
539
+        if ( ! $deleted ) {
540
+            return new WP_Error( 'rest_cannot_delete', __( 'The item cannot be deleted.', 'invoicing' ), array( 'status' => 500 ) );
541
+        }
542 542
 
543
-		/**
544
-		 * Fires immediately after a single item is deleted or trashed via the REST API.
545
-		 *
546
-		 *
547
-		 * @since 1.0.13
548
-		 *
549
-		 * @param WPInv_Item    $item  The deleted or trashed item.
550
-		 * @param WP_REST_Request  $request  The request sent to the API.
551
-		 */
552
-		do_action( "wpinv_rest_delete_item", $item, $request );
543
+        /**
544
+         * Fires immediately after a single item is deleted or trashed via the REST API.
545
+         *
546
+         *
547
+         * @since 1.0.13
548
+         *
549
+         * @param WPInv_Item    $item  The deleted or trashed item.
550
+         * @param WP_REST_Request  $request  The request sent to the API.
551
+         */
552
+        do_action( "wpinv_rest_delete_item", $item, $request );
553 553
 
554
-		return $response;
554
+        return $response;
555 555
 
556
-	}
556
+    }
557 557
     
558 558
     
559 559
     /**
560
-	 * Retrieves the query params for the items collection.
561
-	 *
562
-	 * @since 1.0.13
563
-	 *
564
-	 * @return array Collection parameters.
565
-	 */
566
-	public function get_collection_params() {
560
+     * Retrieves the query params for the items collection.
561
+     *
562
+     * @since 1.0.13
563
+     *
564
+     * @return array Collection parameters.
565
+     */
566
+    public function get_collection_params() {
567 567
         
568 568
         $query_params               = array(
569 569
 
@@ -577,27 +577,27 @@  discard block
 block discarded – undo
577 577
             
578 578
             // Item types
579 579
             'type'                  => array(
580
-				'description'       => __( 'Type of items to fetch.', 'invoicing' ),
581
-				'type'              => 'array',
582
-				'default'           => wpinv_item_types(),
583
-				'items'             => array(
580
+                'description'       => __( 'Type of items to fetch.', 'invoicing' ),
581
+                'type'              => 'array',
582
+                'default'           => wpinv_item_types(),
583
+                'items'             => array(
584 584
                     'enum'          => wpinv_item_types(),
585 585
                     'type'          => 'string',
586 586
                 ),
587
-			),
587
+            ),
588 588
 			
589
-			// Number of results per page
589
+            // Number of results per page
590 590
             'limit'                 => array(
591
-				'description'       => __( 'Number of items to fetch.', 'invoicing' ),
592
-				'type'              => 'integer',
593
-				'default'           => (int) get_option( 'posts_per_page' ),
591
+                'description'       => __( 'Number of items to fetch.', 'invoicing' ),
592
+                'type'              => 'integer',
593
+                'default'           => (int) get_option( 'posts_per_page' ),
594 594
             ),
595 595
 
596 596
             // Pagination
597 597
             'page'     => array(
598
-				'description'       => __( 'Current page to fetch.', 'invoicing' ),
599
-				'type'              => 'integer',
600
-				'default'           => 1,
598
+                'description'       => __( 'Current page to fetch.', 'invoicing' ),
599
+                'type'              => 'integer',
600
+                'default'           => 1,
601 601
             ),
602 602
 
603 603
             // Exclude certain items
@@ -620,9 +620,9 @@  discard block
 block discarded – undo
620 620
                     'date',
621 621
                     'ID',
622 622
                     'modified',
623
-					'title',
624
-					'relevance',
625
-					'rand'
623
+                    'title',
624
+                    'relevance',
625
+                    'rand'
626 626
                 ),
627 627
             ),
628 628
 
@@ -632,617 +632,617 @@  discard block
 block discarded – undo
632 632
                 'type'        => 'string',
633 633
                 'default'     => 'DESC',
634 634
                 'enum'        => array( 'ASC', 'DESC' ),
635
-			),
635
+            ),
636 636
 			
637
-			// Search term
637
+            // Search term
638 638
             'search'                => array(
639
-				'description'       => __( 'Return items that match the search term.', 'invoicing' ),
640
-				'type'              => 'string',
639
+                'description'       => __( 'Return items that match the search term.', 'invoicing' ),
640
+                'type'              => 'string',
641 641
             ),
642 642
         );
643 643
 
644
-		/**
645
-		 * Filter collection parameters for the items controller.
646
-		 *
647
-		 *
648
-		 * @since 1.0.13
649
-		 *
650
-		 * @param array        $query_params JSON Schema-formatted collection parameters.
651
-		 */
652
-		return apply_filters( "wpinv_rest_items_collection_params", $query_params );
644
+        /**
645
+         * Filter collection parameters for the items controller.
646
+         *
647
+         *
648
+         * @since 1.0.13
649
+         *
650
+         * @param array        $query_params JSON Schema-formatted collection parameters.
651
+         */
652
+        return apply_filters( "wpinv_rest_items_collection_params", $query_params );
653 653
     }
654 654
     
655 655
     /**
656
-	 * Checks if a given post type can be viewed or managed.
657
-	 *
658
-	 * @since 1.0.13
659
-	 *
660
-	 * @param object|string $post_type Post type name or object.
661
-	 * @return bool Whether the post type is allowed in REST.
662
-	 */
663
-	protected function check_is_post_type_allowed( $post_type ) {
664
-		return true;
665
-	}
666
-
667
-	/**
668
-	 * Prepares a single item for create or update.
669
-	 *
670
-	 * @since 1.0.13
671
-	 *
672
-	 * @param WP_REST_Request $request Request object.
673
-	 * @return array|WP_Error Invoice Properties or WP_Error.
674
-	 */
675
-	protected function prepare_item_for_database( $request ) {
676
-		$prepared_item = new stdClass();
677
-
678
-		// Post ID.
679
-		if ( isset( $request['id'] ) ) {
680
-			$existing_item = $this->get_post( $request['id'] );
681
-			if ( is_wp_error( $existing_item ) ) {
682
-				return $existing_item;
683
-			}
684
-
685
-			$prepared_item->ID 		  = $existing_item->ID;
686
-		}
687
-
688
-		$schema = $this->get_item_schema();
689
-
690
-		// item title.
691
-		if ( ! empty( $schema['properties']['name'] ) && isset( $request['name'] ) ) {
692
-			$prepared_item->title = sanitize_text_field( $request['name'] );
693
-		}
694
-
695
-		// item summary.
696
-		if ( ! empty( $schema['properties']['summary'] ) && isset( $request['summary'] ) ) {
697
-			$prepared_item->excerpt = wp_kses_post( $request['summary'] );
698
-		}
699
-
700
-		// item price.
701
-		if ( ! empty( $schema['properties']['price'] ) && isset( $request['price'] ) ) {
702
-			$prepared_item->price = floatval( $request['price'] );
703
-		}
704
-
705
-		// minimum price (for dynamc items).
706
-		if ( ! empty( $schema['properties']['minimum_price'] ) && isset( $request['minimum_price'] ) ) {
707
-			$prepared_item->minimum_price = floatval( $request['minimum_price'] );
708
-		}
709
-
710
-		// item status.
711
-		if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
712
-			$prepared_item->status = 'publish' === $request['status'] ? 'publish' : 'pending';
713
-		}
714
-
715
-		// item type.
716
-		if ( ! empty( $schema['properties']['type'] ) && isset( $request['type'] ) ) {
717
-			$prepared_item->type = in_array( $request['type'], wpinv_item_types() ) ? trim( strtolower( $request['type'] ) ) : 'custom';
718
-		}
719
-
720
-		// VAT rule.
721
-		if ( ! empty( $schema['properties']['vat_rule'] ) && isset( $request['vat_rule'] ) ) {
722
-			$prepared_item->vat_rule = 'digital' === $request['vat_rule'] ? 'digital' : 'physical';
723
-		}
724
-
725
-		// Simple strings.
726
-		foreach( array( 'custom_id', 'custom_name', 'custom_singular_name' ) as $property ) {
727
-
728
-			if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
729
-				$prepared_item->$property = sanitize_text_field( $request[$property] );
730
-			}
731
-
732
-		}
733
-
734
-		// Simple integers.
735
-		foreach( array( 'is_recurring', 'recurring_interval', 'recurring_limit', 'free_trial', 'trial_interval', 'dynamic_pricing', 'editable' ) as $property ) {
736
-
737
-			if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
738
-				$prepared_item->$property = intval( $request[$property] );
739
-			}
740
-
741
-		}
742
-
743
-		// Time periods.
744
-		foreach( array( 'recurring_period',  'trial_period' ) as $property ) {
745
-
746
-			if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
747
-				$prepared_item->$property = in_array( $request[$property], array( 'D', 'W', 'M', 'Y' ) ) ? trim( strtoupper( $request[$property] ) ) : 'D';
748
-			}
749
-
750
-		}
751
-
752
-		$item_data = (array) wp_unslash( $prepared_item );
753
-
754
-		/**
755
-		 * Filters an item before it is inserted via the REST API.
756
-		 *
757
-		 * @since 1.0.13
758
-		 *
759
-		 * @param array        $item_data An array of item data
760
-		 * @param WP_REST_Request $request       Request object.
761
-		 */
762
-		return apply_filters( "wpinv_rest_pre_insert_item", $item_data, $request );
763
-
764
-	}
765
-
766
-	/**
767
-	 * Prepares a single item output for response.
768
-	 *
769
-	 * @since 1.0.13
770
-	 *
771
-	 * @param WPInv_Item   $item    item object.
772
-	 * @param WP_REST_Request $request Request object.
773
-	 * @return WP_REST_Response Response object.
774
-	 */
775
-	public function prepare_item_for_response( $item, $request ) {
656
+     * Checks if a given post type can be viewed or managed.
657
+     *
658
+     * @since 1.0.13
659
+     *
660
+     * @param object|string $post_type Post type name or object.
661
+     * @return bool Whether the post type is allowed in REST.
662
+     */
663
+    protected function check_is_post_type_allowed( $post_type ) {
664
+        return true;
665
+    }
776 666
 
777
-		$GLOBALS['post'] = get_post( $item->get_ID() );
667
+    /**
668
+     * Prepares a single item for create or update.
669
+     *
670
+     * @since 1.0.13
671
+     *
672
+     * @param WP_REST_Request $request Request object.
673
+     * @return array|WP_Error Invoice Properties or WP_Error.
674
+     */
675
+    protected function prepare_item_for_database( $request ) {
676
+        $prepared_item = new stdClass();
677
+
678
+        // Post ID.
679
+        if ( isset( $request['id'] ) ) {
680
+            $existing_item = $this->get_post( $request['id'] );
681
+            if ( is_wp_error( $existing_item ) ) {
682
+                return $existing_item;
683
+            }
778 684
 
779
-		setup_postdata( $item->get_ID() );
685
+            $prepared_item->ID 		  = $existing_item->ID;
686
+        }
780 687
 
781
-		// Fetch the fields to include in this response.
782
-		$fields = $this->get_fields_for_response( $request );
688
+        $schema = $this->get_item_schema();
783 689
 
784
-		// Base fields for every item.
785
-		$data = array();
690
+        // item title.
691
+        if ( ! empty( $schema['properties']['name'] ) && isset( $request['name'] ) ) {
692
+            $prepared_item->title = sanitize_text_field( $request['name'] );
693
+        }
786 694
 
787
-		// Set up ID
788
-		if ( rest_is_field_included( 'id', $fields ) ) {
789
-			$data['id'] = $item->get_ID();
790
-		}
695
+        // item summary.
696
+        if ( ! empty( $schema['properties']['summary'] ) && isset( $request['summary'] ) ) {
697
+            $prepared_item->excerpt = wp_kses_post( $request['summary'] );
698
+        }
791 699
 
700
+        // item price.
701
+        if ( ! empty( $schema['properties']['price'] ) && isset( $request['price'] ) ) {
702
+            $prepared_item->price = floatval( $request['price'] );
703
+        }
792 704
 
793
-		// Item properties
794
-		$item_properties = array(
795
-			'name', 'summary', 'price', 'status', 'type',
796
-			'vat_rule', 'vat_class',
797
-			'custom_id', 'custom_name', 'custom_singular_name', 
798
-			'editable'
799
-		);
705
+        // minimum price (for dynamc items).
706
+        if ( ! empty( $schema['properties']['minimum_price'] ) && isset( $request['minimum_price'] ) ) {
707
+            $prepared_item->minimum_price = floatval( $request['minimum_price'] );
708
+        }
709
+
710
+        // item status.
711
+        if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
712
+            $prepared_item->status = 'publish' === $request['status'] ? 'publish' : 'pending';
713
+        }
800 714
 
801
-		foreach( $item_properties as $property ) {
715
+        // item type.
716
+        if ( ! empty( $schema['properties']['type'] ) && isset( $request['type'] ) ) {
717
+            $prepared_item->type = in_array( $request['type'], wpinv_item_types() ) ? trim( strtolower( $request['type'] ) ) : 'custom';
718
+        }
802 719
 
803
-			if ( rest_is_field_included( $property, $fields ) && method_exists( $item, 'get_' . $property ) ) {
804
-				$data[$property] = call_user_func( array( $item, 'get_' . $property ) );
805
-			}
720
+        // VAT rule.
721
+        if ( ! empty( $schema['properties']['vat_rule'] ) && isset( $request['vat_rule'] ) ) {
722
+            $prepared_item->vat_rule = 'digital' === $request['vat_rule'] ? 'digital' : 'physical';
723
+        }
806 724
 
807
-		}
725
+        // Simple strings.
726
+        foreach( array( 'custom_id', 'custom_name', 'custom_singular_name' ) as $property ) {
808 727
 
809
-		// Dynamic pricing.
810
-		if( $item->supports_dynamic_pricing() ) {
728
+            if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
729
+                $prepared_item->$property = sanitize_text_field( $request[$property] );
730
+            }
811 731
 
812
-			if( rest_is_field_included( 'dynamic_pricing', $fields ) ) {
813
-				$data['dynamic_pricing'] = $item->get_is_dynamic_pricing();
814
-			}
732
+        }
815 733
 
816
-			if( rest_is_field_included( 'minimum_price', $fields ) ) {
817
-				$data['minimum_price'] = $item->get_minimum_price();
818
-			}
819
-		}
734
+        // Simple integers.
735
+        foreach( array( 'is_recurring', 'recurring_interval', 'recurring_limit', 'free_trial', 'trial_interval', 'dynamic_pricing', 'editable' ) as $property ) {
820 736
 
821
-		// Subscriptions.
822
-		if( rest_is_field_included( 'is_recurring', $fields ) ) {
823
-			$data['is_recurring'] = $item->get_is_recurring();
824
-		}
737
+            if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
738
+                $prepared_item->$property = intval( $request[$property] );
739
+            }
825 740
 
826
-		if( $item->is_recurring() ) {
741
+        }
827 742
 
828
-			$recurring_fields = array( 'is_recurring', 'recurring_period', 'recurring_interval', 'recurring_limit', 'free_trial' );
829
-			foreach( $recurring_fields as $field ) {
743
+        // Time periods.
744
+        foreach( array( 'recurring_period',  'trial_period' ) as $property ) {
830 745
 
831
-				if ( rest_is_field_included( $field, $fields ) && method_exists( $item, 'get_' . $field ) ) {
832
-					$data[$field] = call_user_func( array( $item, 'get_' . $field ) );
833
-				}
746
+            if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
747
+                $prepared_item->$property = in_array( $request[$property], array( 'D', 'W', 'M', 'Y' ) ) ? trim( strtoupper( $request[$property] ) ) : 'D';
748
+            }
749
+
750
+        }
751
+
752
+        $item_data = (array) wp_unslash( $prepared_item );
753
+
754
+        /**
755
+         * Filters an item before it is inserted via the REST API.
756
+         *
757
+         * @since 1.0.13
758
+         *
759
+         * @param array        $item_data An array of item data
760
+         * @param WP_REST_Request $request       Request object.
761
+         */
762
+        return apply_filters( "wpinv_rest_pre_insert_item", $item_data, $request );
763
+
764
+    }
765
+
766
+    /**
767
+     * Prepares a single item output for response.
768
+     *
769
+     * @since 1.0.13
770
+     *
771
+     * @param WPInv_Item   $item    item object.
772
+     * @param WP_REST_Request $request Request object.
773
+     * @return WP_REST_Response Response object.
774
+     */
775
+    public function prepare_item_for_response( $item, $request ) {
776
+
777
+        $GLOBALS['post'] = get_post( $item->get_ID() );
778
+
779
+        setup_postdata( $item->get_ID() );
780
+
781
+        // Fetch the fields to include in this response.
782
+        $fields = $this->get_fields_for_response( $request );
783
+
784
+        // Base fields for every item.
785
+        $data = array();
786
+
787
+        // Set up ID
788
+        if ( rest_is_field_included( 'id', $fields ) ) {
789
+            $data['id'] = $item->get_ID();
790
+        }
791
+
792
+
793
+        // Item properties
794
+        $item_properties = array(
795
+            'name', 'summary', 'price', 'status', 'type',
796
+            'vat_rule', 'vat_class',
797
+            'custom_id', 'custom_name', 'custom_singular_name', 
798
+            'editable'
799
+        );
800
+
801
+        foreach( $item_properties as $property ) {
802
+
803
+            if ( rest_is_field_included( $property, $fields ) && method_exists( $item, 'get_' . $property ) ) {
804
+                $data[$property] = call_user_func( array( $item, 'get_' . $property ) );
805
+            }
806
+
807
+        }
808
+
809
+        // Dynamic pricing.
810
+        if( $item->supports_dynamic_pricing() ) {
811
+
812
+            if( rest_is_field_included( 'dynamic_pricing', $fields ) ) {
813
+                $data['dynamic_pricing'] = $item->get_is_dynamic_pricing();
814
+            }
815
+
816
+            if( rest_is_field_included( 'minimum_price', $fields ) ) {
817
+                $data['minimum_price'] = $item->get_minimum_price();
818
+            }
819
+        }
820
+
821
+        // Subscriptions.
822
+        if( rest_is_field_included( 'is_recurring', $fields ) ) {
823
+            $data['is_recurring'] = $item->get_is_recurring();
824
+        }
825
+
826
+        if( $item->is_recurring() ) {
827
+
828
+            $recurring_fields = array( 'is_recurring', 'recurring_period', 'recurring_interval', 'recurring_limit', 'free_trial' );
829
+            foreach( $recurring_fields as $field ) {
830
+
831
+                if ( rest_is_field_included( $field, $fields ) && method_exists( $item, 'get_' . $field ) ) {
832
+                    $data[$field] = call_user_func( array( $item, 'get_' . $field ) );
833
+                }
834 834
 	
835
-			}
835
+            }
836 836
 
837
-			if( $item->has_free_trial() ) {
837
+            if( $item->has_free_trial() ) {
838 838
 
839
-				$trial_fields = array( 'trial_period', 'trial_interval' );
840
-				foreach( $trial_fields as $field ) {
839
+                $trial_fields = array( 'trial_period', 'trial_interval' );
840
+                foreach( $trial_fields as $field ) {
841 841
 
842
-					if ( rest_is_field_included( $field, $fields ) && method_exists( $item, 'get_' . $field ) ) {
843
-						$data[$field] = call_user_func( array( $item, 'get_' . $field ) );
844
-					}
842
+                    if ( rest_is_field_included( $field, $fields ) && method_exists( $item, 'get_' . $field ) ) {
843
+                        $data[$field] = call_user_func( array( $item, 'get_' . $field ) );
844
+                    }
845 845
 	
846
-				}
847
-
848
-			}
849
-
850
-		}
851
-
852
-		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
853
-		$data    = $this->add_additional_fields_to_object( $data, $request );
854
-		$data    = $this->filter_response_by_context( $data, $context );
855
-
856
-		// Wrap the data in a response object.
857
-		$response = rest_ensure_response( $data );
858
-
859
-		$links = $this->prepare_links( $item );
860
-		$response->add_links( $links );
861
-
862
-		if ( ! empty( $links['self']['href'] ) ) {
863
-			$actions = $this->get_available_actions( $item, $request );
864
-
865
-			$self = $links['self']['href'];
866
-
867
-			foreach ( $actions as $rel ) {
868
-				$response->add_link( $rel, $self );
869
-			}
870
-		}
871
-
872
-		/**
873
-		 * Filters the item data for a response.
874
-		 *
875
-		 * @since 1.0.13
876
-		 *
877
-		 * @param WP_REST_Response $response The response object.
878
-		 * @param WPInv_Item    $item  The item object.
879
-		 * @param WP_REST_Request  $request  Request object.
880
-		 */
881
-		return apply_filters( "wpinv_rest_prepare_item", $response, $item, $request );
882
-	}
883
-
884
-	/**
885
-	 * Gets an array of fields to be included on the response.
886
-	 *
887
-	 * Included fields are based on item schema and `_fields=` request argument.
888
-	 *
889
-	 * @since 1.0.13
890
-	 *
891
-	 * @param WP_REST_Request $request Full details about the request.
892
-	 * @return array Fields to be included in the response.
893
-	 */
894
-	public function get_fields_for_response( $request ) {
895
-		$schema     = $this->get_item_schema();
896
-		$properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
897
-
898
-		$additional_fields = $this->get_additional_fields();
899
-		foreach ( $additional_fields as $field_name => $field_options ) {
900
-			// For back-compat, include any field with an empty schema
901
-			// because it won't be present in $this->get_item_schema().
902
-			if ( is_null( $field_options['schema'] ) ) {
903
-				$properties[ $field_name ] = $field_options;
904
-			}
905
-		}
906
-
907
-		// Exclude fields that specify a different context than the request context.
908
-		$context = $request['context'];
909
-		if ( $context ) {
910
-			foreach ( $properties as $name => $options ) {
911
-				if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
912
-					unset( $properties[ $name ] );
913
-				}
914
-			}
915
-		}
916
-
917
-		$fields = array_keys( $properties );
918
-
919
-		if ( ! isset( $request['_fields'] ) ) {
920
-			return $fields;
921
-		}
922
-		$requested_fields = wpinv_parse_list( $request['_fields'] );
923
-		if ( 0 === count( $requested_fields ) ) {
924
-			return $fields;
925
-		}
926
-		// Trim off outside whitespace from the comma delimited list.
927
-		$requested_fields = array_map( 'trim', $requested_fields );
928
-		// Always persist 'id', because it can be needed for add_additional_fields_to_object().
929
-		if ( in_array( 'id', $fields, true ) ) {
930
-			$requested_fields[] = 'id';
931
-		}
932
-		// Return the list of all requested fields which appear in the schema.
933
-		return array_reduce(
934
-			$requested_fields,
935
-			function( $response_fields, $field ) use ( $fields ) {
936
-				if ( in_array( $field, $fields, true ) ) {
937
-					$response_fields[] = $field;
938
-					return $response_fields;
939
-				}
940
-				// Check for nested fields if $field is not a direct match.
941
-				$nested_fields = explode( '.', $field );
942
-				// A nested field is included so long as its top-level property is
943
-				// present in the schema.
944
-				if ( in_array( $nested_fields[0], $fields, true ) ) {
945
-					$response_fields[] = $field;
946
-				}
947
-				return $response_fields;
948
-			},
949
-			array()
950
-		);
951
-	}
952
-
953
-	/**
954
-	 * Retrieves the item's schema, conforming to JSON Schema.
955
-	 *
956
-	 * @since 1.0.13
957
-	 *
958
-	 * @return array Item schema data.
959
-	 */
960
-	public function get_item_schema() {
961
-
962
-		// Maybe retrieve the schema from cache.
963
-		if ( $this->schema ) {
964
-			return $this->add_additional_fields_schema( $this->schema );
965
-		}
966
-
967
-		$schema = array(
968
-			'$schema'    => 'http://json-schema.org/draft-04/schema#',
969
-			'title'      => $this->post_type,
970
-			'type'       => 'object',
971
-
972
-			// Base properties for every Item.
973
-			'properties' 		  => array(
974
-
975
-				'id'           => array(
976
-					'description' => __( 'Unique identifier for the item.', 'invoicing' ),
977
-					'type'        => 'integer',
978
-					'context'     => array( 'view', 'edit', 'embed' ),
979
-					'readonly'    => true,
980
-				),
981
-
982
-				'name'			  => array(
983
-					'description' => __( 'The name for the item.', 'invoicing' ),
984
-					'type'        => 'string',
985
-					'context'     => array( 'view', 'edit', 'embed' ),
986
-				),
987
-
988
-				'summary'        => array(
989
-					'description' => __( 'A summary for the item.', 'invoicing' ),
990
-					'type'        => 'string',
991
-					'context'     => array( 'view', 'edit', 'embed' ),
992
-				),
993
-
994
-				'price'        => array(
995
-					'description' => __( 'The price for the item.', 'invoicing' ),
996
-					'type'        => 'number',
997
-					'context'     => array( 'view', 'edit', 'embed' ),
998
-				),
999
-
1000
-				'status'       => array(
1001
-					'description' => __( 'A named status for the item.', 'invoicing' ),
1002
-					'type'        => 'string',
1003
-					'enum'        => array_keys( get_post_stati( array( 'internal' => false ) ) ),
1004
-					'context'     => array( 'view', 'edit' ),
1005
-				),
1006
-
1007
-				'type'       => array(
1008
-					'description' => __( 'The item type.', 'invoicing' ),
1009
-					'type'        => 'string',
1010
-					'enum'        => wpinv_item_types(),
1011
-					'context'     => array( 'view', 'edit', 'embed' ),
1012
-				),
1013
-
1014
-				'vat_rule'       => array(
1015
-					'description' => __( 'VAT rule applied to the item.', 'invoicing' ),
1016
-					'type'        => 'string',
1017
-					'enum'        => array( 'digital', 'physical' ),
1018
-					'context'     => array( 'view', 'edit' ),
1019
-				),
1020
-
1021
-				'vat_class'       => array(
1022
-					'description' => __( 'VAT class for the item.', 'invoicing' ),
1023
-					'type'        => 'string',
1024
-					'context'     => array( 'view', 'edit' ),
1025
-					'readonly'    => true,
1026
-				),
1027
-
1028
-				'custom_id'       => array(
1029
-					'description' => __( 'Custom id for the item.', 'invoicing' ),
1030
-					'type'        => 'string',
1031
-					'context'     => array( 'view', 'edit', 'embed' ),
1032
-				),
846
+                }
847
+
848
+            }
849
+
850
+        }
851
+
852
+        $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
853
+        $data    = $this->add_additional_fields_to_object( $data, $request );
854
+        $data    = $this->filter_response_by_context( $data, $context );
855
+
856
+        // Wrap the data in a response object.
857
+        $response = rest_ensure_response( $data );
858
+
859
+        $links = $this->prepare_links( $item );
860
+        $response->add_links( $links );
861
+
862
+        if ( ! empty( $links['self']['href'] ) ) {
863
+            $actions = $this->get_available_actions( $item, $request );
864
+
865
+            $self = $links['self']['href'];
866
+
867
+            foreach ( $actions as $rel ) {
868
+                $response->add_link( $rel, $self );
869
+            }
870
+        }
871
+
872
+        /**
873
+         * Filters the item data for a response.
874
+         *
875
+         * @since 1.0.13
876
+         *
877
+         * @param WP_REST_Response $response The response object.
878
+         * @param WPInv_Item    $item  The item object.
879
+         * @param WP_REST_Request  $request  Request object.
880
+         */
881
+        return apply_filters( "wpinv_rest_prepare_item", $response, $item, $request );
882
+    }
883
+
884
+    /**
885
+     * Gets an array of fields to be included on the response.
886
+     *
887
+     * Included fields are based on item schema and `_fields=` request argument.
888
+     *
889
+     * @since 1.0.13
890
+     *
891
+     * @param WP_REST_Request $request Full details about the request.
892
+     * @return array Fields to be included in the response.
893
+     */
894
+    public function get_fields_for_response( $request ) {
895
+        $schema     = $this->get_item_schema();
896
+        $properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
897
+
898
+        $additional_fields = $this->get_additional_fields();
899
+        foreach ( $additional_fields as $field_name => $field_options ) {
900
+            // For back-compat, include any field with an empty schema
901
+            // because it won't be present in $this->get_item_schema().
902
+            if ( is_null( $field_options['schema'] ) ) {
903
+                $properties[ $field_name ] = $field_options;
904
+            }
905
+        }
906
+
907
+        // Exclude fields that specify a different context than the request context.
908
+        $context = $request['context'];
909
+        if ( $context ) {
910
+            foreach ( $properties as $name => $options ) {
911
+                if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
912
+                    unset( $properties[ $name ] );
913
+                }
914
+            }
915
+        }
916
+
917
+        $fields = array_keys( $properties );
918
+
919
+        if ( ! isset( $request['_fields'] ) ) {
920
+            return $fields;
921
+        }
922
+        $requested_fields = wpinv_parse_list( $request['_fields'] );
923
+        if ( 0 === count( $requested_fields ) ) {
924
+            return $fields;
925
+        }
926
+        // Trim off outside whitespace from the comma delimited list.
927
+        $requested_fields = array_map( 'trim', $requested_fields );
928
+        // Always persist 'id', because it can be needed for add_additional_fields_to_object().
929
+        if ( in_array( 'id', $fields, true ) ) {
930
+            $requested_fields[] = 'id';
931
+        }
932
+        // Return the list of all requested fields which appear in the schema.
933
+        return array_reduce(
934
+            $requested_fields,
935
+            function( $response_fields, $field ) use ( $fields ) {
936
+                if ( in_array( $field, $fields, true ) ) {
937
+                    $response_fields[] = $field;
938
+                    return $response_fields;
939
+                }
940
+                // Check for nested fields if $field is not a direct match.
941
+                $nested_fields = explode( '.', $field );
942
+                // A nested field is included so long as its top-level property is
943
+                // present in the schema.
944
+                if ( in_array( $nested_fields[0], $fields, true ) ) {
945
+                    $response_fields[] = $field;
946
+                }
947
+                return $response_fields;
948
+            },
949
+            array()
950
+        );
951
+    }
952
+
953
+    /**
954
+     * Retrieves the item's schema, conforming to JSON Schema.
955
+     *
956
+     * @since 1.0.13
957
+     *
958
+     * @return array Item schema data.
959
+     */
960
+    public function get_item_schema() {
961
+
962
+        // Maybe retrieve the schema from cache.
963
+        if ( $this->schema ) {
964
+            return $this->add_additional_fields_schema( $this->schema );
965
+        }
966
+
967
+        $schema = array(
968
+            '$schema'    => 'http://json-schema.org/draft-04/schema#',
969
+            'title'      => $this->post_type,
970
+            'type'       => 'object',
971
+
972
+            // Base properties for every Item.
973
+            'properties' 		  => array(
974
+
975
+                'id'           => array(
976
+                    'description' => __( 'Unique identifier for the item.', 'invoicing' ),
977
+                    'type'        => 'integer',
978
+                    'context'     => array( 'view', 'edit', 'embed' ),
979
+                    'readonly'    => true,
980
+                ),
981
+
982
+                'name'			  => array(
983
+                    'description' => __( 'The name for the item.', 'invoicing' ),
984
+                    'type'        => 'string',
985
+                    'context'     => array( 'view', 'edit', 'embed' ),
986
+                ),
987
+
988
+                'summary'        => array(
989
+                    'description' => __( 'A summary for the item.', 'invoicing' ),
990
+                    'type'        => 'string',
991
+                    'context'     => array( 'view', 'edit', 'embed' ),
992
+                ),
993
+
994
+                'price'        => array(
995
+                    'description' => __( 'The price for the item.', 'invoicing' ),
996
+                    'type'        => 'number',
997
+                    'context'     => array( 'view', 'edit', 'embed' ),
998
+                ),
999
+
1000
+                'status'       => array(
1001
+                    'description' => __( 'A named status for the item.', 'invoicing' ),
1002
+                    'type'        => 'string',
1003
+                    'enum'        => array_keys( get_post_stati( array( 'internal' => false ) ) ),
1004
+                    'context'     => array( 'view', 'edit' ),
1005
+                ),
1006
+
1007
+                'type'       => array(
1008
+                    'description' => __( 'The item type.', 'invoicing' ),
1009
+                    'type'        => 'string',
1010
+                    'enum'        => wpinv_item_types(),
1011
+                    'context'     => array( 'view', 'edit', 'embed' ),
1012
+                ),
1013
+
1014
+                'vat_rule'       => array(
1015
+                    'description' => __( 'VAT rule applied to the item.', 'invoicing' ),
1016
+                    'type'        => 'string',
1017
+                    'enum'        => array( 'digital', 'physical' ),
1018
+                    'context'     => array( 'view', 'edit' ),
1019
+                ),
1020
+
1021
+                'vat_class'       => array(
1022
+                    'description' => __( 'VAT class for the item.', 'invoicing' ),
1023
+                    'type'        => 'string',
1024
+                    'context'     => array( 'view', 'edit' ),
1025
+                    'readonly'    => true,
1026
+                ),
1027
+
1028
+                'custom_id'       => array(
1029
+                    'description' => __( 'Custom id for the item.', 'invoicing' ),
1030
+                    'type'        => 'string',
1031
+                    'context'     => array( 'view', 'edit', 'embed' ),
1032
+                ),
1033 1033
 				
1034
-				'custom_name'       => array(
1035
-					'description' => __( 'Custom name for the item.', 'invoicing' ),
1036
-					'type'        => 'string',
1037
-					'context'     => array( 'view', 'edit', 'embed' ),
1038
-				),
1039
-
1040
-				'custom_singular_name'       => array(
1041
-					'description' => __( 'Custom singular name for the item.', 'invoicing' ),
1042
-					'type'        => 'string',
1043
-					'context'     => array( 'view', 'edit', 'embed' ),
1044
-				),
1045
-
1046
-				'dynamic_pricing'        => array(
1047
-					'description' => __( 'Whether the item allows a user to set their own price.', 'invoicing' ),
1048
-					'type'        => 'integer',
1049
-					'context'     => array( 'view', 'edit', 'embed' ),
1050
-				),
1051
-
1052
-				'minimum_price'        => array(
1053
-					'description' => __( 'For dynamic prices, this is the minimum price that a user can set.', 'invoicing' ),
1054
-					'type'        => 'number',
1055
-					'context'     => array( 'view', 'edit', 'embed' ),
1056
-				),
1057
-
1058
-				'is_recurring'        => array(
1059
-					'description' => __( 'Whether the item is a subscription item.', 'invoicing' ),
1060
-					'type'        => 'integer',
1061
-					'context'     => array( 'view', 'edit', 'embed' ),
1062
-				),
1063
-
1064
-				'recurring_period'        => array(
1065
-					'description' => __( 'The recurring period for a recurring item.', 'invoicing' ),
1066
-					'type'        => 'string',
1067
-					'context'     => array( 'view', 'edit', 'embed' ),
1068
-					'enum'        => array( 'D', 'W', 'M', 'Y' ),
1069
-				),
1070
-
1071
-				'recurring_interval'        => array(
1072
-					'description' => __( 'The recurring interval for a subscription item.', 'invoicing' ),
1073
-					'type'        => 'integer',
1074
-					'context'     => array( 'view', 'edit', 'embed' ),
1075
-				),
1076
-
1077
-				'recurring_limit'        => array(
1078
-					'description' => __( 'The maximum number of renewals for a subscription item.', 'invoicing' ),
1079
-					'type'        => 'integer',
1080
-					'context'     => array( 'view', 'edit', 'embed' ),
1081
-				),
1082
-
1083
-				'free_trial'        => array(
1084
-					'description' => __( 'Whether the item has a free trial period.', 'invoicing' ),
1085
-					'type'        => 'integer',
1086
-					'context'     => array( 'view', 'edit', 'embed' ),
1087
-				),
1088
-
1089
-				'trial_period'        => array(
1090
-					'description' => __( 'The trial period of a recurring item.', 'invoicing' ),
1091
-					'type'        => 'string',
1092
-					'context'     => array( 'view', 'edit', 'embed' ),
1093
-					'enum'        => array( 'D', 'W', 'M', 'Y' ),
1094
-				),
1095
-
1096
-				'trial_interval'        => array(
1097
-					'description' => __( 'The trial interval for a subscription item.', 'invoicing' ),
1098
-					'type'        => 'integer',
1099
-					'context'     => array( 'view', 'edit', 'embed' ),
1100
-				),
1101
-
1102
-				'editable'        => array(
1103
-					'description' => __( 'Whether or not the item is editable.', 'invoicing' ),
1104
-					'type'        => 'integer',
1105
-					'context'     => array( 'view', 'edit' ),
1106
-				),
1107
-
1108
-			),
1109
-		);
1110
-
1111
-		// Add helpful links to the item schem.
1112
-		$schema['links'] = $this->get_schema_links();
1113
-
1114
-		/**
1115
-		 * Filters the item schema for the REST API.
1116
-		 *
1117
-		 * Enables adding extra properties to items.
1118
-		 *
1119
-		 * @since 1.0.13
1120
-		 *
1121
-		 * @param array   $schema    The item schema.
1122
-		 */
1034
+                'custom_name'       => array(
1035
+                    'description' => __( 'Custom name for the item.', 'invoicing' ),
1036
+                    'type'        => 'string',
1037
+                    'context'     => array( 'view', 'edit', 'embed' ),
1038
+                ),
1039
+
1040
+                'custom_singular_name'       => array(
1041
+                    'description' => __( 'Custom singular name for the item.', 'invoicing' ),
1042
+                    'type'        => 'string',
1043
+                    'context'     => array( 'view', 'edit', 'embed' ),
1044
+                ),
1045
+
1046
+                'dynamic_pricing'        => array(
1047
+                    'description' => __( 'Whether the item allows a user to set their own price.', 'invoicing' ),
1048
+                    'type'        => 'integer',
1049
+                    'context'     => array( 'view', 'edit', 'embed' ),
1050
+                ),
1051
+
1052
+                'minimum_price'        => array(
1053
+                    'description' => __( 'For dynamic prices, this is the minimum price that a user can set.', 'invoicing' ),
1054
+                    'type'        => 'number',
1055
+                    'context'     => array( 'view', 'edit', 'embed' ),
1056
+                ),
1057
+
1058
+                'is_recurring'        => array(
1059
+                    'description' => __( 'Whether the item is a subscription item.', 'invoicing' ),
1060
+                    'type'        => 'integer',
1061
+                    'context'     => array( 'view', 'edit', 'embed' ),
1062
+                ),
1063
+
1064
+                'recurring_period'        => array(
1065
+                    'description' => __( 'The recurring period for a recurring item.', 'invoicing' ),
1066
+                    'type'        => 'string',
1067
+                    'context'     => array( 'view', 'edit', 'embed' ),
1068
+                    'enum'        => array( 'D', 'W', 'M', 'Y' ),
1069
+                ),
1070
+
1071
+                'recurring_interval'        => array(
1072
+                    'description' => __( 'The recurring interval for a subscription item.', 'invoicing' ),
1073
+                    'type'        => 'integer',
1074
+                    'context'     => array( 'view', 'edit', 'embed' ),
1075
+                ),
1076
+
1077
+                'recurring_limit'        => array(
1078
+                    'description' => __( 'The maximum number of renewals for a subscription item.', 'invoicing' ),
1079
+                    'type'        => 'integer',
1080
+                    'context'     => array( 'view', 'edit', 'embed' ),
1081
+                ),
1082
+
1083
+                'free_trial'        => array(
1084
+                    'description' => __( 'Whether the item has a free trial period.', 'invoicing' ),
1085
+                    'type'        => 'integer',
1086
+                    'context'     => array( 'view', 'edit', 'embed' ),
1087
+                ),
1088
+
1089
+                'trial_period'        => array(
1090
+                    'description' => __( 'The trial period of a recurring item.', 'invoicing' ),
1091
+                    'type'        => 'string',
1092
+                    'context'     => array( 'view', 'edit', 'embed' ),
1093
+                    'enum'        => array( 'D', 'W', 'M', 'Y' ),
1094
+                ),
1095
+
1096
+                'trial_interval'        => array(
1097
+                    'description' => __( 'The trial interval for a subscription item.', 'invoicing' ),
1098
+                    'type'        => 'integer',
1099
+                    'context'     => array( 'view', 'edit', 'embed' ),
1100
+                ),
1101
+
1102
+                'editable'        => array(
1103
+                    'description' => __( 'Whether or not the item is editable.', 'invoicing' ),
1104
+                    'type'        => 'integer',
1105
+                    'context'     => array( 'view', 'edit' ),
1106
+                ),
1107
+
1108
+            ),
1109
+        );
1110
+
1111
+        // Add helpful links to the item schem.
1112
+        $schema['links'] = $this->get_schema_links();
1113
+
1114
+        /**
1115
+         * Filters the item schema for the REST API.
1116
+         *
1117
+         * Enables adding extra properties to items.
1118
+         *
1119
+         * @since 1.0.13
1120
+         *
1121
+         * @param array   $schema    The item schema.
1122
+         */
1123 1123
         $schema = apply_filters( "wpinv_rest_item_schema", $schema );
1124 1124
 
1125
-		//  Cache the item schema.
1126
-		$this->schema = $schema;
1125
+        //  Cache the item schema.
1126
+        $this->schema = $schema;
1127 1127
 		
1128
-		return $this->add_additional_fields_schema( $this->schema );
1129
-	}
1130
-
1131
-	/**
1132
-	 * Retrieve Link Description Objects that should be added to the Schema for the invoices collection.
1133
-	 *
1134
-	 * @since 1.0.13
1135
-	 *
1136
-	 * @return array
1137
-	 */
1138
-	protected function get_schema_links() {
1139
-
1140
-		$href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
1141
-
1142
-		$links = array();
1143
-
1144
-		$links[] = array(
1145
-			'rel'          => 'https://api.w.org/action-publish',
1146
-			'title'        => __( 'The current user can publish this item.' ),
1147
-			'href'         => $href,
1148
-			'targetSchema' => array(
1149
-				'type'       => 'object',
1150
-				'properties' => array(
1151
-					'status' => array(
1152
-						'type' => 'string',
1153
-						'enum' => array( 'publish', 'future' ),
1154
-					),
1155
-				),
1156
-			),
1157
-		);
1158
-
1159
-		return $links;
1160
-	}
1161
-
1162
-	/**
1163
-	 * Prepares links for the request.
1164
-	 *
1165
-	 * @since 1.0.13
1166
-	 *
1167
-	 * @param WPInv_Item $item Item Object.
1168
-	 * @return array Links for the given item.
1169
-	 */
1170
-	protected function prepare_links( $item ) {
1171
-
1172
-		// Prepare the base REST API endpoint for items.
1173
-		$base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
1174
-
1175
-		// Entity meta.
1176
-		$links = array(
1177
-			'self'       => array(
1178
-				'href' => rest_url( trailingslashit( $base ) . $item->ID ),
1179
-			),
1180
-			'collection' => array(
1181
-				'href' => rest_url( $base ),
1182
-			),
1183
-		);
1184
-
1185
-		/**
1186
-		 * Filters the returned item links for the REST API.
1187
-		 *
1188
-		 * Enables adding extra links to item API responses.
1189
-		 *
1190
-		 * @since 1.0.13
1191
-		 *
1192
-		 * @param array   $links    Rest links.
1193
-		 */
1194
-		return apply_filters( "wpinv_rest_item_links", $links );
1195
-
1196
-	}
1197
-
1198
-	/**
1199
-	 * Get the link relations available for the post and current user.
1200
-	 *
1201
-	 * @since 1.0.13
1202
-	 *
1203
-	 * @param WPInv_Item   $item    Item object.
1204
-	 * @param WP_REST_Request $request Request object.
1205
-	 * @return array List of link relations.
1206
-	 */
1207
-	protected function get_available_actions( $item, $request ) {
1208
-
1209
-		if ( 'edit' !== $request['context'] ) {
1210
-			return array();
1211
-		}
1212
-
1213
-		$rels = array();
1214
-
1215
-		// Retrieve the post type object.
1216
-		$post_type = get_post_type_object( $item->post_type );
1217
-
1218
-		// Mark item as published.
1219
-		if ( current_user_can( $post_type->cap->publish_posts ) ) {
1220
-			$rels[] = 'https://api.w.org/action-publish';
1221
-		}
1222
-
1223
-		/**
1224
-		 * Filters the available item link relations for the REST API.
1225
-		 *
1226
-		 * Enables adding extra link relation for the current user and request to item responses.
1227
-		 *
1228
-		 * @since 1.0.13
1229
-		 *
1230
-		 * @param array   $rels    Available link relations.
1231
-		 */
1232
-		return apply_filters( "wpinv_rest_item_link_relations", $rels );
1233
-	}
1234
-
1235
-	/**
1236
-	 * Handles rest requests for item types.
1237
-	 *
1238
-	 * @since 1.0.13
1239
-	 * 
1240
-	 * 
1241
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
1242
-	 */
1243
-	public function get_item_types() {
1244
-		return rest_ensure_response( wpinv_get_item_types() );
1245
-	}
1128
+        return $this->add_additional_fields_schema( $this->schema );
1129
+    }
1130
+
1131
+    /**
1132
+     * Retrieve Link Description Objects that should be added to the Schema for the invoices collection.
1133
+     *
1134
+     * @since 1.0.13
1135
+     *
1136
+     * @return array
1137
+     */
1138
+    protected function get_schema_links() {
1139
+
1140
+        $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
1141
+
1142
+        $links = array();
1143
+
1144
+        $links[] = array(
1145
+            'rel'          => 'https://api.w.org/action-publish',
1146
+            'title'        => __( 'The current user can publish this item.' ),
1147
+            'href'         => $href,
1148
+            'targetSchema' => array(
1149
+                'type'       => 'object',
1150
+                'properties' => array(
1151
+                    'status' => array(
1152
+                        'type' => 'string',
1153
+                        'enum' => array( 'publish', 'future' ),
1154
+                    ),
1155
+                ),
1156
+            ),
1157
+        );
1158
+
1159
+        return $links;
1160
+    }
1161
+
1162
+    /**
1163
+     * Prepares links for the request.
1164
+     *
1165
+     * @since 1.0.13
1166
+     *
1167
+     * @param WPInv_Item $item Item Object.
1168
+     * @return array Links for the given item.
1169
+     */
1170
+    protected function prepare_links( $item ) {
1171
+
1172
+        // Prepare the base REST API endpoint for items.
1173
+        $base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
1174
+
1175
+        // Entity meta.
1176
+        $links = array(
1177
+            'self'       => array(
1178
+                'href' => rest_url( trailingslashit( $base ) . $item->ID ),
1179
+            ),
1180
+            'collection' => array(
1181
+                'href' => rest_url( $base ),
1182
+            ),
1183
+        );
1184
+
1185
+        /**
1186
+         * Filters the returned item links for the REST API.
1187
+         *
1188
+         * Enables adding extra links to item API responses.
1189
+         *
1190
+         * @since 1.0.13
1191
+         *
1192
+         * @param array   $links    Rest links.
1193
+         */
1194
+        return apply_filters( "wpinv_rest_item_links", $links );
1195
+
1196
+    }
1197
+
1198
+    /**
1199
+     * Get the link relations available for the post and current user.
1200
+     *
1201
+     * @since 1.0.13
1202
+     *
1203
+     * @param WPInv_Item   $item    Item object.
1204
+     * @param WP_REST_Request $request Request object.
1205
+     * @return array List of link relations.
1206
+     */
1207
+    protected function get_available_actions( $item, $request ) {
1208
+
1209
+        if ( 'edit' !== $request['context'] ) {
1210
+            return array();
1211
+        }
1212
+
1213
+        $rels = array();
1214
+
1215
+        // Retrieve the post type object.
1216
+        $post_type = get_post_type_object( $item->post_type );
1217
+
1218
+        // Mark item as published.
1219
+        if ( current_user_can( $post_type->cap->publish_posts ) ) {
1220
+            $rels[] = 'https://api.w.org/action-publish';
1221
+        }
1222
+
1223
+        /**
1224
+         * Filters the available item link relations for the REST API.
1225
+         *
1226
+         * Enables adding extra link relation for the current user and request to item responses.
1227
+         *
1228
+         * @since 1.0.13
1229
+         *
1230
+         * @param array   $rels    Available link relations.
1231
+         */
1232
+        return apply_filters( "wpinv_rest_item_link_relations", $rels );
1233
+    }
1234
+
1235
+    /**
1236
+     * Handles rest requests for item types.
1237
+     *
1238
+     * @since 1.0.13
1239
+     * 
1240
+     * 
1241
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
1242
+     */
1243
+    public function get_item_types() {
1244
+        return rest_ensure_response( wpinv_get_item_types() );
1245
+    }
1246 1246
 
1247 1247
     
1248 1248
 }
1249 1249
\ No newline at end of file
Please login to merge, or discard this patch.
includes/class-wpinv-api.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -52,14 +52,14 @@
 block discarded – undo
52 52
     }
53 53
 
54 54
 
55
-	/**
56
-	 * Registers routes
57
-	 *
55
+    /**
56
+     * Registers routes
57
+     *
58 58
      * @since 1.0.13
59
-	 */
60
-	public function register_rest_routes() {
59
+     */
60
+    public function register_rest_routes() {
61 61
 
62
-		// Invoices.
62
+        // Invoices.
63 63
         $this->invoices_controller->register_routes();
64 64
         
65 65
         // Items.
Please login to merge, or discard this patch.
includes/api/class-wpinv-rest-invoice-controller.php 1 patch
Indentation   +1114 added lines, -1114 removed lines patch added patch discarded remove patch
@@ -20,31 +20,31 @@  discard block
 block discarded – undo
20 20
 class WPInv_REST_Invoice_Controller extends WP_REST_Posts_Controller {
21 21
 
22 22
     /**
23
-	 * Post type.
24
-	 *
25
-	 * @var string
26
-	 */
27
-	protected $post_type = 'wpi_invoice';
23
+     * Post type.
24
+     *
25
+     * @var string
26
+     */
27
+    protected $post_type = 'wpi_invoice';
28 28
 	
29
-	/**
30
-	 * Cached results of get_item_schema.
31
-	 *
32
-	 * @since 1.0.13
33
-	 * @var array
34
-	 */
35
-	protected $schema;
29
+    /**
30
+     * Cached results of get_item_schema.
31
+     *
32
+     * @since 1.0.13
33
+     * @var array
34
+     */
35
+    protected $schema;
36 36
 
37 37
     /**
38
-	 * Constructor.
39
-	 *
40
-	 * @since 1.0.13
41
-	 *
42
-	 * @param string $namespace Api Namespace
43
-	 */
44
-	public function __construct( $namespace ) {
38
+     * Constructor.
39
+     *
40
+     * @since 1.0.13
41
+     *
42
+     * @param string $namespace Api Namespace
43
+     */
44
+    public function __construct( $namespace ) {
45 45
         
46 46
         // Set api namespace...
47
-		$this->namespace = $namespace;
47
+        $this->namespace = $namespace;
48 48
 
49 49
         // ... and the rest base
50 50
         $this->rest_base = 'invoices';
@@ -52,39 +52,39 @@  discard block
 block discarded – undo
52 52
     }
53 53
     
54 54
     /**
55
-	 * Checks if a given request has access to read invoices.
55
+     * Checks if a given request has access to read invoices.
56 56
      * 
57
-	 *
58
-	 * @since 1.0.13
59
-	 *
60
-	 * @param WP_REST_Request $request Full details about the request.
61
-	 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
62
-	 */
63
-	public function get_items_permissions_check( $request ) {
57
+     *
58
+     * @since 1.0.13
59
+     *
60
+     * @param WP_REST_Request $request Full details about the request.
61
+     * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
62
+     */
63
+    public function get_items_permissions_check( $request ) {
64 64
 	
65 65
         $post_type = get_post_type_object( $this->post_type );
66 66
 
67
-		if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) {
68
-			return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit invoices.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
69
-		}
67
+        if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) {
68
+            return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit invoices.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
69
+        }
70 70
 
71
-		// Read checks will be evaluated on a per invoice basis
71
+        // Read checks will be evaluated on a per invoice basis
72 72
 
73
-		return true;
73
+        return true;
74 74
 
75 75
     }
76 76
     
77 77
     /**
78
-	 * Retrieves a collection of invoices.
79
-	 *
80
-	 * @since 1.0.13
81
-	 *
82
-	 * @param WP_REST_Request $request Full details about the request.
83
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
84
-	 */
85
-	public function get_items( $request ) {
78
+     * Retrieves a collection of invoices.
79
+     *
80
+     * @since 1.0.13
81
+     *
82
+     * @param WP_REST_Request $request Full details about the request.
83
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
84
+     */
85
+    public function get_items( $request ) {
86 86
 		
87
-		// Retrieve the list of registered invoice query parameters.
87
+        // Retrieve the list of registered invoice query parameters.
88 88
         $registered = $this->get_collection_params();
89 89
         
90 90
         $args       = array();
@@ -97,54 +97,54 @@  discard block
 block discarded – undo
97 97
 
98 98
         }
99 99
 
100
-		/**
101
-		 * Filters the wpinv_get_invoices arguments for invoices requests.
102
-		 *
103
-		 *
104
-		 * @since 1.0.13
105
-		 *
106
-		 *
107
-		 * @param array           $args    Key value array of query var to query value.
108
-		 * @param WP_REST_Request $request The request used.
109
-		 */
100
+        /**
101
+         * Filters the wpinv_get_invoices arguments for invoices requests.
102
+         *
103
+         *
104
+         * @since 1.0.13
105
+         *
106
+         *
107
+         * @param array           $args    Key value array of query var to query value.
108
+         * @param WP_REST_Request $request The request used.
109
+         */
110 110
         $args       = apply_filters( "wpinv_rest_get_invoices_arguments", $args, $request, $this );
111 111
 		
112
-		// Special args
113
-		$args[ 'return' ]   = 'objects';
114
-		$args[ 'paginate' ] = true;
112
+        // Special args
113
+        $args[ 'return' ]   = 'objects';
114
+        $args[ 'paginate' ] = true;
115 115
 
116 116
         // Run the query.
117
-		$query = wpinv_get_invoices( $args );
117
+        $query = wpinv_get_invoices( $args );
118 118
 		
119
-		// Prepare the retrieved invoices
120
-		$invoices = array();
121
-		foreach( $query->invoices as $invoice ) {
122
-
123
-			if ( ! $this->check_read_permission( $invoice ) ) {
124
-				continue;
125
-			}
126
-
127
-			$data       = $this->prepare_item_for_response( $invoice, $request );
128
-			$invoices[] = $this->prepare_response_for_collection( $data );
129
-
130
-		}
131
-
132
-		// Prepare the response.
133
-		$response = rest_ensure_response( $invoices );
134
-		$response->header( 'X-WP-Total', (int) $query->total );
135
-		$response->header( 'X-WP-TotalPages', (int) $query->max_num_pages );
136
-
137
-		/**
138
-		 * Filters the responses for invoices requests.
139
-		 *
140
-		 *
141
-		 * @since 1.0.13
142
-		 *
143
-		 *
144
-		 * @param arrWP_REST_Response $response    Response object.
145
-		 * @param WP_REST_Request     $request The request used.
119
+        // Prepare the retrieved invoices
120
+        $invoices = array();
121
+        foreach( $query->invoices as $invoice ) {
122
+
123
+            if ( ! $this->check_read_permission( $invoice ) ) {
124
+                continue;
125
+            }
126
+
127
+            $data       = $this->prepare_item_for_response( $invoice, $request );
128
+            $invoices[] = $this->prepare_response_for_collection( $data );
129
+
130
+        }
131
+
132
+        // Prepare the response.
133
+        $response = rest_ensure_response( $invoices );
134
+        $response->header( 'X-WP-Total', (int) $query->total );
135
+        $response->header( 'X-WP-TotalPages', (int) $query->max_num_pages );
136
+
137
+        /**
138
+         * Filters the responses for invoices requests.
139
+         *
140
+         *
141
+         * @since 1.0.13
142
+         *
143
+         *
144
+         * @param arrWP_REST_Response $response    Response object.
145
+         * @param WP_REST_Request     $request The request used.
146 146
          * @param array               $args Array of args used to retrieve the invoices
147
-		 */
147
+         */
148 148
         $response       = apply_filters( "wpinv_rest_invoices_response", $response, $request, $args );
149 149
 
150 150
         return rest_ensure_response( $response );
@@ -152,25 +152,25 @@  discard block
 block discarded – undo
152 152
     }
153 153
 
154 154
     /**
155
-	 * Get the post, if the ID is valid.
156
-	 *
157
-	 * @since 1.0.13
158
-	 *
159
-	 * @param int $invoice_id Supplied ID.
160
-	 * @return WPInv_Invoice|WP_Error Invoice object if ID is valid, WP_Error otherwise.
161
-	 */
162
-	protected function get_post( $invoice_id ) {
155
+     * Get the post, if the ID is valid.
156
+     *
157
+     * @since 1.0.13
158
+     *
159
+     * @param int $invoice_id Supplied ID.
160
+     * @return WPInv_Invoice|WP_Error Invoice object if ID is valid, WP_Error otherwise.
161
+     */
162
+    protected function get_post( $invoice_id ) {
163 163
 		
164
-		$error     = new WP_Error( 'rest_invoice_invalid_id', __( 'Invalid invoice ID.', 'invoicing' ), array( 'status' => 404 ) );
164
+        $error     = new WP_Error( 'rest_invoice_invalid_id', __( 'Invalid invoice ID.', 'invoicing' ), array( 'status' => 404 ) );
165 165
 
166 166
         // Ids start from 1
167 167
         if ( (int) $invoice_id <= 0 ) {
168
-			return $error;
169
-		}
168
+            return $error;
169
+        }
170 170
 
171
-		$invoice = wpinv_get_invoice( (int) $invoice_id );
172
-		if ( empty( $invoice ) ) {
173
-			return $error;
171
+        $invoice = wpinv_get_invoice( (int) $invoice_id );
172
+        if ( empty( $invoice ) ) {
173
+            return $error;
174 174
         }
175 175
 
176 176
         return $invoice;
@@ -178,77 +178,77 @@  discard block
 block discarded – undo
178 178
     }
179 179
 
180 180
     /**
181
-	 * Checks if a given request has access to read an invoice.
182
-	 *
183
-	 * @since 1.0.13
184
-	 *
185
-	 * @param WP_REST_Request $request Full details about the request.
186
-	 * @return bool|WP_Error True if the request has read access for the invoice, WP_Error object otherwise.
187
-	 */
188
-	public function get_item_permissions_check( $request ) {
181
+     * Checks if a given request has access to read an invoice.
182
+     *
183
+     * @since 1.0.13
184
+     *
185
+     * @param WP_REST_Request $request Full details about the request.
186
+     * @return bool|WP_Error True if the request has read access for the invoice, WP_Error object otherwise.
187
+     */
188
+    public function get_item_permissions_check( $request ) {
189 189
 
190 190
         // Retrieve the invoice object.
191 191
         $invoice = $this->get_post( $request['id'] );
192 192
         
193 193
         // Ensure it is valid.
194
-		if ( is_wp_error( $invoice ) ) {
195
-			return $invoice;
196
-		}
194
+        if ( is_wp_error( $invoice ) ) {
195
+            return $invoice;
196
+        }
197 197
 
198
-		if ( $invoice ) {
199
-			return $this->check_read_permission( $invoice );
200
-		}
198
+        if ( $invoice ) {
199
+            return $this->check_read_permission( $invoice );
200
+        }
201 201
 
202
-		return true;
202
+        return true;
203 203
     }
204 204
     
205 205
     /**
206
-	 * Checks if an invoice can be read.
207
-	 * 
208
-	 * An invoice can be read by site admins and owners of the invoice
209
-	 *
210
-	 *
211
-	 * @since 1.0.13
212
-	 *
213
-	 * @param WPInv_Invoice $invoice WPInv_Invoice object.
214
-	 * @return bool Whether the post can be read.
215
-	 */
216
-	public function check_read_permission( $invoice ) {
217
-		return wpinv_user_can_view_invoice( $invoice->ID );
206
+     * Checks if an invoice can be read.
207
+     * 
208
+     * An invoice can be read by site admins and owners of the invoice
209
+     *
210
+     *
211
+     * @since 1.0.13
212
+     *
213
+     * @param WPInv_Invoice $invoice WPInv_Invoice object.
214
+     * @return bool Whether the post can be read.
215
+     */
216
+    public function check_read_permission( $invoice ) {
217
+        return wpinv_user_can_view_invoice( $invoice->ID );
218 218
     }
219 219
     
220 220
     /**
221
-	 * Retrieves a single invoice.
222
-	 *
223
-	 * @since 1.0.13
224
-	 *
225
-	 * @param WP_REST_Request $request Full details about the request.
226
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
227
-	 */
228
-	public function get_item( $request ) {
221
+     * Retrieves a single invoice.
222
+     *
223
+     * @since 1.0.13
224
+     *
225
+     * @param WP_REST_Request $request Full details about the request.
226
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
227
+     */
228
+    public function get_item( $request ) {
229 229
 
230 230
         // Fetch the invoice.
231 231
         $invoice = $this->get_post( $request['id'] );
232 232
         
233 233
         // Abort early if it does not exist
234
-		if ( is_wp_error( $invoice ) ) {
235
-			return $invoice;
236
-		}
237
-
238
-		// Prepare the response
239
-		$response = $this->prepare_item_for_response( $invoice, $request );
240
-		$response->link_header( 'alternate', esc_url( $invoice->get_view_url() ), array( 'type' => 'text/html' ) );
241
-
242
-		/**
243
-		 * Filters the responses for single invoice requests.
244
-		 *
245
-		 *
246
-		 * @since 1.0.13
247
-		 * @var WP_HTTP_Response
248
-		 *
249
-		 * @param WP_HTTP_Response $response Response.
250
-		 * @param WP_REST_Request  $request The request used.
251
-		 */
234
+        if ( is_wp_error( $invoice ) ) {
235
+            return $invoice;
236
+        }
237
+
238
+        // Prepare the response
239
+        $response = $this->prepare_item_for_response( $invoice, $request );
240
+        $response->link_header( 'alternate', esc_url( $invoice->get_view_url() ), array( 'type' => 'text/html' ) );
241
+
242
+        /**
243
+         * Filters the responses for single invoice requests.
244
+         *
245
+         *
246
+         * @since 1.0.13
247
+         * @var WP_HTTP_Response
248
+         *
249
+         * @param WP_HTTP_Response $response Response.
250
+         * @param WP_REST_Request  $request The request used.
251
+         */
252 252
         $response       = apply_filters( "wpinv_rest_get_invoice_response", $response, $request );
253 253
 
254 254
         return rest_ensure_response( $response );
@@ -256,23 +256,23 @@  discard block
 block discarded – undo
256 256
     }
257 257
     
258 258
     /**
259
-	 * Checks if a given request has access to create an invoice.
260
-	 *
261
-	 * @since 1.0.13
262
-	 *
263
-	 * @param WP_REST_Request $request Full details about the request.
264
-	 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
265
-	 */
266
-	public function create_item_permissions_check( $request ) {
259
+     * Checks if a given request has access to create an invoice.
260
+     *
261
+     * @since 1.0.13
262
+     *
263
+     * @param WP_REST_Request $request Full details about the request.
264
+     * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
265
+     */
266
+    public function create_item_permissions_check( $request ) {
267 267
 	
268
-		if ( ! empty( $request['id'] ) ) {
269
-			return new WP_Error( 'rest_invoice_exists', __( 'Cannot create existing invoice.', 'invoicing' ), array( 'status' => 400 ) );
270
-		}
268
+        if ( ! empty( $request['id'] ) ) {
269
+            return new WP_Error( 'rest_invoice_exists', __( 'Cannot create existing invoice.', 'invoicing' ), array( 'status' => 400 ) );
270
+        }
271 271
 
272
-		$post_type = get_post_type_object( $this->post_type );
272
+        $post_type = get_post_type_object( $this->post_type );
273 273
 
274
-		if ( ! current_user_can( $post_type->cap->create_posts ) ) {
275
-			return new WP_Error( 
274
+        if ( ! current_user_can( $post_type->cap->create_posts ) ) {
275
+            return new WP_Error( 
276 276
                 'rest_cannot_create', 
277 277
                 __( 'Sorry, you are not allowed to create invoices as this user.', 'invoicing' ), 
278 278
                 array( 
@@ -281,88 +281,88 @@  discard block
 block discarded – undo
281 281
             );
282 282
         }
283 283
 
284
-		return true;
284
+        return true;
285 285
     }
286 286
     
287 287
     /**
288
-	 * Creates a single invoice.
289
-	 *
290
-	 * @since 1.0.13
291
-	 *
292
-	 * @param WP_REST_Request $request Full details about the request.
293
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
294
-	 */
295
-	public function create_item( $request ) {
296
-
297
-		if ( ! empty( $request['id'] ) ) {
298
-			return new WP_Error( 'rest_invoice_exists', __( 'Cannot create existing invoice.', 'invoicing' ), array( 'status' => 400 ) );
299
-		}
288
+     * Creates a single invoice.
289
+     *
290
+     * @since 1.0.13
291
+     *
292
+     * @param WP_REST_Request $request Full details about the request.
293
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
294
+     */
295
+    public function create_item( $request ) {
296
+
297
+        if ( ! empty( $request['id'] ) ) {
298
+            return new WP_Error( 'rest_invoice_exists', __( 'Cannot create existing invoice.', 'invoicing' ), array( 'status' => 400 ) );
299
+        }
300 300
 
301
-		$request->set_param( 'context', 'edit' );
301
+        $request->set_param( 'context', 'edit' );
302 302
 
303
-		// Prepare the updated data.
304
-		$invoice_data = $this->prepare_item_for_database( $request );
303
+        // Prepare the updated data.
304
+        $invoice_data = $this->prepare_item_for_database( $request );
305 305
 
306
-		if ( is_wp_error( $invoice_data ) ) {
307
-			return $invoice_data;
308
-		}
306
+        if ( is_wp_error( $invoice_data ) ) {
307
+            return $invoice_data;
308
+        }
309 309
 
310
-		// Try creating the invoice
310
+        // Try creating the invoice
311 311
         $invoice = wpinv_insert_invoice( $invoice_data, true );
312 312
 
313
-		if ( is_wp_error( $invoice ) ) {
313
+        if ( is_wp_error( $invoice ) ) {
314 314
             return $invoice;
315
-		}
316
-
317
-		// Prepare the response
318
-		$response = $this->prepare_item_for_response( $invoice, $request );
319
-
320
-		/**
321
-		 * Fires after a single invoice is created or updated via the REST API.
322
-		 *
323
-		 * @since 1.0.13
324
-		 *
325
-		 * @param WPinv_Invoice   $invoice  Inserted or updated invoice object.
326
-		 * @param WP_REST_Request $request  Request object.
327
-		 * @param bool            $creating True when creating a post, false when updating.
328
-		 */
329
-		do_action( "wpinv_rest_insert_invoice", $invoice, $request, true );
330
-
331
-		/**
332
-		 * Filters the responses for creating single invoice requests.
333
-		 *
334
-		 *
335
-		 * @since 1.0.13
336
-		 *
337
-		 *
338
-		 * @param array           $invoice_data Invoice properties.
339
-		 * @param WP_REST_Request $request The request used.
340
-		 */
315
+        }
316
+
317
+        // Prepare the response
318
+        $response = $this->prepare_item_for_response( $invoice, $request );
319
+
320
+        /**
321
+         * Fires after a single invoice is created or updated via the REST API.
322
+         *
323
+         * @since 1.0.13
324
+         *
325
+         * @param WPinv_Invoice   $invoice  Inserted or updated invoice object.
326
+         * @param WP_REST_Request $request  Request object.
327
+         * @param bool            $creating True when creating a post, false when updating.
328
+         */
329
+        do_action( "wpinv_rest_insert_invoice", $invoice, $request, true );
330
+
331
+        /**
332
+         * Filters the responses for creating single invoice requests.
333
+         *
334
+         *
335
+         * @since 1.0.13
336
+         *
337
+         *
338
+         * @param array           $invoice_data Invoice properties.
339
+         * @param WP_REST_Request $request The request used.
340
+         */
341 341
         $response       = apply_filters( "wpinv_rest_create_invoice_response", $response, $request );
342 342
 
343 343
         return rest_ensure_response( $response );
344
-	}
345
-
346
-	/**
347
-	 * Checks if a given request has access to update an invoice.
348
-	 *
349
-	 * @since 1.0.13
350
-	 *
351
-	 * @param WP_REST_Request $request Full details about the request.
352
-	 * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
353
-	 */
354
-	public function update_item_permissions_check( $request ) {
355
-
356
-		// Retrieve the invoice.
357
-		$invoice = $this->get_post( $request['id'] );
358
-		if ( is_wp_error( $invoice ) ) {
359
-			return $invoice;
360
-		}
361
-
362
-		$post_type = get_post_type_object( $this->post_type );
363
-
364
-		if ( ! current_user_can(  $post_type->cap->edit_post, $invoice->ID  ) ) {
365
-			return new WP_Error( 
344
+    }
345
+
346
+    /**
347
+     * Checks if a given request has access to update an invoice.
348
+     *
349
+     * @since 1.0.13
350
+     *
351
+     * @param WP_REST_Request $request Full details about the request.
352
+     * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
353
+     */
354
+    public function update_item_permissions_check( $request ) {
355
+
356
+        // Retrieve the invoice.
357
+        $invoice = $this->get_post( $request['id'] );
358
+        if ( is_wp_error( $invoice ) ) {
359
+            return $invoice;
360
+        }
361
+
362
+        $post_type = get_post_type_object( $this->post_type );
363
+
364
+        if ( ! current_user_can(  $post_type->cap->edit_post, $invoice->ID  ) ) {
365
+            return new WP_Error( 
366 366
                 'rest_cannot_edit', 
367 367
                 __( 'Sorry, you are not allowed to update this invoice.', 'invoicing' ), 
368 368
                 array( 
@@ -371,162 +371,162 @@  discard block
 block discarded – undo
371 371
             );
372 372
         }
373 373
 
374
-		return true;
375
-	}
376
-
377
-	/**
378
-	 * Updates a single invoice.
379
-	 *
380
-	 * @since 1.0.13
381
-	 *
382
-	 * @param WP_REST_Request $request Full details about the request.
383
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
384
-	 */
385
-	public function update_item( $request ) {
374
+        return true;
375
+    }
376
+
377
+    /**
378
+     * Updates a single invoice.
379
+     *
380
+     * @since 1.0.13
381
+     *
382
+     * @param WP_REST_Request $request Full details about the request.
383
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
384
+     */
385
+    public function update_item( $request ) {
386 386
 		
387
-		// Ensure the invoice exists.
387
+        // Ensure the invoice exists.
388 388
         $valid_check = $this->get_post( $request['id'] );
389 389
         
390 390
         // Abort early if it does not exist
391
-		if ( is_wp_error( $valid_check ) ) {
392
-			return $valid_check;
393
-		}
391
+        if ( is_wp_error( $valid_check ) ) {
392
+            return $valid_check;
393
+        }
394 394
 
395
-		$request->set_param( 'context', 'edit' );
395
+        $request->set_param( 'context', 'edit' );
396 396
 
397
-		// Prepare the updated data.
398
-		$data_to_update = $this->prepare_item_for_database( $request );
397
+        // Prepare the updated data.
398
+        $data_to_update = $this->prepare_item_for_database( $request );
399 399
 
400
-		if ( is_wp_error( $data_to_update ) ) {
401
-			return $data_to_update;
402
-		}
400
+        if ( is_wp_error( $data_to_update ) ) {
401
+            return $data_to_update;
402
+        }
403 403
 
404
-		// Abort if no invoice data is provided
404
+        // Abort if no invoice data is provided
405 405
         if( empty( $data_to_update ) ) {
406 406
             return new WP_Error( 'missing_data', __( 'An update request cannot be empty.', 'invoicing' ) );
407 407
         }
408 408
 
409
-		// Include the invoice ID
410
-		$data_to_update['ID'] = $request['id'];
411
-
412
-		// Update the invoice
413
-		$updated_invoice = wpinv_update_invoice( $data_to_update, true );
414
-
415
-		// Incase the update operation failed...
416
-		if ( is_wp_error( $updated_invoice ) ) {
417
-			return $updated_invoice;
418
-		}
419
-
420
-		// Prepare the response
421
-		$response = $this->prepare_item_for_response( $updated_invoice, $request );
422
-
423
-		/** This action is documented in includes/class-wpinv-rest-invoice-controller.php */
424
-		do_action( "wpinv_rest_insert_invoice", $updated_invoice, $request, false );
425
-
426
-		/**
427
-		 * Filters the responses for updating single invoice requests.
428
-		 *
429
-		 *
430
-		 * @since 1.0.13
431
-		 *
432
-		 *
433
-		 * @param array           $invoice_data Invoice properties.
434
-		 * @param WP_REST_Request $request The request used.
435
-		 */
409
+        // Include the invoice ID
410
+        $data_to_update['ID'] = $request['id'];
411
+
412
+        // Update the invoice
413
+        $updated_invoice = wpinv_update_invoice( $data_to_update, true );
414
+
415
+        // Incase the update operation failed...
416
+        if ( is_wp_error( $updated_invoice ) ) {
417
+            return $updated_invoice;
418
+        }
419
+
420
+        // Prepare the response
421
+        $response = $this->prepare_item_for_response( $updated_invoice, $request );
422
+
423
+        /** This action is documented in includes/class-wpinv-rest-invoice-controller.php */
424
+        do_action( "wpinv_rest_insert_invoice", $updated_invoice, $request, false );
425
+
426
+        /**
427
+         * Filters the responses for updating single invoice requests.
428
+         *
429
+         *
430
+         * @since 1.0.13
431
+         *
432
+         *
433
+         * @param array           $invoice_data Invoice properties.
434
+         * @param WP_REST_Request $request The request used.
435
+         */
436 436
         $response       = apply_filters( "wpinv_rest_update_invoice_response", $response, $request );
437 437
 
438 438
         return rest_ensure_response( $response );
439
-	}
440
-
441
-	/**
442
-	 * Checks if a given request has access to delete an invoice.
443
-	 *
444
-	 * @since 1.0.13
445
-	 *
446
-	 * @param WP_REST_Request $request Full details about the request.
447
-	 * @return true|WP_Error True if the request has access to delete the invoice, WP_Error object otherwise.
448
-	 */
449
-	public function delete_item_permissions_check( $request ) {
450
-
451
-		// Retrieve the invoice.
452
-		$invoice = $this->get_post( $request['id'] );
453
-		if ( is_wp_error( $invoice ) ) {
454
-			return $invoice;
455
-		}
456
-
457
-		// Ensure the current user can delete invoices
458
-		if ( wpinv_current_user_can_manage_invoicing() ||  current_user_can( 'delete_invoices', $request['id'] ) ) {
459
-			return new WP_Error( 
439
+    }
440
+
441
+    /**
442
+     * Checks if a given request has access to delete an invoice.
443
+     *
444
+     * @since 1.0.13
445
+     *
446
+     * @param WP_REST_Request $request Full details about the request.
447
+     * @return true|WP_Error True if the request has access to delete the invoice, WP_Error object otherwise.
448
+     */
449
+    public function delete_item_permissions_check( $request ) {
450
+
451
+        // Retrieve the invoice.
452
+        $invoice = $this->get_post( $request['id'] );
453
+        if ( is_wp_error( $invoice ) ) {
454
+            return $invoice;
455
+        }
456
+
457
+        // Ensure the current user can delete invoices
458
+        if ( wpinv_current_user_can_manage_invoicing() ||  current_user_can( 'delete_invoices', $request['id'] ) ) {
459
+            return new WP_Error( 
460 460
                 'rest_cannot_delete', 
461 461
                 __( 'Sorry, you are not allowed to delete this invoice.', 'invoicing' ), 
462 462
                 array( 
463 463
                     'status' => rest_authorization_required_code(),
464 464
                 )
465 465
             );
466
-		}
467
-
468
-		return true;
469
-	}
470
-
471
-	/**
472
-	 * Deletes a single invoice.
473
-	 *
474
-	 * @since 1.0.13
475
-	 *
476
-	 * @param WP_REST_Request $request Full details about the request.
477
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
478
-	 */
479
-	public function delete_item( $request ) {
466
+        }
467
+
468
+        return true;
469
+    }
470
+
471
+    /**
472
+     * Deletes a single invoice.
473
+     *
474
+     * @since 1.0.13
475
+     *
476
+     * @param WP_REST_Request $request Full details about the request.
477
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
478
+     */
479
+    public function delete_item( $request ) {
480 480
 		
481
-		// Retrieve the invoice.
482
-		$invoice = $this->get_post( $request['id'] );
483
-		if ( is_wp_error( $invoice ) ) {
484
-			return $invoice;
485
-		}
481
+        // Retrieve the invoice.
482
+        $invoice = $this->get_post( $request['id'] );
483
+        if ( is_wp_error( $invoice ) ) {
484
+            return $invoice;
485
+        }
486 486
 
487
-		$request->set_param( 'context', 'edit' );
487
+        $request->set_param( 'context', 'edit' );
488 488
 
489
-		// Prepare the invoice id
490
-		$id    = $invoice->ID;
489
+        // Prepare the invoice id
490
+        $id    = $invoice->ID;
491 491
 
492
-		// Prepare the response
493
-		$response = $this->prepare_item_for_response( $invoice, $request );
492
+        // Prepare the response
493
+        $response = $this->prepare_item_for_response( $invoice, $request );
494 494
 
495
-		// Check if the user wants to bypass the trash...
496
-		$force_delete = (bool) $request['force'];
495
+        // Check if the user wants to bypass the trash...
496
+        $force_delete = (bool) $request['force'];
497 497
 
498
-		// Try deleting the invoice.
499
-		$deleted = wp_delete_post( $id, $force_delete );
498
+        // Try deleting the invoice.
499
+        $deleted = wp_delete_post( $id, $force_delete );
500 500
 
501
-		// Abort early if we can't delete the invoice.
502
-		if ( ! $deleted ) {
503
-			return new WP_Error( 'rest_cannot_delete', __( 'The invoice cannot be deleted.', 'invoicing' ), array( 'status' => 500 ) );
504
-		}
501
+        // Abort early if we can't delete the invoice.
502
+        if ( ! $deleted ) {
503
+            return new WP_Error( 'rest_cannot_delete', __( 'The invoice cannot be deleted.', 'invoicing' ), array( 'status' => 500 ) );
504
+        }
505 505
 
506
-		/**
507
-		 * Fires immediately after a single invoice is deleted or trashed via the REST API.
508
-		 *
509
-		 *
510
-		 * @since 1.0.13
511
-		 *
512
-		 * @param WPInv_Invoice    $invoice  The deleted or trashed invoice.
513
-		 * @param WP_REST_Request  $request  The request sent to the API.
514
-		 */
515
-		do_action( "wpinv_rest_delete_invoice", $invoice, $request );
506
+        /**
507
+         * Fires immediately after a single invoice is deleted or trashed via the REST API.
508
+         *
509
+         *
510
+         * @since 1.0.13
511
+         *
512
+         * @param WPInv_Invoice    $invoice  The deleted or trashed invoice.
513
+         * @param WP_REST_Request  $request  The request sent to the API.
514
+         */
515
+        do_action( "wpinv_rest_delete_invoice", $invoice, $request );
516 516
 
517
-		return $response;
517
+        return $response;
518 518
 
519
-	}
519
+    }
520 520
     
521 521
     
522 522
     /**
523
-	 * Retrieves the query params for the invoices collection.
524
-	 *
525
-	 * @since 1.0.13
526
-	 *
527
-	 * @return array Collection parameters.
528
-	 */
529
-	public function get_collection_params() {
523
+     * Retrieves the query params for the invoices collection.
524
+     *
525
+     * @since 1.0.13
526
+     *
527
+     * @return array Collection parameters.
528
+     */
529
+    public function get_collection_params() {
530 530
         
531 531
         $query_params               = array(
532 532
 
@@ -544,22 +544,22 @@  discard block
 block discarded – undo
544 544
 
545 545
             // User.
546 546
             'user'                  => array(
547
-				'description'       => __( 'Limit result set to invoices for a specif user.', 'invoicing' ),
548
-				'type'              => 'integer',
547
+                'description'       => __( 'Limit result set to invoices for a specif user.', 'invoicing' ),
548
+                'type'              => 'integer',
549 549
             ),
550 550
             
551 551
             // Number of results per page
552 552
             'limit'                 => array(
553
-				'description'       => __( 'Number of invoices to fetch.', 'invoicing' ),
554
-				'type'              => 'integer',
555
-				'default'           => (int) get_option( 'posts_per_page' ),
553
+                'description'       => __( 'Number of invoices to fetch.', 'invoicing' ),
554
+                'type'              => 'integer',
555
+                'default'           => (int) get_option( 'posts_per_page' ),
556 556
             ),
557 557
 
558 558
             // Pagination
559 559
             'page'     => array(
560
-				'description'       => __( 'Current page to fetch.', 'invoicing' ),
561
-				'type'              => 'integer',
562
-				'default'           => 1,
560
+                'description'       => __( 'Current page to fetch.', 'invoicing' ),
561
+                'type'              => 'integer',
562
+                'default'           => 1,
563 563
             ),
564 564
 
565 565
             // Exclude certain invoices
@@ -595,789 +595,789 @@  discard block
 block discarded – undo
595 595
             ),
596 596
         );
597 597
 
598
-		/**
599
-		 * Filter collection parameters for the invoices controller.
600
-		 *
601
-		 *
602
-		 * @since 1.0.13
603
-		 *
604
-		 * @param array        $query_params JSON Schema-formatted collection parameters.
605
-		 */
606
-		return apply_filters( "wpinv_rest_invoices_collection_params", $query_params );
598
+        /**
599
+         * Filter collection parameters for the invoices controller.
600
+         *
601
+         *
602
+         * @since 1.0.13
603
+         *
604
+         * @param array        $query_params JSON Schema-formatted collection parameters.
605
+         */
606
+        return apply_filters( "wpinv_rest_invoices_collection_params", $query_params );
607 607
     }
608 608
     
609 609
     /**
610
-	 * Checks if a given post type can be viewed or managed.
611
-	 *
612
-	 * @since 1.0.13
613
-	 *
614
-	 * @param object|string $post_type Post type name or object.
615
-	 * @return bool Whether the post type is allowed in REST.
616
-	 */
617
-	protected function check_is_post_type_allowed( $post_type ) {
618
-		return true;
619
-	}
620
-
621
-	/**
622
-	 * Prepares a single invoice for create or update.
623
-	 *
624
-	 * @since 1.0.13
625
-	 *
626
-	 * @param WP_REST_Request $request Request object.
627
-	 * @return array|WP_Error Invoice Properties or WP_Error.
628
-	 */
629
-	protected function prepare_item_for_database( $request ) {
630
-		$prepared_invoice = new stdClass();
631
-
632
-		// Post ID.
633
-		if ( isset( $request['id'] ) ) {
634
-			$existing_invoice = $this->get_post( $request['id'] );
635
-			if ( is_wp_error( $existing_invoice ) ) {
636
-				return $existing_invoice;
637
-			}
638
-
639
-			$prepared_invoice->ID 		  = $existing_invoice->ID;
640
-			$prepared_invoice->invoice_id = $existing_invoice->ID;
641
-		}
642
-
643
-		$schema = $this->get_item_schema();
644
-
645
-		// Invoice owner.
646
-		if ( ! empty( $schema['properties']['user_id'] ) && isset( $request['user_id'] ) ) {
647
-			$prepared_invoice->user_id = (int) $request['user_id'];
648
-		}
649
-
650
-		// Cart details.
651
-		if ( ! empty( $schema['properties']['cart_details'] ) && isset( $request['cart_details'] ) ) {
652
-			$prepared_invoice->cart_details = (array) $request['cart_details'];
653
-		}
654
-
655
-		// Invoice status.
656
-		if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
657
-
658
-			if ( in_array( $request['status'], array_keys( wpinv_get_invoice_statuses( true, true ) ), true ) ) {
659
-				$prepared_invoice->status = $request['status'];
660
-			}
661
-
662
-		}
663
-
664
-		// User info
665
-		if ( ! empty( $schema['properties']['user_info'] ) && isset( $request['user_info'] ) ) {
666
-			$prepared_invoice->user_info = array();
667
-			$user_info = (array) $request['user_info'];
668
-
669
-			foreach( $user_info as $prop => $value ) {
670
-
671
-				if ( ! empty( $schema['properties']['user_info']['properties'][$prop] ) ) {
672
-
673
-					$prepared_invoice->user_info[$prop] = $value;
610
+     * Checks if a given post type can be viewed or managed.
611
+     *
612
+     * @since 1.0.13
613
+     *
614
+     * @param object|string $post_type Post type name or object.
615
+     * @return bool Whether the post type is allowed in REST.
616
+     */
617
+    protected function check_is_post_type_allowed( $post_type ) {
618
+        return true;
619
+    }
620
+
621
+    /**
622
+     * Prepares a single invoice for create or update.
623
+     *
624
+     * @since 1.0.13
625
+     *
626
+     * @param WP_REST_Request $request Request object.
627
+     * @return array|WP_Error Invoice Properties or WP_Error.
628
+     */
629
+    protected function prepare_item_for_database( $request ) {
630
+        $prepared_invoice = new stdClass();
631
+
632
+        // Post ID.
633
+        if ( isset( $request['id'] ) ) {
634
+            $existing_invoice = $this->get_post( $request['id'] );
635
+            if ( is_wp_error( $existing_invoice ) ) {
636
+                return $existing_invoice;
637
+            }
638
+
639
+            $prepared_invoice->ID 		  = $existing_invoice->ID;
640
+            $prepared_invoice->invoice_id = $existing_invoice->ID;
641
+        }
642
+
643
+        $schema = $this->get_item_schema();
644
+
645
+        // Invoice owner.
646
+        if ( ! empty( $schema['properties']['user_id'] ) && isset( $request['user_id'] ) ) {
647
+            $prepared_invoice->user_id = (int) $request['user_id'];
648
+        }
649
+
650
+        // Cart details.
651
+        if ( ! empty( $schema['properties']['cart_details'] ) && isset( $request['cart_details'] ) ) {
652
+            $prepared_invoice->cart_details = (array) $request['cart_details'];
653
+        }
654
+
655
+        // Invoice status.
656
+        if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
657
+
658
+            if ( in_array( $request['status'], array_keys( wpinv_get_invoice_statuses( true, true ) ), true ) ) {
659
+                $prepared_invoice->status = $request['status'];
660
+            }
661
+
662
+        }
663
+
664
+        // User info
665
+        if ( ! empty( $schema['properties']['user_info'] ) && isset( $request['user_info'] ) ) {
666
+            $prepared_invoice->user_info = array();
667
+            $user_info = (array) $request['user_info'];
668
+
669
+            foreach( $user_info as $prop => $value ) {
670
+
671
+                if ( ! empty( $schema['properties']['user_info']['properties'][$prop] ) ) {
672
+
673
+                    $prepared_invoice->user_info[$prop] = $value;
674 674
 		
675
-				}
675
+                }
676 676
 
677
-			}
677
+            }
678 678
 
679
-		}
679
+        }
680 680
 
681
-		// IP
682
-		if ( ! empty( $schema['properties']['ip'] ) && isset( $request['ip'] ) ) {
683
-			$prepared_invoice->ip = $request['ip'];
684
-		}
681
+        // IP
682
+        if ( ! empty( $schema['properties']['ip'] ) && isset( $request['ip'] ) ) {
683
+            $prepared_invoice->ip = $request['ip'];
684
+        }
685 685
 
686
-		// Payment details
687
-		$prepared_invoice->payment_details = array();
686
+        // Payment details
687
+        $prepared_invoice->payment_details = array();
688 688
 
689
-		if ( ! empty( $schema['properties']['gateway'] ) && isset( $request['gateway'] ) ) {
690
-			$prepared_invoice->payment_details['gateway'] = $request['gateway'];
691
-		}
689
+        if ( ! empty( $schema['properties']['gateway'] ) && isset( $request['gateway'] ) ) {
690
+            $prepared_invoice->payment_details['gateway'] = $request['gateway'];
691
+        }
692 692
 
693
-		if ( ! empty( $schema['properties']['gateway_title'] ) && isset( $request['gateway_title'] ) ) {
694
-			$prepared_invoice->payment_details['gateway_title'] = $request['gateway_title'];
695
-		}
693
+        if ( ! empty( $schema['properties']['gateway_title'] ) && isset( $request['gateway_title'] ) ) {
694
+            $prepared_invoice->payment_details['gateway_title'] = $request['gateway_title'];
695
+        }
696 696
 
697
-		if ( ! empty( $schema['properties']['currency'] ) && isset( $request['currency'] ) ) {
698
-			$prepared_invoice->payment_details['currency'] = $request['currency'];
699
-		}
697
+        if ( ! empty( $schema['properties']['currency'] ) && isset( $request['currency'] ) ) {
698
+            $prepared_invoice->payment_details['currency'] = $request['currency'];
699
+        }
700 700
 
701
-		if ( ! empty( $schema['properties']['transaction_id'] ) && isset( $request['transaction_id'] ) ) {
702
-			$prepared_invoice->payment_details['transaction_id'] = $request['transaction_id'];
703
-		}
701
+        if ( ! empty( $schema['properties']['transaction_id'] ) && isset( $request['transaction_id'] ) ) {
702
+            $prepared_invoice->payment_details['transaction_id'] = $request['transaction_id'];
703
+        }
704 704
 
705
-		// Dates
706
-		if ( ! empty( $schema['properties']['date'] ) && isset( $request['date'] ) ) {
707
-			$post_date = rest_get_date_with_gmt( $request['date'] );
705
+        // Dates
706
+        if ( ! empty( $schema['properties']['date'] ) && isset( $request['date'] ) ) {
707
+            $post_date = rest_get_date_with_gmt( $request['date'] );
708 708
 
709
-			if ( ! empty( $post_date ) ) {
710
-				$prepared_invoice->post_date = $post_date[0];
711
-			}
709
+            if ( ! empty( $post_date ) ) {
710
+                $prepared_invoice->post_date = $post_date[0];
711
+            }
712 712
 			
713
-		}
713
+        }
714 714
 
715
-		if ( ! empty( $schema['properties']['due_date'] ) && isset( $request['due_date'] ) ) {
716
-			$due_date = rest_get_date_with_gmt( $request['due_date'] );
715
+        if ( ! empty( $schema['properties']['due_date'] ) && isset( $request['due_date'] ) ) {
716
+            $due_date = rest_get_date_with_gmt( $request['due_date'] );
717 717
 
718
-			if ( ! empty( $due_date ) ) {
719
-				$prepared_invoice->due_date = $due_date[0];
720
-			}
718
+            if ( ! empty( $due_date ) ) {
719
+                $prepared_invoice->due_date = $due_date[0];
720
+            }
721 721
 
722
-		}
722
+        }
723 723
 
724
-		$invoice_data = (array) wp_unslash( $prepared_invoice );
724
+        $invoice_data = (array) wp_unslash( $prepared_invoice );
725 725
 
726
-		/**
727
-		 * Filters an invoice before it is inserted via the REST API.
728
-		 *
729
-		 * @since 1.0.13
730
-		 *
731
-		 * @param array        $invoice_data An array of invoice data
732
-		 * @param WP_REST_Request $request       Request object.
733
-		 */
734
-		return apply_filters( "wpinv_rest_pre_insert_invoice", $invoice_data, $request );
726
+        /**
727
+         * Filters an invoice before it is inserted via the REST API.
728
+         *
729
+         * @since 1.0.13
730
+         *
731
+         * @param array        $invoice_data An array of invoice data
732
+         * @param WP_REST_Request $request       Request object.
733
+         */
734
+        return apply_filters( "wpinv_rest_pre_insert_invoice", $invoice_data, $request );
735 735
 
736
-	}
736
+    }
737
+
738
+    /**
739
+     * Prepares a single invoice output for response.
740
+     *
741
+     * @since 1.0.13
742
+     *
743
+     * @param WPInv_Invoice   $invoice    Invoice object.
744
+     * @param WP_REST_Request $request Request object.
745
+     * @return WP_REST_Response Response object.
746
+     */
747
+    public function prepare_item_for_response( $invoice, $request ) {
737 748
 
738
-	/**
739
-	 * Prepares a single invoice output for response.
740
-	 *
741
-	 * @since 1.0.13
742
-	 *
743
-	 * @param WPInv_Invoice   $invoice    Invoice object.
744
-	 * @param WP_REST_Request $request Request object.
745
-	 * @return WP_REST_Response Response object.
746
-	 */
747
-	public function prepare_item_for_response( $invoice, $request ) {
749
+        $GLOBALS['post'] = get_post( $invoice->ID );
748 750
 
749
-		$GLOBALS['post'] = get_post( $invoice->ID );
751
+        setup_postdata( $invoice->ID );
750 752
 
751
-		setup_postdata( $invoice->ID );
753
+        // Fetch the fields to include in this response.
754
+        $fields = $this->get_fields_for_response( $request );
752 755
 
753
-		// Fetch the fields to include in this response.
754
-		$fields = $this->get_fields_for_response( $request );
756
+        // Base fields for every invoice.
757
+        $data = array();
758
+
759
+        // Set up ID
760
+        if ( rest_is_field_included( 'id', $fields ) ) {
761
+            $data['id'] = $invoice->ID;
762
+        }
763
+
764
+
765
+        // Basic properties
766
+        $invoice_properties = array(
767
+            'title', 'email', 'ip', 
768
+            'key', 'number', 'transaction_id', 'mode',
769
+            'gateway', 'gateway_title',
770
+            'total', 'discount', 'discount_code', 
771
+            'tax', 'fees_total', 'subtotal', 'currency',
772
+            'status', 'status_nicename', 'post_type'
773
+        );
774
+
775
+        foreach( $invoice_properties as $property ) {
776
+
777
+            if ( rest_is_field_included( $property, $fields ) ) {
778
+                $data[$property] = $invoice->get( $property );
779
+            }
780
+
781
+        }
782
+
783
+        // Cart details
784
+        if ( rest_is_field_included( 'cart_details', $fields ) ) {
785
+            $data['cart_details'] = $invoice->get( 'cart_details' );
786
+        }
787
+
788
+        //Dates
789
+        $invoice_properties = array( 'date', 'due_date', 'completed_date' );
790
+
791
+        foreach( $invoice_properties as $property ) {
792
+
793
+            if ( rest_is_field_included( $property, $fields ) ) {
794
+                $data[$property] = $this->prepare_date_response( '0000-00-00 00:00:00', $invoice->get( $property ) );
795
+            }
796
+
797
+        }
798
+
799
+        // User id
800
+        if ( rest_is_field_included( 'user_id', $fields ) ) {
801
+            $data['user_id'] = (int) $invoice->get( 'user_id' );
802
+        }
803
+
804
+        // User info
805
+        $user_info = array( 'first_name', 'last_name', 'company', 'vat_number', 'vat_rate', 'address', 'city', 'country', 'state', 'zip', 'phone' );
806
+
807
+        foreach( $user_info as $property ) {
808
+
809
+            if ( rest_is_field_included( "user_info.$property", $fields ) ) {
810
+                $data['user_info'][$property] = $invoice->get( $property );
811
+            }
812
+
813
+        }
814
+
815
+        // Slug
816
+        if ( rest_is_field_included( 'slug', $fields ) ) {
817
+            $data['slug'] = $invoice->get( 'post_name' );
818
+        }
819
+
820
+        // View invoice link
821
+        if ( rest_is_field_included( 'link', $fields ) ) {
822
+            $data['link'] = esc_url( $invoice->get_view_url() );
823
+        }
755 824
 
756
-		// Base fields for every invoice.
757
-		$data = array();
758 825
 
759
-		// Set up ID
760
-		if ( rest_is_field_included( 'id', $fields ) ) {
761
-			$data['id'] = $invoice->ID;
762
-		}
826
+        $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
827
+        $data    = $this->add_additional_fields_to_object( $data, $request );
828
+        $data    = $this->filter_response_by_context( $data, $context );
763 829
 
830
+        // Wrap the data in a response object.
831
+        $response = rest_ensure_response( $data );
764 832
 
765
-		// Basic properties
766
-		$invoice_properties = array(
767
-			'title', 'email', 'ip', 
768
-			'key', 'number', 'transaction_id', 'mode',
769
-			'gateway', 'gateway_title',
770
-			'total', 'discount', 'discount_code', 
771
-			'tax', 'fees_total', 'subtotal', 'currency',
772
-			'status', 'status_nicename', 'post_type'
773
-		);
774
-
775
-		foreach( $invoice_properties as $property ) {
776
-
777
-			if ( rest_is_field_included( $property, $fields ) ) {
778
-				$data[$property] = $invoice->get( $property );
779
-			}
780
-
781
-		}
782
-
783
-		// Cart details
784
-		if ( rest_is_field_included( 'cart_details', $fields ) ) {
785
-			$data['cart_details'] = $invoice->get( 'cart_details' );
786
-		}
787
-
788
-		//Dates
789
-		$invoice_properties = array( 'date', 'due_date', 'completed_date' );
790
-
791
-		foreach( $invoice_properties as $property ) {
792
-
793
-			if ( rest_is_field_included( $property, $fields ) ) {
794
-				$data[$property] = $this->prepare_date_response( '0000-00-00 00:00:00', $invoice->get( $property ) );
795
-			}
796
-
797
-		}
798
-
799
-		// User id
800
-		if ( rest_is_field_included( 'user_id', $fields ) ) {
801
-			$data['user_id'] = (int) $invoice->get( 'user_id' );
802
-		}
803
-
804
-		// User info
805
-		$user_info = array( 'first_name', 'last_name', 'company', 'vat_number', 'vat_rate', 'address', 'city', 'country', 'state', 'zip', 'phone' );
806
-
807
-		foreach( $user_info as $property ) {
808
-
809
-			if ( rest_is_field_included( "user_info.$property", $fields ) ) {
810
-				$data['user_info'][$property] = $invoice->get( $property );
811
-			}
812
-
813
-		}
814
-
815
-		// Slug
816
-		if ( rest_is_field_included( 'slug', $fields ) ) {
817
-			$data['slug'] = $invoice->get( 'post_name' );
818
-		}
819
-
820
-		// View invoice link
821
-		if ( rest_is_field_included( 'link', $fields ) ) {
822
-			$data['link'] = esc_url( $invoice->get_view_url() );
823
-		}
824
-
825
-
826
-		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
827
-		$data    = $this->add_additional_fields_to_object( $data, $request );
828
-		$data    = $this->filter_response_by_context( $data, $context );
829
-
830
-		// Wrap the data in a response object.
831
-		$response = rest_ensure_response( $data );
832
-
833
-		$links = $this->prepare_links( $invoice );
834
-		$response->add_links( $links );
835
-
836
-		if ( ! empty( $links['self']['href'] ) ) {
837
-			$actions = $this->get_available_actions( $invoice, $request );
838
-
839
-			$self = $links['self']['href'];
840
-
841
-			foreach ( $actions as $rel ) {
842
-				$response->add_link( $rel, $self );
843
-			}
844
-		}
845
-
846
-		/**
847
-		 * Filters the invoice data for a response.
848
-		 *
849
-		 * @since 1.0.13
850
-		 *
851
-		 * @param WP_REST_Response $response The response object.
852
-		 * @param WPInv_Invoice    $invoice  The invoice object.
853
-		 * @param WP_REST_Request  $request  Request object.
854
-		 */
855
-		return apply_filters( "wpinv_rest_prepare_invoice", $response, $invoice, $request );
856
-	}
857
-
858
-	/**
859
-	 * Gets an array of fields to be included on the response.
860
-	 *
861
-	 * Included fields are based on item schema and `_fields=` request argument.
862
-	 *
863
-	 * @since 1.0.13
864
-	 *
865
-	 * @param WP_REST_Request $request Full details about the request.
866
-	 * @return array Fields to be included in the response.
867
-	 */
868
-	public function get_fields_for_response( $request ) {
869
-		$schema     = $this->get_item_schema();
870
-		$properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
871
-
872
-		$additional_fields = $this->get_additional_fields();
873
-		foreach ( $additional_fields as $field_name => $field_options ) {
874
-			// For back-compat, include any field with an empty schema
875
-			// because it won't be present in $this->get_item_schema().
876
-			if ( is_null( $field_options['schema'] ) ) {
877
-				$properties[ $field_name ] = $field_options;
878
-			}
879
-		}
880
-
881
-		// Exclude fields that specify a different context than the request context.
882
-		$context = $request['context'];
883
-		if ( $context ) {
884
-			foreach ( $properties as $name => $options ) {
885
-				if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
886
-					unset( $properties[ $name ] );
887
-				}
888
-			}
889
-		}
890
-
891
-		$fields = array_keys( $properties );
892
-
893
-		if ( ! isset( $request['_fields'] ) ) {
894
-			return $fields;
895
-		}
896
-		$requested_fields = wpinv_parse_list( $request['_fields'] );
897
-		if ( 0 === count( $requested_fields ) ) {
898
-			return $fields;
899
-		}
900
-		// Trim off outside whitespace from the comma delimited list.
901
-		$requested_fields = array_map( 'trim', $requested_fields );
902
-		// Always persist 'id', because it can be needed for add_additional_fields_to_object().
903
-		if ( in_array( 'id', $fields, true ) ) {
904
-			$requested_fields[] = 'id';
905
-		}
906
-		// Return the list of all requested fields which appear in the schema.
907
-		return array_reduce(
908
-			$requested_fields,
909
-			function( $response_fields, $field ) use ( $fields ) {
910
-				if ( in_array( $field, $fields, true ) ) {
911
-					$response_fields[] = $field;
912
-					return $response_fields;
913
-				}
914
-				// Check for nested fields if $field is not a direct match.
915
-				$nested_fields = explode( '.', $field );
916
-				// A nested field is included so long as its top-level property is
917
-				// present in the schema.
918
-				if ( in_array( $nested_fields[0], $fields, true ) ) {
919
-					$response_fields[] = $field;
920
-				}
921
-				return $response_fields;
922
-			},
923
-			array()
924
-		);
925
-	}
926
-
927
-	/**
928
-	 * Retrieves the invoice's schema, conforming to JSON Schema.
929
-	 *
930
-	 * @since 1.0.13
931
-	 *
932
-	 * @return array Invoice schema data.
933
-	 */
934
-	public function get_item_schema() {
935
-
936
-		// Maybe retrieve the schema from cache.
937
-		if ( $this->schema ) {
938
-			return $this->add_additional_fields_schema( $this->schema );
939
-		}
940
-
941
-		$schema = array(
942
-			'$schema'    => 'http://json-schema.org/draft-04/schema#',
943
-			'title'      => $this->post_type,
944
-			'type'       => 'object',
945
-
946
-			// Base properties for every Invoice.
947
-			'properties' 		  => array(
948
-
949
-				'title'			  => array(
950
-					'description' => __( 'The title for the invoice.', 'invoicing' ),
951
-					'type'        => 'string',
952
-					'context'     => array( 'view', 'edit', 'embed' ),
953
-					'readonly'    => true,
954
-				),
955
-
956
-				'user_id'		  => array(
957
-					'description' => __( 'The ID of the owner of the invoice.', 'invoicing' ),
958
-					'type'        => 'integer',
959
-					'context'     => array( 'view', 'edit', 'embed' ),
960
-				),
961
-
962
-				'email'		  	  => array(
963
-					'description' => __( 'The email of the owner of the invoice.', 'invoicing' ),
964
-					'type'        => 'string',
965
-					'context'     => array( 'view', 'edit', 'embed' ),
966
-					'readonly'    => true,
967
-				),
968
-
969
-				'ip'			  => array(
970
-					'description' => __( 'The IP of the owner of the invoice.', 'invoicing' ),
971
-					'type'        => 'string',
972
-					'context'     => array( 'view', 'edit', 'embed' ),
973
-				),
974
-
975
-				'user_info'       => array(
976
-					'description' => __( 'Information about the owner of the invoice.', 'invoicing' ),
977
-					'type'        => 'object',
978
-					'context'     => array( 'view', 'edit', 'embed' ),
979
-					'properties'  => array(
980
-
981
-						'first_name'      => array(
982
-							'description' => __( 'The first name of the owner of the invoice.', 'invoicing' ),
983
-							'type'        => 'string',
984
-							'context'     => array( 'view', 'edit', 'embed' ),
985
-						),
986
-
987
-						'last_name'       => array(
988
-							'description' => __( 'The last name of the owner of the invoice.', 'invoicing' ),
989
-							'type'        => 'string',
990
-							'context'     => array( 'view', 'edit', 'embed' ),
991
-						),
992
-
993
-						'company'         => array(
994
-							'description' => __( 'The company of the owner of the invoice.', 'invoicing' ),
995
-							'type'        => 'string',
996
-							'context'     => array( 'view', 'edit', 'embed' ),
997
-						),
998
-
999
-						'vat_number'      => array(
1000
-							'description' => __( 'The VAT number of the owner of the invoice.', 'invoicing' ),
1001
-							'type'        => 'string',
1002
-							'context'     => array( 'view', 'edit', 'embed' ),
1003
-						),
1004
-
1005
-						'vat_rate'        => array(
1006
-							'description' => __( 'The VAT rate applied on the invoice.', 'invoicing' ),
1007
-							'type'        => 'string',
1008
-							'context'     => array( 'view', 'edit', 'embed' ),
1009
-						),
1010
-
1011
-						'address'        => array(
1012
-							'description' => __( 'The address of the invoice owner.', 'invoicing' ),
1013
-							'type'        => 'string',
1014
-							'context'     => array( 'view', 'edit', 'embed' ),
1015
-						),
1016
-
1017
-						'city'            => array(
1018
-							'description' => __( 'The city of the invoice owner.', 'invoicing' ),
1019
-							'type'        => 'string',
1020
-							'context'     => array( 'view', 'edit', 'embed' ),
1021
-						),
1022
-
1023
-						'country'         => array(
1024
-							'description' => __( 'The country of the invoice owner.', 'invoicing' ),
1025
-							'type'        => 'string',
1026
-							'context'     => array( 'view', 'edit', 'embed' ),
1027
-						),
1028
-
1029
-						'state'           => array(
1030
-							'description' => __( 'The state of the invoice owner.', 'invoicing' ),
1031
-							'type'        => 'string',
1032
-							'context'     => array( 'view', 'edit', 'embed' ),
1033
-						),
1034
-
1035
-						'zip'             => array(
1036
-							'description' => __( 'The zip code of the invoice owner.', 'invoicing' ),
1037
-							'type'        => 'string',
1038
-							'context'     => array( 'view', 'edit', 'embed' ),
1039
-						),
1040
-
1041
-						'phone'             => array(
1042
-							'description' => __( 'The phone number of the invoice owner.', 'invoicing' ),
1043
-							'type'        => 'string',
1044
-							'context'     => array( 'view', 'edit', 'embed' ),
1045
-						),
1046
-					),
1047
-				),
1048
-
1049
-				'id'           => array(
1050
-					'description' => __( 'Unique identifier for the invoice.', 'invoicing' ),
1051
-					'type'        => 'integer',
1052
-					'context'     => array( 'view', 'edit', 'embed' ),
1053
-					'readonly'    => true,
1054
-				),
1055
-
1056
-				'key'			  => array(
1057
-					'description' => __( 'A unique key for the invoice.', 'invoicing' ),
1058
-					'type'        => 'string',
1059
-					'context'     => array( 'view', 'edit', 'embed' ),
1060
-					'readonly'    => true,
1061
-				),
1062
-
1063
-				'number'		  => array(
1064
-					'description' => __( 'The invoice number.', 'invoicing' ),
1065
-					'type'        => 'string',
1066
-					'context'     => array( 'view', 'edit', 'embed' ),
1067
-					'readonly'    => true,
1068
-				),
1069
-
1070
-				'transaction_id'  => array(
1071
-					'description' => __( 'The transaction id of the invoice.', 'invoicing' ),
1072
-					'type'        => 'string',
1073
-					'context'     => array( 'view', 'edit', 'embed' ),
1074
-				),
1075
-
1076
-				'gateway'		  => array(
1077
-					'description' => __( 'The gateway used to process the invoice.', 'invoicing' ),
1078
-					'type'        => 'string',
1079
-					'context'     => array( 'view', 'edit', 'embed' ),
1080
-				),
1081
-
1082
-				'gateway_title'	  => array(
1083
-					'description' => __( 'The title of the gateway used to process the invoice.', 'invoicing' ),
1084
-					'type'        => 'string',
1085
-					'context'     => array( 'view', 'edit', 'embed' ),
1086
-				),
1087
-
1088
-				'total'	  		  => array(
1089
-					'description' => __( 'The total amount of the invoice.', 'invoicing' ),
1090
-					'type'        => 'number',
1091
-					'context'     => array( 'view', 'edit', 'embed' ),
1092
-					'readonly'    => true,
1093
-				),
1094
-
1095
-				'discount'		  => array(
1096
-					'description' => __( 'The discount applied to the invoice.', 'invoicing' ),
1097
-					'type'        => 'number',
1098
-					'context'     => array( 'view', 'edit', 'embed' ),
1099
-					'readonly'    => true,
1100
-				),
1101
-
1102
-				'discount_code'	  => array(
1103
-					'description' => __( 'The discount code applied to the invoice.', 'invoicing' ),
1104
-					'type'        => 'string',
1105
-					'context'     => array( 'view', 'edit', 'embed' ),
1106
-					'readonly'    => true,
1107
-				),
1108
-
1109
-				'tax'	  		  => array(
1110
-					'description' => __( 'The tax applied to the invoice.', 'invoicing' ),
1111
-					'type'        => 'number',
1112
-					'context'     => array( 'view', 'edit', 'embed' ),
1113
-					'readonly'    => true,
1114
-				),
1115
-
1116
-				'fees_total'	  => array(
1117
-					'description' => __( 'The total fees applied to the invoice.', 'invoicing' ),
1118
-					'type'        => 'number',
1119
-					'context'     => array( 'view', 'edit', 'embed' ),
1120
-					'readonly'    => true,
1121
-				),
1122
-
1123
-				'subtotal'	  	  => array(
1124
-					'description' => __( 'The sub-total for the invoice.', 'invoicing' ),
1125
-					'type'        => 'number',
1126
-					'context'     => array( 'view', 'edit', 'embed' ),
1127
-					'readonly'    => true,
1128
-				),
1129
-
1130
-				'currency'	  	  => array(
1131
-					'description' => __( 'The currency used to process the invoice.', 'invoicing' ),
1132
-					'type'        => 'string',
1133
-					'context'     => array( 'view', 'edit', 'embed' ),
1134
-				),
1135
-
1136
-				'cart_details'	  => array(
1137
-					'description' => __( 'The cart details for invoice.', 'invoicing' ),
1138
-					'type'        => 'array',
1139
-					'context'     => array( 'view', 'edit', 'embed' ),
1140
-					'required'	  => true,
1141
-				),
1142
-
1143
-				'date'         => array(
1144
-					'description' => __( "The date the invoice was published, in the site's timezone.", 'invoicing' ),
1145
-					'type'        => array( 'string', 'null' ),
1146
-					'format'      => 'date-time',
1147
-					'context'     => array( 'view', 'edit', 'embed' ),
1148
-				),
1149
-
1150
-				'due_date'     => array(
1151
-					'description' => __( 'The due date for the invoice.', 'invoicing' ),
1152
-					'type'        => array( 'string', 'null' ),
1153
-					'format'      => 'date-time',
1154
-					'context'     => array( 'view', 'edit', 'embed' ),
1155
-				),
1156
-
1157
-				'completed_date'  => array(
1158
-					'description' => __( 'The completed date for the invoice.', 'invoicing' ),
1159
-					'type'        => array( 'string', 'null' ),
1160
-					'format'      => 'date-time',
1161
-					'context'     => array( 'view', 'edit', 'embed' ),
1162
-					'readonly'    => true,
1163
-				),
833
+        $links = $this->prepare_links( $invoice );
834
+        $response->add_links( $links );
835
+
836
+        if ( ! empty( $links['self']['href'] ) ) {
837
+            $actions = $this->get_available_actions( $invoice, $request );
838
+
839
+            $self = $links['self']['href'];
840
+
841
+            foreach ( $actions as $rel ) {
842
+                $response->add_link( $rel, $self );
843
+            }
844
+        }
845
+
846
+        /**
847
+         * Filters the invoice data for a response.
848
+         *
849
+         * @since 1.0.13
850
+         *
851
+         * @param WP_REST_Response $response The response object.
852
+         * @param WPInv_Invoice    $invoice  The invoice object.
853
+         * @param WP_REST_Request  $request  Request object.
854
+         */
855
+        return apply_filters( "wpinv_rest_prepare_invoice", $response, $invoice, $request );
856
+    }
857
+
858
+    /**
859
+     * Gets an array of fields to be included on the response.
860
+     *
861
+     * Included fields are based on item schema and `_fields=` request argument.
862
+     *
863
+     * @since 1.0.13
864
+     *
865
+     * @param WP_REST_Request $request Full details about the request.
866
+     * @return array Fields to be included in the response.
867
+     */
868
+    public function get_fields_for_response( $request ) {
869
+        $schema     = $this->get_item_schema();
870
+        $properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
871
+
872
+        $additional_fields = $this->get_additional_fields();
873
+        foreach ( $additional_fields as $field_name => $field_options ) {
874
+            // For back-compat, include any field with an empty schema
875
+            // because it won't be present in $this->get_item_schema().
876
+            if ( is_null( $field_options['schema'] ) ) {
877
+                $properties[ $field_name ] = $field_options;
878
+            }
879
+        }
880
+
881
+        // Exclude fields that specify a different context than the request context.
882
+        $context = $request['context'];
883
+        if ( $context ) {
884
+            foreach ( $properties as $name => $options ) {
885
+                if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
886
+                    unset( $properties[ $name ] );
887
+                }
888
+            }
889
+        }
890
+
891
+        $fields = array_keys( $properties );
892
+
893
+        if ( ! isset( $request['_fields'] ) ) {
894
+            return $fields;
895
+        }
896
+        $requested_fields = wpinv_parse_list( $request['_fields'] );
897
+        if ( 0 === count( $requested_fields ) ) {
898
+            return $fields;
899
+        }
900
+        // Trim off outside whitespace from the comma delimited list.
901
+        $requested_fields = array_map( 'trim', $requested_fields );
902
+        // Always persist 'id', because it can be needed for add_additional_fields_to_object().
903
+        if ( in_array( 'id', $fields, true ) ) {
904
+            $requested_fields[] = 'id';
905
+        }
906
+        // Return the list of all requested fields which appear in the schema.
907
+        return array_reduce(
908
+            $requested_fields,
909
+            function( $response_fields, $field ) use ( $fields ) {
910
+                if ( in_array( $field, $fields, true ) ) {
911
+                    $response_fields[] = $field;
912
+                    return $response_fields;
913
+                }
914
+                // Check for nested fields if $field is not a direct match.
915
+                $nested_fields = explode( '.', $field );
916
+                // A nested field is included so long as its top-level property is
917
+                // present in the schema.
918
+                if ( in_array( $nested_fields[0], $fields, true ) ) {
919
+                    $response_fields[] = $field;
920
+                }
921
+                return $response_fields;
922
+            },
923
+            array()
924
+        );
925
+    }
926
+
927
+    /**
928
+     * Retrieves the invoice's schema, conforming to JSON Schema.
929
+     *
930
+     * @since 1.0.13
931
+     *
932
+     * @return array Invoice schema data.
933
+     */
934
+    public function get_item_schema() {
935
+
936
+        // Maybe retrieve the schema from cache.
937
+        if ( $this->schema ) {
938
+            return $this->add_additional_fields_schema( $this->schema );
939
+        }
940
+
941
+        $schema = array(
942
+            '$schema'    => 'http://json-schema.org/draft-04/schema#',
943
+            'title'      => $this->post_type,
944
+            'type'       => 'object',
945
+
946
+            // Base properties for every Invoice.
947
+            'properties' 		  => array(
948
+
949
+                'title'			  => array(
950
+                    'description' => __( 'The title for the invoice.', 'invoicing' ),
951
+                    'type'        => 'string',
952
+                    'context'     => array( 'view', 'edit', 'embed' ),
953
+                    'readonly'    => true,
954
+                ),
955
+
956
+                'user_id'		  => array(
957
+                    'description' => __( 'The ID of the owner of the invoice.', 'invoicing' ),
958
+                    'type'        => 'integer',
959
+                    'context'     => array( 'view', 'edit', 'embed' ),
960
+                ),
961
+
962
+                'email'		  	  => array(
963
+                    'description' => __( 'The email of the owner of the invoice.', 'invoicing' ),
964
+                    'type'        => 'string',
965
+                    'context'     => array( 'view', 'edit', 'embed' ),
966
+                    'readonly'    => true,
967
+                ),
968
+
969
+                'ip'			  => array(
970
+                    'description' => __( 'The IP of the owner of the invoice.', 'invoicing' ),
971
+                    'type'        => 'string',
972
+                    'context'     => array( 'view', 'edit', 'embed' ),
973
+                ),
974
+
975
+                'user_info'       => array(
976
+                    'description' => __( 'Information about the owner of the invoice.', 'invoicing' ),
977
+                    'type'        => 'object',
978
+                    'context'     => array( 'view', 'edit', 'embed' ),
979
+                    'properties'  => array(
980
+
981
+                        'first_name'      => array(
982
+                            'description' => __( 'The first name of the owner of the invoice.', 'invoicing' ),
983
+                            'type'        => 'string',
984
+                            'context'     => array( 'view', 'edit', 'embed' ),
985
+                        ),
986
+
987
+                        'last_name'       => array(
988
+                            'description' => __( 'The last name of the owner of the invoice.', 'invoicing' ),
989
+                            'type'        => 'string',
990
+                            'context'     => array( 'view', 'edit', 'embed' ),
991
+                        ),
992
+
993
+                        'company'         => array(
994
+                            'description' => __( 'The company of the owner of the invoice.', 'invoicing' ),
995
+                            'type'        => 'string',
996
+                            'context'     => array( 'view', 'edit', 'embed' ),
997
+                        ),
998
+
999
+                        'vat_number'      => array(
1000
+                            'description' => __( 'The VAT number of the owner of the invoice.', 'invoicing' ),
1001
+                            'type'        => 'string',
1002
+                            'context'     => array( 'view', 'edit', 'embed' ),
1003
+                        ),
1004
+
1005
+                        'vat_rate'        => array(
1006
+                            'description' => __( 'The VAT rate applied on the invoice.', 'invoicing' ),
1007
+                            'type'        => 'string',
1008
+                            'context'     => array( 'view', 'edit', 'embed' ),
1009
+                        ),
1010
+
1011
+                        'address'        => array(
1012
+                            'description' => __( 'The address of the invoice owner.', 'invoicing' ),
1013
+                            'type'        => 'string',
1014
+                            'context'     => array( 'view', 'edit', 'embed' ),
1015
+                        ),
1016
+
1017
+                        'city'            => array(
1018
+                            'description' => __( 'The city of the invoice owner.', 'invoicing' ),
1019
+                            'type'        => 'string',
1020
+                            'context'     => array( 'view', 'edit', 'embed' ),
1021
+                        ),
1022
+
1023
+                        'country'         => array(
1024
+                            'description' => __( 'The country of the invoice owner.', 'invoicing' ),
1025
+                            'type'        => 'string',
1026
+                            'context'     => array( 'view', 'edit', 'embed' ),
1027
+                        ),
1028
+
1029
+                        'state'           => array(
1030
+                            'description' => __( 'The state of the invoice owner.', 'invoicing' ),
1031
+                            'type'        => 'string',
1032
+                            'context'     => array( 'view', 'edit', 'embed' ),
1033
+                        ),
1034
+
1035
+                        'zip'             => array(
1036
+                            'description' => __( 'The zip code of the invoice owner.', 'invoicing' ),
1037
+                            'type'        => 'string',
1038
+                            'context'     => array( 'view', 'edit', 'embed' ),
1039
+                        ),
1040
+
1041
+                        'phone'             => array(
1042
+                            'description' => __( 'The phone number of the invoice owner.', 'invoicing' ),
1043
+                            'type'        => 'string',
1044
+                            'context'     => array( 'view', 'edit', 'embed' ),
1045
+                        ),
1046
+                    ),
1047
+                ),
1048
+
1049
+                'id'           => array(
1050
+                    'description' => __( 'Unique identifier for the invoice.', 'invoicing' ),
1051
+                    'type'        => 'integer',
1052
+                    'context'     => array( 'view', 'edit', 'embed' ),
1053
+                    'readonly'    => true,
1054
+                ),
1055
+
1056
+                'key'			  => array(
1057
+                    'description' => __( 'A unique key for the invoice.', 'invoicing' ),
1058
+                    'type'        => 'string',
1059
+                    'context'     => array( 'view', 'edit', 'embed' ),
1060
+                    'readonly'    => true,
1061
+                ),
1062
+
1063
+                'number'		  => array(
1064
+                    'description' => __( 'The invoice number.', 'invoicing' ),
1065
+                    'type'        => 'string',
1066
+                    'context'     => array( 'view', 'edit', 'embed' ),
1067
+                    'readonly'    => true,
1068
+                ),
1069
+
1070
+                'transaction_id'  => array(
1071
+                    'description' => __( 'The transaction id of the invoice.', 'invoicing' ),
1072
+                    'type'        => 'string',
1073
+                    'context'     => array( 'view', 'edit', 'embed' ),
1074
+                ),
1075
+
1076
+                'gateway'		  => array(
1077
+                    'description' => __( 'The gateway used to process the invoice.', 'invoicing' ),
1078
+                    'type'        => 'string',
1079
+                    'context'     => array( 'view', 'edit', 'embed' ),
1080
+                ),
1081
+
1082
+                'gateway_title'	  => array(
1083
+                    'description' => __( 'The title of the gateway used to process the invoice.', 'invoicing' ),
1084
+                    'type'        => 'string',
1085
+                    'context'     => array( 'view', 'edit', 'embed' ),
1086
+                ),
1087
+
1088
+                'total'	  		  => array(
1089
+                    'description' => __( 'The total amount of the invoice.', 'invoicing' ),
1090
+                    'type'        => 'number',
1091
+                    'context'     => array( 'view', 'edit', 'embed' ),
1092
+                    'readonly'    => true,
1093
+                ),
1094
+
1095
+                'discount'		  => array(
1096
+                    'description' => __( 'The discount applied to the invoice.', 'invoicing' ),
1097
+                    'type'        => 'number',
1098
+                    'context'     => array( 'view', 'edit', 'embed' ),
1099
+                    'readonly'    => true,
1100
+                ),
1101
+
1102
+                'discount_code'	  => array(
1103
+                    'description' => __( 'The discount code applied to the invoice.', 'invoicing' ),
1104
+                    'type'        => 'string',
1105
+                    'context'     => array( 'view', 'edit', 'embed' ),
1106
+                    'readonly'    => true,
1107
+                ),
1108
+
1109
+                'tax'	  		  => array(
1110
+                    'description' => __( 'The tax applied to the invoice.', 'invoicing' ),
1111
+                    'type'        => 'number',
1112
+                    'context'     => array( 'view', 'edit', 'embed' ),
1113
+                    'readonly'    => true,
1114
+                ),
1115
+
1116
+                'fees_total'	  => array(
1117
+                    'description' => __( 'The total fees applied to the invoice.', 'invoicing' ),
1118
+                    'type'        => 'number',
1119
+                    'context'     => array( 'view', 'edit', 'embed' ),
1120
+                    'readonly'    => true,
1121
+                ),
1122
+
1123
+                'subtotal'	  	  => array(
1124
+                    'description' => __( 'The sub-total for the invoice.', 'invoicing' ),
1125
+                    'type'        => 'number',
1126
+                    'context'     => array( 'view', 'edit', 'embed' ),
1127
+                    'readonly'    => true,
1128
+                ),
1129
+
1130
+                'currency'	  	  => array(
1131
+                    'description' => __( 'The currency used to process the invoice.', 'invoicing' ),
1132
+                    'type'        => 'string',
1133
+                    'context'     => array( 'view', 'edit', 'embed' ),
1134
+                ),
1135
+
1136
+                'cart_details'	  => array(
1137
+                    'description' => __( 'The cart details for invoice.', 'invoicing' ),
1138
+                    'type'        => 'array',
1139
+                    'context'     => array( 'view', 'edit', 'embed' ),
1140
+                    'required'	  => true,
1141
+                ),
1142
+
1143
+                'date'         => array(
1144
+                    'description' => __( "The date the invoice was published, in the site's timezone.", 'invoicing' ),
1145
+                    'type'        => array( 'string', 'null' ),
1146
+                    'format'      => 'date-time',
1147
+                    'context'     => array( 'view', 'edit', 'embed' ),
1148
+                ),
1149
+
1150
+                'due_date'     => array(
1151
+                    'description' => __( 'The due date for the invoice.', 'invoicing' ),
1152
+                    'type'        => array( 'string', 'null' ),
1153
+                    'format'      => 'date-time',
1154
+                    'context'     => array( 'view', 'edit', 'embed' ),
1155
+                ),
1156
+
1157
+                'completed_date'  => array(
1158
+                    'description' => __( 'The completed date for the invoice.', 'invoicing' ),
1159
+                    'type'        => array( 'string', 'null' ),
1160
+                    'format'      => 'date-time',
1161
+                    'context'     => array( 'view', 'edit', 'embed' ),
1162
+                    'readonly'    => true,
1163
+                ),
1164 1164
 				
1165
-				'link'         => array(
1166
-					'description' => __( 'URL to the invoice.', 'invoicing' ),
1167
-					'type'        => 'string',
1168
-					'format'      => 'uri',
1169
-					'context'     => array( 'view', 'edit', 'embed' ),
1170
-					'readonly'    => true,
1171
-				),
1172
-
1173
-				'mode'       	  => array(
1174
-					'description' => __( 'The mode used to process the invoice.', 'invoicing' ),
1175
-					'type'        => 'string',
1176
-					'enum'        => array( 'live', 'test' ),
1177
-					'context'     => array( 'view', 'edit', 'embed' ),
1178
-					'readonly'    => true,
1179
-				),
1180
-
1181
-				'slug'       	  => array(
1182
-					'description' => __( 'An alphanumeric identifier for the invoice.', 'invoicing' ),
1183
-					'type'        => 'string',
1184
-					'context'     => array( 'view', 'edit', 'embed' ),
1185
-					'arg_options' => array(
1186
-						'sanitize_callback' => array( $this, 'sanitize_slug' ),
1187
-					),
1188
-					'readonly'    => true,
1189
-				),
1190
-
1191
-				'status'       	  => array(
1192
-					'description' => __( 'A named status for the invoice.', 'invoicing' ),
1193
-					'type'        => 'string',
1194
-					'enum'        => array_keys( wpinv_get_invoice_statuses( true, true ) ),
1195
-					'context'     => array( 'view', 'edit' ),
1196
-					'default'	  => 'wpi-pending',
1197
-				),
1198
-
1199
-				'status_nicename' => array(
1200
-					'description' => __( 'A human-readable status name for the invoice.', 'invoicing' ),
1201
-					'type'        => 'string',
1202
-					'context'     => array( 'view', 'embed' ),
1203
-					'readonly'    => true,
1204
-				),
1205
-
1206
-				'post_type'       => array(
1207
-					'description' => __( 'The post type for the invoice.', 'invoicing' ),
1208
-					'type'        => 'string',
1209
-					'context'     => array( 'view' ),
1210
-					'readonly'    => true,
1211
-				),
1212
-			),
1213
-		);
1214
-
1215
-		// Add helpful links to the invoice schem.
1216
-		$schema['links'] = $this->get_schema_links();
1217
-
1218
-		/**
1219
-		 * Filters the invoice schema for the REST API.
1220
-		 *
1221
-		 * Enables adding extra properties to invoices.
1222
-		 *
1223
-		 * @since 1.0.13
1224
-		 *
1225
-		 * @param array   $schema    The invoice schema.
1226
-		 */
1165
+                'link'         => array(
1166
+                    'description' => __( 'URL to the invoice.', 'invoicing' ),
1167
+                    'type'        => 'string',
1168
+                    'format'      => 'uri',
1169
+                    'context'     => array( 'view', 'edit', 'embed' ),
1170
+                    'readonly'    => true,
1171
+                ),
1172
+
1173
+                'mode'       	  => array(
1174
+                    'description' => __( 'The mode used to process the invoice.', 'invoicing' ),
1175
+                    'type'        => 'string',
1176
+                    'enum'        => array( 'live', 'test' ),
1177
+                    'context'     => array( 'view', 'edit', 'embed' ),
1178
+                    'readonly'    => true,
1179
+                ),
1180
+
1181
+                'slug'       	  => array(
1182
+                    'description' => __( 'An alphanumeric identifier for the invoice.', 'invoicing' ),
1183
+                    'type'        => 'string',
1184
+                    'context'     => array( 'view', 'edit', 'embed' ),
1185
+                    'arg_options' => array(
1186
+                        'sanitize_callback' => array( $this, 'sanitize_slug' ),
1187
+                    ),
1188
+                    'readonly'    => true,
1189
+                ),
1190
+
1191
+                'status'       	  => array(
1192
+                    'description' => __( 'A named status for the invoice.', 'invoicing' ),
1193
+                    'type'        => 'string',
1194
+                    'enum'        => array_keys( wpinv_get_invoice_statuses( true, true ) ),
1195
+                    'context'     => array( 'view', 'edit' ),
1196
+                    'default'	  => 'wpi-pending',
1197
+                ),
1198
+
1199
+                'status_nicename' => array(
1200
+                    'description' => __( 'A human-readable status name for the invoice.', 'invoicing' ),
1201
+                    'type'        => 'string',
1202
+                    'context'     => array( 'view', 'embed' ),
1203
+                    'readonly'    => true,
1204
+                ),
1205
+
1206
+                'post_type'       => array(
1207
+                    'description' => __( 'The post type for the invoice.', 'invoicing' ),
1208
+                    'type'        => 'string',
1209
+                    'context'     => array( 'view' ),
1210
+                    'readonly'    => true,
1211
+                ),
1212
+            ),
1213
+        );
1214
+
1215
+        // Add helpful links to the invoice schem.
1216
+        $schema['links'] = $this->get_schema_links();
1217
+
1218
+        /**
1219
+         * Filters the invoice schema for the REST API.
1220
+         *
1221
+         * Enables adding extra properties to invoices.
1222
+         *
1223
+         * @since 1.0.13
1224
+         *
1225
+         * @param array   $schema    The invoice schema.
1226
+         */
1227 1227
         $schema = apply_filters( "wpinv_rest_invoice_schema", $schema );
1228 1228
 
1229
-		// Cache the invoice schema.
1230
-		$this->schema = $schema;
1229
+        // Cache the invoice schema.
1230
+        $this->schema = $schema;
1231 1231
 		
1232
-		return $this->add_additional_fields_schema( $this->schema );
1233
-	}
1234
-
1235
-	/**
1236
-	 * Retrieve Link Description Objects that should be added to the Schema for the invoices collection.
1237
-	 *
1238
-	 * @since 1.0.13
1239
-	 *
1240
-	 * @return array
1241
-	 */
1242
-	protected function get_schema_links() {
1243
-
1244
-		$href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
1245
-
1246
-		$links = array();
1247
-
1248
-		$links[] = array(
1249
-			'rel'          => 'https://api.w.org/action-publish',
1250
-			'title'        => __( 'The current user can mark this invoice as completed.', 'invoicing' ),
1251
-			'href'         => $href,
1252
-			'targetSchema' => array(
1253
-				'type'       => 'object',
1254
-				'properties' => array(
1255
-					'status' => array(
1256
-						'type' => 'string',
1257
-						'enum' => array( 'publish', 'wpi-renewal' ),
1258
-					),
1259
-				),
1260
-			),
1261
-		);
1262
-
1263
-		$links[] = array(
1264
-			'rel'          => 'https://api.w.org/action-assign-author',
1265
-			'title'        => __( 'The current user can change the owner of this invoice.', 'invoicing' ),
1266
-			'href'         => $href,
1267
-			'targetSchema' => array(
1268
-				'type'       => 'object',
1269
-				'properties'   => array(
1270
-					'user_id'  => array(
1271
-						'type' => 'integer',
1272
-					),
1273
-				),
1274
-			),
1275
-		);
1276
-
1277
-		return $links;
1278
-	}
1279
-
1280
-	/**
1281
-	 * Prepares links for the request.
1282
-	 *
1283
-	 * @since 1.0.13
1284
-	 *
1285
-	 * @param WPInv_Invoice $invoice Invoice Object.
1286
-	 * @return array Links for the given invoice.
1287
-	 */
1288
-	protected function prepare_links( $invoice ) {
1289
-
1290
-		// Prepare the base REST API endpoint for invoices.
1291
-		$base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
1292
-
1293
-		// Entity meta.
1294
-		$links = array(
1295
-			'self'       => array(
1296
-				'href' => rest_url( trailingslashit( $base ) . $invoice->ID ),
1297
-			),
1298
-			'collection' => array(
1299
-				'href' => rest_url( $base ),
1300
-			),
1301
-		);
1302
-
1303
-		if ( ! empty( $invoice->user_id ) ) {
1304
-			$links['user'] = array(
1305
-				'href'       => rest_url( 'wp/v2/users/' . $invoice->user_id ),
1306
-				'embeddable' => true,
1307
-			);
1308
-		}
1309
-
1310
-		/**
1311
-		 * Filters the returned invoice links for the REST API.
1312
-		 *
1313
-		 * Enables adding extra links to invoice API responses.
1314
-		 *
1315
-		 * @since 1.0.13
1316
-		 *
1317
-		 * @param array   $links    Rest links.
1318
-		 */
1319
-		return apply_filters( "wpinv_rest_invoice_links", $links );
1320
-
1321
-	}
1322
-
1323
-	/**
1324
-	 * Get the link relations available for the post and current user.
1325
-	 *
1326
-	 * @since 1.0.13
1327
-	 *
1328
-	 * @param WPInv_Invoice   $invoice    Invoice object.
1329
-	 * @param WP_REST_Request $request Request object.
1330
-	 * @return array List of link relations.
1331
-	 */
1332
-	protected function get_available_actions( $invoice, $request ) {
1333
-
1334
-		if ( 'edit' !== $request['context'] ) {
1335
-			return array();
1336
-		}
1337
-
1338
-		$rels = array();
1339
-
1340
-		// Retrieve the post type object.
1341
-		$post_type = get_post_type_object( $invoice->post_type );
1342
-
1343
-		// Mark invoice as completed.
1344
-		if ( current_user_can( $post_type->cap->publish_posts ) ) {
1345
-			$rels[] = 'https://api.w.org/action-publish';
1346
-		}
1347
-
1348
-		// Change the owner of the invoice.
1349
-		if ( current_user_can( $post_type->cap->edit_others_posts ) ) {
1350
-			$rels[] = 'https://api.w.org/action-assign-author';
1351
-		}
1352
-
1353
-		/**
1354
-		 * Filters the available invoice link relations for the REST API.
1355
-		 *
1356
-		 * Enables adding extra link relation for the current user and request to invoice responses.
1357
-		 *
1358
-		 * @since 1.0.13
1359
-		 *
1360
-		 * @param array   $rels    Available link relations.
1361
-		 */
1362
-		return apply_filters( "wpinv_rest_invoice_link_relations", $rels );
1363
-	}
1364
-
1365
-	/**
1366
-	 * Sanitizes and validates the list of post statuses.
1367
-	 *
1368
-	 * @since 1.0.13
1369
-	 *
1370
-	 * @param string|array    $statuses  One or more post statuses.
1371
-	 * @param WP_REST_Request $request   Full details about the request.
1372
-	 * @param string          $parameter Additional parameter to pass to validation.
1373
-	 * @return array|WP_Error A list of valid statuses, otherwise WP_Error object.
1374
-	 */
1375
-	public function sanitize_post_statuses( $statuses, $request, $parameter ) {
1376
-
1377
-		$statuses 	  = wp_parse_slug_list( $statuses );
1378
-		$valid_statuses = array_keys( wpinv_get_invoice_statuses( true, true ) );
1379
-		return array_intersect( $statuses, $valid_statuses );
1232
+        return $this->add_additional_fields_schema( $this->schema );
1233
+    }
1234
+
1235
+    /**
1236
+     * Retrieve Link Description Objects that should be added to the Schema for the invoices collection.
1237
+     *
1238
+     * @since 1.0.13
1239
+     *
1240
+     * @return array
1241
+     */
1242
+    protected function get_schema_links() {
1243
+
1244
+        $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
1245
+
1246
+        $links = array();
1247
+
1248
+        $links[] = array(
1249
+            'rel'          => 'https://api.w.org/action-publish',
1250
+            'title'        => __( 'The current user can mark this invoice as completed.', 'invoicing' ),
1251
+            'href'         => $href,
1252
+            'targetSchema' => array(
1253
+                'type'       => 'object',
1254
+                'properties' => array(
1255
+                    'status' => array(
1256
+                        'type' => 'string',
1257
+                        'enum' => array( 'publish', 'wpi-renewal' ),
1258
+                    ),
1259
+                ),
1260
+            ),
1261
+        );
1262
+
1263
+        $links[] = array(
1264
+            'rel'          => 'https://api.w.org/action-assign-author',
1265
+            'title'        => __( 'The current user can change the owner of this invoice.', 'invoicing' ),
1266
+            'href'         => $href,
1267
+            'targetSchema' => array(
1268
+                'type'       => 'object',
1269
+                'properties'   => array(
1270
+                    'user_id'  => array(
1271
+                        'type' => 'integer',
1272
+                    ),
1273
+                ),
1274
+            ),
1275
+        );
1276
+
1277
+        return $links;
1278
+    }
1279
+
1280
+    /**
1281
+     * Prepares links for the request.
1282
+     *
1283
+     * @since 1.0.13
1284
+     *
1285
+     * @param WPInv_Invoice $invoice Invoice Object.
1286
+     * @return array Links for the given invoice.
1287
+     */
1288
+    protected function prepare_links( $invoice ) {
1289
+
1290
+        // Prepare the base REST API endpoint for invoices.
1291
+        $base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
1292
+
1293
+        // Entity meta.
1294
+        $links = array(
1295
+            'self'       => array(
1296
+                'href' => rest_url( trailingslashit( $base ) . $invoice->ID ),
1297
+            ),
1298
+            'collection' => array(
1299
+                'href' => rest_url( $base ),
1300
+            ),
1301
+        );
1302
+
1303
+        if ( ! empty( $invoice->user_id ) ) {
1304
+            $links['user'] = array(
1305
+                'href'       => rest_url( 'wp/v2/users/' . $invoice->user_id ),
1306
+                'embeddable' => true,
1307
+            );
1308
+        }
1309
+
1310
+        /**
1311
+         * Filters the returned invoice links for the REST API.
1312
+         *
1313
+         * Enables adding extra links to invoice API responses.
1314
+         *
1315
+         * @since 1.0.13
1316
+         *
1317
+         * @param array   $links    Rest links.
1318
+         */
1319
+        return apply_filters( "wpinv_rest_invoice_links", $links );
1320
+
1321
+    }
1322
+
1323
+    /**
1324
+     * Get the link relations available for the post and current user.
1325
+     *
1326
+     * @since 1.0.13
1327
+     *
1328
+     * @param WPInv_Invoice   $invoice    Invoice object.
1329
+     * @param WP_REST_Request $request Request object.
1330
+     * @return array List of link relations.
1331
+     */
1332
+    protected function get_available_actions( $invoice, $request ) {
1333
+
1334
+        if ( 'edit' !== $request['context'] ) {
1335
+            return array();
1336
+        }
1337
+
1338
+        $rels = array();
1339
+
1340
+        // Retrieve the post type object.
1341
+        $post_type = get_post_type_object( $invoice->post_type );
1342
+
1343
+        // Mark invoice as completed.
1344
+        if ( current_user_can( $post_type->cap->publish_posts ) ) {
1345
+            $rels[] = 'https://api.w.org/action-publish';
1346
+        }
1347
+
1348
+        // Change the owner of the invoice.
1349
+        if ( current_user_can( $post_type->cap->edit_others_posts ) ) {
1350
+            $rels[] = 'https://api.w.org/action-assign-author';
1351
+        }
1352
+
1353
+        /**
1354
+         * Filters the available invoice link relations for the REST API.
1355
+         *
1356
+         * Enables adding extra link relation for the current user and request to invoice responses.
1357
+         *
1358
+         * @since 1.0.13
1359
+         *
1360
+         * @param array   $rels    Available link relations.
1361
+         */
1362
+        return apply_filters( "wpinv_rest_invoice_link_relations", $rels );
1363
+    }
1364
+
1365
+    /**
1366
+     * Sanitizes and validates the list of post statuses.
1367
+     *
1368
+     * @since 1.0.13
1369
+     *
1370
+     * @param string|array    $statuses  One or more post statuses.
1371
+     * @param WP_REST_Request $request   Full details about the request.
1372
+     * @param string          $parameter Additional parameter to pass to validation.
1373
+     * @return array|WP_Error A list of valid statuses, otherwise WP_Error object.
1374
+     */
1375
+    public function sanitize_post_statuses( $statuses, $request, $parameter ) {
1376
+
1377
+        $statuses 	  = wp_parse_slug_list( $statuses );
1378
+        $valid_statuses = array_keys( wpinv_get_invoice_statuses( true, true ) );
1379
+        return array_intersect( $statuses, $valid_statuses );
1380 1380
 		
1381
-	}
1381
+    }
1382 1382
     
1383 1383
 }
1384 1384
\ No newline at end of file
Please login to merge, or discard this patch.