/** * The Signature Addon only displays the output in the editable form if it thinks it's in the Admin or a form has been submitted * * @since 1.17 * * @param string $field_content Always empty. Returning not-empty overrides the input. * @param GF_Field $field * @param string|array $value If array, it's a field with multiple inputs. If string, single input. * @param int $lead_id Lead ID. Always 0 for the `gform_field_input` filter. * @param int $form_id Form ID * * @return string Empty string forces Gravity Forms to use the $_POST values */ function edit_entry_field_input($field_content = '', $field, $value = '', $lead_id = 0, $form_id = 0) { $context = function_exists('gravityview_get_context') ? gravityview_get_context() : ''; if ('signature' !== $field->type || 'edit' !== $context) { return $field_content; } // We need to fetch a fresh version of the entry, since the saved entry hasn't refreshed in GV yet. $entry = GravityView_View::getInstance()->getCurrentEntry(); $entry = GFAPI::get_entry($entry['id']); $entry_value = rgar($entry, $field->id); $_POST["input_{$field->id}"] = $entry_value; // Used when Edit Entry form *is* submitted $_POST["input_{$form_id}_{$field->id}_signature_filename"] = $entry_value; // Used when Edit Entry form *is not* submitted return ''; // Return empty string to force using $_POST values instead }
/** * Wrapper for the GFFormsModel::matches_operation() method that adds additional comparisons, including: * 'equals', 'greater_than_or_is', 'greater_than_or_equals', 'less_than_or_is', 'less_than_or_equals', * and 'not_contains' * * @since 1.13 You can define context, which displays/hides based on what's being displayed (single, multiple, edit) * * @see http://docs.gravityview.co/article/252-gvlogic-shortcode * @uses GFFormsModel::matches_operation * @since 1.7.5 * * @param string $val1 Left side of comparison * @param string $val2 Right side of comparison * @param string $operation Type of comparison * * @return bool True: matches, false: not matches */ public static function matches_operation($val1, $val2, $operation) { $value = false; if ('context' === $val1) { $matching_contexts = array($val2); // We allow for non-standard contexts. switch ($val2) { // Check for either single or edit case 'singular': $matching_contexts = array('single', 'edit'); break; // Use multiple as alias for directory for consistency // Use multiple as alias for directory for consistency case 'multiple': $matching_contexts = array('directory'); break; } $val1 = in_array(gravityview_get_context(), $matching_contexts) ? $val2 : false; } switch ($operation) { case 'equals': $value = GFFormsModel::matches_operation($val1, $val2, 'is'); break; case 'greater_than_or_is': case 'greater_than_or_equals': $is = GFFormsModel::matches_operation($val1, $val2, 'is'); $gt = GFFormsModel::matches_operation($val1, $val2, 'greater_than'); $value = $is || $gt; break; case 'less_than_or_is': case 'less_than_or_equals': $is = GFFormsModel::matches_operation($val1, $val2, 'is'); $gt = GFFormsModel::matches_operation($val1, $val2, 'less_than'); $value = $is || $gt; break; case 'not_contains': $contains = GFFormsModel::matches_operation($val1, $val2, 'contains'); $value = !$contains; break; default: $value = GFFormsModel::matches_operation($val1, $val2, $operation); } return $value; }
/** * Return an array of files prepared for output. * * 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 * * @since 1.2 * @todo Support `playlist` shortcode for playlist of video/audio * @usedby gravityview_get_files_array() * @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 * @return array Array of file output, with `file_path` and `html` keys (see comments above) */ static function get_files_array($value, $gv_class) { $gravityview_view = GravityView_View::getInstance(); extract($gravityview_view->getCurrentField()); $output_arr = array(); // Get an array of file paths for the field. $file_paths = rgar($field, 'multipleFiles') ? json_decode($value) : array($value); // Process each file path foreach ($file_paths as $file_path) { // If the site is HTTPS, use HTTPS if (function_exists('set_url_scheme')) { $file_path = set_url_scheme($file_path); } // This is from Gravity Forms's code $file_path = esc_attr(str_replace(" ", "%20", $file_path)); // If the field is set to link to the single entry, link to it. $link = !empty($field_settings['show_as_link']) ? GravityView_API::entry_link($entry, $field) : $file_path; // Get file path information $file_path_info = pathinfo($file_path); $html_format = NULL; $disable_lightbox = false; $disable_wrapped_link = false; // Is this an image? $image = new GravityView_Image(array('src' => $file_path, 'class' => 'gv-image gv-field-id-' . $field_settings['id'], 'alt' => $field_settings['label'], 'width' => gravityview_get_context() === 'single' ? NULL : 250)); $content = $image->html(); // The new default content is the image, if it exists. If not, use the file name as the content. $content = !empty($content) ? $content : $file_path_info['basename']; // If pathinfo() gave us the extension of the file, run the switch statement using that. $extension = empty($file_path_info['extension']) ? NULL : strtolower($file_path_info['extension']); switch (true) { // Audio file case in_array($extension, wp_get_audio_extensions()): $disable_lightbox = true; if (shortcode_exists('audio')) { $disable_wrapped_link = true; /** * Modify the settings passed to the `wp_video_shortcode()` function * * @since 1.2 * @var array */ $audio_settings = apply_filters('gravityview_audio_settings', array('src' => $file_path, 'class' => 'wp-audio-shortcode gv-audio gv-field-id-' . $field_settings['id'])); /** * Generate the audio shortcode * @link http://codex.wordpress.org/Audio_Shortcode * @link https://developer.wordpress.org/reference/functions/wp_audio_shortcode/ */ $content = wp_audio_shortcode($audio_settings); } break; // Video file // Video file case in_array($extension, wp_get_video_extensions()): $disable_lightbox = true; if (shortcode_exists('video')) { $disable_wrapped_link = true; /** * Modify the settings passed to the `wp_video_shortcode()` function * * @since 1.2 * @var array */ $video_settings = apply_filters('gravityview_video_settings', array('src' => $file_path, 'class' => 'wp-video-shortcode gv-video gv-field-id-' . $field_settings['id'])); /** * Generate the video shortcode * @link http://codex.wordpress.org/Video_Shortcode * @link https://developer.wordpress.org/reference/functions/wp_video_shortcode/ */ $content = wp_video_shortcode($video_settings); } break; // PDF // PDF case $extension === 'pdf': // PDF needs to be displayed in an IFRAME $link = add_query_arg(array('TB_iframe' => 'true'), $link); break; // if not image, do not set the lightbox (@since 1.5.3) // if not image, do not set the lightbox (@since 1.5.3) case !in_array($extension, array('jpg', 'jpeg', 'jpe', 'gif', 'png')): $disable_lightbox = true; break; } // If using Link to File, override the content. // (We do this here so that the $disable_lightbox can be set. Yes, there's a little more processing time, but oh well.) if (!empty($field_settings['link_to_file'])) { // Force the content to be the file name $content = $file_path_info["basename"]; // Restore the wrapped link $disable_wrapped_link = false; } // Whether to use lightbox or not if ($disable_lightbox || empty($gravityview_view->atts['lightbox']) || !empty($field_settings['show_as_link'])) { $link_atts = empty($field_settings['show_as_link']) ? "target='_blank'" : ''; $link_atts = apply_filters('gravityview/fields/fileupload/link_atts', $link_atts, $gravityview_view->getCurrentField()); } else { $link_atts = sprintf("rel='%s-{$entry['id']}' class='thickbox' target='_blank'", $gv_class); } /** * Filter to alter the default behaviour of wrapping images (or image names) with a link to the content object * * @since 1.5.1 * * @param bool $disable_wrapped_link whether to wrap the content with a link to the content object. * @param array $gravityview_view->field_data * * @see GravityView_API:field_value() for info about $gravityview_view->field_data * */ $disable_wrapped_link = apply_filters('gravityview/fields/fileupload/disable_link', $disable_wrapped_link, $gravityview_view->getCurrentField()); // If the HTML output hasn't been overridden by the switch statement above, use the default format if (!empty($content) && empty($disable_wrapped_link)) { /** * Modify the link text (defaults to the file name) * * @since 1.7 * * @param string $content The existing anchor content. Could be `<img>` tag, audio/video embed or the file name * @param array $field GravityView array of the current field being processed */ $content = apply_filters('gravityview/fields/fileupload/link_content', $content, $gravityview_view->getCurrentField()); $content = '<a href="' . esc_url_raw($link) . '" ' . $link_atts . '>' . $content . '</a>'; } $output_arr[] = array('file_path' => $file_path, 'content' => $content); } // End foreach loop /** * Modify the files array * * @since 1.7 * * @param array $output_arr Associative array of files { * @type string $file_path The path to the file as stored in Gravity Forms * @type string $content The generated output for the file * } * @param array $field GravityView array of the current field being processed */ $output_arr = apply_filters('gravityview/fields/fileupload/files_array', $output_arr, $gravityview_view->getCurrentField()); return $output_arr; }
/** * Core function to render a View based on a set of arguments * * @access public * @static * @param array $passed_args { * * Settings for rendering the View * * @type int $id View id * @type int $page_size Number of entries to show per page * @type string $sort_field Form field id to sort * @type string $sort_direction Sorting direction ('ASC' or 'DESC') * @type string $start_date - Ymd * @type string $end_date - Ymd * @type string $class - assign a html class to the view * @type string $offset (optional) - This is the start point in the current data set (0 index based). * } * * @return string|null HTML output of a View, NULL if View isn't found */ public function render_view($passed_args) { // validate attributes if (empty($passed_args['id'])) { do_action('gravityview_log_error', '[render_view] Returning; no ID defined.', $passed_args); return null; } // Solve problem when loading content via admin-ajax.php // @hack if (!$this->getGvOutputData()) { do_action('gravityview_log_error', '[render_view] gv_output_data not defined; parsing content.', $passed_args); $this->parse_content(); } // Make 100% sure that we're dealing with a properly called situation if (!is_object($this->getGvOutputData()) || !is_callable(array($this->getGvOutputData(), 'get_view'))) { do_action('gravityview_log_error', '[render_view] gv_output_data not an object or get_view not callable.', $this->getGvOutputData()); return null; } $view_id = $passed_args['id']; $view_data = $this->getGvOutputData()->get_view($view_id, $passed_args); do_action('gravityview_log_debug', '[render_view] View Data: ', $view_data); do_action('gravityview_log_debug', '[render_view] Init View. Arguments: ', $passed_args); // The passed args were always winning, even if they were NULL. // This prevents that. Filters NULL, FALSE, and empty strings. $passed_args = array_filter($passed_args, 'strlen'); //Override shortcode args over View template settings $atts = wp_parse_args($passed_args, $view_data['atts']); do_action('gravityview_log_debug', '[render_view] Arguments after merging with View settings: ', $atts); // It's password protected and you need to log in. if (post_password_required($view_id)) { do_action('gravityview_log_error', sprintf('[render_view] Returning: View %d is password protected.', $view_id)); // If we're in an embed or on an archive page, show the password form if (get_the_ID() !== $view_id) { return get_the_password_form(); } // Otherwise, just get outta here return null; } /** * Don't render View if user isn't allowed to see it * @since 1.15 */ if (is_user_logged_in() && false === GVCommon::has_cap('read_gravityview', $view_id)) { return null; } if ($this->isGravityviewPostType()) { /** * @filter `gravityview_direct_access` Should Views be directly accessible, or only visible using the shortcode? * @see https://codex.wordpress.org/Function_Reference/register_post_type#public * @see GravityView_Post_Types::init_post_types * @since 1.15.2 * @param[in,out] boolean `true`: allow Views to be accessible directly. `false`: Only allow Views to be embedded via shortcode. Default: `true` * @param int $view_id The ID of the View currently being requested. `0` for general setting */ $direct_access = apply_filters('gravityview_direct_access', true, $view_id); $embed_only = !empty($atts['embed_only']); if (!$direct_access || $embed_only && !GVCommon::has_cap('read_private_gravityviews')) { return __('You are not allowed to view this content.', 'gravityview'); } } ob_start(); /** * Set globals for templating * @deprecated 1.6.2 */ global $gravityview_view; $gravityview_view = new GravityView_View($view_data); $post_id = !empty($atts['post_id']) ? intval($atts['post_id']) : $this->getPostId(); $gravityview_view->setPostId($post_id); if (!$this->getSingleEntry()) { // user requested Directory View do_action('gravityview_log_debug', '[render_view] Executing Directory View'); //fetch template and slug $view_slug = apply_filters('gravityview_template_slug_' . $view_data['template_id'], 'table', 'directory'); do_action('gravityview_log_debug', '[render_view] View template slug: ', $view_slug); /** * Disable fetching initial entries for views that don't need it (DataTables) */ $get_entries = apply_filters('gravityview_get_view_entries_' . $view_slug, true); /** * Hide View data until search is performed * @since 1.5.4 */ if (!empty($atts['hide_until_searched']) && !$this->isSearch()) { $gravityview_view->setHideUntilSearched(true); $get_entries = false; } if ($get_entries) { if (!empty($atts['sort_columns'])) { // add filter to enable column sorting add_filter('gravityview/template/field_label', array($this, 'add_columns_sort_links'), 100, 3); } $view_entries = self::get_view_entries($atts, $view_data['form_id']); do_action('gravityview_log_debug', sprintf('[render_view] Get Entries. Found %s entries total, showing %d entries', $view_entries['count'], sizeof($view_entries['entries']))); } else { $view_entries = array('count' => null, 'entries' => null, 'paging' => null); do_action('gravityview_log_debug', '[render_view] Not fetching entries because `gravityview_get_view_entries_' . $view_slug . '` is false'); } $gravityview_view->setPaging($view_entries['paging']); $gravityview_view->setContext('directory'); $sections = array('header', 'body', 'footer'); } else { // user requested Single Entry View do_action('gravityview_log_debug', '[render_view] Executing Single View'); do_action('gravityview_render_entry_' . $view_data['id']); $entry = $this->getEntry(); // You are not permitted to view this entry. if (empty($entry) || !self::is_entry_approved($entry, $atts)) { do_action('gravityview_log_debug', '[render_view] Entry does not exist. This may be because of View filters limiting access.'); /** * @since 1.6 */ echo esc_attr(apply_filters('gravityview/render/entry/not_visible', __('You have attempted to view an entry that is not visible or may not exist.', 'gravityview'))); return null; } // We're in single view, but the view being processed is not the same view the single entry belongs to. // important: do not remove this as it prevents fake attempts of displaying entries from other views/forms if ($this->getGvOutputData()->has_multiple_views() && $view_id != $this->get_context_view_id()) { do_action('gravityview_log_debug', '[render_view] In single entry view, but the entry does not belong to this View. Perhaps there are multiple views on the page. View ID: ' . $view_id); return null; } //fetch template and slug $view_slug = apply_filters('gravityview_template_slug_' . $view_data['template_id'], 'table', 'single'); do_action('gravityview_log_debug', '[render_view] View single template slug: ', $view_slug); //fetch entry detail $view_entries['count'] = 1; $view_entries['entries'][] = $entry; do_action('gravityview_log_debug', '[render_view] Get single entry: ', $view_entries['entries']); $back_link_label = isset($atts['back_link_label']) ? $atts['back_link_label'] : null; // set back link label $gravityview_view->setBackLinkLabel($back_link_label); $gravityview_view->setContext('single'); $sections = array('single'); } // add template style self::add_style($view_data['template_id']); // Prepare to render view and set vars $gravityview_view->setEntries($view_entries['entries']); $gravityview_view->setTotalEntries($view_entries['count']); // If Edit if ('edit' === gravityview_get_context()) { do_action('gravityview_log_debug', '[render_view] Edit Entry '); do_action('gravityview_edit_entry', $this->getGvOutputData()); return ob_get_clean(); } else { // finaly we'll render some html $sections = apply_filters('gravityview_render_view_sections', $sections, $view_data['template_id']); do_action('gravityview_log_debug', '[render_view] Sections to render: ', $sections); foreach ($sections as $section) { do_action('gravityview_log_debug', '[render_view] Rendering ' . $section . ' section.'); $gravityview_view->render($view_slug, $section, false); } } //@todo: check why we need the IF statement vs. print the view id always. if ($this->isGravityviewPostType() || $this->isPostHasShortcode()) { // Print the View ID to enable proper cookie pagination echo '<input type="hidden" class="gravityview-view-id" value="' . esc_attr($view_id) . '">'; } $output = ob_get_clean(); return $output; }
/** * * @param $view_id */ public function render_widget_hooks($view_id) { if (empty($view_id) || 'single' == gravityview_get_context()) { return; } $view_data = gravityview_get_current_view_data($view_id); // TODO: Move to sep. method, use an action instead wp_enqueue_style('gravityview_default_style'); // get View widget configuration $widgets = $view_data['widgets']; $rows = GravityView_Plugin::get_default_widget_areas(); switch (current_filter()) { case 'gravityview_before': $zone = 'header'; break; case 'gravityview_after': $zone = 'footer'; break; } // Prevent being called twice if (did_action($zone . '_' . $view_id . '_widgets')) { return; } // TODO Convert to partials ?> <div class="gv-grid"> <?php foreach ($rows as $row) { foreach ($row as $col => $areas) { $column = $col == '2-2' ? '1-2 gv-right' : $col . ' gv-left'; ?> <div class="gv-grid-col-<?php echo esc_attr($column); ?> "> <?php if (!empty($areas)) { foreach ($areas as $area) { if (!empty($widgets[$zone . '_' . $area['areaid']])) { foreach ($widgets[$zone . '_' . $area['areaid']] as $widget) { do_action("gravityview_render_widget_{$widget['id']}", $widget); } } } } ?> </div> <?php } // $row ?> <?php } // $rows ?> </div> <?php // Prevent being called twice do_action($zone . '_' . $view_id . '_widgets'); }
/** * * @param $view_id */ public function render_widget_hooks($view_id) { if (empty($view_id) || 'single' == gravityview_get_context()) { do_action('gravityview_log_debug', __METHOD__ . ' - Not rendering widgets; single entry'); return; } $view_data = gravityview_get_current_view_data($view_id); // TODO: Move to sep. method, use an action instead wp_enqueue_style('gravityview_default_style'); // get View widget configuration $widgets = $view_data['widgets']; $rows = GravityView_Plugin::get_default_widget_areas(); switch (current_filter()) { case 'gravityview_before': $zone = 'header'; break; case 'gravityview_after': $zone = 'footer'; break; } // Prevent being called twice if (did_action($zone . '_' . $view_id . '_widgets')) { do_action('gravityview_log_debug', sprintf('%s - Not rendering %s; already rendered', __METHOD__, $zone . '_' . $view_id . '_widgets')); return; } // TODO Convert to partials ?> <div class="gv-grid"> <?php foreach ($rows as $row) { foreach ($row as $col => $areas) { $column = $col == '2-2' ? '1-2 gv-right' : $col . ' gv-left'; ?> <div class="gv-grid-col-<?php echo esc_attr($column); ?> "> <?php if (!empty($areas)) { foreach ($areas as $area) { if (!empty($widgets[$zone . '_' . $area['areaid']])) { foreach ($widgets[$zone . '_' . $area['areaid']] as $widget) { do_action("gravityview_render_widget_{$widget['id']}", $widget); } } } } ?> </div> <?php } // $row ?> <?php } // $rows ?> </div> <?php /** * Prevent widgets from being called twice. * Checking for loop_start prevents themes and plugins that pre-process shortcodes from triggering the action before displaying. Like, ahem, the Divi theme and WordPress SEO plugin */ if (did_action('loop_start')) { do_action($zone . '_' . $view_id . '_widgets'); } }
/** * * @param $view_id */ public function render_widget_hooks($view_id) { if (empty($view_id) || 'single' == gravityview_get_context()) { do_action('gravityview_log_debug', __METHOD__ . ' - Not rendering widgets; single entry'); return; } $view_data = gravityview_get_current_view_data($view_id); // get View widget configuration $widgets = (array) $view_data['widgets']; switch (current_filter()) { default: case 'gravityview_before': $zone = 'header'; break; case 'gravityview_after': $zone = 'footer'; break; } /** * Filter widgets not in the current zone * @since 1.16 */ foreach ($widgets as $key => $widget) { // The widget isn't in the current zone if (false === strpos($key, $zone)) { unset($widgets[$key]); } } /** * Prevent output if no widgets to show. * @since 1.16 */ if (empty($widgets)) { do_action('gravityview_log_debug', sprintf('No widgets for View #%s', $view_id)); return; } // Prevent being called twice if (did_action($zone . '_' . $view_id . '_widgets')) { do_action('gravityview_log_debug', sprintf('%s - Not rendering %s; already rendered', __METHOD__, $zone . '_' . $view_id . '_widgets')); return; } $rows = GravityView_Plugin::get_default_widget_areas(); // TODO: Move to sep. method, use an action instead wp_enqueue_style('gravityview_default_style'); $default_css_class = 'gv-grid gv-widgets-' . $zone; if (0 === GravityView_View::getInstance()->getTotalEntries()) { $default_css_class .= ' gv-widgets-no-results'; } /** * @filter `gravityview/widgets/wrapper_css_class` The CSS class applied to the widget container `<div>`. * @since 1.16.2 * @param string $css_class Default: `gv-grid gv-widgets-{zone}` where `{zone}` is replaced by the current `$zone` value. If the View has no results, adds ` gv-widgets-no-results` * @param string $zone Current widget zone, either `header` or `footer` * @param array $widgets Array of widget configurations for the current zone, as set by `gravityview_get_current_view_data()['widgets']` */ $css_class = apply_filters('gravityview/widgets/wrapper_css_class', $default_css_class, $zone, $widgets); $css_class = gravityview_sanitize_html_class($css_class); // TODO Convert to partials ?> <div class="<?php echo $css_class; ?> "> <?php foreach ($rows as $row) { foreach ($row as $col => $areas) { $column = $col == '2-2' ? '1-2 gv-right' : $col . ' gv-left'; ?> <div class="gv-grid-col-<?php echo esc_attr($column); ?> "> <?php if (!empty($areas)) { foreach ($areas as $area) { if (!empty($widgets[$zone . '_' . $area['areaid']])) { foreach ($widgets[$zone . '_' . $area['areaid']] as $widget) { do_action("gravityview_render_widget_{$widget['id']}", $widget); } } } } ?> </div> <?php } // $row ?> <?php } // $rows ?> </div> <?php /** * Prevent widgets from being called twice. * Checking for loop_start prevents themes and plugins that pre-process shortcodes from triggering the action before displaying. Like, ahem, the Divi theme and WordPress SEO plugin */ if (did_action('loop_start')) { do_action($zone . '_' . $view_id . '_widgets'); } }