GravityView  1.19.4
The best, easiest way to display Gravity Forms entries on your website.
class-gravityview-field.php
Go to the documentation of this file.
1 <?php
2 /**
3  * @file class-gravityview-field.php
4  * @package GravityView
5  * @subpackage includes\fields
6  */
7 
8 /**
9  * Modify field settings by extending this class.
10  */
11 abstract class GravityView_Field {
12 
13  /**
14  * The name of the GravityView field type
15  * Example: `created_by`, `text`, `fileupload`, `address`, `entry_link`
16  * @var string
17  */
18  public $name;
19 
20  /**
21  * @internal Not yet implemented
22  * @since 1.15.2
23  * @type string The description of the field in the field picker
24  */
25  public $description;
26 
27  /**
28  * @since 1.15.2
29  * @type string The label of the field in the field picker
30  */
31  public $label;
32 
33  /**
34  * @var string The default search label used by the search widget, if not set
35  */
37 
38  /**
39  * `standard`, `advanced`, `post`, `pricing`, `meta`, `gravityview`
40  * @since 1.15.2
41  * @type string The group belongs to this field in the field picker
42  */
43  public $group;
44 
45  /**
46  * @internal Not yet implemented
47  * @type boolean Can the field be searched?
48  * @since 1.15.2
49  */
50  public $is_searchable = true;
51 
52  /**
53  * @internal Not yet implemented
54  * @type array $search_operators The type of search operators available for this field
55  * @since 1.15.2
56  */
58 
59  /**
60  * @type boolean Can the field be sorted in search?
61  * @since 1.15.2
62  */
63  public $is_sortable = true;
64 
65  /**
66  * @type boolean Is field content number-based?
67  * @since 1.15.2
68  */
69  public $is_numeric;
70 
71  /**
72  * @var null|string The key used to search and sort entry meta in Gravity Forms. Used if the field stores data as custom entry meta.
73  * @see https://www.gravityhelp.com/documentation/article/gform_entry_meta/
74  * @since TODO
75  */
76  public $entry_meta_key = null;
77 
78  /**
79  * @var string|array Optional. The callback function after entry meta is updated, only used if $entry_meta_key is set.
80  * @see https://www.gravityhelp.com/documentation/article/gform_entry_meta/
81  * @since TODO
82  */
84 
85  /**
86  * @var bool Whether to show meta when set to true automatically adds the column to the entry list, without having to edit and add the column for display
87  * @since TODO
88  */
90 
91  /**
92  * @internal Not yet implemented
93  * @todo implement supports_context() method
94  * The contexts in which a field is available. Some fields aren't editable, for example.
95  * - `singular` is an alias for both `single` and `edit`
96  * - `multiple` is an alias for `directory` (backward compatibility)
97  * @type array
98  * @since 1.15.2
99  */
100  public $contexts = array( 'single', 'multiple', 'edit', 'export' );
101 
102  /**
103  * @since 1.15.2
104  * @since 1.16.2.2 Changed access to public (previously, protected)
105  * @type string The name of a corresponding Gravity Forms GF_Field class, if exists
106  */
108 
109  /**
110  * @var string The field ID being requested
111  * @since 1.14
112  */
113  protected $_field_id = '';
114 
115  /**
116  * @var string Field options to be rendered
117  * @since 1.14
118  */
119  protected $_field_options = array();
120 
121  /**
122  * @var bool|string Name of merge tag (without curly brackets), if the field has custom GravityView merge tags to add. Otherwise, false.
123  * @since 1.16
124  */
125  protected $_custom_merge_tag = false;
126 
127  /**
128  * GravityView_Field constructor.
129  */
130  public function __construct() {
131 
132  // Modify the field options based on the name of the field type
133  add_filter( sprintf( 'gravityview_template_%s_options', $this->name ), array( &$this, 'field_options' ), 10, 5 );
134 
135  add_filter( 'gravityview/sortable/field_blacklist', array( $this, '_filter_sortable_fields' ), 1 );
136 
137  if( $this->entry_meta_key ) {
138  add_filter( 'gform_entry_meta', array( $this, 'add_entry_meta' ) );
139  add_filter( 'gravityview/common/sortable_fields', array( $this, 'add_sortable_field' ), 10, 2 );
140  }
141 
142  if( $this->_custom_merge_tag ) {
143  add_filter( 'gform_custom_merge_tags', array( $this, '_filter_gform_custom_merge_tags' ), 10, 4 );
144  add_filter( 'gform_replace_merge_tags', array( $this, '_filter_gform_replace_merge_tags' ), 10, 7 );
145  }
146 
147  if( 'meta' === $this->group || '' !== $this->default_search_label ) {
148  add_filter( 'gravityview_search_field_label', array( $this, 'set_default_search_label' ), 10, 3 );
149  }
150 
152  }
153 
154  /**
155  * Add the field to the Filter & Sort available fields
156  *
157  * @since TODO
158  *
159  * @param array $fields Sub-set of GF form fields that are sortable
160  *
161  * @return array Modified $fields array to include approval status in the sorting dropdown
162  */
163  public function add_sortable_field( $fields ) {
164 
165  $added_field = array(
166  'label' => $this->label,
167  'type' => $this->name
168  );
169 
170  $fields["{$this->entry_meta_key}"] = $added_field;
171 
172  return $fields;
173  }
174 
175  /**
176  * Allow setting a default search label for search fields based on the field type
177  *
178  * Useful for entry meta "fields" that don't have Gravity Forms labels, like `created_by`
179  *
180  * @since 1.17.3
181  *
182  * @param string $label Existing label text, sanitized.
183  * @param array $gf_field Gravity Forms field array, as returned by `GFFormsModel::get_field()`
184  * @param array $field Field setting as sent by the GV configuration - has `field`, `input` (input type), and `label` keys
185  *
186  * @return string
187  */
188  function set_default_search_label( $label = '', $gf_field = null, $field = array() ) {
189 
190  if( $this->name === $field['field'] && '' === $label ) {
191  $label = esc_html( $this->default_search_label );
192  }
193 
194  return $label;
195  }
196 
197  /**
198  * Match the merge tag in replacement text for the field. DO NOT OVERRIDE.
199  *
200  * @see replace_merge_tag Override replace_merge_tag() to handle any matches
201  *
202  * @since 1.16
203  *
204  * @param string $text Text to replace
205  * @param array $form Gravity Forms form array
206  * @param array $entry Entry array
207  * @param bool $url_encode Whether to URL-encode output
208  *
209  * @return string Original text if {_custom_merge_tag} isn't found. Otherwise, replaced text.
210  */
211  public function _filter_gform_replace_merge_tags( $text, $form = array(), $entry = array(), $url_encode = false, $esc_html = false ) {
212 
213  /**
214  * This prevents the gform_replace_merge_tags filter from being called twice, as defined in:
215  * @see GFCommon::replace_variables()
216  * @see GFCommon::replace_variables_prepopulate()
217  * @todo Remove eventually: Gravity Forms fixed this issue in 1.9.14
218  */
219  if( false === $form ) {
220  return $text;
221  }
222 
223  // Is there is field merge tag? Strip whitespace off the ned, too.
224  preg_match_all( '/{' . preg_quote( $this->_custom_merge_tag ) . ':?(.*?)(?:\s)?}/ism', $text, $matches, PREG_SET_ORDER );
225 
226  // If there are no matches, return original text
227  if ( empty( $matches ) ) {
228  return $text;
229  }
230 
231  return $this->replace_merge_tag( $matches, $text, $form, $entry, $url_encode, $esc_html );
232  }
233 
234  /**
235  * Run GravityView filters when using GFCommon::replace_variables()
236  *
237  * Instead of adding multiple hooks, add all hooks into this one method to improve speed
238  *
239  * @since 1.8.4
240  *
241  * @param array $matches Array of Merge Tag matches found in text by preg_match_all
242  * @param string $text Text to replace
243  * @param array|bool $form Gravity Forms form array. When called inside {@see GFCommon::replace_variables()} (now deprecated), `false`
244  * @param array|bool $entry Entry array. When called inside {@see GFCommon::replace_variables()} (now deprecated), `false`
245  * @param bool $url_encode Whether to URL-encode output
246  * @param bool $esc_html Whether to apply `esc_html()` to output
247  *
248  * @return mixed
249  */
250  public function replace_merge_tag( $matches = array(), $text = '', $form = array(), $entry = array(), $url_encode = false, $esc_html = false ) {
251 
252  foreach( $matches as $match ) {
253 
254  $full_tag = $match[0];
255 
256  // Strip the Merge Tags
257  $tag = str_replace( array( '{', '}'), '', $full_tag );
258 
259  // Replace the value from the entry, if exists
260  if( isset( $entry[ $tag ] ) ) {
261 
262  $value = $entry[ $tag ];
263 
264  if( is_callable( array( $this, 'get_content') ) ) {
265  $value = $this->get_content( $value );
266  }
267 
268  $text = str_replace( $full_tag, $value, $text );
269  }
270  }
271 
272  unset( $value, $tag, $full_tag );
273 
274  return $text;
275  }
276 
277  /**
278  * Add custom merge tags to merge tag options. DO NOT OVERRIDE.
279  *
280  * @internal Not to be overridden by fields
281  *
282  * @since 1.8.4
283  *
284  * @param array $custom_merge_tags
285  * @param int $form_id GF Form ID
286  * @param GF_Field[] $fields Array of fields in the form
287  * @param string $element_id The ID of the input that Merge Tags are being used on
288  *
289  * @return array Modified merge tags
290  */
291  public function _filter_gform_custom_merge_tags( $custom_merge_tags = array(), $form_id, $fields = array(), $element_id = '' ) {
292 
294 
295  $field_merge_tags = $this->custom_merge_tags( $form, $fields );
296 
297  return array_merge( $custom_merge_tags, $field_merge_tags );
298  }
299 
300  /**
301  * Add custom Merge Tags to Merge Tag options, if custom Merge Tags exist
302  *
303  * Should be overridden if there's more than one Merge Tag to add or if the Merge Tag isn't {_custom_merge_tag}
304  *
305  * @since 1.16
306  *
307  * @param array $form GF Form array
308  * @param GF_Field[] $fields Array of fields in the form
309  *
310  * @return array Merge tag array with `label` and `tag` keys based on class `label` and `_custom_merge_tag` variables
311  */
312  protected function custom_merge_tags( $form = array(), $fields = array() ) {
313 
314  // Use variables to make it unnecessary for other fields to override
315  $merge_tags = array(
316  array(
317  'label' => $this->label,
318  'tag' => '{' . $this->_custom_merge_tag . '}',
319  ),
320  );
321 
322  return $merge_tags;
323  }
324 
325  /**
326  * Use field settings to modify whether a field is sortable
327  *
328  * @see GravityView_frontend::is_field_sortable
329  * @since 1.15.3
330  *
331  * @param array $not_sortable Existing field types that aren't sortable
332  *
333  * @return array
334  */
335  public function _filter_sortable_fields( $not_sortable ) {
336 
337  if( ! $this->is_sortable ) {
338  $not_sortable[] = $this->name;
339  }
340 
341  return $not_sortable;
342  }
343 
344  /**
345  * Add the custom entry meta key to make it searchable and sortable
346  *
347  * @see https://www.gravityhelp.com/documentation/article/gform_entry_meta/
348  *
349  * @param array $entry_meta Array of custom entry meta keys with associative arrays
350  *
351  * @return mixed
352  */
353  function add_entry_meta( $entry_meta ) {
354 
355  if( ! isset( $entry_meta["{$this->entry_meta_key}"] ) ) {
356 
357  $added_meta = array(
358  'label' => $this->label,
359  'is_numeric' => $this->is_numeric,
360  'is_default_column' => $this->entry_meta_is_default_column,
361  );
362 
363  if ( $this->entry_meta_update_callback && is_callable( $this->entry_meta_update_callback ) ) {
364  $added_meta['update_entry_meta_callback'] = $this->entry_meta_update_callback;
365  }
366 
367  $entry_meta["{$this->entry_meta_key}"] = $added_meta;
368 
369  } else {
370  do_action( 'gravityview_log_error', __METHOD__ . ' Entry meta already set: ' . $this->entry_meta_key, $entry_meta["{$this->entry_meta_key}"] );
371  }
372 
373  return $entry_meta;
374  }
375 
376  private function field_support_options() {
377  $options = array(
378  'link_to_post' => array(
379  'type' => 'checkbox',
380  'label' => __( 'Link to the post', 'gravityview' ),
381  'desc' => __( 'Link to the post created by the entry.', 'gravityview' ),
382  'value' => false,
383  ),
384  'link_to_term' => array(
385  'type' => 'checkbox',
386  'label' => __( 'Link to the category or tag', 'gravityview' ),
387  'desc' => __( 'Link to the current category or tag. "Link to single entry" must be unchecked.', 'gravityview' ),
388  'value' => false,
389  ),
390  'dynamic_data' => array(
391  'type' => 'checkbox',
392  'label' => __( 'Use the live post data', 'gravityview' ),
393  'desc' => __( 'Instead of using the entry data, instead use the current post data.', 'gravityview' ),
394  'value' => true,
395  ),
396  'date_display' => array(
397  'type' => 'text',
398  'label' => __( 'Override Date Format', 'gravityview' ),
399  'desc' => sprintf( __( 'Define how the date is displayed (using %sthe PHP date format%s)', 'gravityview'), '<a href="https://codex.wordpress.org/Formatting_Date_and_Time">', '</a>' ),
400  /**
401  * @filter `gravityview_date_format` Override the date format with a [PHP date format](https://codex.wordpress.org/Formatting_Date_and_Time)
402  * @param[in,out] null|string $date_format Date Format (default: null)
403  */
404  'value' => apply_filters( 'gravityview_date_format', null )
405  ),
406  'new_window' => array(
407  'type' => 'checkbox',
408  'label' => __( 'Open link in a new tab or window?', 'gravityview' ),
409  'value' => false,
410  ),
411  );
412 
413  /**
414  * @filter `gravityview_field_support_options` Modify the settings that a field supports
415  * @param array $options Options multidimensional array with each key being the input name, with each array setting having `type`, `label`, `desc` and `value` (default values) keys
416  */
417  return apply_filters( 'gravityview_field_support_options', $options );
418  }
419 
420  function add_field_support( $key = '', &$field_options ) {
421 
422  $options = $this->field_support_options();
423 
424  if( isset( $options[ $key ] ) ) {
425  $field_options[ $key ] = $options[ $key ];
426  }
427 
428  return $field_options;
429  }
430 
431  /**
432  * Tap in here to modify field options.
433  *
434  * Here's an example:
435  *
436  * <pre>
437  * $field_options['name_display'] = array(
438  * 'type' => 'select',
439  * 'label' => __( 'User Format', 'gravityview' ),
440  * 'desc' => __( 'How should the User information be displayed?', 'gravityview'),
441  * 'choices' => array(
442  * array(
443  * 'value' => 'display_name',
444  * 'label' => __('Display Name (Example: "Ellen Ripley")', 'gravityview'),
445  * ),
446  * array(
447  * 'value' => 'user_login',
448  * 'label' => __('Username (Example: "nostromo")', 'gravityview')
449  * ),
450  * 'value' => 'display_name'
451  * );
452  * </pre>
453  *
454  * @param array $field_options [description]
455  * @param string $template_id [description]
456  * @param string $field_id [description]
457  * @param string $context [description]
458  * @param string $input_type [description]
459  * @return array [description]
460  */
461  public function field_options( $field_options, $template_id, $field_id, $context, $input_type ) {
462 
463  $this->_field_options = $field_options;
464  $this->_field_id = $field_id;
465 
466  return $field_options;
467  }
468 
469  /**
470  * Check whether the `enableChoiceValue` flag is set for a GF field
471  *
472  * Gets the current form ID, gets the field at that ID, then checks for the enableChoiceValue value.
473  *
474  * @access protected
475  *
476  * @uses GFAPI::get_form
477  *
478  * @since 1.17
479  *
480  * @return bool True: Enable Choice Value is active for field; False: not active, or form invalid, or form not found.
481  */
482  protected function is_choice_value_enabled() {
483 
484  // If "Add Field" button is processing, get the Form ID
485  $connected_form = rgpost( 'form_id' );
486 
487  // Otherwise, get the Form ID from the Post page
488  if( empty( $connected_form ) ) {
489  $connected_form = gravityview_get_form_id( get_the_ID() );
490  }
491 
492  if( empty( $connected_form ) ) {
493  do_action( 'gravityview_log_error', sprintf( '%s: Form not found for form ID "%s"', __METHOD__, $connected_form ) );
494  return false;
495  }
496 
497  $form = GFAPI::get_form( $connected_form );
498 
499  if ( ! $form ) {
500  do_action( 'gravityview_log_error', sprintf( '%s: Form not found for field ID of "%s", when checking for a form with ID of "%s"', __METHOD__, $this->_field_id, $connected_form ) );
501  return false;
502  }
503 
504  $field = gravityview_get_field( $form, $this->_field_id );
505 
506  return ! empty( $field->enableChoiceValue );
507  }
508 
509 }
Modify field settings by extending this class.
__construct()
GravityView_Field constructor.
$is_numeric
boolean Is field content number-based?
static get_form($form_id)
Returns the form object for a given Form ID.
add_entry_meta($entry_meta)
Add the custom entry meta key to make it searchable and sortable.
gravityview_get_field($form, $field_id)
Returns the field details array of a specific form given the field id.
replace_merge_tag($matches=array(), $text= '', $form=array(), $entry=array(), $url_encode=false, $esc_html=false)
Run GravityView filters when using GFCommon::replace_variables()
field_options($field_options, $template_id, $field_id, $context, $input_type)
Tap in here to modify field options.
$group
standard, advanced, post, pricing, meta, gravityview
add_field_support($key= '', &$field_options)
_filter_gform_replace_merge_tags($text, $form=array(), $entry=array(), $url_encode=false, $esc_html=false)
Match the merge tag in replacement text for the field.
add_sortable_field($fields)
Add the field to the Filter & Sort available fields.
$is_sortable
boolean Can the field be sorted in search?
set_default_search_label($label= '', $gf_field=null, $field=array())
Allow setting a default search label for search fields based on the field type.
is_choice_value_enabled()
Check whether the enableChoiceValue flag is set for a GF field.
$field_id
Definition: time.php:17
if(empty($created_by)) $form_id
_filter_sortable_fields($not_sortable)
Use field settings to modify whether a field is sortable.
_filter_gform_custom_merge_tags($custom_merge_tags=array(), $form_id, $fields=array(), $element_id= '')
Add custom merge tags to merge tag options.
$entry
Definition: notes.php:27
gravityview_get_form_id($view_id)
Get the connected form ID from a View ID.
custom_merge_tags($form=array(), $fields=array())
Add custom Merge Tags to Merge Tag options, if custom Merge Tags exist.
$field
Definition: gquiz_grade.php:11