GravityView  2.10.1
The best, easiest way to display Gravity Forms entries on your website.
class-gv-field.php
Go to the documentation of this file.
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 Field class.
11  *
12  * Houses all base Field functionality.
13  */
14 class Field {
15 
16  /**
17  * @var array The custom View configuration for this field.
18  *
19  * Everything else is in the properties.
20  */
21  private $configuration = array();
22 
23  /**
24  * @var string The field position in the view.
25  * @api
26  * @since 2.0
27  */
28  public $position = '';
29 
30  /**
31  * @var string UID for this field.
32  *
33  * A unique relation identifier between this field and a view.
34  *
35  * @api
36  * @since 2.0
37  */
38  public $UID = '';
39 
40  /**
41  * @var string The form field ID for this field.
42  * @api
43  * @since 2.0
44  */
45  public $ID = '';
46 
47  /**
48  * @var string The form label for this field.
49  * @api
50  * @since 2.0
51  */
52  public $label = '';
53 
54  /**
55  * @var string The custom label for this field.
56  * @api
57  * @since 2.0
58  */
59  public $custom_label = '';
60 
61  /**
62  * @var bool Whether to show the label or not for this field.
63  * @api
64  * @since 2.0
65  */
66  public $show_label = true;
67 
68  /**
69  * @var string The custom class for this field.
70  * @api
71  * @since 2.0
72  */
73  public $custom_class = '';
74 
75  /**
76  * @var string The capability required to view this field.
77  *
78  * If empty, anyone can view it, including non-logged in users.
79  *
80  * @api
81  * @since 2.0
82  */
83  public $cap = '';
84 
85  /**
86  * @var bool Show as a link to entry.
87  *
88  * @api
89  * @since 2.0
90  */
91  public $show_as_link = false;
92 
93  /**
94  * @var bool Filter this field from searching.
95  *
96  * @api
97  * @since 2.0
98  */
99  public $search_filter = false;
100 
101  /**
102  * Return an array of the old format as used by callers of `GVCommon:get_directory_fields()` for example.
103  *
104  * 'id' => string '9' (length=1)
105  * 'label' => string 'Screenshots' (length=11)
106  * 'show_label' => string '1' (length=1)
107  * 'custom_label' => string '' (length=0)
108  * 'custom_class' => string 'gv-gallery' (length=10)
109  * 'only_loggedin' => string '0' (length=1)
110  * 'only_loggedin_cap' => string 'read' (length=4)
111  * 'search_filter' => string '0'
112  * 'show_as_link' => string '0'
113  *
114  * + whatever else specific field types may have
115  *
116  * @internal
117  * @since 2.0
118  *
119  * @return array
120  */
121  public function as_configuration() {
122  return array_merge( array(
123  'id' => $this->ID,
124  'label' => $this->label,
125  'show_label' => $this->show_label ? '1' : '0',
126  'custom_label' => $this->custom_label,
127  'custom_class' => $this->custom_class,
128  'only_loggedin' => $this->cap ? '1' : '0',
129  'only_loggedin_cap' => $this->cap,
130  'search_filter' => $this->search_filter ? '1' : '0',
131  'show_as_link' => $this->show_as_link ? '1' : '0',
132  ), $this->configuration );
133  }
134 
135  /**
136  * An alias for \GV\Source::get_field()
137  *
138  * @see \GV\Source::get_field()
139  * @param string $source A \GV\Source class as string this field is tied to.
140  * @param array $args The arguments required for the backend to fetch the field (usually just the ID).
141  *
142  * @return \GV\Field|null A \GV\Field instance or null if not found.
143  */
144  final public static function get( $source, $args ) {
145  if ( ! is_string( $source ) || ! class_exists( $source ) ) {
146  gravityview()->log->error( '{source} class not found', array( 'source' => $source ) );
147  return null;
148  }
149 
150  if ( ! method_exists( $source, 'get_field' ) ) {
151  gravityview()->log->error( '{source} does not appear to be a valid \GV\Source subclass (get_field method missing)', array( 'source' => $source ) );
152  return null;
153  }
154 
155  return call_user_func_array( array( $source, 'get_field' ), is_array( $args ) ? $args : array( $args ) );
156  }
157 
158  /**
159  * Create self from a configuration array.
160  *
161  * @param array $configuration The configuration array.
162  * @see \GV\Field::as_configuration()
163  * @internal
164  * @since 2.0
165  *
166  * @return \GV\Field The field implementation from configuration (\GV\GF_Field, \GV\Internal_Field).
167  */
168  public static function from_configuration( $configuration ) {
169  if ( empty( $configuration['id'] ) ) {
170  $field = new self();
171  gravityview()->log->error( 'Trying to get field from configuration without a field ID.', array( 'data' => $configuration ) );
172  $field->update_configuration( $configuration );
173  return $field;
174  }
175 
176  /** Prevent infinte loops here from unimplemented children. */
177  if ( version_compare( phpversion(), '5.4', '>=' ) ) {
178  $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 );
179  } else {
180  $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
181  }
182  $trace = $trace[1];
183  if ( $trace['function'] == 'from_configuration' && $trace['class'] == __CLASS__ ) {
184  $field = new self();
185  gravityview()->log->error( 'Infinite loop protection tripped. Returning default class here.' );
186  $field->update_configuration( $configuration );
187  return $field;
188  }
189 
190  /** @type \GV\GF_Field|\GV\Internal_Field $field_class Determine the field implementation to use, and try to use. */
191  $field_class = is_numeric( $configuration['id'] ) ? '\GV\GF_Field' : '\GV\Internal_Field';
192 
193  /**
194  * @filter `gravityview/field/class` Filter the field class about to be created from the configuration.
195  * @param string $field_class The field class about to be used.
196  * @param array $configuration The configuration as per \GV\Field::as_configuration()
197  */
198  $field_class = apply_filters( 'gravityview/field/class', $field_class, $configuration );
199 
200  if ( ! class_exists( $field_class ) || ! method_exists( $field_class, 'from_configuration' ) ) {
201  $field = new self();
202  gravityview()->log->error( 'Class {field_class}::from_configuration does not exist.', array( 'field_class' => $field_class ) );
203  $field->update_configuration( $configuration );
204  return $field;
205  }
206 
207  $field = $field_class::from_configuration( $configuration );
208 
209  if ( ! $field ) {
210  $field = new self();
211  gravityview()->log->error( 'Could not configure {field_class} with given configuration.', array( 'field_class' => __CLASS__, 'data' => $configuration ) );
212  $field->update_configuration( $configuration );
213  }
214 
215  return $field;
216  }
217 
218  /**
219  * Update configuration.
220  *
221  * @param array $configuration The configuration array.
222  * @see \GV\Field::as_configuration()
223  * @since 2.0
224  *
225  * @return void
226  */
227  public function update_configuration( $configuration ) {
228  $configuration = wp_parse_args( $configuration, $this->as_configuration() );
229 
230  if ( $this->ID != $configuration['id'] ) {
231  /** Smelling trouble here... */
232  gravityview()->log->warning( 'ID is being changed for {field_class} instance, but implementation is not. Use ::from_configuration instead', array( 'field_class', __CLASS__ ) );
233  }
234 
235  $this->ID = $configuration['id'];
236  $this->label = $configuration['label'];
237  $this->show_label = $configuration['show_label'] == '1';
238  $this->custom_label = $configuration['custom_label'];
239  $this->custom_class = $configuration['custom_class'];
240  $this->cap = $configuration['only_loggedin'] == '1' ? $configuration['only_loggedin_cap'] : '';
241  $this->search_filter = $configuration['search_filter'] == '1';
242  $this->show_as_link = $configuration['show_as_link'] == '1';
243 
244  /** Shared among all field types (sort of). */
245  $shared_configuration_keys = array(
246  'id', 'label', 'show_label', 'custom_label', 'custom_class',
247  'only_loggedin' ,'only_loggedin_cap', 'search_filter', 'show_as_link',
248  );
249 
250  /** Everything else goes into the properties for now. @todo subclasses! */
251  foreach ( $configuration as $key => $value ) {
252  if ( ! in_array( $key, $shared_configuration_keys ) ) {
253  $this->configuration[ $key ] = $value;
254  }
255  }
256  }
257 
258  /**
259  * Retrieve the label for this field.
260  *
261  * @param \GV\View $view The view for this context if applicable.
262  * @param \GV\Source $source The source (form) for this context if applicable.
263  * @param \GV\Entry $entry The entry for this context if applicable.
264  * @param \GV\Request $request The request for this context if applicable.
265  *
266  * @return string The label for this field. Nothing here.
267  */
268  public function get_label( View $view = null, Source $source = null, Entry $entry = null, Request $request = null ) {
269 
270  if ( ! $this->show_label ) {
271  return '';
272  }
273 
274  /** A custom label is available. */
275  if ( ! empty( $this->custom_label ) ) {
276  return \GravityView_API::replace_variables( $this->custom_label, $source ? $source->form ? : null : null, $entry ? $entry->as_entry() : null );
277  }
278 
279  return '';
280  }
281 
282  /**
283  * Retrieve the value for this field.
284  *
285  * Returns null in this implementation (or, rather, lack thereof).
286  *
287  * @param \GV\View $view The view for this context if applicable.
288  * @param \GV\Source $source The source (form) for this context if applicable.
289  * @param \GV\Entry $entry The entry for this context if applicable.
290  * @param \GV\Request $request The request for this context if applicable.
291  *
292  * @return mixed The value for this field.
293  */
294  public function get_value( View $view = null, Source $source = null, Entry $entry = null, Request $request = null ) {
295  return $this->get_value_filters( null, $view, $source, $entry, $request );
296  }
297 
298  /**
299  * Apply all the required filters after get_value() was called.
300  *
301  * @param mixed $value The value that will be filtered.
302  * @param \GV\View $view The view for this context if applicable.
303  * @param \GV\Source $source The source (form) for this context if applicable.
304  * @param \GV\Entry $entry The entry for this context if applicable.
305  * @param \GV\Request $request The request for this context if applicable.
306  *
307  * This is in its own function since \GV\Field subclasses have to call it.
308  */
309  protected function get_value_filters( $value, View $view = null, Source $source = null, Entry $entry = null, Request $request = null ) {
310  if ( $this->type ) {
311  /**
312  * @filter `gravityview/field/$type/value` Override the displayed value here.
313  * @param string $value The value.
314  * @param \GV\Field The field we're doing this for.
315  * @param \GV\View $view The view for this context if applicable.
316  * @param \GV\Source $source The source (form) for this context if applicable.
317  * @param \GV\Entry $entry The entry for this context if applicable.
318  * @param \GV\Request $request The request for this context if applicable.
319  */
320  $value = apply_filters( "gravityview/field/{$this->type}/value", $value, $this, $view, $source, $entry, $request );
321  }
322 
323  /**
324  * @filter `gravityview/field/value` Override the displayed value here.
325  * @param string $value The value.
326  * @param \GV\Field The field we're doing this for.
327  * @param \GV\View $view The view for this context if applicable.
328  * @param \GV\Source $source The source (form) for this context if applicable.
329  * @param \GV\Entry $entry The entry for this context if applicable.
330  * @param \GV\Request $request The request for this context if applicable.
331  */
332  return apply_filters( 'gravityview/field/value', $value, $this, $view, $source, $entry, $request );
333  }
334 
335  /**
336  * Whether or not this field is visible.
337  *
338  * @param \GV\View|null Is visible where exactly?
339  * @since develop
340  *
341  * @return bool
342  */
343  public function is_visible( $view = null ) {
344  /**
345  * @filter `gravityview/field/is_visible` Should this field be visible?
346  *
347  * @param boolean $visible Visible or not, defaults to the set field capability requirement if defined.
348  * @param \GV\Field $field The field we're looking at.
349  * @param \GV\View|null A context view. Since @develop
350  */
351  return apply_filters( 'gravityview/field/is_visible', ( ! $this->cap || \GVCommon::has_cap( $this->cap ) ), $this, $view );
352  }
353 
354  /**
355  * Get one of the extra configuration keys via property accessors.
356  *
357  * @param string $key The key to get.
358  *
359  * @return mixed|null The value for the given configuration key, null if doesn't exist.
360  */
361  public function __get( $key ) {
362  switch( $key ) {
363  default:
364  if ( isset( $this->configuration[ $key ] ) ) {
365  return $this->configuration[ $key ];
366  }
367  }
368 
369  return null;
370  }
371 
372  /**
373  * Is this set?
374  *
375  * @param string $key The key to get.
376  *
377  * @return boolean Whether this $key is set or not.
378  */
379  public function __isset( $key ) {
380  switch( $key ) {
381  default:
382  return isset( $this->configuration[ $key ] );
383  }
384  }
385 }
If this file is called directly, abort.
static from_configuration( $configuration)
Create self from a configuration array.
get_value(View $view=null, Source $source=null, Entry $entry=null, Request $request=null)
Retrieve the value for this field.
get_value_filters( $value, View $view=null, Source $source=null, Entry $entry=null, Request $request=null)
Apply all the required filters after get_value() was called.
If this file is called directly, abort.
gravityview()
Definition: _stubs.php:26
$show_label
Definition: select.php:20
as_configuration()
Return an array of the old format as used by callers of GVCommon:get_directory_fields() for example...
If this file is called directly, abort.
__get( $key)
Get one of the extra configuration keys via property accessors.
__isset( $key)
Is this set?
If this file is called directly, abort.
If this file is called directly, abort.
update_configuration( $configuration)
Update configuration.
static has_cap( $caps='', $object_id=null, $user_id=null)
Alias of GravityView_Roles_Capabilities::has_cap()
$entry
Definition: notes.php:27
get_label(View $view=null, Source $source=null, Entry $entry=null, Request $request=null)
Retrieve the label for this field.
$field
Definition: gquiz_grade.php:11
is_visible( $view=null)
Whether or not this field is visible.