File: /volume1/web/qrcodesforeveryone/wp-content/plugins/gravityview/src/API/class-api.php
<?php
/**
* GravityView template tags API
*
* @package GravityView
* @license GPL2+
* @author GravityKit <hello@gravitykit.com>
* @link http://www.gravitykit.com
* @copyright Copyright 2014, Katz Web Services, Inc.
*
* @since 1.0.0
*/
if ( ! class_exists( 'GravityView_API', false ) ) :
/**
* Legacy API class alias for backward compatibility.
*
* Keeps the historical GravityView_API class name available while delegating
* behavior to the PSR-4 API implementation.
*
* @since 3.0.0
*/
class GravityView_API extends \GravityKit\GravityView\API\API {
}
endif; // class_exists guard.
/**
* Returns query parameters from $_GET with reserved internal GravityView keys removed
*
* @uses stripslashes_deep() $_GET is passed through stripslashes_deep().
* @uses urldecode_deep() $_GET is passed through urldecode_deep().
*
* Important: The return value of gv_get_query_args() is not escaped by default. Output should be
* late-escaped with esc_url() or similar to help prevent vulnerability to cross-site scripting
* (XSS) attacks.
*
* @since 2.10
*
* @return array
*/
function gv_get_query_args() { // phpcs:ignore Universal.Files.SeparateFunctionsFromOO.Mixed -- The legacy class alias and the template tag functions ship together for backward compatibility.
$passed_get = isset( $_GET ) ? $_GET : array(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only access to build query args; callers are documented as responsible for late escaping.
$passed_get = stripslashes_deep( $passed_get );
$passed_get = urldecode_deep( $passed_get );
if ( empty( $passed_get ) ) {
return array();
}
$query_args = $passed_get;
$reserved_args = array(
'entry',
'gvid',
'status',
'action',
'view_id',
'entry_id',
'pagenum',
'gv_updated',
);
// Per-View pagination keys are internal state, like the base `pagenum` above. Registering them
// before the filter runs lets callbacks see them and un-reserve them, same as the base key.
$scoped_pagination_keys = \GravityKit\GravityView\Pagination\PaginationKeys::scoped_keys_in( $query_args );
$reserved_args = array_merge( $reserved_args, $scoped_pagination_keys );
/**
* Modify the URL arguments that should not be used because they are internal to GravityView.
*
* @since 2.10
* @since TBD The list includes any `pagenum_{View ID}` per-View pagination keys present in the request.
* @param array $reserved_args Array of URL query keys that should not be used except internally.
*/
$reserved_args = apply_filters( 'gravityview/api/reserved_query_args', $reserved_args );
foreach ( $reserved_args as $reserved_arg ) {
unset( $query_args[ $reserved_arg ] );
}
return $query_args;
}
// inside loop functions.
/**
* Returns the label for a field, generated by GravityView_API::field_label().
*
* @deprecated 3.0.0 \GV\Field::get_label()
*
* @param array $field GravityView field array.
* @param array|null $entry Gravity Forms entry array.
*/
function gv_label( $field, $entry = null ) {
return GravityView_API::field_label( $field, $entry );
}
/**
* Returns the CSS class for a field, generated by GravityView_API::field_class().
*
* @param array $field GravityView field array.
* @param array|null $form Gravity Forms form array.
* @param array $entry Gravity Forms entry array.
*/
function gv_class( $field, $form = null, $entry = array() ) {
return GravityView_API::field_class( $field, $form, $entry );
}
/**
* Generate a CSS class to be added to the wrapper <div> of a View
*
* @since 1.5.4
* @since 1.16 Added $echo parameter.
* @since 2.0 Added $context parameter.
*
* @param string $passed_css_class Default: `gv-container gv-container-{view id}`. If View is hidden until search, adds ` hidden`.
* @param boolean $echo Whether to echo the output. Default: true.
* @param \GV\Template_Context $context The template context.
*
* @return string CSS class, sanitized by gravityview_sanitize_html_class()
*/
function gv_container_class( $passed_css_class = '', $echo = true, $context = null ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.echoFound -- Renaming the parameter could break PHP 8 named-argument callers of this template tag.
if ( $context instanceof \GV\Template_Context ) {
$hide = false;
$total_entries = 0;
$view_id = 0;
if ( $context->view ) {
$view_id = $context->view->ID;
if ( $context->view->settings->get( 'hide_until_searched' ) ) {
$hide = ( empty( $context->entry ) && ! $context->request->is_search() );
}
}
if ( $context->entries ) {
$total_entries = $context->entries->total();
} elseif ( $context->entry ) {
$total_entries = 1;
}
} else {
/** @deprecated 3.0.0 execution path */
$view_id = GravityView_View::getInstance()->getViewId();
$hide = GravityView_View::getInstance()->isHideUntilSearched();
$total_entries = GravityView_View::getInstance()->getTotalEntries();
}
$passed_css_class = trim( $passed_css_class );
$default_css_class = ! empty( $view_id ) ? sprintf( 'gv-container gv-container-%d', $view_id ) : 'gv-container';
// `gv-themed` is stamped on the View container here, and on the
// per-View `gv-template-*` wrapper by
// `Frontend::add_theme_class_to_wrapper()`, so both same-element
// compounds (`.gv-table-container.gv-themed`) and descendant rules
// (`.gv-themed .gv-widget-search`) resolve per-View. Added BEFORE the
// `gravityview/render/container/class` filter fires so sites that
// strip `gv-container` still keep the theme marker.
//
// Two paths qualify a View for the marker:
// 1. The View's `theme` setting is a non-legacy theme (normal frontend).
// 2. The `gk/gravityview/theme/force-active` filter returns
// true: surfaces that need the theme stack to apply during
// transient state hook this so token / grid / Custom CSS edits
// reflect before the customer hits Save.
$theme = $context instanceof \GV\Template_Context && $context->view
? (string) $context->view->settings->get( 'theme', 'legacy' )
: 'legacy';
$is_themed_view = 'legacy' !== $theme;
/**
* Force the theme stack onto a View regardless of its saved
* `theme` setting.
*
* Returning true stamps `.gv-themed` on the View container AND
* enqueues the theme stylesheet (the `Frontend.php` enqueue gate
* reads the same filter). Returning false defers to the saved
* setting (the default).
*
* @since TBD
*
* @param bool $force_active Default false.
* @param \GV\Template_Context|null $context Render context, or null.
*/
$force_active = (bool) apply_filters(
'gk/gravityview/theme/force-active',
false,
$context instanceof \GV\Template_Context ? $context : null
);
if ( $is_themed_view || $force_active ) {
$theme_slug = 'legacy' !== $theme ? $theme : 'vantage';
$default_css_class .= ' gv-themed gv-theme-' . $theme_slug;
}
if ( 0 === $total_entries ) {
$default_css_class .= ' gv-container-no-results';
if (
! gravityview()->request->is_search()
&& $context instanceof \GV\Template_Context
&& 3 === (int) $context->view->settings->get( 'no_entries_options', '0' )
) {
$hide = true;
}
}
if ( $hide ) {
$default_css_class .= ' gv-hidden';
}
if ( $context instanceof \GV\Template_Context && $context->view ) {
$default_css_class .= ' ' . $context->view->settings->get( 'class', '' );
}
$css_class = trim( $passed_css_class . ' ' . $default_css_class );
/**
* Modify the CSS class to be added to the wrapper div of a View.
*
* @since 1.5.4
* @param 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`
* @since 2.0
* @param \GV\Template_Context $context The context.
*/
$css_class = apply_filters( 'gravityview/render/container/class', $css_class, $context );
$css_class = gravityview_sanitize_html_class( $css_class );
if ( $echo ) {
echo $css_class; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Sanitized with gravityview_sanitize_html_class() immediately above.
}
return $css_class;
}
/**
* Checks whether a non-legacy theme applies to a View.
*
* Returns true when the View's `theme` setting is a non-legacy theme or when
* the `gk/gravityview/theme/force-active` filter forces the stack
* on. This is the supported detection API for themes and integrations that
* need to branch on the themed front-end, and it matches the gate
* `gv_container_class()` uses to stamp the `gv-themed` marker class on the
* View container.
*
* When called without a View on a page that renders multiple Views, returns
* true if any of those Views qualifies.
*
* @api
* @since TBD
*
* @param \GV\View|int|string|null $view The View, a View ID, or null to detect
* the current View from context.
*
* @return bool True when a non-legacy theme applies.
*/
function gravityview_is_themed( $view = null ) {
if ( ! $view instanceof \GV\View ) {
$view = gravityview()->views->get( $view );
}
$is_themed = false;
if ( $view instanceof \GV\View_Collection ) {
foreach ( $view->all() as $single_view ) {
if ( $single_view instanceof \GV\View && 'legacy' !== (string) $single_view->settings->get( 'theme', 'legacy' ) ) {
$is_themed = true;
break;
}
}
$view = null;
} elseif ( $view instanceof \GV\View ) {
$is_themed = 'legacy' !== (string) $view->settings->get( 'theme', 'legacy' );
} else {
$view = null;
}
if ( $is_themed ) {
return true;
}
/** This filter is documented in src/Frontend/Frontend.php */
return (bool) apply_filters( 'gk/gravityview/theme/force-active', false, $view );
}
/**
* Returns the field value for an entry, generated by GravityView_API::field_value().
*
* @deprecated 3.0.0 \GV\Field_Template::render()
*
* @param array $entry Gravity Forms entry array.
* @param array $field GravityView field array.
*/
function gv_value( $entry, $field ) {
$value = GravityView_API::field_value( $entry, $field );
if ( '' === $value ) {
/**
* What to display when a field is empty.
*
* @param string $value (empty string)
*/
$value = apply_filters( 'gravityview_empty_value', '' );
}
return $value;
}
/**
* Returns the URL to the Multiple Entries (directory) context of a View.
*
* @see GravityView_API::directory_link()
*
* @param int|null $post Post ID to link to. Defaults to the current post.
* @param bool $add_pagination Whether to include pagination in the URL.
* @param \GV\Template_Context|null $context The template context.
*/
function gv_directory_link( $post = null, $add_pagination = true, $context = null ) {
return GravityView_API::directory_link( $post, $add_pagination, $context );
}
/**
* Returns the URL to the Single Entry context of an entry.
*
* @see GravityView_API::entry_link()
*
* @param array $entry Gravity Forms entry array.
* @param int|null $post_id Post ID to link to. Defaults to the current post.
*/
function gv_entry_link( $entry, $post_id = null ) {
return GravityView_API::entry_link( $entry, $post_id );
}
/**
* Returns the "no results" text for a View.
*
* @see GravityView_API::no_results()
*
* @param bool $wpautop Whether to apply wpautop() to the output.
* @param \GV\Template_Context|null $context The template context.
*/
function gv_no_results( $wpautop = true, $context = null ) {
return GravityView_API::no_results( $wpautop, $context );
}
/**
* Generate HTML for the back link from single entry view
*
* @since 1.0.1
* @since 2.0
* @param \GV\Template_Context $context The context this link is being displayed from.
* @return string|null If no GV post exists, null. Otherwise, HTML string of back link.
*/
function gravityview_back_link( $context = null ) {
$href = gv_directory_link( null, true, $context );
/**
* Modify the back link URL.
*
* @since 1.17.5
* @see gv_directory_link() Generated the original back link
* @param string $href Existing label URL
*/
$href = GravityView_Deprecated_Hook_Notices::apply_filters( 'gravityview_go_back_url', [ $href ], '2.55', 'gravityview/template/links/back/url' );
/**
* Modify the back link URL.
*
* @since 2.0
* @see gv_directory_link() Generated the original back link
* @param string $href Existing label URL
* @param \GV\Template_Context The context.
*/
$href = apply_filters( 'gravityview/template/links/back/url', $href, $context );
if ( empty( $href ) ) {
return null;
}
if ( $context instanceof \GV\Template_Context ) {
$view_id = $context->view->ID;
$view_label = $context->template->get_back_label();
} else {
/** @deprecated 3.0.0 path */
$gravityview_view = GravityView_View::getInstance();
$view_id = $gravityview_view->getViewId();
$view_label = $gravityview_view->getBackLinkLabel() ? $gravityview_view->getBackLinkLabel() : false;
}
/** Default */
$label = $view_label ? $view_label : __( '← Go back', 'gk-gravityview' );
/**
* Modify the back link text.
*
* @since 1.0.9
* @param string $label Existing label text
*/
$label = GravityView_Deprecated_Hook_Notices::apply_filters( 'gravityview_go_back_label', [ $label ], '2.55', 'gravityview/template/links/back/label' );
/**
* Modify the back link text.
*
* @since 2.0
* @see gv_directory_link() Generated the original back link
* @param string $label Existing label text
* @param \GV\Template_Context The context.
*/
$label = apply_filters( 'gravityview/template/links/back/label', $label, $context );
/**
* Modify the attributes used on the back link anchor tag.
*
* @since 2.1
* @param array $atts Original attributes, default: [ data-viewid => $view_id ]
* @param \GV\Template_Context The context.
*/
$atts = apply_filters( 'gravityview/template/links/back/atts', array( 'data-viewid' => $view_id ), $context );
$link = gravityview_get_link( $href, esc_html( $label ), $atts );
return $link;
}
/**
* Handle getting values for complex Gravity Forms fields
*
* If the field is complex, like a product, the field ID, for example, 11, won't exist. Instead,
* it will be 11.1, 11.2, and 11.3. This handles being passed 11 and 11.2 with the same function.
*
* @since 1.0.4
* @param array $entry GF entry array.
* @param string $field_id The field ID, which may include an input part (for example, 11 or 11.2).
* @param string $display_value The value generated by Gravity Forms.
* @return string Value
*/
function gravityview_get_field_value( $entry, $field_id, $display_value ) {
if ( floatval( $field_id ) === floor( floatval( $field_id ) ) ) {
// For the complete field value as generated by Gravity Forms.
return $display_value;
} else {
// For one part of the address (City, ZIP, etc.).
return isset( $entry[ $field_id ] ) ? $entry[ $field_id ] : '';
}
}
/**
* Take a passed CSV of terms and generate a linked list of terms
*
* Gravity Forms passes categories as "Name:ID" so we handle that using the ID, which
* is more accurate than checking the name, which is more likely to change.
*
* @param string $value Existing value.
* @param string $taxonomy Type of term (`post_tag` or `category`).
* @return string CSV of linked terms
*/
function gravityview_convert_value_to_term_list( $value, $taxonomy = 'post_tag' ) {
$output = array();
if ( is_array( $value ) ) {
$terms = array_filter( array_values( $value ), 'strlen' );
} else {
$terms = explode( ', ', $value );
}
foreach ( $terms as $term_name ) {
// If we're processing a category.
if ( 'category' === $taxonomy ) {
// Use rgexplode to prevent errors if : doesn't exist.
list( $term_name, $term_id ) = rgexplode( ':', $term_name, 2 );
// The explode was succesful; we have the category ID.
if ( ! empty( $term_id ) ) {
$term = get_term_by( 'id', $term_id, $taxonomy );
} else {
// We have to fall back to the name.
$term = get_term_by( 'name', $term_name, $taxonomy );
}
} else {
// Use the name of the tag to get the full term information.
$term = get_term_by( 'name', $term_name, $taxonomy );
}
// There's still a tag/category here.
if ( $term ) {
$term_link = get_term_link( $term, $taxonomy );
// If there was an error, continue to the next term.
if ( is_wp_error( $term_link ) ) {
continue;
}
$output[] = gravityview_get_link( $term_link, esc_html( $term->name ) );
}
}
return implode( ', ', $output );
}
/**
* Get the links for post_tags and post_category output based on post ID
*
* @param int $post_id The ID of the post.
* @param boolean $link Whether to add links to the terms.
* @param string $taxonomy Taxonomy of term to fetch.
* @return string String with terms
*/
function gravityview_get_the_term_list( $post_id, $link = true, $taxonomy = 'post_tag' ) {
$output = get_the_term_list( $post_id, $taxonomy, null, ', ' );
if ( empty( $link ) ) {
return wp_strip_all_tags( $output );
}
return $output;
}
/**
* Get all views processed so far for the current page load
*
* @see GravityView_View_Data::add_view()
* @return array Array of View data, each View data with `id`, `view_id`, `form_id`, `template_id`, `atts`, `fields`, `widgets`, `form` keys.
*/
function gravityview_get_current_views() {
$fe = GravityView_frontend::getInstance();
// Solve problem when loading content via admin-ajax.php.
if ( ! $fe->getGvOutputData() ) {
\gravityview()->log->debug( 'gv_output_data not defined; parsing content.' );
$fe->parse_content();
}
// Make 100% sure that we're dealing with a properly called situation.
if ( ! is_a( $fe->getGvOutputData(), 'GravityView_View_Data' ) ) {
\gravityview()->log->debug( 'gv_output_data not an object or get_view not callable.', array( 'data' => $fe->getGvOutputData() ) );
return array();
}
return $fe->getGvOutputData()->get_views();
}
/**
* Get data for a specific view
*
* @deprecated 3.0.0 \GV\View API instead
* @since 2.5
*
* @see GravityView_View_Data::get_view()
*
* @param int $view_id The View ID. Default: 0 (uses the current View).
*
* @return array View data with `id`, `view_id`, `form_id`, `template_id`, `atts`, `fields`, `widgets`, `form` keys.
*/
function gravityview_get_current_view_data( $view_id = 0 ) {
if ( $view_id ) {
$view = \GV\View::by_id( $view_id );
if ( $view ) {
return $view; // Implements ArrayAccess.
}
return array();
}
$fe = GravityView_frontend::getInstance();
// If not set, grab the current view ID.
if ( empty( $view_id ) ) {
$view_id = $fe->get_context_view_id();
}
if ( ! $fe->getGvOutputData() ) {
return array(); }
return $fe->getGvOutputData()->get_view( $view_id );
}
// Templates' hooks.
/**
* Fires the `gravityview/template/before` action and the deprecated `gravityview_before` action.
*
* Accepts an optional \GV\Template_Context object as the first argument, passed by template files.
*/
function gravityview_before() {
/**
* Append content to the view.
*
* @param object $gravityview The $gravityview object available in templates.
*/
$args = func_get_args();
if ( count( $args ) ) {
$gravityview = reset( $args );
if ( $gravityview instanceof \GV\Template_Context ) {
/**
* Prepend content to the View.
*
* @param \GV\Template_Context $gravityview The $gravityview object available in templates.
*/
do_action( 'gravityview/template/before', $gravityview );
return GravityView_Deprecated_Hook_Notices::do_action( 'gravityview_before', [ $gravityview->view->ID ], '2.55', 'gravityview/template/before' );
}
}
/**
* Prepend content to the View container div.
*
* @param int $view_id The ID of the View being displayed
*/
GravityView_Deprecated_Hook_Notices::do_action( 'gravityview_before', [ gravityview_get_view_id() ], '2.55', 'gravityview/template/before' );
}
/**
* Fires the `gravityview/template/header` action and the deprecated `gravityview_header` action.
*
* Accepts an optional \GV\Template_Context object as the first argument, passed by template files.
*/
function gravityview_header() {
/**
* Append content to the view.
*
* @param object $gravityview The $gravityview object available in templates.
*/
$args = func_get_args();
if ( count( $args ) ) {
$gravityview = reset( $args );
if ( $gravityview instanceof \GV\Template_Context ) {
/**
* Prepend content to the View container div.
*
* @param \GV\Template_Context $gravityview The $gravityview object available in templates.
*/
do_action( 'gravityview/template/header', $gravityview );
return GravityView_Deprecated_Hook_Notices::do_action( 'gravityview_header', [ $gravityview->view->ID ], '2.55', 'gravityview/template/header' );
}
}
/**
* Prepend content to the View container div.
*
* @param int $view_id The ID of the View being displayed
*/
GravityView_Deprecated_Hook_Notices::do_action( 'gravityview_header', [ gravityview_get_view_id() ], '2.55', 'gravityview/template/header' );
}
/**
* Fires the `gravityview/template/footer` action and the deprecated `gravityview_footer` action.
*
* Accepts an optional \GV\Template_Context object as the first argument, passed by template files.
*/
function gravityview_footer() {
/**
* Append content to the view.
*
* @param object $gravityview The $gravityview object available in templates.
*/
$args = func_get_args();
if ( count( $args ) ) {
$gravityview = reset( $args );
if ( $gravityview instanceof \GV\Template_Context ) {
/**
* Prepend outside the View container div.
*
* @param \GV\Template_Context $gravityview The $gravityview object available in templates.
*/
do_action( 'gravityview/template/footer', $gravityview );
/* Documented elsewhere. */
return GravityView_Deprecated_Hook_Notices::do_action( 'gravityview_footer', [ $gravityview->view->ID ], '2.55', 'gravityview/template/footer' );
}
}
/**
* Display content after a View. Used to render footer widget areas. Rendered outside the View container div.
*
* @param int $view_id The ID of the View being displayed
*/
GravityView_Deprecated_Hook_Notices::do_action( 'gravityview_footer', [ gravityview_get_view_id() ], '2.55', 'gravityview/template/footer' );
}
/**
* Fires the `gravityview/template/after` action and the deprecated `gravityview_after` action.
*
* Accepts an optional \GV\Template_Context object as the first argument, passed by template files.
*/
function gravityview_after() {
$args = func_get_args();
if ( count( $args ) ) {
$gravityview = reset( $args );
if ( $gravityview instanceof \GV\Template_Context ) {
/**
* Append content to the View.
*
* @param \GV\Template_Context $gravityview The $gravityview object available in templates.
* @since 2.0
*/
do_action( 'gravityview/template/after', $gravityview );
/* Documented elsewhere. */
GravityView_Deprecated_Hook_Notices::do_action( 'gravityview_after', [ $gravityview->view->ID ], '2.55', 'gravityview/template/after' );
return;
}
}
/**
* Append content to the View container div.
*
* @param int $view_id The ID of the View being displayed
*/
GravityView_Deprecated_Hook_Notices::do_action( 'gravityview_after', [ gravityview_get_view_id() ], '2.55', 'gravityview/template/after' );
}
/**
* Get the current View ID being rendered
*
* Prefers the rendering stack, which tracks the View actually being rendered
* (including embedded and nested Views on multi-View pages); falls back to
* the legacy GravityView_View singleton for code paths that predate the
* renderers.
*
* @global GravityView_View $gravityview_view
*
* @return int View ID, if exists. `0` if `GravityView_View` doesn't exist, like in the admin, or no View is set.
*/
function gravityview_get_view_id() {
$rendering_view_id = \GravityKit\GravityView\View\View::get_current_rendering();
if ( $rendering_view_id ) {
return (int) $rendering_view_id;
}
if ( ! class_exists( \GravityKit\GravityView\View\ViewLegacy::class ) ) {
return 0;
}
return GravityView_View::getInstance()->getViewId();
}
/**
* Returns the current GravityView context, or empty string if not GravityView
*
* - Returns empty string on GravityView archive pages
* - Returns empty string on archive pages containing embedded Views
* - Returns empty string for embedded Views, not 'directory'
* - Returns empty string for embedded entries (oEmbed or [gventry]), not 'single'
* - Returns 'single' when viewing a [gravityview] shortcode-embedded single entry
*
* @global GravityView_View $gravityview_view
* @deprecated 3.0.0 2.0.6.2 Use `gravityview()->request`
* @return string View context "directory", "single", "edit", or empty string if not GravityView
*/
function gravityview_get_context() {
global $wp_query;
if ( isset( $wp_query ) && $wp_query->post_count > 1 ) {
return '';
}
if ( gravityview()->request->is_edit_entry() ) {
return 'edit';
} elseif ( gravityview()->request->is_entry() ) {
return 'single';
} elseif ( gravityview()->request->is_view( false ) ) {
return 'directory';
} elseif ( gravityview()->views->get() ) {
return 'directory';
}
return '';
}
/**
* Return an array of files prepared for output. Wrapper for GravityView_Field_FileUpload::get_files_array()
*
* Processes files by file type and generates unique output for each.
*
* Returns array for each file, with the following keys:
*
* `file_path` => The file path of the file, with a line break
* `html` => The file output HTML formatted
*
* @see GravityView_Field_FileUpload::get_files_array()
*
* @since 1.2
* @param string $value Field value passed by Gravity Forms. String of file URL, or serialized string of file URL array.
* @param string $gv_class Field class to add to the output HTML.
* @since 2.0
* @param \GV\Template_Context $context The context.
* @return array Array of file output, with `file_path` and `html` keys (see comments above)
*/
function gravityview_get_files_array( $value, $gv_class = '', $context = null ) {
/** @define "GRAVITYVIEW_DIR" "../" */
if ( is_null( $context ) ) {
_doing_it_wrong( __FUNCTION__, '2.0', 'Please pass an \GV\Template_Context object as the 3rd parameter' );
}
return GravityView_Field_FileUpload::get_files_array( $value, $gv_class, $context );
}
/**
* Generate a mapping link from an address
*
* The address should be plain text with new line (`\n`) or `<br />` line breaks separating sections
*
* @since 2.14.1 Added $atts parameter
*
* @todo use GF's field get_export_value() instead
*
* @see https://docs.gravitykit.com/article/59-modify-the-map-it-address-link Read how to modify the link
* @param string $address Address.
* @param array $atts Attributes to add to the anchor tag. Default: empty array.
* @return string URL of link to map of address
*/
function gravityview_get_map_link( $address, $atts = array() ) {
$address_qs = str_replace( array( '<br />', "\n" ), ' ', $address ); // Replace \n with spaces.
$address_qs = urlencode( $address_qs ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.urlencode_urlencode -- Switching to rawurlencode() would change the generated map URLs.
$url = "https://maps.google.com/maps?q={$address_qs}";
$link_text = esc_html__( 'Map It', 'gk-gravityview' );
$atts = array_merge(
array(
'class' => 'map-it-link',
),
$atts
);
$link = gravityview_get_link( $url, $link_text, $atts );
/**
* Modify the map link generated. You can use a different mapping service, for example.
*
* @param string $link Map link
* @param string $address Address to generate link for
* @param string $url URL generated by the function
*/
$link = apply_filters( 'gravityview_map_link', $link, $address, $url );
return $link;
}
/**
* Output field based on a certain html markup
*
* Markup - string to be used on a sprintf statement.
* Use:
* {{label}} - field label
* {{value}} - entry field value
* {{class}} - field class
*
* wpautop - true will filter the value using wpautop function
*
* @since 1.1.5
* @param array $passed_args Associative array with field data. `field` and `form` are required.
* @since 2.0
* @param \GV\Template_Context $context The template context.
* @return string Field output. If empty value and hide empty is true, return empty.
*/
function gravityview_field_output( $passed_args, $context = null ) {
$defaults = array(
'entry' => null,
'field' => null,
'form' => null,
'hide_empty' => true,
'markup' => '<div id="{{ field_id }}" class="{{ class }}"{{ style_attr }}>{{ label }}{{ value }}</div>',
'label_markup' => '',
'wpautop' => false,
'zone_id' => null,
);
$args = wp_parse_args( $passed_args, $defaults );
/**
* Modify the args before generation begins.
*
* @since 1.7
* @param array $args Associative array; `field` and `form` is required.
* @param array $passed_args Original associative array with field data. `field` and `form` are required.
* @since 2.0
* @param \GV\Template_Context $context The context.
* @deprecated 3.0.0
*/
$args = GravityView_Deprecated_Hook_Notices::apply_filters( 'gravityview/field_output/args', [ $args, $passed_args, $context ], '2.55', 'gravityview/template/field_output/context', 'To modify field values, use gravityview/field_output/context/{$tag}. To modify the final HTML, use gravityview/field_output/html.' );
/**
* Modify the context before generation begins.
*
* @since 2.0
* @param \GV\Template_Context $context The context.
* @param array $args The sanitized arguments, these should not be trusted any longer.
* @param array $passed_args The passed arguments, these should not be trusted any longer.
*/
$context = apply_filters( 'gravityview/template/field_output/context', $context, $args, $passed_args );
if ( $context instanceof \GV\Template_Context ) {
if ( ! $context->field || ! $context->view || ! $context->view->form ) {
\gravityview()->log->error( 'Field or form are empty.', array( 'data' => array( $context->field, $context->view->form ) ) );
return '';
}
} elseif ( empty( $args['field'] ) || empty( $args['form'] ) ) {
// @deprecated 3.0.0 path; `field` and `form` args are required.
\gravityview()->log->error( 'Field or form are empty.', array( 'data' => $args ) );
return '';
}
if ( $context instanceof \GV\Template_Context ) {
$entry = $args['entry'] ? $args['entry'] : ( $context->entry ? $context->entry->as_entry() : array() );
$field = $args['field'] ? $args['field'] : ( $context->field ? $context->field->as_configuration() : array() );
$form = $args['form'] ? $args['form'] : ( $context->view->form ? $context->view->form->form : array() );
} else {
// @deprecated 3.0.0
$entry = empty( $args['entry'] ) ? array() : $args['entry'];
$field = $args['field'];
$form = $args['form'];
}
/**
* Create the content variables for replacing.
*
* @since 1.11
*/
$placeholders = [
'value' => '',
'width' => '',
'width:style' => '',
'label' => '',
'label_value' => '',
'label_value:esc_attr' => '',
'label_value:data-label' => '',
'class' => '',
'field_id' => '',
'rowspan' => $args['rowspan'] ?? null,
'row' => $args['row'] ?? 0,
];
if ( $context instanceof \GV\Template_Context && array_key_exists( 'value', $args ) ) {
$placeholders['value'] = \GV\Utils::get( $args, 'value', '' );
} else {
// Falls through here when no context is set (deprecated path) or when a context is
// provided without a pre-computed value (legacy renderZone path) — preserves the
// original timing of `gv_value()` relative to the field-output filters.
$placeholders['value'] = gv_value( $entry, $field );
}
// If the value is empty and we're hiding empty, return empty.
if ( '' === $placeholders['value'] && ! empty( $args['hide_empty'] ) ) {
return '';
}
if ( '' !== $placeholders['value'] && ! empty( $args['wpautop'] ) && 'gravityview_view' !== ( $field['id'] ?? '' ) ) {
$placeholders['value'] = wpautop( $placeholders['value'] );
}
// Get width setting, if exists.
$placeholders['width'] = GravityView_API::field_width( $field );
// If replacing with CSS inline formatting, let's do it.
$placeholders['width:style'] = (string) GravityView_API::field_width( $field, 'width:' . $placeholders['width'] . '%;' );
// Grab the Class using `gv_class`.
$placeholders['class'] = gv_class( $field, $form, $entry );
$placeholders['field_id'] = GravityView_API::field_html_attr_id( $field, $form, $entry );
// Per-field inline style overrides were removed; the {{ style_attr }}
// template token always resolves to an empty attribute.
$placeholders['style_attr'] = '';
if ( $context instanceof \GV\Template_Context && array_key_exists( 'label', $args ) ) {
$placeholders['label_value'] = \GV\Utils::get( $args, 'label', '' );
} else {
// Falls through here when no context is set (deprecated path) or when a context is
// provided without a pre-computed label (legacy renderZone path).
$placeholders['label_value'] = gv_label( $field, $entry );
}
$placeholders['label_value:data-label'] = trim( esc_attr( strip_tags( str_replace( '> ', '>', $placeholders['label_value'] ) ) ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions.strip_tags_strip_tags -- wp_strip_all_tags() also removes script and style tag contents, which would change the data-label output.
$placeholders['label_value:esc_attr'] = esc_attr( $placeholders['label_value'] );
if ( empty( $placeholders['label'] ) && ! empty( $placeholders['label_value'] ) ) {
$placeholders['label'] = '<span class="gv-field-label">{{ label_value }}</span>';
}
/**
* Allow Pre filtering of the HTML.
*
* @since 1.11
* @param string $markup The HTML for the markup
* @param array $args All args for the field output
* @since 2.0
* @param \GV\Template_Context $context The context.
*/
$html = apply_filters( 'gravityview/field_output/pre_html', $args['markup'], $args, $context );
/**
* Modify the opening tags for the template content placeholders.
*
* @since 1.11
* @param string $open_tag Open tag for template content placeholders. Default: `{{`
* @since 2.0
* @param \GV\Template_Context $context The context.
*/
$open_tag = apply_filters( 'gravityview/field_output/open_tag', '{{', $args, $context );
/**
* Modify the closing tags for the template content placeholders.
*
* @since 1.11
* @param string $close_tag Close tag for template content placeholders. Default: `}}`
* @since 2.0
* @param \GV\Template_Context $context The context.
*/
$close_tag = apply_filters( 'gravityview/field_output/close_tag', '}}', $args, $context );
/**
* Loop through each of the tags to replace and replace both `{{tag}}` and `{{ tag }}` with the values
*
* @since 1.11
*/
foreach ( $placeholders as $tag => $value ) {
// If the tag doesn't exist just skip it.
if ( false === strpos( $html, $open_tag . $tag . $close_tag ) && false === strpos( $html, $open_tag . ' ' . $tag . ' ' . $close_tag ) ) {
continue;
}
// Array to search.
$search = array(
$open_tag . $tag . $close_tag,
$open_tag . ' ' . $tag . ' ' . $close_tag,
);
/**
* `gravityview/field_output/context/{$tag}` Allow users to filter content on context
*
* @since 1.11
* @param string $value The content to be shown instead of the {{tag}} placeholder
* @param array $args Arguments passed to the function
* @since 2.0
* @param \GV\Template_Context $context The context.
*/
$value = apply_filters( 'gravityview/field_output/context/' . $tag, $value, $args, $context );
// Finally do the replace.
$html = str_replace( $search, (string) $value, $html );
}
/**
* Modify field HTML output.
*
* @param string $html Existing HTML output
* @param array $args Arguments passed to the function
* @since 2.0
* @param \GV\Template_Context $context The context.
*/
$html = GravityView_Deprecated_Hook_Notices::apply_filters( 'gravityview_field_output', [ $html, $args, $context ], '2.55', 'gravityview/field_output/html' );
/**
* Modify field HTML output.
*
* @param string $html Existing HTML output
* @param array $args Arguments passed to the function
* @since 2.0
* @param \GV\Template_Context $context The context.
*/
$html = apply_filters( 'gravityview/field_output/html', $html, $args, $context );
/** @since 2.0.8 Remove unused atts */
$html = str_replace( array( ' style=""', ' class=""', ' id=""' ), '', $html );
return $html;
}
/**
* Generate an HTML anchor tag with a list of supported attributes
*
* @see GVCommon::get_link_html()
*
* @since 1.6
*
* @param string $href URL of the link.
* @param string $anchor_text The text or HTML inside the anchor. This is not sanitized in the function.
* @param array|string $atts Attributes to be added to the anchor tag.
*
* @return string HTML output of anchor link. If empty $href, returns NULL
*/
function gravityview_get_link( $href = '', $anchor_text = '', $atts = [] ) {
return GVCommon::get_link_html( $href, $anchor_text, $atts );
}
/**
* Former alias for GravityView_Admin::is_admin_page()
*
* @param string $hook The hook suffix of the current admin page.
* @param null|string $page Optional. String return value of page to compare against.
*
* @deprecated 3.0.0 `gravityview()->request->is_admin` or `\GV\Request::is_admin`
*
* @return bool|string If `false`, not a GravityView page. `true` if $page is passed and is the same as current page. Otherwise, the name of the page (`single`, `settings`, or `views`)
*/
function gravityview_is_admin_page( $hook = '', $page = null ) {
\gravityview()->log->warning( 'The gravityview_is_admin_page() function is deprecated. Use gravityview()->request->is_admin' );
return gravityview()->request->is_admin( $hook, $page );
}