GravityView  2.9.2
The best, easiest way to display Gravity Forms entries on your website.
class-api.php
Go to the documentation of this file.
1 <?php
2 /**
3  * GravityView template tags API
4  *
5  * @package GravityView
6  * @license GPL2+
7  * @author GravityView <hello@gravityview.co>
8  * @link http://gravityview.co
9  * @copyright Copyright 2014, Katz Web Services, Inc.
10  *
11  * @since 1.0.0
12  */
13 
15 
16  /**
17  * Fetch Field Label
18  *
19  * @deprecated Use \GV\Field::get_label()
20  *
21  * @static
22  * @param array $field GravityView field array
23  * @param array $entry Gravity Forms entry array
24  * @param boolean $force_show_label Whether to always show the label, regardless of field settings
25  * @return string
26  */
27  public static function field_label( $field, $entry = array(), $force_show_label = false ) {
28 
30 
31  $form = $gravityview_view->getForm();
32 
33  if ( defined( 'DOING_GRAVITYVIEW_TESTS' ) && ! empty( $GLOBALS['GravityView_API_field_label_override'] ) ) {
34  /** Allow to fall through for back compatibility testing purposes. */
35  } else {
37  }
38 
39  $label = '';
40 
41  if( !empty( $field['show_label'] ) || $force_show_label ) {
42 
43  $label = $field['label'];
44 
45  // Support Gravity Forms 1.9+
46  if( class_exists( 'GF_Field' ) ) {
47 
48  $field_object = RGFormsModel::get_field( $form, $field['id'] );
49 
50  if( $field_object ) {
51 
52  $input = GFFormsModel::get_input( $field_object, $field['id'] );
53 
54  // This is a complex field, with labels on a per-input basis
55  if( $input ) {
56 
57  // Does the input have a custom label on a per-input basis? Otherwise, default label.
58  $label = ! empty( $input['customLabel'] ) ? $input['customLabel'] : $input['label'];
59 
60  } else {
61 
62  // This is a field with one label
63  $label = $field_object->get_field_label( true, $field['label'] );
64 
65  }
66 
67  }
68 
69  }
70 
71  // Use Gravity Forms label by default, but if a custom label is defined in GV, use it.
72  if ( !empty( $field['custom_label'] ) ) {
73 
74  $label = self::replace_variables( $field['custom_label'], $form, $entry );
75 
76  }
77 
78  /**
79  * @filter `gravityview_render_after_label` Append content to a field label
80  * @param[in,out] string $appended_content Content you can add after a label. Empty by default.
81  * @param[in] array $field GravityView field array
82  */
83  $label .= apply_filters( 'gravityview_render_after_label', '', $field );
84 
85  } // End $field['show_label']
86 
87  /**
88  * @filter `gravityview/template/field_label` Modify field label output
89  * @since 1.7
90  * @param[in,out] string $label Field label HTML
91  * @param[in] array $field GravityView field array
92  * @param[in] array $form Gravity Forms form array
93  * @param[in] array $entry Gravity Forms entry array
94  *
95  * @deprecated Use the context-aware version `gravityview/template/field/label`
96  */
97  $label = apply_filters( 'gravityview/template/field_label', $label, $field, $form, $entry );
98 
99  return $label;
100  }
101 
102  /**
103  * Alias for GravityView_Merge_Tags::replace_variables()
104  *
105  * @see GravityView_Merge_Tags::replace_variables() Moved in 1.8.4
106  * @since 1.22.4 - Added $nl2br, $format, $aux_data args
107  *
108  * @param string $text Text to replace variables in
109  * @param array $form GF Form array
110  * @param array $entry GF Entry array
111  * @param bool $url_encode Pass return value through `url_encode()`
112  * @param bool $esc_html Pass return value through `esc_html()`
113  * @param bool $nl2br Convert newlines to <br> HTML tags
114  * @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
115  * @param array $aux_data Additional data to be used to replace merge tags {@see https://www.gravityhelp.com/documentation/article/gform_merge_tag_data/}
116  * @return string Text with variables maybe replaced
117  */
118  public static function replace_variables( $text, $form = array(), $entry = array(), $url_encode = false, $esc_html = true, $nl2br = true, $format = 'html', $aux_data = array() ) {
119  return GravityView_Merge_Tags::replace_variables( $text, $form, $entry, $url_encode, $esc_html, $nl2br, $format, $aux_data );
120  }
121 
122  /**
123  * Get column width from the field setting
124  *
125  * @since 1.9
126  *
127  * @param array $field Array of settings for the field
128  * @param string $format Format for width. "%" (default) will return
129  *
130  * @return string|null If not empty, string in $format format. Otherwise, null.
131  */
132  public static function field_width( $field, $format = '%d%%' ) {
133 
134  $width = NULL;
135 
136  if( !empty( $field['width'] ) ) {
137  $width = absint( $field['width'] );
138 
139  // If using percentages, limit to 100%
140  if( '%d%%' === $format && $width > 100 ) {
141  $width = 100;
142  }
143 
144  $width = sprintf( $format, $width );
145  }
146 
147  return $width;
148  }
149 
150  /**
151  * Fetch Field class
152  *
153  * @static
154  * @param mixed $field
155  * @return string
156  */
157  public static function field_class( $field, $form = NULL, $entry = NULL ) {
158  $classes = array();
159 
160  if( !empty( $field['custom_class'] ) ) {
161 
162  $custom_class = $field['custom_class'];
163 
164  if( !empty( $entry ) ) {
165 
166  // We want the merge tag to be formatted as a class. The merge tag may be
167  // replaced by a multiple-word value that should be output as a single class.
168  // "Office Manager" will be formatted as `.OfficeManager`, not `.Office` and `.Manager`
169  add_filter('gform_merge_tag_filter', 'sanitize_html_class');
170 
171  $custom_class = self::replace_variables( $custom_class, $form, $entry);
172 
173  // And then we want life to return to normal
174  remove_filter('gform_merge_tag_filter', 'sanitize_html_class');
175  }
176 
177  // And now we want the spaces to be handled nicely.
178  $classes[] = gravityview_sanitize_html_class( $custom_class );
179 
180  }
181 
182  if(!empty($field['id'])) {
183  if( !empty( $form ) && !empty( $form['id'] ) ) {
184  $form_id = '-'.$form['id'];
185  } else {
186  // @deprecated path. Form should always be given.
187  gravityview()->log->warning( 'GravityView_View::getInstance() legacy API called' );
189  $form_id = $gravityview_view->getFormId() ? '-'. $gravityview_view->getFormId() : '';
190  }
191 
192  $classes[] = 'gv-field'.$form_id.'-'.$field['id'];
193  }
194 
195  return esc_attr(implode(' ', $classes));
196  }
197 
198  /**
199  * Fetch Field HTML ID
200  *
201  * @since 1.11
202  *
203  * @static
204  * @param array $field GravityView field array passed to gravityview_field_output()
205  * @param array $form Gravity Forms form array, if set.
206  * @param array $entry Gravity Forms entry array
207  * @return string Sanitized unique HTML `id` attribute for the field
208  */
209  public static function field_html_attr_id( $field, $form = array(), $entry = array() ) {
210  $id = $field['id'];
211 
212  if ( ! empty( $id ) ) {
213  if ( ! empty( $form ) && ! empty( $form['id'] ) ) {
214  $form_id = '-' . $form['id'];
215  } else {
216  // @deprecated path. Form should always be given.
217  gravityview()->log->warning( 'GravityView_View::getInstance() legacy API called' );
219  $form_id = $gravityview_view->getFormId() ? '-' . $gravityview_view->getFormId() : '';
220  }
221 
222  $id = 'gv-field' . $form_id . '-' . $field['id'];
223  }
224 
225  return esc_attr( $id );
226  }
227 
228 
229  /**
230  * Given an entry and a form field id, calculate the entry value for that field.
231  *
232  * @deprecated Use \GV\Field_Template::render() or the more low-level \GV\Field::get_value()
233  *
234  * @param array $entry
235  * @param array $field
236  * @return null|string
237  */
238  public static function field_value( $entry, $field_settings, $format = 'html' ) {
239  gravityview()->log->notice( '\GravityView_API::field_value is deprecated. Use \GV\Field_Template::render() or \GV\Field::get_value()' );
241  }
242 
243  /**
244  * Generate an anchor tag that links to an entry.
245  *
246  * @since 1.6
247  * @see GVCommon::get_link_html()
248  *
249  * @param string $anchor_text The text or HTML inside the link
250  * @param array $entry Gravity Forms entry array
251  * @param array|string $passed_tag_atts Attributes to be added to the anchor tag, such as `title` or `rel`.
252  * @param array $field_settings Array of field settings. Optional, but passed to the `gravityview_field_entry_link` filter
253  *
254  * @since 2.0
255  * @param int $base_id The post or the view that this entry is linked from.
256  *
257  * @return string|null Returns HTML for an anchor link. Null if $entry isn't defined or is missing an ID.
258  */
259  public static function entry_link_html( $entry = array(), $anchor_text = '', $passed_tag_atts = array(), $field_settings = array(), $base_id = null ) {
260 
261  if ( empty( $entry ) || ! is_array( $entry ) || ! isset( $entry['id'] ) ) {
262  gravityview()->log->debug( 'Entry not defined; returning null', array( 'data' => $entry ) );
263  return NULL;
264  }
265 
266  $href = self::entry_link( $entry, $base_id );
267 
268  if( '' === $href ) {
269  return NULL;
270  }
271 
272  $link = gravityview_get_link( $href, $anchor_text, $passed_tag_atts );
273 
274  /**
275  * @filter `gravityview_field_entry_link` Modify the link HTML
276  * @param string $link HTML output of the link
277  * @param string $href URL of the link
278  * @param array $entry The GF entry array
279  * @param array $field_settings Settings for the particular GV field
280  */
281  $output = apply_filters( 'gravityview_field_entry_link', $link, $href, $entry, $field_settings );
282 
283  return $output;
284  }
285 
286  /**
287  * Get the "No Results" text depending on whether there were results.
288  * @param boolean $wpautop Apply wpautop() to the output?
289  *
290  * @since 2.0
291  * @param \GV\Template_Context $context The context
292  *
293  * @return string HTML of "no results" text
294  */
295  public static function no_results( $wpautop = true, $context = null ) {
296  $is_search = false;
297 
298  if ( $context instanceof \GV\Template_Context ) {
299  if ( $context->request->is_search() ) {
300  $is_search = true;
301  }
302  } else {
304 
305  if( $gravityview_view && ( $gravityview_view->curr_start || $gravityview_view->curr_end || $gravityview_view->curr_search ) ) {
306  $is_search = true;
307  }
308  }
309 
310  $setting = '';
311 
312  if ( $is_search ) {
313 
314  $output = esc_html__( 'This search returned no results.', 'gravityview' );
315 
316  if( $context ) {
317  $setting = $context->view->settings->get( 'no_search_results_text', $output );
318  }
319 
320  } else {
321 
322  $output = esc_html__( 'No entries match your request.', 'gravityview' );
323 
324  if( $context ) {
325  $setting = $context->view->settings->get( 'no_results_text', $output );
326  }
327  }
328 
329  if ( '' !== $setting ) {
330  $output = $setting;
331  }
332 
333  /**
334  * Added now that users are able to modify via View settings
335  * @since 2.8.2
336  */
337  $output = wp_kses(
338  $output,
339  array(
340  'p' => array( 'class' => array(), 'id' => array() ),
341  'h1' => array( 'class' => array(), 'id' => array() ),
342  'h2' => array( 'class' => array(), 'id' => array() ),
343  'h3' => array( 'class' => array(), 'id' => array() ),
344  'h4' => array( 'class' => array(), 'id' => array() ),
345  'h5' => array( 'class' => array(), 'id' => array() ),
346  'strong' => array( 'class' => array(), 'id' => array() ),
347  'span' => array( 'class' => array(), 'id' => array() ),
348  'b' => array( 'class' => array(), 'id' => array() ),
349  'em' => array( 'class' => array(), 'id' => array() ),
350  'a' => array( 'class' => array(), 'id' => array(), 'href' => array(), 'title' => array(), 'rel' => array(), 'target' => array() ),
351  'div' => array( 'class' => array(), 'id' => array() ),
352  'br' => array(),
353  )
354  );
355 
356  /**
357  * @filter `gravitview_no_entries_text` Modify the text displayed when there are no entries.
358  * Note: this filter is, and always has been, misspelled. This will not be fixed, since the filter is deprecated.
359  * @param string $output The existing "No Entries" text
360  * @param boolean $is_search Is the current page a search result, or just a multiple entries screen?
361  * @return string The modified text.
362  * @deprecated Use `gravityview/template/text/no_entries`
363  */
364  $output = apply_filters( 'gravitview_no_entries_text', $output, $is_search );
365 
366  /**
367  * @filter `gravityview/template/text/no_entries` Modify the text displayed when there are no entries.
368  * @since 2.0
369  * @param string $output The existing "No Entries" text
370  * @param boolean $is_search Is the current page a search result, or just a multiple entries screen?
371  * @param \GV\Template_Context $context The context.
372  * @return string The modified text.
373  */
374  $output = apply_filters( 'gravityview/template/text/no_entries', $output, $is_search, $context );
375 
376  return $wpautop ? wpautop( $output ) : $output;
377  }
378 
379  /**
380  * Generate a URL to the Directory context
381  *
382  * Uses `wp_cache_get` and `wp_cache_get` (since 1.3) to speed up repeated requests to get permalink, which improves load time. Since we may be doing this hundreds of times per request, it adds up!
383  *
384  * @param int $post_id Post ID
385  * @param boolean $add_query_args Add pagination and sorting arguments
386  *
387  * @since 2.0
388  * @param \GV\Template_Context $context The context this is being used in.
389  *
390  * @return string Permalink to multiple entries view
391  */
392  public static function directory_link( $post_id = NULL, $add_query_args = true, $context = null ) {
393  global $post;
394 
395  if ( empty( $post_id ) ) {
396  // DataTables passes the Post ID
397  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
398  $post_id = \GV\Utils::_POST( 'post_id', false );
399  } else {
400  if ( $context instanceof \GV\Template_Context ) {
401  // Shortcodes, embeds
402  if ( is_a( $post, 'WP_Post' ) ) {
403  $post_id = $post->ID;
404 
405  // Actual views
406  } else {
407  $post_id = $context->view ? $context->view->ID : false;
408  }
409  } else {
410  /** @deprecated path of execution */
412 
413  // The Post ID has been passed via the shortcode
414  if ( ! empty( $gravityview_view ) && $gravityview_view->getPostId() ) {
415  $post_id = $gravityview_view->getPostId();
416  } else {
417  // This is a GravityView post type
418  if ( GravityView_frontend::getInstance()->isGravityviewPostType() ) {
419  $post_id = isset( $gravityview_view ) ? $gravityview_view->getViewId() : $post->ID;
420  } else {
421  // This is an embedded GravityView; use the embedded post's ID as the base.
422  if ( GravityView_frontend::getInstance()->isPostHasShortcode() && is_a( $post, 'WP_Post' ) ) {
423  $post_id = $post->ID;
424  } elseif ( $gravityview_view->getViewId() ) {
425  // The GravityView has been embedded in a widget or in a template, and
426  // is not in the current content. Thus, we defer to the View's own ID.
427  $post_id = $gravityview_view->getViewId();
428  }
429  }
430  }
431  }
432  }
433  }
434 
435  // No post ID, get outta here.
436  if ( empty( $post_id ) ) {
437  return null;
438  }
439 
440  // If we've saved the permalink in memory, use it
441  // @since 1.3
442  $link = wp_cache_get( 'gv_directory_link_'.$post_id );
443 
444  if ( (int) $post_id === (int) get_option( 'page_on_front' ) ) {
445  $link = home_url();
446  }
447 
448  if ( empty( $link ) ) {
449  $link = get_permalink( $post_id );
450 
451  // If not yet saved, cache the permalink.
452  // @since 1.3
453  wp_cache_set( 'gv_directory_link_'.$post_id, $link );
454  }
455 
456  // Deal with returning to proper pagination for embedded views
457  if ( $link && $add_query_args ) {
458 
459  $args = array();
460 
461  if( $pagenum = \GV\Utils::_GET( 'pagenum' ) ) {
462  $args['pagenum'] = intval( $pagenum );
463  }
464 
465  if( $sort = \GV\Utils::_GET( 'sort' ) ) {
466  $args['sort'] = $sort;
467  $args['dir'] = \GV\Utils::_GET( 'dir' );
468  }
469 
470  $link = add_query_arg( $args, $link );
471  }
472 
473  /**
474  * @filter `gravityview_directory_link` Modify the URL to the View "directory" context
475  * @since 1.19.4
476  * @param string $link URL to the View's "directory" context (Multiple Entries screen)
477  * @param int $post_id ID of the post to link to. If the View is embedded, it is the post or page ID
478  */
479  $link = apply_filters( 'gravityview_directory_link', $link, $post_id );
480 
481  /**
482  * @filter `gravityview/view/links/directory` Modify the URL to the View "directory" context
483  * @since 2.0
484  * @param string $link URL to the View's "directory" context (Multiple Entries screen)
485  * @param \GV\Template_Context $context
486  */
487  return apply_filters( 'gravityview/view/links/directory', $link, $context );
488  }
489 
490  /**
491  * Calculate an *unique* hash for an entry based on the entry ID
492  *
493  * This allows you to be more discrete as to the number of the entry - if you don't want users to know that you have made a certain number of sales, for example, or that their entry in the giveaway is entry #3.
494  *
495  * The hashed value MUST be unique, otherwise multiple entries will share the same URL, which leads to obvious problems.
496  *
497  * @param int|string $id Entry ID to generate the hash for.
498  * @param array $entry Entry data passed to provide additional information when generating the hash. Optional - don't rely on it being available.
499  * @return string Hashed unique value for entry
500  */
501  private static function get_custom_entry_slug( $id, $entry = array() ) {
502 
503  // Generate an unique hash to use as the default value
504  $slug = substr( wp_hash( $id, 'gravityview'.$id ), 0, 8 );
505 
506  /**
507  * @filter `gravityview_entry_slug` Modify the unique hash ID generated, if you want to improve usability or change the format. This will allow for custom URLs, such as `{entryid}-{first-name}` or even, if unique, `{first-name}-{last-name}`
508  * @param string $hash Existing hash generated by GravityView
509  * @param string $id The entry ID
510  * @param array $entry Entry data array. May be empty.
511  */
512  $slug = apply_filters( 'gravityview_entry_slug', $slug, $id, $entry );
513 
514  // Make sure we have something - use the original ID as backup.
515  if( empty( $slug ) ) {
516  $slug = $id;
517  }
518 
519  return sanitize_title( $slug );
520  }
521 
522  /**
523  * Get the entry slug for the entry. By default, it is the entry ID.
524  *
525  *
526  * @see gravityview_get_entry()
527  * @uses GravityView_API::get_custom_entry_slug() If using custom slug, gets the custom slug value
528  * @since 1.4
529  * @param int|string $id_or_string ID of the entry, or custom slug string
530  * @param array $entry Gravity Forms Entry array, optional. Used only to provide data to customize the `gravityview_entry_slug` filter
531  * @return string Unique slug ID, passed through `sanitize_title()`
532  */
533  public static function get_entry_slug( $id_or_string, $entry = array() ) {
534 
535  /**
536  * Default: use the entry ID as the unique identifier
537  */
538  $slug = $id_or_string;
539 
540  /**
541  * @filter `gravityview_custom_entry_slug` Whether to enable and use custom entry slugs.
542  * @param boolean True: Allow for slugs based on entry values. False: always use entry IDs (default)
543  */
544  $custom = apply_filters( 'gravityview_custom_entry_slug', false );
545 
546  // If we're using custom slug...
547  if ( $custom ) {
548 
549  // Get the entry hash
550  $hash = self::get_custom_entry_slug( $id_or_string, $entry );
551 
552  // Cache the slugs
553  static $cache = array();
554 
555  if ( ! isset( $cache[ $id_or_string ] ) ) {
556  global $wpdb;
557 
558  if ( version_compare( GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) ) {
559  $table = GFFormsModel::get_entry_meta_table_name();
560  $column = 'entry_id';
561  } else {
562  $table = RGFormsModel::get_lead_meta_table_name();
563  $column = 'lead_id';
564  }
565 
566  $results = $wpdb->get_results( $wpdb->prepare( "SELECT $column, meta_value FROM $table WHERE form_id = (SELECT form_id FROM $table WHERE $column = %d LIMIT 1) AND meta_key = 'gravityview_unique_id'", $id_or_string ) );
567 
568  if ( $results ) {
569  $cache = array_replace( $cache, array_combine( wp_list_pluck( $results, $column ), wp_list_pluck( $results, 'meta_value' ) ) );
570  }
571 
572  if ( ! isset( $cache[ $id_or_string ] ) ) {
573  $cache[ $id_or_string ] = false;
574  }
575  }
576 
577  $value = $cache[ $id_or_string ];
578 
579  // If it does have a hash set, and the hash is expected, use it.
580  // This check allows users to change the hash structure using the
581  // gravityview_entry_hash filter and have the old hashes expire.
582  if ( empty( $value ) || $value !== $hash ) {
583  gravityview()->log->debug( 'Setting hash for entry {entry}: {hash}', array( 'entry' => $id_or_string, 'hash' => $hash ) );
584  gform_update_meta( $id_or_string, 'gravityview_unique_id', $hash, \GV\Utils::get( $entry, 'form_id' ) );
585  }
586 
587  $slug = $hash;
588 
589  unset( $value, $hash );
590  }
591 
592  return sanitize_title( $slug );
593  }
594 
595  /**
596  * If using the entry custom slug feature, make sure the new entries have the custom slug created and saved as meta
597  *
598  * Triggered by add_action( 'gform_entry_created', array( 'GravityView_API', 'entry_create_custom_slug' ), 10, 2 );
599  *
600  * @param $entry array Gravity Forms entry object
601  * @param $form array Gravity Forms form object
602  */
603  public static function entry_create_custom_slug( $entry, $form ) {
604  /**
605  * @filter `gravityview_custom_entry_slug` On entry creation, check if we are using the custom entry slug feature and update the meta
606  * @param boolean $custom Should we process the custom entry slug?
607  */
608  $custom = apply_filters( 'gravityview_custom_entry_slug', false );
609  if( $custom ) {
610  // create the gravityview_unique_id and save it
611 
612  // Get the entry hash
613  $hash = self::get_custom_entry_slug( $entry['id'], $entry );
614 
615  gravityview()->log->debug( 'Setting hash for entry {entry_id}: {hash}', array( 'entry_id' => $entry['id'], 'hash' => $hash ) );
616 
617  gform_update_meta( $entry['id'], 'gravityview_unique_id', $hash, \GV\Utils::get( $entry, 'form_id' ) );
618 
619  }
620  }
621 
622 
623 
624 
625  /**
626  * return href for single entry
627  *
628  * @since 1.7.3 Added $add_directory_args parameter
629  * @since 2.7.2 Added $view_id parameter
630  *
631  * @param array|int $entry Entry array or entry ID
632  * @param int|null $post_id If wanting to define the parent post, pass a post ID
633  * @param boolean $add_directory_args True: Add args to help return to directory; False: only include args required to get to entry
634  * @param int $view_id
635  *
636  * @return string Link to the entry with the directory parent slug, or empty string if embedded post or View doesn't exist
637  */
638  public static function entry_link( $entry, $post_id = NULL, $add_directory_args = true, $view_id = 0 ) {
639 
640  if ( ! empty( $entry ) && ! is_array( $entry ) ) {
642  } else if( empty( $entry ) ) {
643  // @deprecated path
645  }
646 
647  // Second parameter used to be passed as $field; this makes sure it's not an array
648  if ( ! is_numeric( $post_id ) ) {
649  $post_id = NULL;
650  }
651 
652  // Get the permalink to the View
653  $directory_link = self::directory_link( $post_id, false );
654 
655  // No post ID? Get outta here.
656  if ( empty( $directory_link ) ) {
657  return '';
658  }
659 
660  $query_arg_name = \GV\Entry::get_endpoint_name();
661 
662  if ( ! empty( $entry['_multi'] ) ) {
663  $entry_slugs = array();
664 
665  foreach ( $entry['_multi'] as $_multi ) {
666 
667  if( $gv_multi = \GV\GF_Entry::from_entry( $_multi ) ) {
668  $entry_slugs[] = $gv_multi->get_slug();
669  } else {
670  // TODO: This path isn't covered by unit tests
671  $entry_slugs[] = \GravityView_API::get_entry_slug( $_multi['id'], $_multi );
672  }
673 
674  unset( $gv_multi );
675 
676  $forms[] = $_multi['form_id'];
677  }
678 
679  $entry_slug = implode( ',', $entry_slugs );
680  } else {
681 
682  // Fallback when
683  if( $gv_entry = \GV\GF_Entry::from_entry( $entry ) ) {
684  $entry_slug = $gv_entry->get_slug();
685  } else {
686  // TODO: This path isn't covered by unit tests
688  }
689 
690  unset( $gv_entry );
691  }
692 
693  if ( get_option('permalink_structure') && !is_preview() ) {
694 
695  $args = array();
696 
697  /**
698  * Make sure the $directory_link doesn't contain any query otherwise it will break when adding the entry slug.
699  * @since 1.16.5
700  */
701  $link_parts = explode( '?', $directory_link );
702 
703  $query = !empty( $link_parts[1] ) ? '?'.$link_parts[1] : '';
704 
705  $directory_link = trailingslashit( $link_parts[0] ) . $query_arg_name . '/'. $entry_slug .'/' . $query;
706 
707  } else {
708 
709  $args = array( $query_arg_name => $entry_slug );
710  }
711 
712  /**
713  * @since 1.7.3
714  */
715  if ( $add_directory_args ) {
716 
717  if ( ! empty( $_GET['pagenum'] ) ) {
718  $args['pagenum'] = intval( $_GET['pagenum'] );
719  }
720 
721  /**
722  * @since 1.7
723  */
724  if ( $sort = \GV\Utils::_GET( 'sort' ) ) {
725  $args['sort'] = $sort;
726  $args['dir'] = \GV\Utils::_GET( 'dir' );
727  }
728 
729  }
730 
731  if( $post_id ) {
732  $passed_post = get_post( $post_id );
733  $views = \GV\View_Collection::from_post( $passed_post );
734  $has_multiple_views = $views->count() > 1;
735  } else {
736  $has_multiple_views = class_exists( 'GravityView_View_Data' ) && GravityView_View_Data::getInstance()->has_multiple_views();
737  }
738 
739  if ( $has_multiple_views ) {
740  $args['gvid'] = $view_id ? $view_id : gravityview_get_view_id();
741  }
742 
743  return add_query_arg( $args, $directory_link );
744 
745  }
746 
747 
748 }
749 
750 
751 // inside loop functions
752 
753 /**
754  * @deprecated Use \GV\Field::get_label()
755  */
756 function gv_label( $field, $entry = NULL ) {
758 }
759 
760 function gv_class( $field, $form = NULL, $entry = array() ) {
762 }
763 
764 /**
765  * Generate a CSS class to be added to the wrapper <div> of a View
766  *
767  * @since 1.5.4
768  * @since 1.16 Added $echo parameter.
769  * @since 2.0 Added $context parameter.
770  *
771  * @param string $passed_css_class Default: `gv-container gv-container-{view id}`. If View is hidden until search, adds ` hidden`
772  * @param boolean $echo Whether to echo the output. Default: true
773  * @param \GV\Template_Context $context The template context.
774  *
775  * @return string CSS class, sanitized by gravityview_sanitize_html_class()
776  */
777 function gv_container_class( $passed_css_class = '', $echo = true, $context = null ) {
778  if ( $context instanceof \GV\Template_Context ) {
779  $hide_until_searched = false;
780  $total_entries = 0;
781  $view_id = 0;
782  if ( $context->view ) {
783  $view_id = $context->view->ID;
784  if( $context->view->settings->get( 'hide_until_searched' ) ) {
785  $hide_until_searched = ( empty( $context->entry ) && ! $context->request->is_search() );
786  }
787  }
788  if ( $context->entries ) {
789  $total_entries = $context->entries->total();
790  } else if ( $context->entry ) {
791  $total_entries = 1;
792  }
793  } else {
794  /** @deprecated legacy execution path */
795  $view_id = GravityView_View::getInstance()->getViewId();
796  $hide_until_searched = GravityView_View::getInstance()->isHideUntilSearched();
797  $total_entries = GravityView_View::getInstance()->getTotalEntries();
798  }
799 
800  $passed_css_class = trim( $passed_css_class );
801 
802  $default_css_class = ! empty( $view_id ) ? sprintf( 'gv-container gv-container-%d', $view_id ) : 'gv-container';
803 
804  if ( $hide_until_searched ) {
805  $default_css_class .= ' hidden';
806  }
807 
808  if ( 0 === $total_entries ) {
809  $default_css_class .= ' gv-container-no-results';
810  }
811 
812  if ( $context instanceof \GV\Template_Context && $context->view ) {
813  $default_css_class .= ' ' . $context->view->settings->get( 'class', '' );
814  }
815 
816  $css_class = trim( $passed_css_class . ' '. $default_css_class );
817 
818  /**
819  * @filter `gravityview/render/container/class` Modify the CSS class to be added to the wrapper <div> of a View
820  * @since 1.5.4
821  * @param[in,out] string $css_class Default: `gv-container gv-container-{view id}`. If View is hidden until search, adds ` hidden`. If the View has no results, adds `gv-container-no-results`
822  * @since 2.0
823  * @param \GV\Template_Context $context The context.
824  */
825  $css_class = apply_filters( 'gravityview/render/container/class', $css_class, $context );
826 
827  $css_class = gravityview_sanitize_html_class( $css_class );
828 
829  if ( $echo ) {
830  echo $css_class;
831  }
832 
833  return $css_class;
834 }
835 
836 /**
837  * @deprecated Use \GV\Field_Template::render()
838  */
839 function gv_value( $entry, $field ) {
840 
842 
843  if( $value === '' ) {
844  /**
845  * @filter `gravityview_empty_value` What to display when a field is empty
846  * @param string $value (empty string)
847  */
848  $value = apply_filters( 'gravityview_empty_value', '' );
849  }
850 
851  return $value;
852 }
853 
854 function gv_directory_link( $post = NULL, $add_pagination = true, $context = null ) {
855  return GravityView_API::directory_link( $post, $add_pagination, $context );
856 }
857 
858 function gv_entry_link( $entry, $post_id = NULL ) {
859  return GravityView_API::entry_link( $entry, $post_id );
860 }
861 
862 function gv_no_results( $wpautop = true, $context = null ) {
863  return GravityView_API::no_results( $wpautop, $context );
864 }
865 
866 /**
867  * Generate HTML for the back link from single entry view
868  * @since 1.0.1
869  * @since 2.0
870  * @param \GV\Template_Context $context The context this link is being displayed from.
871  * @return string|null If no GV post exists, null. Otherwise, HTML string of back link.
872  */
873 function gravityview_back_link( $context = null ) {
874 
875  $href = gv_directory_link( null, true, $context );
876 
877  /**
878  * @filter `gravityview_go_back_url` Modify the back link URL
879  * @since 1.17.5
880  * @see gv_directory_link() Generated the original back link
881  * @param string $href Existing label URL
882  * @deprecated Use `gravityview/template/links/back/url`
883  */
884  $href = apply_filters( 'gravityview_go_back_url', $href );
885 
886  /**
887  * @filter `gravityview/template/links/back/url` Modify the back link URL
888  * @since 2.0
889  * @see gv_directory_link() Generated the original back link
890  * @param string $href Existing label URL
891  * @param \GV\Template_Context The context.
892  */
893  $href = apply_filters( 'gravityview/template/links/back/url', $href, $context );
894 
895  if ( empty( $href ) ) {
896  return NULL;
897  }
898 
899  if ( $context instanceof \GV\Template_Context ) {
900  $view_id = $context->view->ID;
901  $view_label = $context->template->get_back_label();
902  } else {
903  /** @deprecated legacy path */
905  $view_id = $gravityview_view->getViewId();
906  $view_label = $gravityview_view->getBackLinkLabel() ? $gravityview_view->getBackLinkLabel() : false;
907  }
908 
909  /** Default */
910  $label = $view_label ? $view_label : __( '&larr; Go back', 'gravityview' );
911 
912  /**
913  * @filter `gravityview_go_back_label` Modify the back link text
914  * @since 1.0.9
915  * @param string $label Existing label text
916  * @deprecated Use `gravityview/template/links/back/label`
917  */
918  $label = apply_filters( 'gravityview_go_back_label', $label );
919 
920  /**
921  * @filter `gravityview/template/links/back/label` Modify the back link text
922  * @since 2.0
923  * @see gv_directory_link() Generated the original back link
924  * @param string $label Existing label text
925  * @param \GV\Template_Context The context.
926  */
927  $label = apply_filters( 'gravityview/template/links/back/label', $label, $context );
928 
929  /**
930  * @filter `gravityview/template/links/back/atts` Modify the attributes used on the back link anchor tag
931  * @since 2.1
932  * @param array $atts Original attributes, default: [ data-viewid => $view_id ]
933  * @param \GV\Template_Context The context.
934  */
935  $atts = apply_filters( 'gravityview/template/links/back/atts', array( 'data-viewid' => $view_id ), $context );
936 
937  $link = gravityview_get_link( $href, esc_html( $label ), $atts );
938 
939  return $link;
940 }
941 
942 /**
943  * Handle getting values for complex Gravity Forms fields
944  *
945  * If the field is complex, like a product, the field ID, for example, 11, won't exist. Instead,
946  * it will be 11.1, 11.2, and 11.3. This handles being passed 11 and 11.2 with the same function.
947  *
948  * @since 1.0.4
949  * @param array $entry GF entry array
950  * @param string $field_id [description]
951  * @param string $display_value The value generated by Gravity Forms
952  * @return string Value
953  */
955 
956  if( floatval( $field_id ) === floor( floatval( $field_id ) ) ) {
957 
958  // For the complete field value as generated by Gravity Forms
959  return $display_value;
960 
961  } else {
962 
963  // For one part of the address (City, ZIP, etc.)
964  return isset( $entry[ $field_id ] ) ? $entry[ $field_id ] : '';
965 
966  }
967 
968 }
969 
970 /**
971  * Take a passed CSV of terms and generate a linked list of terms
972  *
973  * Gravity Forms passes categories as "Name:ID" so we handle that using the ID, which
974  * is more accurate than checking the name, which is more likely to change.
975  *
976  * @param string $value Existing value
977  * @param string $taxonomy Type of term (`post_tag` or `category`)
978  * @return string CSV of linked terms
979  */
980 function gravityview_convert_value_to_term_list( $value, $taxonomy = 'post_tag' ) {
981 
982  $output = array();
983 
984  if ( is_array( $value ) ) {
985  $terms = array_filter( array_values( $value ), 'strlen' );
986  } else {
987  $terms = explode( ', ', $value );
988  }
989 
990  foreach ($terms as $term_name ) {
991 
992  // If we're processing a category,
993  if( $taxonomy === 'category' ) {
994 
995  // Use rgexplode to prevent errors if : doesn't exist
996  list( $term_name, $term_id ) = rgexplode( ':', $term_name, 2 );
997 
998  // The explode was succesful; we have the category ID
999  if( !empty( $term_id )) {
1000  $term = get_term_by( 'id', $term_id, $taxonomy );
1001  } else {
1002  // We have to fall back to the name
1003  $term = get_term_by( 'name', $term_name, $taxonomy );
1004  }
1005 
1006  } else {
1007  // Use the name of the tag to get the full term information
1008  $term = get_term_by( 'name', $term_name, $taxonomy );
1009  }
1010 
1011  // There's still a tag/category here.
1012  if( $term ) {
1013 
1014  $term_link = get_term_link( $term, $taxonomy );
1015 
1016  // If there was an error, continue to the next term.
1017  if ( is_wp_error( $term_link ) ) {
1018  continue;
1019  }
1020 
1021  $output[] = gravityview_get_link( $term_link, esc_html( $term->name ) );
1022  }
1023  }
1024 
1025  return implode(', ', $output );
1026 }
1027 
1028 /**
1029  * Get the links for post_tags and post_category output based on post ID
1030  * @param int $post_id The ID of the post
1031  * @param boolean $link Add links or no?
1032  * @param string $taxonomy Taxonomy of term to fetch.
1033  * @return string String with terms
1034  */
1035 function gravityview_get_the_term_list( $post_id, $link = true, $taxonomy = 'post_tag' ) {
1036 
1037  $output = get_the_term_list( $post_id, $taxonomy, NULL, ', ' );
1038 
1039  if( empty( $link ) ) {
1040  return strip_tags( $output);
1041  }
1042 
1043  return $output;
1044 
1045 }
1046 
1047 
1048 /**
1049  * Get all views processed so far for the current page load
1050  *
1051  * @see GravityView_View_Data::add_view()
1052  * @return array Array of View data, each View data with `id`, `view_id`, `form_id`, `template_id`, `atts`, `fields`, `widgets`, `form` keys.
1053  */
1055 
1057 
1058  // Solve problem when loading content via admin-ajax.php
1059  if( ! $fe->getGvOutputData() ) {
1060 
1061  gravityview()->log->debug( 'gv_output_data not defined; parsing content.' );
1062 
1063  $fe->parse_content();
1064  }
1065 
1066  // Make 100% sure that we're dealing with a properly called situation
1067  if( !is_a( $fe->getGvOutputData(), 'GravityView_View_Data' ) ) {
1068 
1069  gravityview()->log->debug( 'gv_output_data not an object or get_view not callable.', array( 'data' => $fe->getGvOutputData() ) );
1070 
1071  return array();
1072  }
1073 
1074  return $fe->getGvOutputData()->get_views();
1075 }
1076 
1077 /**
1078  * Get data for a specific view
1079  *
1080  * @deprecated use \GV\View API instead
1081  * @since 2.5
1082  *
1083  * @see GravityView_View_Data::get_view()
1084  * @return array View data with `id`, `view_id`, `form_id`, `template_id`, `atts`, `fields`, `widgets`, `form` keys.
1085  */
1087  if ( $view_id ) {
1088  if ( $view = \GV\View::by_id( $view_id ) ) {
1089  return $view; // implements ArrayAccess
1090  }
1091  return array();
1092  }
1093 
1095 
1096  // If not set, grab the current view ID
1097  if ( empty( $view_id ) ) {
1098  $view_id = $fe->get_context_view_id();
1099  }
1100 
1101  if ( ! $fe->getGvOutputData() ) { return array(); }
1102 
1103  return $fe->getGvOutputData()->get_view( $view_id );
1104 }
1105 
1106 // Templates' hooks
1108  /**
1109  * @action `gravityview/template/before` Append content to the view.
1110  * @param object $gravityview The $gravityview object available in templates.
1111  */
1112  if ( count( $args = func_get_args() ) ) {
1113  $gravityview = reset( $args );
1114  if ( $gravityview instanceof \GV\Template_Context ) {
1115  /**
1116  * @action `gravityview/template/before` Prepend content to the view.
1117  * @param \GV\Template_Context $gravityview The $gravityview object available in templates.
1118  */
1119  do_action( 'gravityview/template/before', $gravityview );
1120 
1121  /**
1122  * @deprecated Use `gravityview/template/before`
1123  */
1124  return do_action( 'gravityview_before', $gravityview->view->ID );
1125  }
1126  }
1127 
1128  /**
1129  * @action `gravityview_before` Prepend content to the View container `<div>`
1130  * @deprecated Use `gravityview/template/before`.
1131  * @param int $view_id The ID of the View being displayed
1132  */
1133  do_action( 'gravityview_before', gravityview_get_view_id() );
1134 }
1135 
1137  /**
1138  * @action `gravityview/template/header` Append content to the view.
1139  * @param object $gravityview The $gravityview object available in templates.
1140  */
1141  if ( count( $args = func_get_args() ) ) {
1142  $gravityview = reset( $args );
1143  if ( $gravityview instanceof \GV\Template_Context ) {
1144  /**
1145  * @action `gravityview/template/header` Prepend content to the view container <div>.
1146  * @param \GV\Template_Context $gravityview The $gravityview object available in templates.
1147  */
1148  do_action( 'gravityview/template/header', $gravityview );
1149 
1150  /**
1151  * @deprecated Use `gravityview/template/header`
1152  */
1153  return do_action( 'gravityview_header', $gravityview->view->ID );
1154  }
1155  }
1156 
1157  /**
1158  * @action `gravityview_header` Prepend content to the View container `<div>`
1159  * @deprecated Use `gravityview/template/header`.
1160  * @param int $view_id The ID of the View being displayed
1161  */
1162  do_action( 'gravityview_header', gravityview_get_view_id() );
1163 }
1164 
1166  /**
1167  * @action `gravityview/template/footer` Append content to the view.
1168  * @param object $gravityview The $gravityview object available in templates.
1169  */
1170  if ( count( $args = func_get_args() ) ) {
1171  $gravityview = reset( $args );
1172  if ( $gravityview instanceof \GV\Template_Context ) {
1173  /**
1174  * @action `gravityview/template/footer` Prepend outside of the view container <div>.
1175  * @param \GV\Template_Context $gravityview The $gravityview object available in templates.
1176  */
1177  do_action( 'gravityview/template/footer', $gravityview );
1178 
1179  /**
1180  * @deprecated Use `gravityview/template/footer`
1181  */
1182  return do_action( 'gravityview_footer', $gravityview->view->ID );
1183  }
1184  }
1185 
1186  /**
1187  * @action `gravityview_after` Display content after a View. Used to render footer widget areas. Rendered outside the View container `<div>`
1188  * @deprecated Use `gravityview/template/footer`.
1189  * @param int $view_id The ID of the View being displayed
1190  */
1191  do_action( 'gravityview_footer', gravityview_get_view_id() );
1192 }
1193 
1194 function gravityview_after() {
1195  if ( count( $args = func_get_args() ) ) {
1196  $gravityview = reset( $args );
1197  if ( $gravityview instanceof \GV\Template_Context ) {
1198  /**
1199  * @action `gravityview/template/after` Append content to the view.
1200  * @param \GV\Template_Context $gravityview The $gravityview object available in templates.
1201  */
1202  do_action( 'gravityview/template/after', $gravityview );
1203 
1204  /**
1205  * @deprecated Use `gravityview/template/after`
1206  */
1207  do_action( 'gravityview_after', $gravityview->view->ID );
1208 
1209  return;
1210  }
1211  }
1212 
1213  /**
1214  * @action `gravityview_after` Append content to the View container `<div>`
1215  * @deprecated Use `gravityview/template/after`
1216  * @param int $view_id The ID of the View being displayed
1217  */
1218  do_action( 'gravityview_after', gravityview_get_view_id() );
1219 }
1220 
1221 /**
1222  * Get the current View ID being rendered
1223  *
1224  * @global GravityView_View $gravityview_view
1225  *
1226  * @return int View ID, if exists. `0` if `GravityView_View` doesn't exist, like in the admin, or no View is set.
1227  */
1229 
1230  if ( ! class_exists( 'GravityView_View' ) ) {
1231  return 0;
1232  }
1233 
1234  return GravityView_View::getInstance()->getViewId();
1235 }
1236 
1237 /**
1238  * Returns the current GravityView context, or empty string if not GravityView
1239  *
1240  * - Returns empty string on GravityView archive pages
1241  * - Returns empty string on archive pages containing embedded Views
1242  * - Returns empty string for embedded Views, not 'directory'
1243  * - Returns empty string for embedded entries (oEmbed or [gventry]), not 'single'
1244  * - Returns 'single' when viewing a [gravityview] shortcode-embedded single entry
1245  *
1246  * @global GravityView_View $gravityview_view
1247  * @deprecated since 2.0.6.2 Use `gravityview()->request`
1248  * @return string View context "directory", "single", "edit", or empty string if not GravityView
1249  */
1251  global $wp_query;
1252 
1253  if ( isset( $wp_query ) && $wp_query->post_count > 1 ) {
1254  return '';
1255  }
1256 
1257  /**
1258  * @filter `gravityview_is_edit_entry` Whether we're currently on the Edit Entry screen \n
1259  * The Edit Entry functionality overrides this value.
1260  * @param boolean $is_edit_entry
1261  */
1262  $is_edit_entry = apply_filters( 'gravityview_is_edit_entry', false );
1263 
1264  if ( $is_edit_entry ) {
1265  return 'edit';
1266  } else if ( gravityview()->request->is_entry() ) {
1267  return 'single';
1268  } else if ( gravityview()->request->is_view() ) {
1269  return 'directory';
1270  }
1271 
1272  return '';
1273 }
1274 
1275 
1276 /**
1277  * Return an array of files prepared for output. Wrapper for GravityView_Field_FileUpload::get_files_array()
1278  *
1279  * Processes files by file type and generates unique output for each.
1280  *
1281  * Returns array for each file, with the following keys:
1282  *
1283  * `file_path` => The file path of the file, with a line break
1284  * `html` => The file output HTML formatted
1285  *
1286  * @see GravityView_Field_FileUpload::get_files_array()
1287  *
1288  * @since 1.2
1289  * @param string $value Field value passed by Gravity Forms. String of file URL, or serialized string of file URL array
1290  * @param string $gv_class Field class to add to the output HTML
1291  * @since 2.0
1292  * @param \GV\Template_Context $context The context
1293  * @return array Array of file output, with `file_path` and `html` keys (see comments above)
1294  */
1295 function gravityview_get_files_array( $value, $gv_class = '', $context = null ) {
1296  /** @define "GRAVITYVIEW_DIR" "../" */
1297 
1298  if( !class_exists( 'GravityView_Field' ) ) {
1299  include_once( GRAVITYVIEW_DIR .'includes/fields/class-gravityview-field.php' );
1300  }
1301 
1302  if( !class_exists( 'GravityView_Field_FileUpload' ) ) {
1303  include_once( GRAVITYVIEW_DIR .'includes/fields/class-gravityview-field-fileupload.php' );
1304  }
1305 
1306  if ( is_null( $context ) ) {
1307  _doing_it_wrong( __FUNCTION__, '2.0', 'Please pass an \GV\Template_Context object as the 3rd parameter' );
1308  }
1309 
1310  return GravityView_Field_FileUpload::get_files_array( $value, $gv_class, $context );
1311 }
1312 
1313 /**
1314  * Generate a mapping link from an address
1315  *
1316  * The address should be plain text with new line (`\n`) or `<br />` line breaks separating sections
1317  *
1318  * @todo use GF's field get_export_value() instead
1319  *
1320  * @see https://gravityview.co/support/documentation/201608159 Read how to modify the link
1321  * @param string $address Address
1322  * @return string URL of link to map of address
1323  */
1324 function gravityview_get_map_link( $address ) {
1325 
1326  $address_qs = str_replace( array( '<br />', "\n" ), ' ', $address ); // Replace \n with spaces
1327  $address_qs = urlencode( $address_qs );
1328 
1329  $url = "https://maps.google.com/maps?q={$address_qs}";
1330 
1331  $link_text = esc_html__( 'Map It', 'gravityview' );
1332 
1333  $link = gravityview_get_link( $url, $link_text, 'class=map-it-link' );
1334 
1335  /**
1336  * @filter `gravityview_map_link` Modify the map link generated. You can use a different mapping service, for example.
1337  * @param[in,out] string $link Map link
1338  * @param[in] string $address Address to generate link for
1339  * @param[in] string $url URL generated by the function
1340  */
1341  $link = apply_filters( 'gravityview_map_link', $link, $address, $url );
1342 
1343  return $link;
1344 }
1345 
1346 
1347 /**
1348  * Output field based on a certain html markup
1349  *
1350  * markup - string to be used on a sprintf statement.
1351  * Use:
1352  * {{label}} - field label
1353  * {{value}} - entry field value
1354  * {{class}} - field class
1355  *
1356  * wpautop - true will filter the value using wpautop function
1357  *
1358  * @since 1.1.5
1359  * @param array $passed_args Associative array with field data. `field` and `form` are required.
1360  * @since 2.0
1361  * @param \GV\Template_Context The template context.
1362  * @return string Field output. If empty value and hide empty is true, return empty.
1363  */
1364 function gravityview_field_output( $passed_args, $context = null ) {
1365  $defaults = array(
1366  'entry' => null,
1367  'field' => null,
1368  'form' => null,
1369  'hide_empty' => true,
1370  'markup' => '<div id="{{ field_id }}" class="{{ class }}">{{ label }}{{ value }}</div>',
1371  'label_markup' => '',
1372  'wpautop' => false,
1373  'zone_id' => null,
1374  );
1375 
1376  $args = wp_parse_args( $passed_args, $defaults );
1377 
1378  /**
1379  * @filter `gravityview/field_output/args` Modify the args before generation begins
1380  * @since 1.7
1381  * @param array $args Associative array; `field` and `form` is required.
1382  * @param array $passed_args Original associative array with field data. `field` and `form` are required.
1383  * @since 2.0
1384  * @param \GV\Template_Context $context The context.
1385  * @deprecated
1386  */
1387  $args = apply_filters( 'gravityview/field_output/args', $args, $passed_args, $context );
1388 
1389  /**
1390  * @filter `gravityview/template/field_output/context` Modify the context before generation begins.
1391  * @since 2.0
1392  * @param[in,out] \GV\Template_Context $context The context.
1393  * @param array $args The sanitized arguments, these should not be trusted any longer.
1394  * @param array $passed_args The passed arguments, these should not be trusted any longer.
1395  */
1396  $context = apply_filters( 'gravityview/template/field_output/context', $context, $args, $passed_args );
1397 
1398  if ( $context instanceof \GV\Template_Context ) {
1399  if ( ! $context->field || ! $context->view || ! $context->view->form ) {
1400  gravityview()->log->error( 'Field or form are empty.', array( 'data' => array( $context->field, $context->view->form ) ) );
1401  return '';
1402  }
1403  } else {
1404  // @deprecated path
1405  // Required fields.
1406  if ( empty( $args['field'] ) || empty( $args['form'] ) ) {
1407  gravityview()->log->error( 'Field or form are empty.', array( 'data' => $args ) );
1408  return '';
1409  }
1410  }
1411 
1412  if ( $context instanceof \GV\Template_Context ) {
1413  $entry = $args['entry'] ? : ( $context->entry ? $context->entry->as_entry() : array() );
1414  $field = $args['field'] ? : ( $context->field ? $context->field->as_configuration() : array() );
1415  $form = $args['form'] ? : ( $context->view->form ? $context->view->form->form : array() );
1416  } else {
1417  // @deprecated path
1418  $entry = empty( $args['entry'] ) ? array() : $args['entry'];
1419  $field = $args['field'];
1420  $form = $args['form'];
1421  }
1422 
1423  /**
1424  * Create the content variables for replacing.
1425  * @since 1.11
1426  */
1427  $placeholders = array(
1428  'value' => '',
1429  'width' => '',
1430  'width:style' => '',
1431  'label' => '',
1432  'label_value' => '',
1433  'label_value:esc_attr' => '',
1434  'label_value:data-label' => '',
1435  'class' => '',
1436  'field_id' => '',
1437  );
1438 
1439  if ( $context instanceof \GV\Template_Context ) {
1440  $placeholders['value'] = \GV\Utils::get( $args, 'value', '' );
1441  } else {
1442  // @deprecated path
1443  $placeholders['value'] = gv_value( $entry, $field );
1444  }
1445 
1446  // If the value is empty and we're hiding empty, return empty.
1447  if ( $placeholders['value'] === '' && ! empty( $args['hide_empty'] ) ) {
1448  return '';
1449  }
1450 
1451  if ( $placeholders['value'] !== '' && ! empty( $args['wpautop'] ) ) {
1452  $placeholders['value'] = wpautop( $placeholders['value'] );
1453  }
1454 
1455  // Get width setting, if exists
1456  $placeholders['width'] = GravityView_API::field_width( $field );
1457 
1458  // If replacing with CSS inline formatting, let's do it.
1459  $placeholders['width:style'] = GravityView_API::field_width( $field, 'width:' . $placeholders['width'] . '%;' );
1460 
1461  // Grab the Class using `gv_class`
1462  $placeholders['class'] = gv_class( $field, $form, $entry );
1463  $placeholders['field_id'] = GravityView_API::field_html_attr_id( $field, $form, $entry );
1464 
1465  if ( $context instanceof \GV\Template_Context ) {
1466  $placeholders['label_value'] = \GV\Utils::get( $args, 'label' );
1467  } else {
1468  // Default Label value
1469  $placeholders['label_value'] = gv_label( $field, $entry );
1470  }
1471 
1472  $placeholders['label_value:data-label'] = trim( esc_attr( strip_tags( str_replace( '>&nbsp;', '>', $placeholders['label_value'] ) ) ) );
1473  $placeholders['label_value:esc_attr'] = esc_attr( $placeholders['label_value'] );
1474 
1475  if ( empty( $placeholders['label'] ) && ! empty( $placeholders['label_value'] ) ){
1476  $placeholders['label'] = '<span class="gv-field-label">{{ label_value }}</span>';
1477  }
1478 
1479  /**
1480  * @filter `gravityview/field_output/pre_html` Allow Pre filtering of the HTML
1481  * @since 1.11
1482  * @param string $markup The HTML for the markup
1483  * @param array $args All args for the field output
1484  * @since 2.0
1485  * @param \GV\Template_Context $context The context.
1486  */
1487  $html = apply_filters( 'gravityview/field_output/pre_html', $args['markup'], $args, $context );
1488 
1489  /**
1490  * @filter `gravityview/field_output/open_tag` Modify the opening tags for the template content placeholders
1491  * @since 1.11
1492  * @param string $open_tag Open tag for template content placeholders. Default: `{{`
1493  * @since 2.0
1494  * @param \GV\Template_Context $context The context.
1495  */
1496  $open_tag = apply_filters( 'gravityview/field_output/open_tag', '{{', $args, $context );
1497 
1498  /**
1499  * @filter `gravityview/field_output/close_tag` Modify the closing tags for the template content placeholders
1500  * @since 1.11
1501  * @param string $close_tag Close tag for template content placeholders. Default: `}}`
1502  * @since 2.0
1503  * @param \GV\Template_Context $context The context.
1504  */
1505  $close_tag = apply_filters( 'gravityview/field_output/close_tag', '}}', $args, $context );
1506 
1507  /**
1508  * Loop through each of the tags to replace and replace both `{{tag}}` and `{{ tag }}` with the values
1509  * @since 1.11
1510  */
1511  foreach ( $placeholders as $tag => $value ) {
1512 
1513  // If the tag doesn't exist just skip it
1514  if ( false === strpos( $html, $open_tag . $tag . $close_tag ) && false === strpos( $html, $open_tag . ' ' . $tag . ' ' . $close_tag ) ){
1515  continue;
1516  }
1517 
1518  // Array to search
1519  $search = array(
1520  $open_tag . $tag . $close_tag,
1521  $open_tag . ' ' . $tag . ' ' . $close_tag,
1522  );
1523 
1524  /**
1525  * `gravityview/field_output/context/{$tag}` Allow users to filter content on context
1526  * @since 1.11
1527  * @param string $value The content to be shown instead of the {{tag}} placeholder
1528  * @param array $args Arguments passed to the function
1529  * @since 2.0
1530  * @param \GV\Template_Context $context The context.
1531  */
1532  $value = apply_filters( 'gravityview/field_output/context/' . $tag, $value, $args, $context );
1533 
1534  // Finally do the replace
1535  $html = str_replace( $search, $value, $html );
1536  }
1537 
1538  /**
1539  * @filter `gravityview_field_output` Modify field HTML output
1540  * @param string $html Existing HTML output
1541  * @param array $args Arguments passed to the function
1542  * @since 2.0
1543  * @param \GV\Template_Context $context The context.
1544  */
1545  $html = apply_filters( 'gravityview_field_output', $html, $args, $context );
1546 
1547  /**
1548  * @filter `gravityview/field_output/html` Modify field HTML output
1549  * @param string $html Existing HTML output
1550  * @param array $args Arguments passed to the function
1551  * @since 2.0
1552  * @param \GV\Template_Context $context The context.
1553  */
1554  $html = apply_filters( 'gravityview/field_output/html', $html, $args, $context );
1555 
1556  /** @since 2.0.8 Remove unused atts */
1557  $html = str_replace( array( ' style=""', ' class=""', ' id=""' ), '', $html );
1558 
1559  return $html;
1560 }
gravityview_get_view_id()
Get the current View ID being rendered.
Definition: class-api.php:1228
const GRAVITYVIEW_DIR
"GRAVITYVIEW_DIR" "./" The absolute path to the plugin directory, with trailing slash ...
Definition: gravityview.php:40
$url
Definition: post_image.php:25
gv_value( $entry, $field)
Definition: class-api.php:839
gv_no_results( $wpautop=true, $context=null)
Definition: class-api.php:862
static no_results( $wpautop=true, $context=null)
Get the "No Results" text depending on whether there were results.
Definition: class-api.php:295
static _GET( $name, $default=null)
Grab a value from the _GET superglobal or default.
$forms
Definition: data-source.php:19
gravityview_get_field_value( $entry, $field_id, $display_value)
Handle getting values for complex Gravity Forms fields.
Definition: class-api.php:954
global $post
Definition: edit-entry.php:7
static getInstance( $passed_post=NULL)
gravityview_get_files_array( $value, $gv_class='', $context=null)
Return an array of files prepared for output.
Definition: class-api.php:1295
gv_directory_link( $post=NULL, $add_pagination=true, $context=null)
Definition: class-api.php:854
gravityview_get_the_term_list( $post_id, $link=true, $taxonomy='post_tag')
Get the links for post_tags and post_category output based on post ID.
Definition: class-api.php:1035
gravityview_after()
Definition: class-api.php:1194
static getInstance( $passed_post=NULL)
Definition: class-data.php:120
gravityview_get_map_link( $address)
Generate a mapping link from an address.
Definition: class-api.php:1324
if(gv_empty( $field['value'], false, false)) $format
$display_value
gravityview_footer()
Definition: class-api.php:1165
gravityview_get_current_view_data( $view_id=0)
Get data for a specific view.
Definition: class-api.php:1086
$field_settings['content']
Definition: custom.php:27
static replace_variables( $text, $form=array(), $entry=array(), $url_encode=false, $esc_html=true, $nl2br=true, $format='html', $aux_data=array())
Alias for GFCommon::replace_variables()
gravityview_get_link( $href='', $anchor_text='', $atts=array())
Generate an HTML anchor tag with a list of supported attributes.
static from_post(\WP_Post $post)
Get a list of objects inside the supplied .
gravityview()
Definition: _stubs.php:26
GravityView_API_field_value( $entry, $field_settings, $format)
The old function does a bit too much, not only does it retrieve the value for a field, but it also renders some output.
Definition: _mocks.php:144
get( $key, $default=null)
Retrieve a setting.
static get_custom_entry_slug( $id, $entry=array())
Calculate an unique hash for an entry based on the entry ID.
Definition: class-api.php:501
static entry_create_custom_slug( $entry, $form)
If using the entry custom slug feature, make sure the new entries have the custom slug created and sa...
Definition: class-api.php:603
gravityview_back_link( $context=null)
Generate HTML for the back link from single entry view.
Definition: class-api.php:873
static directory_link( $post_id=NULL, $add_query_args=true, $context=null)
Generate a URL to the Directory context.
Definition: class-api.php:392
gv_container_class( $passed_css_class='', $echo=true, $context=null)
Generate a CSS class to be added to the wrapper of a View.
Definition: class-api.php:777
$link
static get_endpoint_name()
Return the endpoint name for a single Entry.
static get_files_array( $value, $gv_class, $context=null)
Return an array of files prepared for output.
static field_html_attr_id( $field, $form=array(), $entry=array())
Fetch Field HTML ID.
Definition: class-api.php:209
static entry_link_html( $entry=array(), $anchor_text='', $passed_tag_atts=array(), $field_settings=array(), $base_id=null)
Generate an anchor tag that links to an entry.
Definition: class-api.php:259
static field_value( $entry, $field_settings, $format='html')
Given an entry and a form field id, calculate the entry value for that field.
Definition: class-api.php:238
gravityview_header()
Definition: class-api.php:1136
$field_id
Definition: time.php:17
gravityview_convert_value_to_term_list( $value, $taxonomy='post_tag')
Take a passed CSV of terms and generate a linked list of terms.
Definition: class-api.php:980
static field_width( $field, $format='%d%%')
Get column width from the field setting.
Definition: class-api.php:132
gv_label( $field, $entry=NULL)
Definition: class-api.php:756
static replace_variables( $text, $form=array(), $entry=array(), $url_encode=false, $esc_html=true, $nl2br=true, $format='html', $aux_data=array())
Alias for GravityView_Merge_Tags::replace_variables()
Definition: class-api.php:118
gv_class( $field, $form=NULL, $entry=array())
Definition: class-api.php:760
if(empty( $created_by)) $form_id
GravityView_API_field_label( $form, $field_settings, $entry, $force_show_label=false)
Mock out the ::field_label method.
Definition: _mocks.php:214
static get_entry_slug( $id_or_string, $entry=array())
Get the entry slug for the entry.
Definition: class-api.php:533
static get( $array, $key, $default=null)
Grab a value from an array or an object or default.
gv_entry_link( $entry, $post_id=NULL)
Definition: class-api.php:858
gravityview_get_context()
Returns the current GravityView context, or empty string if not GravityView.
Definition: class-api.php:1250
static field_class( $field, $form=NULL, $entry=NULL)
Fetch Field class.
Definition: class-api.php:157
$entry_slug
Definition: notes.php:30
static get_entry( $entry_slug, $force_allow_ids=false, $check_entry_display=true, $view=null)
Return a single entry object.
gravityview_field_output( $passed_args, $context=null)
Output field based on a certain html markup.
Definition: class-api.php:1364
$entry
Definition: notes.php:27
static entry_link( $entry, $post_id=NULL, $add_directory_args=true, $view_id=0)
return href for single entry
Definition: class-api.php:638
gravityview_before()
Definition: class-api.php:1107
$field
Definition: gquiz_grade.php:11
static _POST( $name, $default=null)
Grab a value from the _POST superglobal or default.
static field_label( $field, $entry=array(), $force_show_label=false)
Fetch Field Label.
Definition: class-api.php:27
static getInstance()
Get the one true instantiated self.
gravityview_get_current_views()
Get all views processed so far for the current page load.
Definition: class-api.php:1054