@@ -1106,69 +1132,69 @@ function render_active_areas( $template_id, $type, $zone, $rows, $values ) {
- $field ) {
- // Provide the button label to the field.
- $field['add_button_label'] = $button_label;
-
- // Maybe has a form ID
- $form_id = empty( $field['form_id'] ) ? $form_id : $field['form_id'];
-
- $input_type = null;
-
- if ( $form_id ) {
- $original_item = isset( $available_items[ $form_id ] [ $field['id'] ] ) ? $available_items[ $form_id ] [ $field['id'] ] : false;
- } else {
- $original_item = isset( $available_items[ $field['id'] ] ) ? $available_items[ $field['id'] ] : false;
- }
-
- if ( ! $original_item ) {
-
- global $pagenow;
- if ( 'post-new.php' !== $pagenow ) {
- gravityview()->log->error(
- 'An item was not available when rendering the output; maybe it was added by a plugin that is now de-activated.',
- array(
- ' data' => array(
- 'available_items' => $available_items,
- 'field' => $field,
- ),
- )
- );
- }
-
- $original_item = $field;
- }
-
- $input_type = isset( $original_item['type'] ) ? $original_item['type'] : null;
-
- // Field options dialog box
- $field_options = GravityView_Render_Settings::render_field_options( $form_id, $type, $template_id, $field['id'], $original_item['label'], $zone . '_' . $area['areaid'], $input_type, $uniqid, $field, $zone, $original_item );
-
- $item = array(
- 'input_type' => $input_type,
- 'settings_html' => $field_options,
- 'label_type' => $type,
- );
-
- // Merge the values with the current item to pass things like widget descriptions and original field names
- if ( $original_item ) {
- $item = wp_parse_args( $item, $original_item );
- }
-
- switch ( $type ) {
- case 'widget':
- echo new GravityView_Admin_View_Widget( $item['label'], $field['id'], $item, $field );
- break;
- default:
- echo new GravityView_Admin_View_Field( $field['label'], $field['id'], $item, $field, $form_id, $form );
- }
- }
- } // End if zone is not empty
- ?>
+ $field ) {
+ // Provide the button label to the field.
+ $field['add_button_label'] = $button_label;
+
+ // Maybe has a form ID
+ $form_id = empty( $field['form_id'] ) ? $form_id : $field['form_id'];
+
+ $input_type = null;
+
+ if ( $form_id ) {
+ $original_item = isset( $available_items[ $form_id ] [ $field['id'] ] ) ? $available_items[ $form_id ] [ $field['id'] ] : false;
+ } else {
+ $original_item = isset( $available_items[ $field['id'] ] ) ? $available_items[ $field['id'] ] : false;
+ }
+
+ if ( ! $original_item ) {
+
+ global $pagenow;
+ if ( 'post-new.php' !== $pagenow ) {
+ gravityview()->log->error(
+ 'An item was not available when rendering the output; maybe it was added by a plugin that is now de-activated.',
+ array(
+ ' data' => array(
+ 'available_items' => $available_items,
+ 'field' => $field,
+ ),
+ )
+ );
+ }
+
+ $original_item = $field;
+ }
+
+ $input_type = isset( $original_item['type'] ) ? $original_item['type'] : null;
+
+ // Field options dialog box
+ $field_options = GravityView_Render_Settings::render_field_options( $form_id, $type, $template_id, $field['id'], $original_item['label'], $zone . '_' . $area['areaid'], $input_type, $uniqid, $field, $zone, $original_item );
+
+ $item = array(
+ 'input_type' => $input_type,
+ 'settings_html' => $field_options,
+ 'label_type' => $type,
+ );
+
+ // Merge the values with the current item to pass things like widget descriptions and original field names
+ if ( $original_item ) {
+ $item = wp_parse_args( $item, $original_item );
+ }
+
+ switch ( $type ) {
+ case 'widget':
+ echo new GravityView_Admin_View_Widget( $item['label'], $field['id'], $item, $field );
+ break;
+ default:
+ echo new GravityView_Admin_View_Field( $field['label'], $field['id'], $item, $field, $form_id, $form );
+ }
+ }
+ } // End if zone is not empty
+ ?>
';
endforeach;
}
+ /**
+ * Renders the row actions.
+ *
+ * @since $ver$
+ *
+ * @param bool $is_dynamic Whether the rows are actionable.
+ */
+ public function render_actions(
+ bool $is_dynamic,
+ string $template_id,
+ string $type,
+ string $zone
+ ): void {
+ if ( ! $is_dynamic ) {
+ return;
+ }
+
+ echo '
';
+ $actions = '
+
+
+
';
+
+ /**
+ * Modifies the actions rendered in the View editor.
+ *
+ * @since $ver$
+ *
+ * @filter `gk/gravityview/admin-views/rows-actions`
+ *
+ * @param string $actions The HTML for the actions.
+ * @param string $template_id The template ID.
+ * @param string $type The object type (widget or field).
+ * @param string $zone The render zone.
+ */
+ echo apply_filters( 'gk/gravityview/admin-views/rows-actions', $actions, $template_id, $type, $zone );
+
+ echo '
';
+ }
/**
* Render the widget active areas
*
@@ -1202,42 +1298,49 @@ function render_widgets_active_areas( $template_id = '', $zone = '', $post_id =
$default_widget_areas = \GV\Widget::get_default_widget_areas();
- $widgets = array();
+ $widgets = [];
+ $unique_id = static fn(): string => substr( md5( microtime( true ) ), 0, 13 );
+
+ $header_top = 'header_' . ($default_widget_areas[0]['1-1'][0]['areaid'] ?? 'top');
+ $header_left = 'header_' . ($default_widget_areas[1]['1-2 left'][0]['areaid'] ?? 'left');
+ $header_right = 'header_' . ($default_widget_areas[1]['1-2 right'][0]['areaid'] ?? 'right');
+ $footer_right = 'footer_' . ($default_widget_areas[1]['1-2 right'][0]['areaid'] ?? 'right');
+
if ( ! empty( $post_id ) ) {
if ( 'auto-draft' === get_post_status( $post_id ) ) {
// This is a new View, prefill the widgets
- $widgets = array(
- 'header_top' => array(
- substr( md5( microtime( true ) ), 0, 13 ) => array(
+ $widgets = [
+ $header_top => [
+ $unique_id() => [
'id' => 'search_bar',
'label' => __( 'Search Bar', 'gk-gravityview' ),
'search_layout' => 'horizontal',
'search_clear' => '0',
'search_fields' => '[{"field":"search_all","input":"input_text"}]',
'search_mode' => 'any',
- ),
- ),
- 'header_left' => array(
- substr( md5( microtime( true ) ), 0, 13 ) => array(
+ ],
+ ],
+ $header_left => [
+ $unique_id() => [
'id' => 'page_info',
'label' => __( 'Show Pagination Info', 'gk-gravityview' ),
- ),
- ),
- 'header_right' => array(
- substr( md5( microtime( true ) ), 0, 13 ) => array(
+ ],
+ ],
+ $header_right => [
+ $unique_id() => [
'id' => 'page_links',
'label' => __( 'Page Links', 'gk-gravityview' ),
'show_all' => '0',
- ),
- ),
- 'footer_right' => array(
- substr( md5( microtime( true ) ), 0, 13 ) => array(
+ ],
+ ],
+ $footer_right => [
+ $unique_id() => [
'id' => 'page_links',
'label' => __( 'Page Links', 'gk-gravityview' ),
'show_all' => '0',
- ),
- ),
- );
+ ],
+ ],
+ ];
/**
* Modify the default widgets for new Views.
@@ -1246,9 +1349,11 @@ function render_widgets_active_areas( $template_id = '', $zone = '', $post_id =
* @param string $zone The widget zone that's being requested
* @param int $post_id The auto-draft post ID
*/
- $widgets = apply_filters( 'gravityview/view/widgets/default', $widgets, $template_id, $zone, $post_id );
+ $widgets = (array) apply_filters( 'gravityview/view/widgets/default', $widgets, $template_id, $zone, $post_id );
} else {
- $widgets = gravityview_get_directory_widgets( $post_id );
+ $widgets = (array) gravityview_get_directory_widgets( $post_id );
+ $collection = Widget_Collection::from_configuration( $widgets );
+ $default_widget_areas = Grid::get_rows_from_collection( $collection, $zone ) ?: $default_widget_areas;
}
}
@@ -1256,7 +1361,24 @@ function render_widgets_active_areas( $template_id = '', $zone = '', $post_id =
?>
- render_active_areas( $template_id, 'widget', $zone, $default_widget_areas, $widgets ); ?>
+ is_dynamic( $template_id, $type, $zone );
+
+ $this->render_active_areas( $template_id, $type, $zone, $default_widget_areas, $widgets );
+
+ /**
+ * Allows additional content after the zone was rendered.
+ *
+ * @filter `gk/gravityview/admin/view/after-zone`
+
+ * @param string $template_id Template ID.
+ * @param string $type The zone type (field or widget).
+ * @param string $context Current View context: `directory`, `single`, or `edit` (default: 'single')
+ * @param bool $is_dynamic Whether the zone is dynamic.
+ */
+ do_action( 'gk/gravityview/admin-views/view/after-zone', $template_id, $type, $zone, $is_dynamic );
+ ?>
' . esc_html__( 'The data is not lost; re-activate the associated plugin and the configuration will re-appear.', 'gk-gravityview' ) . '';
$output .= '
';
} else {
-
- $fields = gravityview_get_directory_fields( $post_id, true, $form_id );
+ /**
+ * Modifies the template area's before rendering.
+ *
+ * @filter `gk/gravityview/admin-views/view/template/active-areas`
+ * @since $ver$
+
+ * @param array $template_areas The template areas.
+ * @param string $template_id Template ID.
+ * @param string $context Current View context: `directory`, `single`, or `edit` (default: 'single')
+ * @param array $fields The fields for the View.
+ */
+ $fields = (array) gravityview_get_directory_fields( $post_id, true, $form_id );
+ $template_areas = (array) apply_filters( 'gk/gravityview/admin-views/view/template/active-areas', $template_areas, $template_id, $context, $fields );
+ $type = 'field';
+ $is_dynamic = $this->is_dynamic( $template_id, $type, $context );
ob_start();
- $this->render_active_areas( $template_id, 'field', $context, $template_areas, $fields );
- $output = ob_get_clean();
+ $this->render_active_areas( $template_id, $type, $context, $template_areas, $fields );
+
+ /**
+ * Allows additional content after the zone was rendered.
+ *
+ * @filter `gk/gravityview/admin/view/after-zone`
+
+ * @param string $template_id Template ID.
+ * @param string $type The zone type (field or widget).
+ * @param string $context Current View context: `directory`, `single`, or `edit` (default: 'single')
+ * @param bool $is_dynamic Whether the zone is dynamic.
+ */
+ do_action( 'gk/gravityview/admin-views/view/after-zone', $template_id, $type, $context, $is_dynamic );
+ $output = ob_get_clean();
}
if ( $echo ) {
@@ -1369,6 +1516,100 @@ function render_directory_active_areas( $template_id = '', $context = 'single',
return $output;
}
+ /**
+ * Returns an "add row" button for a template zone.
+ *
+ * @since $ver$
+ *
+ * @param string $template_id The template ID.
+ * @param string $type The object type (widget or field).)
+ * @param string $zone The zone ID.
+ * @param bool $is_dynamic Whether the zone is dynamic.
+ */
+ public function render_add_row( string $template_id, string $type, string $zone, bool $is_dynamic ): void {
+ if ( ! $is_dynamic ) {
+ return;
+ }
+
+ $controls_id = 'gv-grid-options-' . wp_generate_password( 12, false, false );
+ $button = <<
+
%s
+ %s
+
+HTML;
+ ?>
+
+
+
+
+
+ $_ ) {
+ $columns = explode( '/', $key );
+ $icon = '
';
+ foreach ( $columns as $column ) {
+ $icon .= sprintf(
+ '
%s
',
+ esc_attr( $column ),
+ esc_html( $column ),
+ );
+ }
+ $icon .= '
';
+ printf(
+ $button,
+ esc_attr( $zone ),
+ esc_attr( $template_id ),
+ $type,
+ esc_attr( $key ),
+ esc_attr(
+ str_replace(
+ '[type]',
+ $key,
+ esc_html__( 'Add [type] row', 'gk-gravityview' ),
+ )
+ ),
+ $icon
+ );
+ }
+ ?>
+
+
+
+
+
+
+
+ settings->get( 'use_dynamic_widgets', false );
+ }
+
/**
* Set the default fields for new Views.
*
@@ -1440,7 +1681,7 @@ public function set_default_view_fields( $fields = array(), $view = null, $form_
$directory_fields = $entry_fields;
// If we're showing all fields, we want to show the first field as a link.
- foreach( $directory_fields as &$field ) {
+ foreach ( $directory_fields as &$field ) {
$gf_field = GF_Fields::get( $field['type'] );
if ( ! $gf_field ) {
@@ -1534,11 +1775,12 @@ static function add_scripts_and_styles( $hook ) {
'gravityview-jquery-cookie',
'jquery-ui-datepicker',
'underscore',
- 'clipboard'
+ 'clipboard',
],
\GV\Plugin::$version
);
wp_enqueue_script( 'gravityview_view_dropdown', plugins_url( 'assets/js/admin-view-dropdown' . $script_debug . '.js', GRAVITYVIEW_FILE ), [ 'jquery' ], \GV\Plugin::$version );
+ wp_enqueue_script( 'gravityview_grid', plugins_url( 'assets/js/admin-grid' . $script_debug . '.js', GRAVITYVIEW_FILE ), [ 'jquery' ], \GV\Plugin::$version );
wp_localize_script(
'gravityview_views_scripts',
@@ -1644,6 +1886,31 @@ function register_no_conflict( $registered ) {
return array_merge( $registered, $allowed_dependencies );
}
+
+ /**
+ * Returns whether the zone is dynamic.
+ *
+ * @since $ver$
+ *
+ * @param string $template_id The template ID.
+ * @param string $type The type.
+ * @param string $zone The zone.
+ * @return bool Whether the zone is dynamic.
+ */
+ private function is_dynamic( string $template_id, string $type, string $zone ): bool {
+ /**
+ * Modifies whether the zone is sortable.
+ *
+ * @filter `gk/gravityview/view/template/active-areas`
+ * @since $ver$
+
+ * @param bool $is_dynamic Whether area is dynamic, meaning sortable / deletable / acionable.
+ * @param string $template_id Template ID.
+ * @param string $type The object type; widget or field.
+ * @param string $zone Current View context: `directory`, `single`, or `edit` (default: 'single')
+ */
+ return (bool) apply_filters( 'gk/gravityview/admin-views/view/is-dynamic', false, $template_id, $type, $zone );
+ }
}
new GravityView_Admin_Views();
diff --git a/includes/class-admin-welcome.php b/includes/class-admin-welcome.php
index e0e0b09f4c..3762f30344 100644
--- a/includes/class-admin-welcome.php
+++ b/includes/class-admin-welcome.php
@@ -296,6 +296,52 @@ public function changelog_screen() {
* - If 4.28, include to 4.26.
*/
?>
+
2.31 on November 4, 2024
+
+
This release introduces flexible widget positioning in Views, enhances entry-in-a-lightbox functionality, and adds support for the Gravity Forms 2.9+ Image Choice field. It also addresses compatibility issues with LiteSpeed, Divi, and LifterLMS, along with various other fixes and improvements.
+
+
🚀 Added
+
+
+ - Ability to position widgets in the View editor using predefined layouts, offering a range of single or multi-column configurations with varying widths.
+ - View setting to control what happens when a user clicks the Cancel link when editing an entry in the lightbox.
+ - Support for the upcoming Image Choice field in Gravity Forms 2.9+.
+
+
+
🐛 Fixed
+
+
+ - GravityView tab not displaying in certain cases under GravityKit > Settings menu.
+ - Widgets could not be configured after being added to a new, unsaved View.
+ - Compatibility with the Divi theme that prevented the Signature field from being edited on the Edit Entry screen.
+ - Conflict with the LiteSpeed plugin that caused a fatal error when redirecting users after duplicating an entry.
+ - JavaScript enqueued in the site's footer was not executed when editing an entry in the lightbox.
+ - It was not possible to add new entry notes when viewing a single entry in the lightbox.
+ - Validation error displayed when adding merge tags to the Entry Slug setting input in the View editor.
+ - The search box in the Change Entry Creator field did not return results when editing an entry on the Forms > Entries screen.
+ - Fatal error when activating LifterLMS with GravityView active.
+ - Searching across all fields not working as expected when the search value contains special characters or accents (e.g., ä, ß, İ).
+
+
+
🔧 Updated
+
+
+
+
💻 Developer Updates
+
+
+ - Added
gk/gravityview/lightbox/entry/before-output
action that fires before the entry content is output in the lightbox.
+ - Added
gk/gravityview/lightbox/entry/output/head-before
action that fires after the <head>
tag is opened.
+ - Added
gk/gravityview/lightbox/entry/output/head-after
action that fires before the </head>
tag is closed.
+ - Added
gk/gravityview/lightbox/entry/output/content-before
action that fires after the <body>
tag is opened and before the content is rendered.
+ - Added
gk/gravityview/lightbox/entry/output/content-after
action that fires after the content is rendered and before the footer.
+ - Added
gk/gravityview/lightbox/entry/output/footer-after
action that fires after the footer and before the closing </body>
tag.
+ - Added
gravityview/fields/image_choice/image_markup
filter to modify the Image Choice field (Gravity Forms 2.9+) markup.
+ - Added
gravityview/fields/image_choice/output_label
filter to control whether to display the value or label of an Image Choice field.
+
+
2.30.1 on October 15, 2024
This hotfix release resolves an issue with the Multiple Forms extension.
diff --git a/includes/class-ajax.php b/includes/class-ajax.php
index 7d4d29ef5b..772e57b700 100644
--- a/includes/class-ajax.php
+++ b/includes/class-ajax.php
@@ -1,37 +1,41 @@
check_ajax_nonce();
$context = rgpost( 'context' );
// Return markup for a single or multiple contexts
if ( $context ) {
- $data = array(
+ $data = [
esc_attr( $context ) => '',
- );
+ ];
} else {
- $data = array(
+ $data = [
'directory' => '',
'edit' => '',
'single' => '',
- );
+ ];
}
if ( is_array( rgpost( 'form_preset_ids' ) ) ) {
$form_ids = rgpost( 'form_preset_ids' );
} else {
$this->_exit( false );
+
return; // If inside unit tests, which don't exit, don't continue.
}
@@ -118,11 +122,25 @@ function get_active_areas() {
}
ob_start();
- do_action( 'gravityview_render_directory_active_areas', \GV\Utils::_POST( 'template_id' ), 'directory', '', true, \GV\Utils::_POST( 'form_id', 0 ) );
+ do_action(
+ 'gravityview_render_directory_active_areas',
+ \GV\Utils::_POST( 'template_id' ),
+ 'directory',
+ '',
+ true,
+ \GV\Utils::_POST( 'form_id', 0 )
+ );
$response['directory'] = ob_get_clean();
ob_start();
- do_action( 'gravityview_render_directory_active_areas', \GV\Utils::_POST( 'template_id' ), 'single', '', true, \GV\Utils::_POST( 'form_id', 0 ) );
+ do_action(
+ 'gravityview_render_directory_active_areas',
+ \GV\Utils::_POST( 'template_id' ),
+ 'single',
+ '',
+ true,
+ \GV\Utils::_POST( 'form_id', 0 )
+ );
$response['single'] = ob_get_clean();
$response = array_map( 'gravityview_strip_whitespace', $response );
@@ -130,13 +148,53 @@ function get_active_areas() {
$this->_exit( json_encode( $response ) );
}
+ /**
+ * Returns the HTML for a new grid row.
+ *
+ * @since $ver$
+ */
+ public function create_row() {
+ $this->check_ajax_nonce();
+
+ if (
+ empty( $_POST['zone'] )
+ || empty( $_POST['type'] )
+ || empty( $_POST['row_type'] )
+ ) {
+ $this->_exit( false );
+ }
+
+ $type = $_POST['type'] ?? 'widget';
+ if ( 'widget' !== $type && empty( $_POST['template_id'] ?? '' ) ) {
+ $this->_exit( false );
+ }
+
+ $row = Grid::prefixed(
+ 'widget' !== $type ? $_POST['template_id'] : '',
+ static fn () => Grid::get_row_by_type( $_POST['row_type'] )
+ );
+
+ ob_start();
+
+ do_action(
+ 'gravityview_render_active_areas',
+ $_POST['template_id'],
+ $type,
+ $_POST['zone'],
+ [ $row ],
+ []
+ );
+ $response['row'] = ob_get_clean();
+
+ $this->_exit( json_encode( $response ) );
+ }
+
/**
* Fill in active areas with preset configuration according to the template selected
*
* @return void
*/
function get_preset_fields_config() {
-
$this->check_ajax_nonce();
if ( empty( $_POST['template_id'] ) ) {
@@ -144,45 +202,73 @@ function get_preset_fields_config() {
}
// get the fields xml config file for this specific preset
- $preset_fields_path = apply_filters( 'gravityview_template_fieldsxml', array(), $_POST['template_id'] );
+ $preset_fields_path = apply_filters( 'gravityview_template_fieldsxml', [], $_POST['template_id'] );
// import fields
if ( ! empty( $preset_fields_path ) ) {
$presets = $this->import_fields( $preset_fields_path );
} else {
- $presets = array(
- 'widgets' => array(),
- 'fields' => array(),
- );
+ $presets = [
+ 'widgets' => [],
+ 'fields' => [],
+ ];
}
$template_id = esc_attr( $_POST['template_id'] );
// template areas
- $template_areas_directory = apply_filters( 'gravityview_template_active_areas', array(), $template_id, 'directory' );
- $template_areas_single = apply_filters( 'gravityview_template_active_areas', array(), $template_id, 'single' );
+ $template_areas_directory = apply_filters( 'gravityview_template_active_areas', [], $template_id, 'directory' );
+ $template_areas_single = apply_filters( 'gravityview_template_active_areas', [], $template_id, 'single' );
// widget areas
$default_widget_areas = \GV\Widget::get_default_widget_areas();
ob_start();
- do_action( 'gravityview_render_active_areas', $template_id, 'widget', 'header', $default_widget_areas, $presets['widgets'] );
+ do_action(
+ 'gravityview_render_active_areas',
+ $template_id,
+ 'widget',
+ 'header',
+ $default_widget_areas,
+ $presets['widgets']
+ );
$response['header'] = ob_get_clean();
ob_start();
- do_action( 'gravityview_render_active_areas', $template_id, 'widget', 'footer', $default_widget_areas, $presets['widgets'] );
+ do_action(
+ 'gravityview_render_active_areas',
+ $template_id,
+ 'widget',
+ 'footer',
+ $default_widget_areas,
+ $presets['widgets']
+ );
$response['footer'] = ob_get_clean();
ob_start();
- do_action( 'gravityview_render_active_areas', $template_id, 'field', 'directory', $template_areas_directory, $presets['fields'] );
+ do_action(
+ 'gravityview_render_active_areas',
+ $template_id,
+ 'field',
+ 'directory',
+ $template_areas_directory,
+ $presets['fields']
+ );
$response['directory'] = ob_get_clean();
ob_start();
- do_action( 'gravityview_render_active_areas', $template_id, 'field', 'single', $template_areas_single, $presets['fields'] );
+ do_action(
+ 'gravityview_render_active_areas',
+ $template_id,
+ 'field',
+ 'single',
+ $template_areas_single,
+ $presets['fields']
+ );
$response['single'] = ob_get_clean();
$response = array_map( 'gravityview_strip_whitespace', $response );
- gravityview()->log->debug( '[get_preset_fields_config] AJAX Response', array( 'data' => $response ) );
+ gravityview()->log->debug( '[get_preset_fields_config] AJAX Response', [ 'data' => $response ] );
$this->_exit( json_encode( $response ) );
}
@@ -193,7 +279,6 @@ function get_preset_fields_config() {
* @return void
*/
function create_preset_form() {
-
$this->check_ajax_nonce();
if ( empty( $_POST['template_id'] ) ) {
@@ -210,7 +295,10 @@ function create_preset_form() {
// get the form ID
if ( false === $form ) {
// send error to user
- gravityview()->log->error( 'Error importing form for template id: {template_id}', array( 'template_id' => (int) $_POST['template_id'] ) );
+ gravityview()->log->error(
+ 'Error importing form for template id: {template_id}',
+ [ 'template_id' => (int) $_POST['template_id'] ]
+ );
$this->_exit( false );
}
@@ -221,15 +309,19 @@ function create_preset_form() {
/**
* Import Gravity Form XML or JSON
*
- * @param string $xml_or_json_path Path to form XML or JSON file
+ * @param string $xml_or_json_path Path to form XML or JSON file
+ *
* @return int|bool Imported form ID or false
*/
function import_form( $xml_or_json_path = '' ) {
-
- gravityview()->log->debug( '[import_form] Import Preset Form. (File) {path}', array( 'path' => $xml_or_json_path ) );
+ gravityview()->log->debug( '[import_form] Import Preset Form. (File) {path}', [ 'path' => $xml_or_json_path ] );
if ( empty( $xml_or_json_path ) || ! class_exists( 'GFExport' ) || ! file_exists( $xml_or_json_path ) ) {
- gravityview()->log->error( 'Class GFExport or file not found. file: {path}', array( 'path' => $xml_or_json_path ) );
+ gravityview()->log->error(
+ 'Class GFExport or file not found. file: {path}',
+ [ 'path' => $xml_or_json_path ]
+ );
+
return false;
}
@@ -237,11 +329,12 @@ function import_form( $xml_or_json_path = '' ) {
$forms = '';
$count = GFExport::import_file( $xml_or_json_path, $forms );
- gravityview()->log->debug( '[import_form] Importing form (Result) {count}', array( 'count' => $count ) );
- gravityview()->log->debug( '[import_form] Importing form (Form) ', array( 'data' => $forms ) );
+ gravityview()->log->debug( '[import_form] Importing form (Result) {count}', [ 'count' => $count ] );
+ gravityview()->log->debug( '[import_form] Importing form (Form) ', [ 'data' => $forms ] );
if ( 1 != $count || empty( $forms[0]['id'] ) ) {
gravityview()->log->error( 'Form Import Failed!' );
+
return false;
}
@@ -249,7 +342,6 @@ function import_form( $xml_or_json_path = '' ) {
return $forms[0];
}
-
/**
* Returns field options - called by ajax when dropping fields into active areas
* AJAX callback
@@ -275,7 +367,18 @@ function get_field_options() {
$context = isset( $_post['context'] ) ? esc_attr( $_post['context'] ) : null;
$form_id = empty( $_post['form_id'] ) ? null : $_post['form_id'];
- $response = GravityView_Render_Settings::render_field_options( $form_id, $_post['field_type'], $_post['template'], $_post['field_id'], $_post['field_label'], $_post['area'], $input_type, '', '', $context );
+ $response = GravityView_Render_Settings::render_field_options(
+ $form_id,
+ $_post['field_type'],
+ $_post['template'],
+ $_post['field_id'],
+ $_post['field_label'],
+ $_post['area'],
+ $input_type,
+ '',
+ '',
+ $context
+ );
$response = gravityview_strip_whitespace( $response );
@@ -295,15 +398,10 @@ function get_sortable_fields() {
// if form id is set, use it, else, get form from preset
if ( ! empty( $_POST['form_id'] ) ) {
-
$form = (int) $_POST['form_id'];
-
- }
- // get form from preset
+ } // get form from preset
elseif ( ! empty( $_POST['template_id'] ) ) {
-
$form = self::pre_get_form_fields( $_POST['template_id'] );
-
}
$response = gravityview_get_sortable_fields( $form );
@@ -316,24 +414,26 @@ function get_sortable_fields() {
/**
* Get the form fields for a preset (no form created yet)
*
- * @param string $template_id Preset template
+ * @param string $template_id Preset template
*
* @return array|false
*/
static function pre_get_form_fields( $template_id = '' ) {
if ( empty( $template_id ) ) {
gravityview()->log->error( 'Template ID not set.' );
+
return false;
} else {
$form_file = apply_filters( 'gravityview_template_formxml', '', $template_id );
if ( ! file_exists( $form_file ) ) {
gravityview()->log->error(
'[{template_id}] form file does not exist: {path}.',
- array(
+ [
'template_id' => $template_id,
'path' => $form_file,
- )
+ ]
);
+
return false;
}
}
@@ -344,7 +444,7 @@ static function pre_get_form_fields( $template_id = '' ) {
$forms = json_decode( $forms_json, true );
if ( ! $forms ) {
- gravityview()->log->error( 'Could not read the {path} template file.', array( 'path' => $form_file ) );
+ gravityview()->log->error( 'Could not read the {path} template file.', [ 'path' => $form_file ] );
return false;
}
@@ -354,10 +454,10 @@ static function pre_get_form_fields( $template_id = '' ) {
gravityview()->log->debug(
'[pre_get_form_fields] Importing Form Fields for preset [{template_id}]. (Form)',
- array(
+ [
'template_id' => $template_id,
'data' => $form,
- )
+ ]
);
return $form;
@@ -366,13 +466,14 @@ static function pre_get_form_fields( $template_id = '' ) {
/**
* Import fields configuration from an exported WordPress View preset
*
- * @param string $file path to file
+ * @param string $file path to file
+ *
* @return array Fields config array (unserialized)
*/
function import_fields( $file ) {
-
if ( empty( $file ) || ! file_exists( $file ) ) {
- gravityview()->log->error( 'Importing Preset Fields. File not found. (File) {path}', array( 'path' => $file ) );
+ gravityview()->log->error( 'Importing Preset Fields. File not found. (File) {path}', [ 'path' => $file ] );
+
return false;
}
@@ -384,18 +485,23 @@ function import_fields( $file ) {
$presets = $parser->parse( $file );
if ( is_wp_error( $presets ) ) {
- gravityview()->log->error( 'Importing Preset Fields failed. Threw WP_Error.', array( 'data' => $presets ) );
+ gravityview()->log->error( 'Importing Preset Fields failed. Threw WP_Error.', [ 'data' => $presets ] );
+
return false;
}
if ( empty( $presets['posts'][0]['postmeta'] ) && ! is_array( $presets['posts'][0]['postmeta'] ) ) {
- gravityview()->log->error( 'Importing Preset Fields failed. Meta not found in file. {path}', array( 'path' => $file ) );
+ gravityview()->log->error(
+ 'Importing Preset Fields failed. Meta not found in file. {path}',
+ [ 'path' => $file ]
+ );
+
return false;
}
- gravityview()->log->debug( '[import_fields] postmeta', array( 'data' => $presets['posts'][0]['postmeta'] ) );
+ gravityview()->log->debug( '[import_fields] postmeta', [ 'data' => $presets['posts'][0]['postmeta'] ] );
- $fields = $widgets = array();
+ $fields = $widgets = [];
foreach ( $presets['posts'][0]['postmeta'] as $meta ) {
switch ( $meta['key'] ) {
case '_gravityview_directory_fields':
@@ -407,13 +513,13 @@ function import_fields( $file ) {
}
}
- gravityview()->log->debug( '[import_fields] Imported Preset (Fields)', array( 'data' => $fields ) );
- gravityview()->log->debug( '[import_fields] Imported Preset (Widgets)', array( 'data' => $widgets ) );
+ gravityview()->log->debug( '[import_fields] Imported Preset (Fields)', [ 'data' => $fields ] );
+ gravityview()->log->debug( '[import_fields] Imported Preset (Widgets)', [ 'data' => $widgets ] );
- return array(
+ return [
'fields' => $fields,
'widgets' => $widgets,
- );
+ ];
}
}
diff --git a/includes/class-gravityview-change-entry-creator.php b/includes/class-gravityview-change-entry-creator.php
index dfc47a4c8f..eefc775db4 100644
--- a/includes/class-gravityview-change-entry-creator.php
+++ b/includes/class-gravityview-change-entry-creator.php
@@ -433,6 +433,12 @@ public function add_select( $form_id, $entry ) {
'selected' => true,
'disabled' => true,
],
+ 'input' => [
+ 'type' => true,
+ 'id' => true,
+ 'name' => true,
+ 'value' => true,
+ ],
]
);
}
diff --git a/includes/class-template.php b/includes/class-template.php
index a33c904994..813b0a6525 100644
--- a/includes/class-template.php
+++ b/includes/class-template.php
@@ -12,6 +12,9 @@
*/
/** If this file is called directly, abort. */
+
+use GV\Grid;
+
if ( ! defined( 'ABSPATH' ) ) {
die;
}
@@ -530,7 +533,7 @@ public function getPaginationCounts() {
* @since 1.13
* @param array $counts Array with $first, $last, $total numbers in that order
*/
- list( $first, $last, $total ) = apply_filters( 'gravityview_pagination_counts', array( $first, $last, $total ) );
+ [ $first, $last, $total ] = apply_filters( 'gravityview_pagination_counts', array( $first, $last, $total ) );
return array(
'first' => (int) $first,
@@ -945,7 +948,7 @@ public function render_widget_hooks( $view_id_or_context ) {
return;
}
- $rows = \GV\Widget::get_default_widget_areas();
+ $rows = Grid::get_rows_from_collection( $widgets, $zone );
// TODO: Move to sep. method, use an action instead
wp_enqueue_style( 'gravityview_default_style' );
@@ -975,10 +978,12 @@ public function render_widget_hooks( $view_id_or_context ) {
// TODO Convert to partials
?>
-
+
+ $areas ) {
- $column = ( '2-2' == $col ) ? '1-2 gv-right' : "$col gv-left";
+ $is_right = ( '2-2' === $col || strpos( $col, ' right' ) !== false );
+ $column = $col . ' gv-' . ( $is_right ? 'right' : 'left' );
?>
+
diff --git a/includes/extensions/duplicate-entry/class-duplicate-entry.php b/includes/extensions/duplicate-entry/class-duplicate-entry.php
index a82a8edf15..b0deb23aba 100644
--- a/includes/extensions/duplicate-entry/class-duplicate-entry.php
+++ b/includes/extensions/duplicate-entry/class-duplicate-entry.php
@@ -437,7 +437,7 @@ public function process_duplicate() {
$redirect_to_base = esc_url_raw( remove_query_arg( array( 'action', 'gvid', 'entry_id' ) ) );
$redirect_to = add_query_arg( $messages, $redirect_to_base );
- if ( defined( 'DOING_GRAVITYVIEW_TESTS' ) || ! apply_filters( 'wp_redirect', $redirect_to ) ) {
+ if ( defined( 'DOING_GRAVITYVIEW_TESTS' ) || ! apply_filters( 'wp_redirect', $redirect_to, 302 ) ) {
return $redirect_to;
}
diff --git a/includes/extensions/edit-entry/class-edit-entry-admin.php b/includes/extensions/edit-entry/class-edit-entry-admin.php
index d9d7b4dcb7..0893a00f7b 100644
--- a/includes/extensions/edit-entry/class-edit-entry-admin.php
+++ b/includes/extensions/edit-entry/class-edit-entry-admin.php
@@ -64,6 +64,8 @@ public function view_settings_metabox( $current_settings ) {
GravityView_Render_Settings::render_setting_row( 'action_label_update', $current_settings );
+ GravityView_Render_Settings::render_setting_row( 'edit_cancel_lightbox_action', $current_settings );
+
GravityView_Render_Settings::render_setting_row( 'action_label_cancel', $current_settings );
}
diff --git a/includes/extensions/edit-entry/class-edit-entry-render.php b/includes/extensions/edit-entry/class-edit-entry-render.php
index 74d2c9dc78..450e849d0c 100644
--- a/includes/extensions/edit-entry/class-edit-entry-render.php
+++ b/includes/extensions/edit-entry/class-edit-entry-render.php
@@ -1556,7 +1556,7 @@ private function get_field_value( $field ) {
$override_saved_value = apply_filters( 'gravityview/edit_entry/pre_populate/override', false, $field );
// We're dealing with multiple inputs (e.g. checkbox) but not time or date (as it doesn't store data in input IDs)
- if ( isset( $field->inputs ) && is_array( $field->inputs ) && ! in_array( $field->type, array( 'time', 'date' ) ) ) {
+ if ( isset( $field->inputs ) && is_array( $field->inputs ) && ! in_array( $field->type, array( 'time', 'date' ) ) && ! ( $field instanceof GF_Field_Radio && in_array($field->type, array('image_choice','multi_choice')) ) ) {
$field_value = array();
diff --git a/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php b/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php
index bff8b447ee..03767f9b1b 100644
--- a/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php
+++ b/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php
@@ -43,6 +43,7 @@ public function __construct() {
add_filter( 'gravityview/view/links/directory', [ $this, 'rewrite_directory_link' ] );
add_filter( 'gform_get_form_confirmation_filter', [ $this, 'process_gravity_forms_form_submission' ] );
add_filter( 'gform_get_form_filter', [ $this, 'process_gravity_forms_form_submission' ] );
+ add_filter( 'gk/gravityview/lightbox/entry/output/head-after', [ $this, 'run_during_head_output' ], 10, 2 );
}
/**
@@ -323,7 +324,14 @@ private function process_edit_entry( $nonce, $view, $entry, $form ) {
}
add_filter( 'gravityview/edit_entry/verify_nonce', '__return_true' );
- add_filter( 'gravityview/edit_entry/cancel_onclick', '__return_empty_string' );
+
+ add_filter( 'gravityview/edit_entry/cancel_onclick', function () use ( $view ) {
+ if ( 'close_lightbox' === $view->settings->get( 'edit_cancel_lightbox_action' ) ) {
+ return 'window.parent.postMessage( { closeFancybox: true, } );';
+ } else {
+ return '';
+ }
+ } );
// Prevent redirection inside the lightbox by sending event to the parent window and hiding the success message.
if ( ! in_array( $view->settings->get( 'edit_redirect' ), [ '1', '2' ] ) ) {
@@ -464,6 +472,22 @@ private function render_entry( $type, $view, $entry, $form ) {
do_action_ref_array( 'wp', [ $wp ] );
+ /**
+ * Fires before rendering the lightbox entry view.
+ *
+ * @action `gk/gravityview/lightbox/entry/before-output`
+ *
+ * @since 2.31.0
+ *
+ * @param array $args {
+ * @type View $view The View object being rendered.
+ * @type GF_Entry $entry The Gravity Forms entry data.
+ * @type array $form The Gravity Forms form array.
+ * @type Entry_Render $entry_renderer The renderer object responsible for rendering the entry.
+ * }
+ */
+ do_action_ref_array( 'gk/gravityview/lightbox/entry/before-output', [ &$view, &$entry, &$form, &$entry_renderer ] );
+
ob_start();
$title = do_shortcode(
@@ -483,9 +507,25 @@ private function render_entry( $type, $view, $entry, $form ) {
?>
+ tag.
+ *
+ * @action `gk/gravityview/lightbox/entry/output/head-before`
+ *
+ * @since 2.31.0
+ *
+ * @param string $type The type of the entry view (single or edit).
+ * @param View $view The View object being rendered.
+ * @param GF_Entry $entry The Gravity Forms entry data.
+ * @param array $form The Gravity Forms form array.
+ */
+ do_action( 'gk/gravityview/lightbox/entry/output/head-before', $type, $view, $entry, $form );
+ ?>
+
-
+