1
|
|
|
<?php |
|
|
|
|
2
|
|
|
namespace GV; |
3
|
|
|
|
4
|
|
|
/** If this file is called directly, abort. */ |
5
|
|
|
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) { |
6
|
|
|
die(); |
7
|
|
|
} |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* The default GravityView View class. |
11
|
|
|
* |
12
|
|
|
* Houses all base View functionality. |
13
|
|
|
* |
14
|
|
|
* Can be accessed as an array for old compatibility's sake |
15
|
|
|
* in line with the elements inside the \GravityView_View_Data::$views array. |
16
|
|
|
*/ |
17
|
|
|
class View implements \ArrayAccess { |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @var \WP_Post The backing post instance. |
21
|
|
|
*/ |
22
|
|
|
private $post; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var \GV\View_Settings The settings. |
26
|
|
|
* |
27
|
|
|
* @api |
28
|
|
|
* @since 2.0 |
29
|
|
|
*/ |
30
|
|
|
public $settings; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var \GV\Widget_Collection The widets attached here. |
34
|
|
|
* |
35
|
|
|
* @api |
36
|
|
|
* @since 2.0 |
37
|
|
|
*/ |
38
|
|
|
public $widgets; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @var \GV\GF_Form|\GV\Form The backing form for this view. |
42
|
|
|
* |
43
|
|
|
* Contains the form that is sourced for entries in this view. |
44
|
|
|
* |
45
|
|
|
* @api |
46
|
|
|
* @since 2.0 |
47
|
|
|
*/ |
48
|
|
|
public $form; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @var \GV\Field_Collection The fields for this view. |
52
|
|
|
* |
53
|
|
|
* Contains all the fields that are attached to this view. |
54
|
|
|
* |
55
|
|
|
* @api |
56
|
|
|
* @since 2.0 |
57
|
|
|
*/ |
58
|
|
|
public $fields; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* @var array |
62
|
|
|
* |
63
|
|
|
* Internal static cache for gets, and whatnot. |
64
|
|
|
* This is not persistent, resets across requests. |
65
|
|
|
|
66
|
|
|
* @internal |
67
|
|
|
*/ |
68
|
|
|
private static $cache = array(); |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* @var \GV\Join[] The joins for all sources in this view. |
72
|
|
|
* |
73
|
|
|
* @api |
74
|
|
|
* @since future |
75
|
|
|
*/ |
76
|
|
|
public $joins = array(); |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* The constructor. |
80
|
|
|
*/ |
81
|
67 |
|
public function __construct() { |
82
|
67 |
|
$this->settings = new View_Settings(); |
83
|
67 |
|
$this->fields = new Field_Collection(); |
84
|
67 |
|
$this->widgets = new Widget_Collection(); |
85
|
67 |
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Register the gravityview WordPress Custom Post Type. |
89
|
|
|
* |
90
|
|
|
* @internal |
91
|
|
|
* @return void |
92
|
|
|
*/ |
93
|
|
|
public static function register_post_type() { |
94
|
|
|
|
95
|
|
|
/** Register only once */ |
96
|
|
|
if ( post_type_exists( 'gravityview' ) ) { |
97
|
|
|
return; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @filter `gravityview_is_hierarchical` Make GravityView Views hierarchical by returning TRUE |
102
|
|
|
* This will allow for Views to be nested with Parents and also allows for menu order to be set in the Page Attributes metabox |
103
|
|
|
* @since 1.13 |
104
|
|
|
* @param boolean $is_hierarchical Default: false |
105
|
|
|
*/ |
106
|
|
|
$is_hierarchical = (bool)apply_filters( 'gravityview_is_hierarchical', false ); |
|
|
|
|
107
|
|
|
|
108
|
|
|
$supports = array( 'title', 'revisions' ); |
109
|
|
|
|
110
|
|
|
if ( $is_hierarchical ) { |
111
|
|
|
$supports[] = 'page-attributes'; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* @filter `gravityview_post_type_supports` Modify post type support values for `gravityview` post type |
116
|
|
|
* @see add_post_type_support() |
117
|
|
|
* @since 1.15.2 |
118
|
|
|
* @param array $supports Array of features associated with a functional area of the edit screen. Default: 'title', 'revisions'. If $is_hierarchical, also 'page-attributes' |
119
|
|
|
* @param[in] boolean $is_hierarchical Do Views support parent/child relationships? See `gravityview_is_hierarchical` filter. |
120
|
|
|
*/ |
121
|
|
|
$supports = apply_filters( 'gravityview_post_type_support', $supports, $is_hierarchical ); |
122
|
|
|
|
123
|
|
|
/** Register Custom Post Type - gravityview */ |
124
|
|
|
$labels = array( |
125
|
|
|
'name' => _x( 'Views', 'Post Type General Name', 'gravityview' ), |
126
|
|
|
'singular_name' => _x( 'View', 'Post Type Singular Name', 'gravityview' ), |
127
|
|
|
'menu_name' => _x( 'Views', 'Menu name', 'gravityview' ), |
128
|
|
|
'parent_item_colon' => __( 'Parent View:', 'gravityview' ), |
129
|
|
|
'all_items' => __( 'All Views', 'gravityview' ), |
130
|
|
|
'view_item' => _x( 'View', 'View Item', 'gravityview' ), |
131
|
|
|
'add_new_item' => __( 'Add New View', 'gravityview' ), |
132
|
|
|
'add_new' => __( 'New View', 'gravityview' ), |
133
|
|
|
'edit_item' => __( 'Edit View', 'gravityview' ), |
134
|
|
|
'update_item' => __( 'Update View', 'gravityview' ), |
135
|
|
|
'search_items' => __( 'Search Views', 'gravityview' ), |
136
|
|
|
'not_found' => \GravityView_Admin::no_views_text(), |
137
|
|
|
'not_found_in_trash' => __( 'No Views found in Trash', 'gravityview' ), |
138
|
|
|
'filter_items_list' => __( 'Filter Views list', 'gravityview' ), |
139
|
|
|
'items_list_navigation' => __( 'Views list navigation', 'gravityview' ), |
140
|
|
|
'items_list' => __( 'Views list', 'gravityview' ), |
141
|
|
|
'view_items' => __( 'See Views', 'gravityview' ), |
142
|
|
|
'attributes' => __( 'View Attributes', 'gravityview' ), |
143
|
|
|
); |
144
|
|
|
$args = array( |
145
|
|
|
'label' => __( 'view', 'gravityview' ), |
146
|
|
|
'description' => __( 'Create views based on a Gravity Forms form', 'gravityview' ), |
147
|
|
|
'labels' => $labels, |
148
|
|
|
'supports' => $supports, |
149
|
|
|
'hierarchical' => $is_hierarchical, |
150
|
|
|
/** |
151
|
|
|
* @filter `gravityview_direct_access` Should Views be directly accessible, or only visible using the shortcode? |
152
|
|
|
* @see https://codex.wordpress.org/Function_Reference/register_post_type#public |
153
|
|
|
* @since 1.15.2 |
154
|
|
|
* @param[in,out] boolean `true`: allow Views to be accessible directly. `false`: Only allow Views to be embedded via shortcode. Default: `true` |
155
|
|
|
* @param int $view_id The ID of the View currently being requested. `0` for general setting |
156
|
|
|
*/ |
157
|
|
|
'public' => apply_filters( 'gravityview_direct_access', gravityview()->plugin->is_compatible(), 0 ), |
158
|
|
|
'show_ui' => gravityview()->plugin->is_compatible(), |
159
|
|
|
'show_in_menu' => gravityview()->plugin->is_compatible(), |
160
|
|
|
'show_in_nav_menus' => true, |
161
|
|
|
'show_in_admin_bar' => true, |
162
|
|
|
'menu_position' => 17, |
163
|
|
|
'menu_icon' => '', |
164
|
|
|
'can_export' => true, |
165
|
|
|
/** |
166
|
|
|
* @filter `gravityview_has_archive` Enable Custom Post Type archive? |
167
|
|
|
* @since 1.7.3 |
168
|
|
|
* @param boolean False: don't have frontend archive; True: yes, have archive. Default: false |
169
|
|
|
*/ |
170
|
|
|
'has_archive' => apply_filters( 'gravityview_has_archive', false ), |
171
|
|
|
'exclude_from_search' => true, |
172
|
|
|
'rewrite' => array( |
173
|
|
|
/** |
174
|
|
|
* @filter `gravityview_slug` Modify the url part for a View. |
175
|
|
|
* @see https://docs.gravityview.co/article/62-changing-the-view-slug |
176
|
|
|
* @param string $slug The slug shown in the URL |
177
|
|
|
*/ |
178
|
|
|
'slug' => apply_filters( 'gravityview_slug', 'view' ), |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* @filter `gravityview/post_type/with_front` Should the permalink structure |
182
|
|
|
* be prepended with the front base. |
183
|
|
|
* (example: if your permalink structure is /blog/, then your links will be: false->/view/, true->/blog/view/). |
184
|
|
|
* Defaults to true. |
185
|
|
|
* @see https://codex.wordpress.org/Function_Reference/register_post_type |
186
|
|
|
* @since 2.0 |
187
|
|
|
* @param bool $with_front |
188
|
|
|
*/ |
189
|
|
|
'with_front' => apply_filters( 'gravityview/post_type/with_front', true ), |
190
|
|
|
), |
191
|
|
|
'capability_type' => 'gravityview', |
192
|
|
|
'map_meta_cap' => true, |
193
|
|
|
); |
194
|
|
|
|
195
|
|
|
register_post_type( 'gravityview', $args ); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* A renderer filter for the View post type content. |
200
|
|
|
* |
201
|
|
|
* @param string $content Should be empty, as we don't store anything there. |
202
|
|
|
* |
203
|
|
|
* @return string $content The view content as output by the renderers. |
204
|
|
|
*/ |
205
|
5 |
|
public static function content( $content ) { |
206
|
5 |
|
$request = gravityview()->request; |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* This is not a View. Bail. |
210
|
|
|
* |
211
|
|
|
* Shortcodes and oEmbeds and whatnot will be handled |
212
|
|
|
* elsewhere. |
213
|
|
|
*/ |
214
|
5 |
|
if ( ! $view = $request->is_view() ) { |
215
|
2 |
|
return $content; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* This View is password protected. Nothing to do here. |
220
|
|
|
* WordPress outputs the form automagically inside `get_the_content`. |
221
|
|
|
*/ |
222
|
3 |
|
if ( post_password_required( $view->ID ) ) { |
|
|
|
|
223
|
1 |
|
gravityview()->log->notice( 'Post password is required for View #{view_id}', array( 'view_id' => $view->ID ) ); |
|
|
|
|
224
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
225
|
|
|
} |
226
|
|
|
|
227
|
3 |
|
if ( ! $view->form ) { |
228
|
|
|
gravityview()->log->notice( 'View #{id} has no form attached to it.', array( 'id' => $view->ID ) ); |
|
|
|
|
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* This View has no data source. There's nothing to show really. |
232
|
|
|
* ...apart from a nice message if the user can do anything about it. |
233
|
|
|
*/ |
234
|
|
|
if ( \GVCommon::has_cap( array( 'edit_gravityviews', 'edit_gravityview' ), $view->ID ) ) { |
|
|
|
|
235
|
|
|
return __( sprintf( 'This View is not configured properly. Start by <a href="%s">selecting a form</a>.', esc_url( get_edit_post_link( $view->ID, false ) ) ), 'gravityview' ); |
|
|
|
|
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return $content; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Is this View directly accessible via a post URL? |
243
|
|
|
* |
244
|
|
|
* @see https://codex.wordpress.org/Function_Reference/register_post_type#public |
245
|
|
|
*/ |
246
|
|
|
|
247
|
|
|
/** |
248
|
|
|
* @filter `gravityview_direct_access` Should Views be directly accessible, or only visible using the shortcode? |
249
|
|
|
* @deprecated |
250
|
|
|
* @param[in,out] boolean `true`: allow Views to be accessible directly. `false`: Only allow Views to be embedded. Default: `true` |
251
|
|
|
* @param int $view_id The ID of the View currently being requested. `0` for general setting |
252
|
|
|
*/ |
253
|
3 |
|
$direct_access = apply_filters( 'gravityview_direct_access', true, $view->ID ); |
|
|
|
|
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* @filter `gravityview/request/output/direct` Should this View be directly accessbile? |
257
|
|
|
* @since 2.0 |
258
|
|
|
* @param[in,out] boolean Accessible or not. Default: accessbile. |
259
|
|
|
* @param \GV\View $view The View we're trying to directly render here. |
260
|
|
|
* @param \GV\Request $request The current request. |
261
|
|
|
*/ |
262
|
3 |
|
if ( ! apply_filters( 'gravityview/view/output/direct', $direct_access, $view, $request ) ) { |
263
|
|
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Is this View an embed-only View? If so, don't allow rendering here, |
268
|
|
|
* as this is a direct request. |
269
|
|
|
*/ |
270
|
3 |
|
if ( $view->settings->get( 'embed_only' ) && ! \GVCommon::has_cap( 'read_private_gravityviews' ) ) { |
271
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** Private, pending, draft, etc. */ |
275
|
3 |
|
$public_states = get_post_stati( array( 'public' => true ) ); |
276
|
3 |
|
if ( ! in_array( $view->post_status, $public_states ) && ! \GVCommon::has_cap( 'read_gravityview', $view->ID ) ) { |
|
|
|
|
277
|
1 |
|
gravityview()->log->notice( 'The current user cannot access this View #{view_id}', array( 'view_id' => $view->ID ) ); |
|
|
|
|
278
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Editing a single entry. |
283
|
|
|
*/ |
284
|
3 |
|
if ( $entry = $request->is_edit_entry() ) { |
285
|
|
|
if ( $entry['status'] != 'active' ) { |
|
|
|
|
286
|
|
|
gravityview()->log->notice( 'Entry ID #{entry_id} is not active', array( 'entry_id' => $entry->ID ) ); |
287
|
|
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
if ( apply_filters( 'gravityview_custom_entry_slug', false ) && $entry->slug != get_query_var( \GV\Entry::get_endpoint_name() ) ) { |
|
|
|
|
291
|
|
|
gravityview()->log->error( 'Entry ID #{entry_id} was accessed by a bad slug', array( 'entry_id' => $entry->ID ) ); |
292
|
|
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
if ( $view->settings->get( 'show_only_approved' ) ) { |
296
|
|
|
if ( ! \GravityView_Entry_Approval_Status::is_approved( gform_get_meta( $entry->ID, \GravityView_Entry_Approval::meta_key ) ) ) { |
297
|
|
|
gravityview()->log->error( 'Entry ID #{entry_id} is not approved for viewing', array( 'entry_id' => $entry->ID ) ); |
298
|
|
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
299
|
|
|
} |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
$renderer = new Edit_Entry_Renderer(); |
303
|
|
|
return $renderer->render( $entry, $view, $request ); |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* Viewing a single entry. |
307
|
|
|
*/ |
308
|
3 |
|
} else if ( $entry = $request->is_entry() ) { |
309
|
1 |
|
if ( $entry['status'] != 'active' ) { |
|
|
|
|
310
|
1 |
|
gravityview()->log->notice( 'Entry ID #{entry_id} is not active', array( 'entry_id' => $entry->ID ) ); |
311
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
312
|
|
|
} |
313
|
|
|
|
314
|
1 |
|
if ( apply_filters( 'gravityview_custom_entry_slug', false ) && $entry->slug != get_query_var( \GV\Entry::get_endpoint_name() ) ) { |
315
|
1 |
|
gravityview()->log->error( 'Entry ID #{entry_id} was accessed by a bad slug', array( 'entry_id' => $entry->ID ) ); |
316
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
317
|
|
|
} |
318
|
|
|
|
319
|
1 |
|
if ( $view->settings->get( 'show_only_approved' ) ) { |
320
|
1 |
|
if ( ! \GravityView_Entry_Approval_Status::is_approved( gform_get_meta( $entry->ID, \GravityView_Entry_Approval::meta_key ) ) ) { |
321
|
1 |
|
gravityview()->log->error( 'Entry ID #{entry_id} is not approved for viewing', array( 'entry_id' => $entry->ID ) ); |
322
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
323
|
|
|
} |
324
|
|
|
} |
325
|
|
|
|
326
|
1 |
|
$renderer = new Entry_Renderer(); |
327
|
1 |
|
return $renderer->render( $entry, $view, $request ); |
328
|
|
|
|
329
|
|
|
/** |
330
|
|
|
* Plain old View. |
331
|
|
|
*/ |
332
|
|
|
} else { |
333
|
2 |
|
$renderer = new View_Renderer(); |
334
|
2 |
|
return $renderer->render( $view, $request ); |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
return $content; |
|
|
|
|
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* Construct a \GV\View instance from a \WP_Post. |
343
|
|
|
* |
344
|
|
|
* @param \WP_Post $post The \WP_Post instance to wrap. |
345
|
|
|
* |
346
|
|
|
* @api |
347
|
|
|
* @since 2.0 |
348
|
|
|
* @return \GV\View|null An instance around this \WP_Post if valid, null otherwise. |
349
|
|
|
*/ |
350
|
68 |
|
public static function from_post( $post ) { |
351
|
68 |
|
if ( ! $post || get_post_type( $post ) != 'gravityview' ) { |
|
|
|
|
352
|
2 |
|
gravityview()->log->error( 'Only gravityview post types can be \GV\View instances.' ); |
353
|
2 |
|
return null; |
354
|
|
|
} |
355
|
|
|
|
356
|
68 |
|
if ( $view = Utils::get( self::$cache, "View::from_post:{$post->ID}" ) ) { |
357
|
30 |
|
return $view; |
358
|
|
|
} |
359
|
|
|
|
360
|
68 |
|
$view = new self(); |
361
|
68 |
|
$view->post = $post; |
362
|
|
|
|
363
|
|
|
/** Get connected form. */ |
364
|
68 |
|
$view->form = GF_Form::by_id( $view->_gravityview_form_id ); |
|
|
|
|
365
|
68 |
|
if ( ! $view->form ) { |
366
|
|
|
gravityview()->log->error( 'View #{view_id} tried attaching non-existent Form #{form_id} to it.', array( |
367
|
|
|
'view_id' => $view->ID, |
|
|
|
|
368
|
|
|
'form_id' => $view->_gravityview_form_id ? : 0, |
|
|
|
|
369
|
|
|
) ); |
370
|
68 |
|
} else if ( gravityview()->plugin->supports( Plugin::FEATURE_JOINS ) ) { |
371
|
|
|
/** And the connected joins. */ |
372
|
68 |
|
foreach( (array)get_post_meta( $view->ID, '_gravityview_form_joins', true ) as $_join ) { |
|
|
|
|
373
|
4 |
|
if ( ! is_array( $_join ) || count( $_join ) != 4 ) { |
|
|
|
|
374
|
|
|
continue; |
375
|
|
|
} |
376
|
4 |
|
list( $join, $join_column, $join_on, $join_on_column ) = $_join; |
377
|
|
|
|
378
|
4 |
|
$join = GF_Form::by_id( $join ); |
379
|
4 |
|
$join_on = GF_Form::by_id( $join_on ); |
380
|
|
|
|
381
|
4 |
|
$join_column = is_numeric( $join_column ) ? GF_Field::by_id( $join, $join_column ) : Internal_Field( $join_column ); |
382
|
4 |
|
$join_on_column = is_numeric( $join_on_column ) ? GF_Field::by_id( $join_on, $join_on_column ) : Internal_Field( $join_on_column ); |
383
|
|
|
|
384
|
4 |
|
$view->joins []= new Join( $join, $join_column, $join_on, $join_on_column ); |
|
|
|
|
385
|
|
|
} |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
/** |
389
|
|
|
* @filter `gravityview/configuration/fields` Filter the View fields' configuration array. |
390
|
|
|
* @since 1.6.5 |
391
|
|
|
* |
392
|
|
|
* @deprecated Use `gravityview/view/configuration/fields` or `gravityview/view/fields` filters. |
393
|
|
|
* |
394
|
|
|
* @param $fields array Multi-array of fields with first level being the field zones. |
395
|
|
|
* @param $view_id int The View the fields are being pulled for. |
396
|
|
|
*/ |
397
|
68 |
|
$configuration = apply_filters( 'gravityview/configuration/fields', (array)$view->_gravityview_directory_fields, $view->ID ); |
|
|
|
|
398
|
|
|
|
399
|
|
|
/** |
400
|
|
|
* @filter `gravityview/view/configuration/fields` Filter the View fields' configuration array. |
401
|
|
|
* @since 2.0 |
402
|
|
|
* |
403
|
|
|
* @param array $fields Multi-array of fields with first level being the field zones. |
404
|
|
|
* @param \GV\View $view The View the fields are being pulled for. |
405
|
|
|
*/ |
406
|
68 |
|
$configuration = apply_filters( 'gravityview/view/configuration/fields', $configuration, $view ); |
407
|
|
|
|
408
|
|
|
/** |
409
|
|
|
* @filter `gravityview/view/fields` Filter the Field Collection for this View. |
410
|
|
|
* @since 2.0 |
411
|
|
|
* |
412
|
|
|
* @param \GV\Field_Collection $fields A collection of fields. |
413
|
|
|
* @param \GV\View $view The View the fields are being pulled for. |
414
|
|
|
*/ |
415
|
68 |
|
$view->fields = apply_filters( 'gravityview/view/fields', Field_Collection::from_configuration( $configuration ), $view ); |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* @filter `gravityview/view/configuration/widgets` Filter the View widgets' configuration array. |
419
|
|
|
* @since 2.0 |
420
|
|
|
* |
421
|
|
|
* @param array $fields Multi-array of widgets with first level being the field zones. |
422
|
|
|
* @param \GV\View $view The View the widgets are being pulled for. |
423
|
|
|
*/ |
424
|
68 |
|
$configuration = apply_filters( 'gravityview/view/configuration/widgets', (array)$view->_gravityview_directory_widgets, $view ); |
|
|
|
|
425
|
|
|
|
426
|
|
|
/** |
427
|
|
|
* @filter `gravityview/view/widgets` Filter the Widget Collection for this View. |
428
|
|
|
* @since 2.0 |
429
|
|
|
* |
430
|
|
|
* @param \GV\Widget_Collection $widgets A collection of widgets. |
431
|
|
|
* @param \GV\View $view The View the widgets are being pulled for. |
432
|
|
|
*/ |
433
|
68 |
|
$view->widgets = apply_filters( 'gravityview/view/widgets', Widget_Collection::from_configuration( $configuration ), $view ); |
434
|
|
|
|
435
|
|
|
/** View configuration. */ |
436
|
68 |
|
$view->settings->update( gravityview_get_template_settings( $view->ID ) ); |
|
|
|
|
437
|
|
|
|
438
|
|
|
/** Add the template name into the settings. */ |
439
|
68 |
|
$view->settings->update( array( 'template' => gravityview_get_template_id( $view->ID ) ) ); |
|
|
|
|
440
|
|
|
|
441
|
|
|
/** View basics. */ |
442
|
68 |
|
$view->settings->update( array( |
443
|
68 |
|
'id' => $view->ID, |
|
|
|
|
444
|
|
|
) ); |
445
|
|
|
|
446
|
68 |
|
self::$cache[ "View::from_post:{$post->ID}" ] = &$view; |
447
|
|
|
|
448
|
68 |
|
return $view; |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
/** |
452
|
|
|
* Flush the view cache. |
453
|
|
|
* |
454
|
|
|
* @param int $view_id The View to reset cache for. Optional. Default: resets everything. |
455
|
|
|
* |
456
|
|
|
* @internal |
457
|
|
|
*/ |
458
|
79 |
|
public static function _flush_cache( $view_id = null ) { |
459
|
79 |
|
if ( $view_id ) { |
|
|
|
|
460
|
72 |
|
unset( self::$cache[ "View::from_post:$view_id" ] ); |
461
|
72 |
|
return; |
462
|
|
|
} |
463
|
61 |
|
self::$cache = array(); |
464
|
61 |
|
} |
465
|
|
|
|
466
|
|
|
/** |
467
|
|
|
* Construct a \GV\View instance from a post ID. |
468
|
|
|
* |
469
|
|
|
* @param int|string $post_id The post ID. |
470
|
|
|
* |
471
|
|
|
* @api |
472
|
|
|
* @since 2.0 |
473
|
|
|
* @return \GV\View|null An instance around this \WP_Post or null if not found. |
474
|
|
|
*/ |
475
|
31 |
|
public static function by_id( $post_id ) { |
476
|
31 |
|
if ( ! $post_id || ! $post = get_post( $post_id ) ) { |
477
|
3 |
|
return null; |
478
|
|
|
} |
479
|
31 |
|
return self::from_post( $post ); |
480
|
|
|
} |
481
|
|
|
|
482
|
|
|
/** |
483
|
|
|
* Determines if a view exists to begin with. |
484
|
|
|
* |
485
|
|
|
* @param int|\WP_Post|null $view The WordPress post ID, a \WP_Post object or null for global $post; |
486
|
|
|
* |
487
|
|
|
* @api |
488
|
|
|
* @since 2.0 |
489
|
|
|
* @return bool Whether the post exists or not. |
490
|
|
|
*/ |
491
|
4 |
|
public static function exists( $view ) { |
492
|
4 |
|
return get_post_type( $view ) == 'gravityview'; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
/** |
496
|
|
|
* ArrayAccess compatibility layer with GravityView_View_Data::$views |
497
|
|
|
* |
498
|
|
|
* @internal |
499
|
|
|
* @deprecated |
500
|
|
|
* @since 2.0 |
501
|
|
|
* @return bool Whether the offset exists or not, limited to GravityView_View_Data::$views element keys. |
502
|
|
|
*/ |
503
|
9 |
|
public function offsetExists( $offset ) { |
|
|
|
|
504
|
9 |
|
$data_keys = array( 'id', 'view_id', 'form_id', 'template_id', 'atts', 'fields', 'widgets', 'form' ); |
505
|
9 |
|
return in_array( $offset, $data_keys ); |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
/** |
509
|
|
|
* ArrayAccess compatibility layer with GravityView_View_Data::$views |
510
|
|
|
* |
511
|
|
|
* Maps the old keys to the new data; |
512
|
|
|
* |
513
|
|
|
* @internal |
514
|
|
|
* @deprecated |
515
|
|
|
* @since 2.0 |
516
|
|
|
* |
517
|
|
|
* @return mixed The value of the requested view data key limited to GravityView_View_Data::$views element keys. |
518
|
|
|
*/ |
519
|
9 |
|
public function offsetGet( $offset ) { |
|
|
|
|
520
|
|
|
|
521
|
9 |
|
gravityview()->log->notice( 'This is a \GV\View object should not be accessed as an array.' ); |
522
|
|
|
|
523
|
9 |
|
if ( ! isset( $this[ $offset ] ) ) { |
524
|
|
|
return null; |
525
|
|
|
} |
526
|
|
|
|
527
|
9 |
|
switch ( $offset ) { |
528
|
9 |
|
case 'id': |
529
|
9 |
|
case 'view_id': |
530
|
1 |
|
return $this->ID; |
|
|
|
|
531
|
9 |
|
case 'form': |
532
|
9 |
|
return $this->form; |
533
|
1 |
|
case 'form_id': |
534
|
1 |
|
return $this->form ? $this->form->ID : null; |
535
|
1 |
|
case 'atts': |
536
|
|
|
return $this->settings->as_atts(); |
|
|
|
|
537
|
1 |
|
case 'template_id': |
538
|
1 |
|
return $this->settings->get( 'template' ); |
539
|
|
|
case 'widgets': |
540
|
|
|
return $this->widgets->as_configuration(); |
541
|
|
|
} |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
/** |
545
|
|
|
* ArrayAccess compatibility layer with GravityView_View_Data::$views |
546
|
|
|
* |
547
|
|
|
* @internal |
548
|
|
|
* @deprecated |
549
|
|
|
* @since 2.0 |
550
|
|
|
* |
551
|
|
|
* @return void |
552
|
|
|
*/ |
553
|
1 |
|
public function offsetSet( $offset, $value ) { |
|
|
|
|
554
|
1 |
|
gravityview()->log->error( 'The old view data is no longer mutable. This is a \GV\View object should not be accessed as an array.' ); |
555
|
1 |
|
} |
556
|
|
|
|
557
|
|
|
/** |
558
|
|
|
* ArrayAccess compatibility layer with GravityView_View_Data::$views |
559
|
|
|
* |
560
|
|
|
* @internal |
561
|
|
|
* @deprecated |
562
|
|
|
* @since 2.0 |
563
|
|
|
* @return void |
564
|
|
|
*/ |
565
|
1 |
|
public function offsetUnset( $offset ) { |
|
|
|
|
566
|
1 |
|
gravityview()->log->error( 'The old view data is no longer mutable. This is a \GV\View object should not be accessed as an array.' ); |
567
|
1 |
|
} |
568
|
|
|
|
569
|
|
|
/** |
570
|
|
|
* Be compatible with the old data object. |
571
|
|
|
* |
572
|
|
|
* Some external code expects an array (doing things like foreach on this, or array_keys) |
573
|
|
|
* so let's return an array in the old format for such cases. Do not use unless using |
574
|
|
|
* for back-compatibility. |
575
|
|
|
* |
576
|
|
|
* @internal |
577
|
|
|
* @deprecated |
578
|
|
|
* @since 2.0 |
579
|
|
|
* @return array |
580
|
|
|
*/ |
581
|
5 |
|
public function as_data() { |
582
|
|
|
return array( |
583
|
5 |
|
'id' => $this->ID, |
|
|
|
|
584
|
5 |
|
'view_id' => $this->ID, |
|
|
|
|
585
|
5 |
|
'form_id' => $this->form ? $this->form->ID : null, |
586
|
5 |
|
'form' => $this->form ? gravityview_get_form( $this->form->ID ) : null, |
587
|
5 |
|
'atts' => $this->settings->as_atts(), |
|
|
|
|
588
|
5 |
|
'fields' => $this->fields->by_visible()->as_configuration(), |
589
|
5 |
|
'template_id' => $this->settings->get( 'template' ), |
590
|
5 |
|
'widgets' => $this->widgets->as_configuration(), |
591
|
|
|
); |
592
|
|
|
} |
593
|
|
|
|
594
|
|
|
/** |
595
|
|
|
* Retrieve the entries for the current view and request. |
596
|
|
|
* |
597
|
|
|
* @param \GV\Request The request. Usued for now. |
598
|
|
|
* |
599
|
|
|
* @return \GV\Entry_Collection The entries. |
600
|
|
|
*/ |
601
|
20 |
|
public function get_entries( $request ) { |
602
|
20 |
|
$entries = new \GV\Entry_Collection(); |
603
|
20 |
|
if ( $this->form ) { |
604
|
|
|
/** |
605
|
|
|
* @todo: Stop using _frontend and use something like $request->get_search_criteria() instead |
606
|
|
|
*/ |
607
|
20 |
|
$parameters = \GravityView_frontend::get_view_entries_parameters( $this->settings->as_atts(), $this->form->ID ); |
|
|
|
|
608
|
20 |
|
$parameters['context_view_id'] = $this->ID; |
|
|
|
|
609
|
20 |
|
$parameters = \GVCommon::calculate_get_entries_criteria( $parameters, $this->form->ID ); |
610
|
|
|
|
611
|
20 |
|
if ( $request instanceof REST\Request ) { |
612
|
3 |
|
$atts = $this->settings->as_atts(); |
|
|
|
|
613
|
3 |
|
$paging_parameters = wp_parse_args( $request->get_paging(), array( |
614
|
3 |
|
'paging' => array( 'page_size' => $atts['page_size'] ), |
615
|
|
|
) ); |
|
|
|
|
616
|
3 |
|
$parameters['paging'] = $paging_parameters['paging']; |
617
|
|
|
} |
618
|
|
|
|
619
|
20 |
|
$page = Utils::get( $parameters['paging'], 'current_page' ) ? |
620
|
20 |
|
: ( ( ( $parameters['paging']['offset'] - $this->settings->get( 'offset' ) ) / $parameters['paging']['page_size'] ) + 1 ); |
621
|
|
|
|
622
|
20 |
|
if ( gravityview()->plugin->supports( Plugin::FEATURE_GFQUERY ) ) { |
623
|
|
|
/** |
624
|
|
|
* New \GF_Query stuff :) |
625
|
|
|
*/ |
626
|
20 |
|
$query = new \GF_Query( $this->form->ID, $parameters['search_criteria'], $parameters['sorting'] ); |
627
|
|
|
|
628
|
20 |
|
$query->limit( $parameters['paging']['page_size'] ) |
629
|
20 |
|
->offset( ( ( $page - 1 ) * $parameters['paging']['page_size'] ) + $this->settings->get( 'offset' ) ); |
630
|
|
|
|
631
|
|
|
/** |
632
|
|
|
* Any joins? |
633
|
|
|
*/ |
634
|
20 |
|
if ( Plugin::FEATURE_JOINS && count( $this->joins ) ) { |
635
|
4 |
|
foreach ( $this->joins as $join ) { |
636
|
4 |
|
$query = $join->as_query_join( $query ); |
637
|
|
|
} |
638
|
|
|
} |
639
|
|
|
|
640
|
|
|
/** |
641
|
|
|
* @action `gravityview/view/query` Override the \GF_Query before the get() call. |
642
|
|
|
* @param \GF_Query $query The current query object |
643
|
|
|
* @param \GV\View $this The current view object |
644
|
|
|
* @param \GV\Request $request The request object |
645
|
|
|
*/ |
646
|
20 |
|
do_action( 'gravityview/view/query', $query, $this, $request ); |
647
|
|
|
|
648
|
|
|
/** |
649
|
|
|
* Map from Gravity Forms entries arrays to an Entry_Collection. |
650
|
|
|
*/ |
651
|
20 |
|
if ( count( $this->joins ) ) { |
652
|
4 |
|
foreach ( $query->get() as $entry ) { |
653
|
4 |
|
$entries->add( |
654
|
4 |
|
Multi_Entry::from_entries( array_map( '\GV\GF_Entry::from_entry', $entry ) ) |
655
|
|
|
); |
656
|
|
|
} |
657
|
|
|
} else { |
658
|
16 |
|
array_map( array( $entries, 'add' ), array_map( '\GV\GF_Entry::from_entry', $query->get() ) ); |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
/** |
662
|
|
|
* Add total count callback. |
663
|
|
|
*/ |
664
|
20 |
|
$entries->add_count_callback( function() use ( $query ) { |
665
|
15 |
|
return $query->total_found; |
666
|
20 |
|
} ); |
667
|
|
|
} else { |
668
|
|
|
$entries = $this->form->entries |
|
|
|
|
669
|
|
|
->filter( \GV\GF_Entry_Filter::from_search_criteria( $parameters['search_criteria'] ) ) |
670
|
|
|
->offset( $this->settings->get( 'offset' ) ) |
671
|
|
|
->limit( $parameters['paging']['page_size'] ) |
672
|
|
|
->page( $page ); |
673
|
|
|
|
674
|
|
|
if ( ! empty( $parameters['sorting'] ) && ! empty( $parameters['sorting']['key'] ) ) { |
675
|
|
|
$field = new \GV\Field(); |
676
|
|
|
$field->ID = $parameters['sorting']['key']; |
677
|
|
|
$direction = strtolower( $parameters['sorting']['direction'] ) == 'asc' ? \GV\Entry_Sort::ASC : \GV\Entry_Sort::DESC; |
678
|
|
|
$entries = $entries->sort( new \GV\Entry_Sort( $field, $direction ) ); |
679
|
|
|
} |
680
|
|
|
} |
681
|
|
|
} |
682
|
|
|
|
683
|
|
|
/** |
684
|
|
|
* @filter `gravityview/view/entries` Modify the entry fetching filters, sorts, offsets, limits. |
685
|
|
|
* @param \GV\Entry_Collection $entries The entries for this view. |
686
|
|
|
* @param \GV\View $view The view. |
687
|
|
|
* @param \GV\Request $request The request. |
688
|
|
|
*/ |
689
|
20 |
|
return apply_filters( 'gravityview/view/entries', $entries, $this, $request ); |
690
|
|
|
} |
691
|
|
|
|
692
|
67 |
|
public function __get( $key ) { |
693
|
67 |
|
if ( $this->post ) { |
694
|
67 |
|
$raw_post = $this->post->filter( 'raw' ); |
695
|
67 |
|
return $raw_post->{$key}; |
696
|
|
|
} |
697
|
|
|
return isset( $this->{$key} ) ? $this->{$key} : null; |
698
|
|
|
} |
699
|
|
|
} |
700
|
|
|
|
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.