1
|
|
|
<?php |
|
|
|
|
2
|
|
|
namespace GV\Shortcodes; |
3
|
|
|
|
4
|
|
|
/** If this file is called directly, abort. */ |
5
|
|
|
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) { |
6
|
|
|
die(); |
7
|
|
|
} |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* The [gravityview] shortcode. |
11
|
|
|
*/ |
12
|
|
|
class gravityview extends \GV\Shortcode { |
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* {@inheritDoc} |
15
|
|
|
*/ |
16
|
|
|
public $name = 'gravityview'; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Process and output the [gravityview] shortcode. |
20
|
|
|
* |
21
|
|
|
* @param array $atts The attributes passed. |
22
|
|
|
* @param string $content The content inside the shortcode. |
23
|
|
|
* |
24
|
|
|
* @return string|null The output. |
25
|
|
|
*/ |
26
|
3 |
|
public function callback( $atts, $content = null ) { |
27
|
|
|
|
28
|
3 |
|
$request = gravityview()->request; |
29
|
|
|
|
30
|
3 |
|
if ( $request->is_admin() ) { |
31
|
|
|
return ''; |
32
|
|
|
} |
33
|
|
|
|
34
|
3 |
|
$atts = wp_parse_args( $atts, array( |
35
|
3 |
|
'id' => 0, |
36
|
|
|
'view_id' => 0, |
37
|
|
|
'detail' => null, |
38
|
|
|
) ); |
39
|
|
|
|
40
|
|
|
if ( ! $view_id = $atts['id'] ? : $atts['view_id'] ) { |
41
|
3 |
|
if ( $atts['detail'] && $view = $request->is_view() ) { |
42
|
|
|
$view_id = $view->ID; |
|
|
|
|
43
|
3 |
|
} |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
$view = \GV\View::by_id( $view_id ); |
47
|
|
|
|
48
|
|
|
if ( ! $view ) { |
49
|
|
|
gravityview()->log->error( 'View does not exist #{view_id}', array( 'view_id' => $view_id ) ); |
50
|
|
|
return ''; |
51
|
|
|
} |
52
|
3 |
|
|
53
|
3 |
|
/** |
54
|
3 |
|
* When this shortcode is embedded inside a View we can only display it as a directory. There's no other way. |
55
|
|
|
* Try to detect that we're not embedded to allow edit and single contexts. |
56
|
|
|
*/ |
57
|
|
|
$is_reembedded = false; // Assume not embedded unless detected otherwise. |
58
|
|
|
if ( in_array( get_class( $request ), array( 'GV\Frontend_Request', 'GV\Mock_Request' ) ) ) { |
59
|
|
|
if ( ( $_view = $request->is_view() ) && $_view->ID !== $view->ID ) { |
|
|
|
|
60
|
|
|
$is_reembedded = true; |
61
|
|
|
} |
62
|
3 |
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Remove Widgets on a nested embedded View. |
66
|
3 |
|
*/ |
67
|
3 |
|
if ( $is_reembedded ) { |
68
|
|
|
$view->widgets = new \GV\Widget_Collection(); |
69
|
3 |
|
} |
70
|
1 |
|
|
71
|
1 |
|
$view->settings->update( $atts ); |
72
|
|
|
$entries = $view->get_entries( $request ); |
73
|
|
|
|
74
|
3 |
|
if ( post_password_required( $view->ID ) ) { |
|
|
|
|
75
|
|
|
gravityview()->log->notice( 'Post password is required for View #{view_id}', array( 'view_id' => $view->ID ) ); |
|
|
|
|
76
|
|
|
return get_the_password_form( $view->ID ); |
|
|
|
|
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
if ( ! $view->form ) { |
80
|
|
|
gravityview()->log->notice( 'View #{id} has no form attached to it.', array( 'id' => $view->ID ) ); |
|
|
|
|
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* This View has no data source. There's nothing to show really. |
84
|
|
|
* ...apart from a nice message if the user can do anything about it. |
85
|
|
|
*/ |
86
|
|
|
if ( \GVCommon::has_cap( array( 'edit_gravityviews', 'edit_gravityview' ), $view->ID ) ) { |
|
|
|
|
87
|
|
|
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' ); |
|
|
|
|
88
|
|
|
} |
89
|
3 |
|
|
90
|
3 |
|
return $content; |
91
|
1 |
|
} |
92
|
1 |
|
|
93
|
|
|
/** Private, pending, draft, etc. */ |
94
|
|
|
$public_states = get_post_stati( array( 'public' => true ) ); |
95
|
|
|
if ( ! in_array( $view->post_status, $public_states ) && ! \GVCommon::has_cap( 'read_gravityview', $view->ID ) ) { |
|
|
|
|
96
|
|
|
gravityview()->log->notice( 'The current user cannot access this View #{view_id}', array( 'view_id' => $view->ID ) ); |
|
|
|
|
97
|
|
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
98
|
3 |
|
} |
99
|
2 |
|
|
100
|
|
|
/** |
101
|
|
|
* View details. |
102
|
|
|
*/ |
103
|
|
|
if ( $atts['detail'] ) { |
104
|
2 |
|
return $this->detail( $view, $entries, $atts ); |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Editing a single entry. |
108
|
|
|
*/ |
109
|
|
|
} else if ( ! $is_reembedded && ( $entry = $request->is_edit_entry() ) ) { |
110
|
|
|
if ( $entry['status'] != 'active' ) { |
|
|
|
|
111
|
|
|
gravityview()->log->notice( 'Entry ID #{entry_id} is not active', array( 'entry_id' => $entry->ID ) ); |
112
|
|
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
if ( apply_filters( 'gravityview_custom_entry_slug', false ) && $entry->slug != get_query_var( \GV\Entry::get_endpoint_name() ) ) { |
|
|
|
|
116
|
|
|
gravityview()->log->error( 'Entry ID #{entry_id} was accessed by a bad slug', array( 'entry_id' => $entry->ID ) ); |
117
|
|
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
if ( $view->settings->get( 'show_only_approved' ) ) { |
121
|
|
|
if ( ! \GravityView_Entry_Approval_Status::is_approved( gform_get_meta( $entry->ID, \GravityView_Entry_Approval::meta_key ) ) ) { |
122
|
|
|
gravityview()->log->error( 'Entry ID #{entry_id} is not approved for viewing', array( 'entry_id' => $entry->ID ) ); |
123
|
|
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
$renderer = new \GV\Edit_Entry_Renderer(); |
128
|
2 |
|
return $renderer->render( $entry, $view, $request ); |
129
|
1 |
|
|
130
|
1 |
|
/** |
131
|
1 |
|
* Viewing a single entry. |
132
|
|
|
*/ |
133
|
|
|
} else if ( ! $is_reembedded && ( $entry = $request->is_entry() ) ) { |
134
|
1 |
|
if ( $entry['status'] != 'active' ) { |
|
|
|
|
135
|
1 |
|
gravityview()->log->notice( 'Entry ID #{entry_id} is not active', array( 'entry_id' => $entry->ID ) ); |
136
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
137
|
|
|
} |
138
|
|
|
|
139
|
1 |
|
if ( apply_filters( 'gravityview_custom_entry_slug', false ) && $entry->slug != get_query_var( \GV\Entry::get_endpoint_name() ) ) { |
140
|
1 |
|
gravityview()->log->error( 'Entry ID #{entry_id} was accessed by a bad slug', array( 'entry_id' => $entry->ID ) ); |
141
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
142
|
1 |
|
} |
143
|
|
|
|
144
|
|
|
if ( $view->settings->get( 'show_only_approved' ) ) { |
145
|
|
|
if ( ! \GravityView_Entry_Approval_Status::is_approved( gform_get_meta( $entry->ID, \GravityView_Entry_Approval::meta_key ) ) ) { |
146
|
1 |
|
gravityview()->log->error( 'Entry ID #{entry_id} is not approved for viewing', array( 'entry_id' => $entry->ID ) ); |
147
|
1 |
|
return __( 'You are not allowed to view this content.', 'gravityview' ); |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
$renderer = new \GV\Entry_Renderer(); |
152
|
|
|
return $renderer->render( $entry, $view, $request ); |
153
|
1 |
|
|
154
|
|
|
/** |
155
|
|
|
* Just this view. |
156
|
|
|
*/ |
157
|
|
|
} else { |
158
|
|
|
if ( $is_reembedded ) { |
159
|
|
|
|
160
|
|
|
// Mock the request with the actual View, not the global one |
161
|
|
|
$mock_request = new \GV\Mock_Request(); |
162
|
|
|
$mock_request->returns['is_view'] = $view; |
163
|
|
|
$mock_request->returns['is_entry'] = $request->is_entry(); |
164
|
|
|
$mock_request->returns['is_edit_entry'] = $request->is_edit_entry(); |
165
|
1 |
|
$mock_request->returns['is_search'] = $request->is_search(); |
166
|
1 |
|
|
167
|
|
|
$request = $mock_request; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
$renderer = new \GV\View_Renderer(); |
171
|
|
|
return $renderer->render( $view, $request ); |
172
|
|
|
} |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Output view details. |
177
|
|
|
* |
178
|
|
|
* @param \GV\View $view The View. |
179
|
|
|
* @param \GV\Entry_Collection $entries The calculated entries. |
180
|
1 |
|
* @param array $atts The shortcode attributes (with defaults). |
181
|
1 |
|
* |
182
|
|
|
* @return string The output. |
183
|
1 |
|
*/ |
184
|
1 |
|
private function detail( $view, $entries, $atts ) { |
185
|
1 |
|
$output = ''; |
186
|
1 |
|
|
187
|
|
|
switch ( $key = $atts['detail'] ): |
188
|
|
|
case 'total_entries': |
189
|
|
|
$output = number_format_i18n( $entries->total() ); |
190
|
|
|
break; |
191
|
|
|
case 'first_entry': |
192
|
|
|
$output = number_format_i18n( min( $entries->total(), $view->settings->get( 'offset' ) + 1 ) ); |
193
|
|
|
break; |
194
|
|
|
case 'last_entry': |
195
|
|
|
$output = number_format_i18n( $view->settings->get( 'page_size' ) + $view->settings->get( 'offset' ) ); |
196
|
|
|
break; |
197
|
|
|
case 'page_size': |
198
|
1 |
|
$output = number_format_i18n( $view->settings->get( $key ) ); |
199
|
|
|
break; |
200
|
|
|
endswitch; |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* @filter `gravityview/shortcode/detail/{$detail}` Filter the detail output returned from `[gravityview detail="$detail"]` |
204
|
|
|
* @since 1.13 |
205
|
|
|
* @param string[in,out] $output Existing output |
|
|
|
|
206
|
|
|
* |
207
|
|
|
* @since 2.0.3 |
208
|
|
|
* @param \GV\View $view The view. |
209
|
|
|
* @param \GV\Entry_Collection $entries The entries. |
210
|
|
|
* @param array $atts The shortcode atts with defaults. |
211
|
|
|
*/ |
212
|
|
|
$output = apply_filters( "gravityview/shortcode/detail/$key", $output, $view ); |
213
|
|
|
|
214
|
|
|
return $output; |
215
|
|
|
} |
216
|
|
|
} |
217
|
|
|
|
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.