Completed
Push — master ( 4ba683...3a59f6 )
by Zack
31:21 queued 27:45
created

Views_Route::prepare_entry_for_response()   F

Complexity

Conditions 14
Paths 294

Size

Total Lines 89

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 38
CRAP Score 14

Importance

Changes 0
Metric Value
cc 14
nc 294
nop 5
dl 0
loc 89
ccs 38
cts 38
cp 1
crap 14
rs 3.6466
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 18 and the first side effect is on line 15.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * @package   GravityView
4
 * @license   GPL2+
5
 * @author    Josh Pollock <[email protected]>
6
 * @link      http://gravityview.co
7
 * @copyright Copyright 2015, Katz Web Services, Inc.
8
 *
9
 * @since 2.0
10
 */
11
namespace GV\REST;
12
13
/** If this file is called directly, abort. */
14 1
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
15
	die();
16
}
17
18
class Views_Route extends Route {
19
	/**
20
	 * Route Name
21
	 *
22
	 * @since 2.0
23
	 *
24
	 * @access protected
25
	 * @string
26
	 */
27
	protected $route_name = 'views';
28
29
	/**
30
	 * Sub type, forms {$namespace}/route_name/{id}/sub_type type endpoints
31
	 *
32
	 * @since 2.0
33
	 * @access protected
34
	 * @var string
35
	 */
36
	protected $sub_type = 'entries';
37
38
39
	/**
40
	 * Get a collection of views
41
	 *
42
	 * Callback for GET /v1/views/
43
	 *
44
	 * @param \WP_REST_Request $request Full data about the request.
45
	 * @return \WP_Error|\WP_REST_Response
46
	 */
47 3
	public function get_items( $request ) {
48
49 3
		$page = $request->get_param( 'page' );
50 3
		$limit = $request->get_param( 'limit' );
51
52 3
		$items = \GVCommon::get_all_views( array(
53 3
			'posts_per_page' => $limit,
54 3
			'paged' => $page,
55
		) );
56
57 3
		if ( empty( $items ) ) {
58
			return new \WP_Error( 'gravityview-no-views', __( 'No Views found.', 'gravityview' ) ); //@todo message
59
		}
60
61
		$data = array(
62 3
			'views' => array(),
63 3
			'total' => wp_count_posts( 'gravityview' )->publish,
64
		);
65 3
		foreach ( $items as $item ) {
66 3
			$data['views'][] = $this->prepare_view_for_response( $item, $request );
67
		}
68
69 3
		return new \WP_REST_Response( $data, 200 );
70
	}
71
72
	/**
73
	 * Get one view
74
	 *
75
	 * Callback for /v1/views/{id}/
76
	 *
77
	 * @since 2.0
78
	 * @param \WP_REST_Request $request Full data about the request.
79
	 * @return \WP_Error|\WP_REST_Response
80
	 */
81 2
	public function get_item( $request ) {
82
83 2
		$url = $request->get_url_params();
84
85 2
		$view_id = intval( $url['id'] );
86
87 2
		$item = get_post( $view_id );
88
89
		//return a response or error based on some conditional
90 2
		if ( $item && ! is_wp_error( $item ) ) {
91 2
			$data = $this->prepare_view_for_response( $item, $request );
92 2
			return new \WP_REST_Response( $data, 200 );
93
		}
94
95
		return new \WP_Error( 'code', sprintf( 'A View with ID #%d was not found.', $view_id ) );
96
	}
97
98
	/**
99
	 * Prepare the item for the REST response
100
	 *
101
	 * @since 2.0
102
	 * @param \GV\View $view The view.
103
	 * @param \GV\Entry $entry WordPress representation of the item.
104
	 * @param \WP_REST_Request $request Request object.
105
	 * @param string $context The context (directory, single)
106
	 * @param string $class The value renderer. Default: null (raw value)
107
	 *
108
	 * @since 2.1 Add value renderer override $class parameter.
109
	 *
110
	 * @return mixed The data that is sent.
111
	 */
112 8
	public function prepare_entry_for_response( $view, $entry, \WP_REST_Request $request, $context, $class = null ) {
113
114
		// Only output the fields that should be displayed.
115 8
		$allowed = array();
116 8
		foreach ( $view->fields->by_position( "{$context}_*" )->by_visible()->all() as $field ) {
117 8
			$allowed[] = $field;
118
		}
119
120
		/**
121
		 * @filter `gravityview/rest/entry/fields` Whitelist more entry fields that are output in regular REST requests.
122
		 * @param[in,out] array $allowed The allowed ones, default by_visible, by_position( "context_*" ), i.e. as set in the view.
123
		 * @param \GV\View $view The view.
124
		 * @param \GV\Entry $entry The entry.
125
		 * @param \WP_REST_Request $request Request object.
126
		 * @param string $context The context (directory, single)
127
		 */
128 8
		$allowed_field_ids = apply_filters( 'gravityview/rest/entry/fields', wp_list_pluck( $allowed, 'ID' ), $view, $entry, $request, $context );
129
130 8
		$allowed = array_filter( $allowed, function( $field ) use ( $allowed_field_ids ) {
131 8
			return in_array( $field->ID, $allowed_field_ids, true );
132 8
		} );
133
134
		// Tack on additional fields if needed
135 8
		foreach ( array_diff( $allowed_field_ids, wp_list_pluck( $allowed, 'ID' ) ) as $field_id ) {
136 2
			$allowed[] = is_numeric( $field_id ) ? \GV\GF_Field::by_id( $view->form, $field_id ) : \GV\Internal_Field::by_id( $field_id );
137
		}
138
139 8
		$r = new Request( $request );
140 8
		$return = array();
141
142 8
		$renderer = new \GV\Field_Renderer();
143
		
144 8
		$used_ids = array();
145
146 8
		foreach ( $allowed as $field ) {
147 8
			$source = is_numeric( $field->ID ) ? $view->form : new \GV\Internal_Source();
148
149 8
			$field_id = $field->ID;
150 8
			$index = null;
151
152 8
			if ( ! isset( $used_ids[ $field_id ] ) ) {
153 8
				$used_ids[ $field_id ] = 0;
154
			} else {
155 1
				$index = ++$used_ids[ $field_id ];
156
			}
157
158 8
			if ( $index ) {
159
				/**
160
				 * Modify non-unique IDs (custom, id, etc.) to be unique and not gobbled up.
161
				 */
162 1
				$field_id = sprintf( '%s(%d)', $field_id, $index + 1 );
163
			}
164
165
			/**
166
			 * @filter `gravityview/api/field/key` Filter the key name in the results for JSON output.
167
			 * @param[in,out] string $field_id The ID. Should be unique or keys will be gobbled up.
168
			 * @param \GV\View $view The view.
169
			 * @param \GV\Entry $entry The entry.
170
			 * @param \WP_REST_Request $request Request object.
171
			 * @param string $context The context (directory, single)
172
			 */
173 8
			$field_id = apply_filters( 'gravityview/api/field/key', $field_id, $view, $entry, $request, $context );
174
175 8
			if ( ! $class && in_array( $field->ID, array( 'custom' ) ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $class of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
176
				/**
177
				 * Custom fields (and perhaps some others) will require rendering as they don't
178
				 * contain an intrinsic value (for custom their value is stored in the view and requires a renderer).
179
				 * We force the CSV template to take over in such cases, it's good enough for most cases.
180
				 */
181 2
				$return[ $field_id ] = $renderer->render( $field, $view, $source, $entry, $r, '\GV\Field_CSV_Template' );
182 8
			} else if ( $class ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $class of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
183 4
				$return[ $field_id ] = $renderer->render( $field, $view, $source, $entry, $r, $class );
184
			} else {
185 6
				switch ( $field->type ):
186 6
					case 'list':
187 1
						$return[ $field_id ] = unserialize( $field->get_value( $view, $source, $entry, $r ) );
188 1
						break;
189 6
					case 'fileupload':
190 6
					case 'business_hours':
191 1
						$return[ $field_id ] = json_decode( $field->get_value( $view, $source, $entry, $r ) );
192 1
						break;
193
					default;
194 6
						$return[ $field_id ] = $field->get_value( $view, $source, $entry, $r );
195
				endswitch;
196
			}
197
		}
198
199 8
		return $return;
200
	}
201
202
	/**
203
	 * Get entries from a view
204
	 *
205
	 * Callback for /v1/views/{id}/entries/
206
	 *
207
	 * @since 2.0
208
	 * @param \WP_REST_Request $request Full data about the request.
209
	 * @return \WP_Error|\WP_REST_Response
210
	 */
211 6
	public function get_sub_items( $request ) {
212
213 6
		$url     = $request->get_url_params();
214 6
		$view_id = intval( $url['id'] );
215 6
		$format  = \GV\Utils::get( $url, 'format', 'json' );
216
217 6
		if( $post_id = $request->get_param('post_id') ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
218
			global $post;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
219
220
			$post = get_post( $post_id );
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
221
222
			if ( ! $post || is_wp_error( $post ) ) {
223
				return new \WP_Error( 'gravityview-post-not-found', sprintf( 'A post with ID #%d was not found.', $post_id ) );
224
			}
225
226
			$collection = \GV\View_Collection::from_post( $post );
227
228
			if ( ! $collection->contains( $view_id ) ) {
229
				return new \WP_Error( 'gravityview-post-not-contains', sprintf( 'The post with ID #%d does not contain a View with ID #%d', $post_id, $view_id ) );
230
			}
231
		}
232
233 6
		$view = \GV\View::by_id( $view_id );
234
235 6
		if ( 'html' === $format ) {
236
237 1
			$renderer = new \GV\View_Renderer();
238 1
			$count = $total = 0;
239
240
			/** @var \GV\Template_Context $context */
241 1
			add_action( 'gravityview/template/view/render', function( $context ) use ( &$count, &$total ) {
242 1
				$count = $context->entries->count();
243 1
				$total = $context->entries->total();
244 1
			} );
245
246 1
			$output = $renderer->render( $view, new Request( $request ) );
247
248
			/**
249
			 * @filter `gravityview/rest/entries/html/insert_meta` Whether to include `http-equiv` meta tags in the HTML output describing the data
250
			 * @since 2.0
251
			 * @param bool $insert_meta Add <meta> tags? [Default: true]
252
			 * @param int $count The number of entries being rendered
253
			 * @param \GV\View $view The view.
254
			 * @param \WP_REST_Request $request Request object.
255
			 * @param int $total The number of total entries for the request
256
			 */
257 1
			$insert_meta = apply_filters( 'gravityview/rest/entries/html/insert_meta', true, $count, $view, $request, $total );
258
259 1
			if ( $insert_meta ) {
260 1
				$output = '<meta http-equiv="X-Item-Count" content="' . $count . '" />' . $output;
261 1
				$output = '<meta http-equiv="X-Item-Total" content="' . $total . '" />' . $output;
262
			}
263
264 1
			$response = new \WP_REST_Response( $output, 200 );
265 1
			$response->header( 'X-Item-Count', $count );
266 1
			$response->header( 'X-Item-Total', $total );
267
268 1
			return $response;
269
		}
270
271 6
		$entries = $view->get_entries( new Request( $request ) );
272
273 6
		if ( ! $entries->all() ) {
274
			return new \WP_Error( 'gravityview-no-entries', __( 'No Entries found.', 'gravityview' ) );
275
		}
276
277 6
		if ( 'csv' === $format ) {
278 4
			ob_start();
279
280 4
			$csv = fopen( 'php://output', 'w' );
281
282
			/** Da' BOM :) */
283 4
			if ( apply_filters( 'gform_include_bom_export_entries', true, $view->form ? $view->form->form : null ) ) {
284 4
				fputs( $csv, "\xef\xbb\xbf" );
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using fputs()
Loading history...
285
			}
286
287 4
			$headers_done = false;
288
289 4
			foreach ( $entries->all() as $entry ) {
290 4
				$entry = $this->prepare_entry_for_response( $view, $entry, $request, 'directory', '\GV\Field_CSV_Template' );
291
292 4
				if ( ! $headers_done ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $headers_done of type false|integer is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
293 4
					$headers_done = fputcsv( $csv, array_map( array( '\GV\Utils', 'strip_excel_formulas' ), array_keys( $entry ) ) );
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using fputcsv()
Loading history...
294
				}
295
296 4
				fputcsv( $csv, array_map( array( '\GV\Utils', 'strip_excel_formulas' ), $entry ) );
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using fputcsv()
Loading history...
297
			}
298
299 4
			$response = new \WP_REST_Response( '', 200 );
300 4
			$response->header( 'X-Item-Count', $entries->count() );
301 4
			$response->header( 'X-Item-Total', $entries->total() );
302 4
			$response->header( 'Content-Type', 'text/csv' );
303
304 4
			fflush( $csv );
305
306 4
			$data = rtrim( ob_get_clean() );
307
308 4
			add_filter( 'rest_pre_serve_request', function() use ( $data ) {
309
				echo $data;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$data'
Loading history...
310
				return true;
311 4
			} );
312
313 4
			if ( defined( 'DOING_GRAVITYVIEW_TESTS' ) && DOING_GRAVITYVIEW_TESTS ) {
314 4
				echo $data; // rest_pre_serve_request is not called in tests
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$data'
Loading history...
315
			}
316
317 4
			return $response;
318
		}
319
320 4
		$data = array( 'entries' => $entries->all(), 'total' => $entries->total() );
321
322 4
		foreach ( $data['entries'] as &$entry ) {
323 4
			$entry = $this->prepare_entry_for_response( $view, $entry, $request, 'directory' );
324
		}
325
326 4
		return new \WP_REST_Response( $data, 200 );
327
	}
328
329
	/**
330
	 * Get one entry from view
331
	 *
332
	 * Callback for /v1/views/{id}/entries/{id}/
333
	 *
334
	 * @uses GVCommon::get_entry
335
	 * @since 2.0
336
	 * @param \WP_REST_Request $request Full data about the request.
337
	 * @return \WP_Error|\WP_REST_Response
338
	 */
339 4
	public function get_sub_item( $request ) {
340 4
		$url      = $request->get_url_params();
341 4
		$view_id  = intval( $url['id'] );
342 4
		$entry_id = intval( $url['s_id'] );
343 4
		$format   = \GV\Utils::get( $url, 'format', 'json' );
344
345 4
		$view  = \GV\View::by_id( $view_id );
346 4
		$entry = \GV\GF_Entry::by_id( $entry_id );
347
348 4
		if ( $format === 'html' ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
349 1
			$renderer = new \GV\Entry_Renderer();
350 1
			return $renderer->render( $entry, $view, new Request( $request ) );
351
		}
352
353 4
		return $this->prepare_entry_for_response( $view, $entry, $request, 'single' );
354
	}
355
356
	/**
357
	 * Prepare the item for the REST response
358
	 *
359
	 * @since 2.0
360
	 * @param \WP_Post $view_post WordPress representation of the item.
361
	 * @param \WP_REST_Request $request Request object.
362
	 * @return mixed
363
	 */
364 4
	public function prepare_view_for_response( $view_post, \WP_REST_Request $request ) {
365 4
		if ( is_wp_error( $this->get_item_permissions_check( $request, $view_post->ID ) ) ) {
366
			// Redacted out view.
367 1
			return array( 'ID' => $view_post->ID, 'post_content' => __( 'You are not allowed to access this content.', 'gravityview' ) );
368
		}
369
370 4
		$view = \GV\View::from_post( $view_post );
371
372 4
		$item = $view->as_data();
373
374
		// Add all the WP_Post data
375 4
		$view_post = $view_post->to_array();
376
377 4
		unset( $view_post['to_ping'], $view_post['ping_status'], $view_post['pinged'], $view_post['post_type'], $view_post['filter'], $view_post['post_category'], $view_post['tags_input'], $view_post['post_content'], $view_post['post_content_filtered'] );
378
379 4
		$return = wp_parse_args( $item, $view_post );
380
381 4
		$return['title'] = $return['post_title'];
382
383 4
		$return['settings'] = isset( $return['atts'] ) ? $return['atts'] : array();
384 4
		unset( $return['atts'], $return['view_id'] );
385
386 4
		$return['search_criteria'] = array(
387 4
			'page_size' => rgars( $return, 'settings/page_size' ),
388 4
			'sort_field' => rgars( $return, 'settings/sort_field' ),
389 4
			'sort_direction' => rgars( $return, 'settings/sort_direction' ),
390 4
			'offset' => rgars( $return, 'settings/offset' ),
391
		);
392
393 4
		unset( $return['settings']['page_size'], $return['settings']['sort_field'], $return['settings']['sort_direction'] );
394
395
		// Redact for non-logged ins
396 4
		if ( ! \GVCommon::has_cap( 'edit_others_gravityviews' ) ) {
397 4
			unset( $return['settings'] );
398 4
			unset( $return['search_criteria'] );
399
		}
400
		
401 4
		if ( ! \GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) {
402 4
			unset( $return['form'] );
403
		}
404
405 4
		return $return;
406
	}
407
408
	/**
409
	 * @param \WP_REST_Request $request
410
	 *
411
	 * @return bool|\WP_Error
412
	 */
413 8
	public function get_item_permissions_check( $request ) {
414 8
		if ( func_num_args() === 2 ) {
0 ignored issues
show
introduced by
Found "=== 2". Use Yoda Condition checks, you must
Loading history...
415 4
			$view_id = func_get_arg( 1 ); // $view_id override
416
		} else {
417 7
			$url     = $request->get_url_params();
418 7
			$view_id = intval( $url['id'] );
419
		}
420
421 8
		if ( ! $view = \GV\View::by_id( $view_id ) ) {
422
			return new \WP_Error( 'rest_forbidden', __( 'You are not allowed to access this content.', 'gravityview' ) );
423
		}
424
425 8
		while ( $error = $view->can_render( array( 'rest' ), $request ) ) {
426
427 8
			if ( ! is_wp_error( $error ) ) {
428 8
				break;
429
			}
430
431 1
			switch ( str_replace( 'gravityview/', '', $error->get_error_code() ) ) {
432 1
				case 'rest_disabled':
433 1
				case 'post_password_required':
434 1
				case 'not_public':
435
				case 'embed_only':
436
				case 'no_direct_access':
437 1
					return new \WP_Error( 'rest_forbidden', __( 'You are not allowed to access this content.', 'gravityview' ) );
438
				case 'no_form_attached':
439
					return new \WP_Error( 'rest_forbidden', __( 'This View is not configured properly.', 'gravityview' ) );
440
				default:
441
					return new \WP_Error( 'rest_forbidden', __( 'You are not allowed to access this content.', 'gravityview' ) );
442
			}
443
		}
444
445
		/**
446
		 * @filter `gravityview/view/output/rest` Disable rest output. Final chance.
447
		 * @param[in,out] bool Enable or not.
448
		 * @param \GV\View $view The view.
449
		 */
450 8
		if ( ! apply_filters( 'gravityview/view/output/rest', true, $view ) ) {
451 1
			return new \WP_Error( 'rest_forbidden', __( 'You are not allowed to access this content.', 'gravityview' ) );
452
		}
453
454 8
		return true;
455
	}
456
457 4
	public function get_sub_item_permissions_check( $request ) {
458
		// Accessing a single entry needs the View access permissions.
459 4
		if ( is_wp_error( $error = $this->get_items_permissions_check( $request ) ) ) {
460
			return $error;
461
		}
462
463 4
		$url     = $request->get_url_params();
464 4
		$view_id = intval( $url['id'] );
465 4
		$entry_id = intval( $url['s_id'] );
466
467 4
		$view = \GV\View::by_id( $view_id );
468
469 4
		if ( ! $entry = \GV\GF_Entry::by_id( $entry_id ) ) {
470
			return new \WP_Error( 'rest_forbidden', 'You are not allowed to view this content.', 'gravityview' );
471
		}
472
473 4
		if ( $entry['form_id'] != $view->form->ID ) {
474
			return new \WP_Error( 'rest_forbidden', 'You are not allowed to view this content.', 'gravityview' );
475
		}
476
477 4
		if ( $entry['status'] != 'active' ) {
0 ignored issues
show
introduced by
Found "!= '". Use Yoda Condition checks, you must
Loading history...
478
			return new \WP_Error( 'rest_forbidden', 'You are not allowed to view this content.', 'gravityview' );
479
		}
480
481 4
		if ( apply_filters( 'gravityview_custom_entry_slug', false ) && $entry->slug != get_query_var( \GV\Entry::get_endpoint_name() ) ) {
482
			return new \WP_Error( 'rest_forbidden', 'You are not allowed to view this content.', 'gravityview' );
483
		}
484
485 4
		$is_admin_and_can_view = $view->settings->get( 'admin_show_all_statuses' ) && \GVCommon::has_cap('gravityview_moderate_entries', $view->ID );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
486
487 4
		if ( $view->settings->get( 'show_only_approved' ) && ! $is_admin_and_can_view ) {
488 1
			if ( ! \GravityView_Entry_Approval_Status::is_approved( gform_get_meta( $entry->ID, \GravityView_Entry_Approval::meta_key ) )  ) {
489 1
				return new \WP_Error( 'rest_forbidden', 'You are not allowed to view this content.', 'gravityview' );
490
			}
491
		}
492
493 4
		return true;
494
	}
495
496 6
	public function get_items_permissions_check( $request ) {
497
		// Getting a list of all Views is always possible.
498 6
		return true;
499
	}
500
501 6
	public function get_sub_items_permissions_check( $request ) {
502
		// Accessing all entries of a View needs the same permissions as accessing the View.
503 6
		return $this->get_item_permissions_check( $request );
504
	}
505
}
506