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 Gravity Forms Form class implementation. |
11
|
|
|
* |
12
|
|
|
* Accessible as an array for back-compatibility. |
13
|
|
|
*/ |
14
|
|
|
class GF_Form extends Form implements \ArrayAccess { |
|
|
|
|
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @var string The identifier of the backend used for this form. |
18
|
|
|
* @api |
19
|
|
|
* @since 2.0 |
20
|
|
|
*/ |
21
|
|
|
public static $backend = self::BACKEND_GRAVITYFORMS; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Initialization. |
25
|
|
|
*/ |
26
|
71 |
|
private function __construct() { |
27
|
71 |
|
if ( ! class_exists( 'GFAPI' ) ) { |
28
|
|
|
gravityview()->log->error( 'Gravity Forms plugin is not active.' ); |
29
|
|
|
} |
30
|
71 |
|
} |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Construct a \GV\GF_Form instance by ID. |
34
|
|
|
* |
35
|
|
|
* @param int|string $form_id The internal form ID. |
36
|
|
|
* |
37
|
|
|
* @api |
38
|
|
|
* @since 2.0 |
39
|
|
|
* @return \GV\GF_Form|null An instance of this form or null if not found. |
40
|
|
|
*/ |
41
|
72 |
|
public static function by_id( $form_id ) { |
42
|
|
|
|
43
|
72 |
|
$form = wp_cache_get( 'gf_form_' . $form_id, 'gravityview' ); |
44
|
|
|
|
45
|
72 |
|
if ( ! $form ) { |
46
|
72 |
|
$form = \GFAPI::get_form( $form_id ); |
47
|
|
|
} |
48
|
|
|
|
49
|
72 |
|
if ( ! $form ) { |
50
|
1 |
|
return null; |
51
|
|
|
} |
52
|
|
|
|
53
|
72 |
|
wp_cache_set( 'gf_form_' . $form_id, $form, 'gravityview' ); |
54
|
|
|
|
55
|
72 |
|
$self = new self(); |
56
|
72 |
|
$self->form = $form; |
|
|
|
|
57
|
|
|
|
58
|
72 |
|
$self->ID = $self->form['id']; |
|
|
|
|
59
|
|
|
|
60
|
72 |
|
return $self; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Construct a \GV\Form instance from a Gravity Forms form array. |
65
|
|
|
* |
66
|
|
|
* @since 2.0.7 |
67
|
|
|
* |
68
|
|
|
* @param array $form The form array |
69
|
|
|
* |
70
|
|
|
* @return \GV\GF_Form|null An instance of this form or null if not found. |
71
|
|
|
*/ |
72
|
|
|
public static function from_form( $form ) { |
73
|
|
|
if ( empty( $form['id'] ) ) { |
74
|
|
|
return null; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$self = new self(); |
78
|
|
|
$self->form = $form; |
|
|
|
|
79
|
|
|
$self->ID = $self->form['id']; |
|
|
|
|
80
|
|
|
|
81
|
|
|
return $self; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Get all entries for this form. |
86
|
|
|
* |
87
|
|
|
* @api |
88
|
|
|
* @since 2.0 |
89
|
|
|
* |
90
|
|
|
* @return \GV\Entry_Collection The \GV\Entry_Collection |
91
|
|
|
*/ |
92
|
1 |
|
public function get_entries() { |
93
|
1 |
|
$entries = new \GV\Entry_Collection(); |
94
|
|
|
|
95
|
1 |
|
$form = &$this; |
96
|
|
|
|
97
|
|
|
/** Add the fetcher lazy callback. */ |
98
|
1 |
|
$entries->add_fetch_callback( function( $filters, $sorts, $offset ) use ( $form ) { |
99
|
1 |
|
$entries = new \GV\Entry_Collection(); |
100
|
|
|
|
101
|
1 |
|
$search_criteria = array(); |
102
|
1 |
|
$sorting = array(); |
103
|
1 |
|
$paging = array(); |
104
|
|
|
|
105
|
|
|
/** Apply the filters */ |
106
|
1 |
|
foreach ( $filters as $filter ) { |
107
|
1 |
|
$search_criteria = $filter::merge_search_criteria( $search_criteria, $filter->as_search_criteria() ); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** Apply the sorts */ |
111
|
1 |
|
foreach ( $sorts as $sort ) { |
112
|
|
|
/** Gravity Forms does not have multi-sorting, so just overwrite. */ |
113
|
|
|
$sorting = array( |
114
|
|
|
'key' => $sort->field->ID, |
115
|
|
|
'direction' => $sort->direction, |
116
|
|
|
'is_numeric' => $sort->mode == Entry_Sort::NUMERIC, |
117
|
|
|
); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** The offset and limit */ |
121
|
1 |
|
if ( ! empty( $offset->limit ) ) { |
122
|
1 |
|
$paging['page_size'] = $offset->limit; |
123
|
|
|
} |
124
|
|
|
|
125
|
1 |
|
if ( ! empty( $offset->offset ) ) { |
126
|
|
|
$paging['offset'] = $offset->offset; |
127
|
|
|
} |
128
|
|
|
|
129
|
1 |
|
foreach ( \GFAPI::get_entries( $form->ID, $search_criteria, $sorting, $paging ) as $entry ) { |
130
|
1 |
|
$entries->add( \GV\GF_Entry::from_entry( $entry ) ); |
131
|
|
|
} |
132
|
|
|
|
133
|
1 |
|
return $entries; |
134
|
1 |
|
} ); |
135
|
|
|
|
136
|
|
|
/** Add the counter lazy callback. */ |
137
|
1 |
|
$entries->add_count_callback( function( $filters ) use ( $form ) { |
138
|
|
|
$search_criteria = array(); |
139
|
|
|
$sorting = array(); |
140
|
|
|
|
141
|
|
|
/** Apply the filters */ |
142
|
|
|
/** @var \GV\GF_Entry_Filter|\GV\Entry_Filter $filter */ |
143
|
|
|
foreach ( $filters as $filter ) { |
144
|
|
|
$search_criteria = $filter::merge_search_criteria( $search_criteria, $filter->as_search_criteria() ); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
return \GFAPI::count_entries( $form->ID, $search_criteria ); |
148
|
1 |
|
} ); |
149
|
|
|
|
150
|
1 |
|
return $entries; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Get a \GV\Field by Form and Field ID for this data source. |
155
|
|
|
* |
156
|
|
|
* @param \GV\GF_Form $form The Gravity Form form ID. |
|
|
|
|
157
|
|
|
* @param int $field_id The Gravity Form field ID for the $form_id. |
|
|
|
|
158
|
|
|
* |
159
|
|
|
* @return \GV\Field|null The requested field or null if not found. |
160
|
|
|
*/ |
161
|
3 |
|
public static function get_field( /** varargs */ ) { |
162
|
3 |
|
$args = func_get_args(); |
163
|
|
|
|
164
|
3 |
|
if ( ! is_array( $args ) || count( $args ) != 2 ) { |
|
|
|
|
165
|
1 |
|
gravityview()->log->error( '{source} expects 2 arguments for ::get_field ($form, $field_id)', array( 'source' => __CLASS__ ) ); |
166
|
1 |
|
return null; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** Unwrap the arguments. */ |
170
|
3 |
|
list( $form, $field_id ) = $args; |
171
|
|
|
|
172
|
|
|
/** Wrap it up into a \GV\Field. */ |
173
|
3 |
|
return GF_Field::by_id( $form, $field_id ); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Get an array of GV Fields for this data source |
178
|
|
|
* |
179
|
|
|
* @return \GV\Field[]|array Empty array if no fields |
180
|
|
|
*/ |
181
|
|
|
public function get_fields() { |
182
|
|
|
$fields = array(); |
183
|
|
|
foreach ( $this['fields'] as $field ) { |
184
|
|
|
foreach ( empty( $field['inputs'] ) ? array( $field['id'] ) : wp_list_pluck( $field['inputs'], 'id' ) as $id ) { |
185
|
|
|
if ( is_numeric( $id ) ) { |
186
|
|
|
$fields[ $id ] = self::get_field( $this, $id ); |
187
|
|
|
} else { |
188
|
|
|
$fields[ $id ] = Internal_Field::by_id( $id ); |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
return array_filter( $fields ); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Proxies. |
198
|
|
|
* |
199
|
|
|
* @param string $key The property to get. |
200
|
|
|
* |
201
|
|
|
* @return mixed |
202
|
|
|
*/ |
203
|
1 |
|
public function __get( $key ) { |
204
|
1 |
|
switch ( $key ) { |
205
|
1 |
|
case 'fields': |
206
|
|
|
return $this->get_fields(); |
207
|
|
|
default: |
208
|
1 |
|
return parent::__get( $key ); |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* ArrayAccess compatibility layer with a Gravity Forms form array. |
214
|
|
|
* |
215
|
|
|
* @internal |
216
|
|
|
* @deprecated |
217
|
|
|
* @since 2.0 |
218
|
|
|
* @return bool Whether the offset exists or not. |
219
|
|
|
*/ |
220
|
15 |
|
public function offsetExists( $offset ) { |
|
|
|
|
221
|
15 |
|
return isset( $this->form[$offset] ); |
|
|
|
|
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* ArrayAccess compatibility layer with a Gravity Forms form array. |
226
|
|
|
* |
227
|
|
|
* Maps the old keys to the new data; |
228
|
|
|
* |
229
|
|
|
* @internal |
230
|
|
|
* @deprecated |
231
|
|
|
* @since 2.0 |
232
|
|
|
* |
233
|
|
|
* @return mixed The value of the requested form data. |
234
|
|
|
*/ |
235
|
11 |
|
public function offsetGet( $offset ) { |
|
|
|
|
236
|
11 |
|
return $this->form[$offset]; |
|
|
|
|
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* ArrayAccess compatibility layer with a Gravity Forms form array. |
241
|
|
|
* |
242
|
|
|
* @internal |
243
|
|
|
* @deprecated |
244
|
|
|
* @since 2.0 |
245
|
|
|
* |
246
|
|
|
* @return void |
247
|
|
|
*/ |
248
|
|
|
public function offsetSet( $offset, $value ) { |
|
|
|
|
249
|
|
|
gravityview()->log->error( 'The underlying Gravity Forms form is immutable. This is a \GV\Form object and should not be accessed as an array.' ); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* ArrayAccess compatibility layer with a Gravity Forms form array. |
254
|
|
|
* |
255
|
|
|
* @internal |
256
|
|
|
* @deprecated |
257
|
|
|
* @since 2.0 |
258
|
|
|
* @return void |
259
|
|
|
*/ |
260
|
|
|
public function offsetUnset( $offset ) { |
|
|
|
|
261
|
|
|
gravityview()->log->error( 'The underlying Gravity Forms form is immutable. This is a \GV\Form object and should not be accessed as an array.' ); |
262
|
|
|
} |
263
|
|
|
} |
264
|
|
|
|
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.