GravityView  2.17
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, 'data' => $configuration ) );
203  $field->update_configuration( $configuration );
204  return $field;
205  }
206 
207  /** @type \GV\GF_Field|\GV\Internal_Field $field */
208  $field = $field_class::from_configuration( $configuration );
209 
210  if ( ! $field ) {
211  $field = new self();
212  gravityview()->log->error( 'Could not configure {field_class} with given configuration.', array( 'field_class' => __CLASS__, 'data' => $configuration ) );
213  $field->update_configuration( $configuration );
214  }
215 
216  return $field;
217  }
218 
219  /**
220  * Update configuration.
221  *
222  * @param array $configuration The configuration array.
223  * @see \GV\Field::as_configuration()
224  * @since 2.0
225  *
226  * @return void
227  */
228  public function update_configuration( $configuration ) {
229  $configuration = wp_parse_args( $configuration, $this->as_configuration() );
230 
231  if ( $this->ID != $configuration['id'] ) {
232  /** Smelling trouble here... */
233  gravityview()->log->warning( 'ID is being changed for {field_class} instance, but implementation is not. Use ::from_configuration instead', array( 'field_class', __CLASS__ ) );
234  }
235 
236  $this->ID = $configuration['id'];
237  $this->label = $configuration['label'];
238  $this->show_label = $configuration['show_label'] == '1';
239  $this->custom_label = $configuration['custom_label'];
240  $this->custom_class = $configuration['custom_class'];
241  $this->cap = $configuration['only_loggedin'] == '1' ? $configuration['only_loggedin_cap'] : '';
242  $this->search_filter = $configuration['search_filter'] == '1';
243  $this->show_as_link = $configuration['show_as_link'] == '1';
244 
245  /** Shared among all field types (sort of). */
246  $shared_configuration_keys = array(
247  'id', 'label', 'show_label', 'custom_label', 'custom_class',
248  'only_loggedin' ,'only_loggedin_cap', 'search_filter', 'show_as_link',
249  );
250 
251  /** Everything else goes into the properties for now. @todo subclasses! */
252  foreach ( $configuration as $key => $value ) {
253  if ( ! in_array( $key, $shared_configuration_keys ) ) {
254  $this->configuration[ $key ] = $value;
255  }
256  }
257  }
258 
259  /**
260  * Retrieve the label for this field.
261  *
262  * @param \GV\View $view The view for this context if applicable.
263  * @param \GV\Source $source The source (form) for this context if applicable.
264  * @param \GV\Entry $entry The entry for this context if applicable.
265  * @param \GV\Request $request The request for this context if applicable.
266  *
267  * @return string The label for this field. Nothing here.
268  */
269  public function get_label( View $view = null, Source $source = null, Entry $entry = null, Request $request = null ) {
270 
271  if ( ! $this->show_label ) {
272  return '';
273  }
274 
275  /** A custom label is available. */
276  if ( ! empty( $this->custom_label ) ) {
277  return \GravityView_API::replace_variables( $this->custom_label, $source ? $source->form ? : null : null, $entry ? $entry->as_entry() : null );
278  }
279 
280  return '';
281  }
282 
283  /**
284  * Retrieve the value for this field.
285  *
286  * Returns null in this implementation (or, rather, lack thereof).
287  *
288  * @param \GV\View $view The view for this context if applicable.
289  * @param \GV\Source $source The source (form) for this context if applicable.
290  * @param \GV\Entry $entry The entry for this context if applicable.
291  * @param \GV\Request $request The request for this context if applicable.
292  *
293  * @return mixed The value for this field.
294  */
295  public function get_value( View $view = null, Source $source = null, Entry $entry = null, Request $request = null ) {
296  return $this->get_value_filters( null, $view, $source, $entry, $request );
297  }
298 
299  /**
300  * Apply all the required filters after get_value() was called.
301  *
302  * @param mixed $value The value that will be filtered.
303  * @param \GV\View $view The view for this context if applicable.
304  * @param \GV\Source $source The source (form) for this context if applicable.
305  * @param \GV\Entry $entry The entry for this context if applicable.
306  * @param \GV\Request $request The request for this context if applicable.
307  *
308  * This is in its own function since \GV\Field subclasses have to call it.
309  */
310  protected function get_value_filters( $value, View $view = null, Source $source = null, Entry $entry = null, Request $request = null ) {
311  if ( $this->type ) {
312  /**
313  * @filter `gravityview/field/$type/value` Override the displayed value here.
314  * @param string $value The value.
315  * @param \GV\Field The field we're doing this for.
316  * @param \GV\View $view The view for this context if applicable.
317  * @param \GV\Source $source The source (form) for this context if applicable.
318  * @param \GV\Entry $entry The entry for this context if applicable.
319  * @param \GV\Request $request The request for this context if applicable.
320  */
321  $value = apply_filters( "gravityview/field/{$this->type}/value", $value, $this, $view, $source, $entry, $request );
322  }
323 
324  /**
325  * @filter `gravityview/field/value` Override the displayed value here.
326  * @param string $value The value.
327  * @param \GV\Field The field we're doing this for.
328  * @param \GV\View $view The view for this context if applicable.
329  * @param \GV\Source $source The source (form) for this context if applicable.
330  * @param \GV\Entry $entry The entry for this context if applicable.
331  * @param \GV\Request $request The request for this context if applicable.
332  */
333  return apply_filters( 'gravityview/field/value', $value, $this, $view, $source, $entry, $request );
334  }
335 
336  /**
337  * Whether or not this field is visible.
338  *
339  * @param \GV\View|null Is visible where exactly?
340  * @since develop
341  *
342  * @return bool
343  */
344  public function is_visible( $view = null ) {
345  /**
346  * @filter `gravityview/field/is_visible` Should this field be visible?
347  *
348  * @param boolean $visible Visible or not, defaults to the set field capability requirement if defined.
349  * @param \GV\Field $field The field we're looking at.
350  * @param \GV\View|null A context view. Since @develop
351  */
352  return apply_filters( 'gravityview/field/is_visible', ( ! $this->cap || \GVCommon::has_cap( $this->cap ) ), $this, $view );
353  }
354 
355  /**
356  * Get one of the extra configuration keys via property accessors.
357  *
358  * @param string $key The key to get.
359  *
360  * @return mixed|null The value for the given configuration key, null if doesn't exist.
361  */
362  public function __get( $key ) {
363  switch( $key ) {
364  default:
365  if ( isset( $this->configuration[ $key ] ) ) {
366  return $this->configuration[ $key ];
367  }
368  }
369 
370  return null;
371  }
372 
373  /**
374  * Is this set?
375  *
376  * @param string $key The key to get.
377  *
378  * @return boolean Whether this $key is set or not.
379  */
380  public function __isset( $key ) {
381  switch( $key ) {
382  default:
383  return isset( $this->configuration[ $key ] );
384  }
385  }
386 }
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.
$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.
gravityview()
The main GravityView wrapper function.
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.
is_visible( $view=null)
Whether or not this field is visible.