From 2d3f7d73c7862d7c09b6f5ea4189e936c7a3de3b Mon Sep 17 00:00:00 2001 From: Vlad Date: Tue, 27 Aug 2024 11:50:11 -0400 Subject: [PATCH 1/3] Add filter to control sorting in View entries query (#1759) This allows for more granular control of sorting parameters for each when fetching View entries. --- future/includes/class-gv-view.php | 57 +++++++++++++++++++++---------- readme.txt | 3 ++ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/future/includes/class-gv-view.php b/future/includes/class-gv-view.php index 26cfc7edfd..7d1a756ad5 100644 --- a/future/includes/class-gv-view.php +++ b/future/includes/class-gv-view.php @@ -7,6 +7,8 @@ use GravityKitFoundation; use GravityView_Compatibility; use GravityView_Cache; +use GravityView_frontend; +use GVCommon; /** If this file is called directly, abort. */ if ( ! defined( 'GRAVITYVIEW_DIR' ) ) { @@ -327,7 +329,7 @@ public static function content( $content ) { * This View has no data source. There's nothing to show really. * ...apart from a nice message if the user can do anything about it. */ - if ( \GVCommon::has_cap( array( 'edit_gravityviews', 'edit_gravityview' ), $view->ID ) ) { + if ( GVCommon::has_cap( array( 'edit_gravityviews', 'edit_gravityview' ), $view->ID ) ) { $title = sprintf( __( 'This View is not configured properly. Start by selecting a form.', 'gk-gravityview' ), esc_url( get_edit_post_link( $view->ID, false ) ) ); @@ -335,7 +337,7 @@ public static function content( $content ) { $image = sprintf( '%s', esc_attr__( 'Data Source', 'gk-gravityview' ), esc_url( plugins_url( 'assets/images/screenshots/data-source.png', GRAVITYVIEW_FILE ) ) ); - return \GVCommon::generate_notice( '

' . $title . '

' . wpautop( $message . $image ), 'notice' ); + return GVCommon::generate_notice( '

' . $title . '

' . wpautop( $message . $image ), 'notice' ); } break; case 'in_trash': @@ -357,7 +359,7 @@ public static function content( $content ) { return $content; } - $is_admin_and_can_view = $view->settings->get( 'admin_show_all_statuses' ) && \GVCommon::has_cap( 'gravityview_moderate_entries', $view->ID ); + $is_admin_and_can_view = $view->settings->get( 'admin_show_all_statuses' ) && GVCommon::has_cap( 'gravityview_moderate_entries', $view->ID ); /** * Editing a single entry. @@ -414,7 +416,7 @@ public static function content( $content ) { } } - $error = \GVCommon::check_entry_display( $e->as_entry(), $view ); + $error = GVCommon::check_entry_display( $e->as_entry(), $view ); if ( is_wp_error( $error ) ) { gravityview()->log->error( @@ -535,7 +537,7 @@ public function can_render( $context = null, $request = null ) { * Is this View an embed-only View? If so, don't allow rendering here, * as this is a direct request. */ - if ( $this->settings->get( 'embed_only' ) && ! \GVCommon::has_cap( 'read_private_gravityviews' ) ) { + if ( $this->settings->get( 'embed_only' ) && ! GVCommon::has_cap( 'read_private_gravityviews' ) ) { return new \WP_Error( 'gravityview/embed_only' ); } } @@ -546,7 +548,7 @@ public function can_render( $context = null, $request = null ) { /** Private, pending, draft, etc. */ $public_states = get_post_stati( array( 'public' => true ) ); - if ( ! in_array( $this->post_status, $public_states, true ) && ! \GVCommon::has_cap( 'read_gravityview', $this->ID ) ) { + if ( ! in_array( $this->post_status, $public_states, true ) && ! GVCommon::has_cap( 'read_gravityview', $this->ID ) ) { gravityview()->log->notice( 'The current user cannot access this View #{view_id}', array( 'view_id' => $this->ID ) ); return new \WP_Error( 'gravityview/not_public' ); } @@ -1018,10 +1020,10 @@ public function get_entries( $request = null ) { /** * @todo: Stop using _frontend and use something like $request->get_search_criteria() instead */ - $parameters = \GravityView_frontend::get_view_entries_parameters( $parameters, $this->form->ID ); + $parameters = GravityView_frontend::get_view_entries_parameters( $parameters, $this->form->ID ); $parameters['context_view_id'] = $this->ID; - $parameters = \GVCommon::calculate_get_entries_criteria( $parameters, $this->form->ID ); + $parameters = GVCommon::calculate_get_entries_criteria( $parameters, $this->form->ID ); if ( ! is_array( $parameters ) ) { $parameters = array(); @@ -1102,24 +1104,43 @@ public function get_entries( $request = null ) { $sort_directions = $view_setting_sort_directions; } - foreach ( (array) $sort_field_ids as $key => $sort_field_id ) { - $sort_field_id = \GravityView_frontend::_override_sorting_id_by_field_type( $sort_field_id, $this->form->ID ); - $sort_direction = strtoupper( \GV\Utils::get( $sort_directions, $key, 'ASC' ) ); + $sorting_parameters = []; - if ( empty( $sort_field_id ) ) { + foreach ( $sort_field_ids as $key => $id ) { + $sorting_parameters[ $id ] = [ + 'id' => GravityView_frontend::_override_sorting_id_by_field_type( $id, $this->form->ID ), + 'type' => GVCommon::is_field_numeric( $this->form->ID, $id ) ? 'numeric' : 'string', + 'direction' => strtoupper( \GV\Utils::get( $sort_directions, $key, 'ASC' ) ), + ]; + } + + /** + * Modifies the sorting parameters applied during the retrieval of View entries. + * + * @filter `gk/gravityview/view/entries/query/sorting-parameters` + * + * @since TBD + * + * @param array $sorting_parameters The array of sorting parameters, including field IDs, directions, and casting types. + * @param View $this The View instance. + */ + $sorting_parameters = apply_filters( 'gk/gravityview/view/entries/query/sorting-parameters', $sorting_parameters, $this ); + + foreach ( $sorting_parameters as $field ) { + if ( empty( $field['id'] ) ) { continue; } - $sort_field_id = explode( '|', $sort_field_id ); + $sort_field_ids = explode( '|', $field['id'] ); - foreach ( $sort_field_id as $id ) { - $order = new \GF_Query_Column( $id, $this->form->ID ); + foreach ( $sort_field_ids as $field_id ) { + $order = new \GF_Query_Column( $field_id, $this->form->ID ); - if ( 'id' !== $id && \GVCommon::is_field_numeric( $this->form->ID, $id ) ) { + if ( 'id' !== $field_id && 'numeric' === $field['type'] ) { $order = \GF_Query_Call::CAST( $order, defined( 'GF_Query::TYPE_DECIMAL' ) ? \GF_Query::TYPE_DECIMAL : \GF_Query::TYPE_SIGNED ); } - $query->order( $order, $sort_direction ); + $query->order( $order, $field['direction'] ); } } } @@ -1816,7 +1837,7 @@ protected function apply_legacy_join_is_approved_query_conditions( \GF_Query $qu return; } - $is_admin_and_can_view = $this->settings->get( 'admin_show_all_statuses' ) && \GVCommon::has_cap( 'gravityview_moderate_entries', $this->ID ); + $is_admin_and_can_view = $this->settings->get( 'admin_show_all_statuses' ) && GVCommon::has_cap( 'gravityview_moderate_entries', $this->ID ); if ( $is_admin_and_can_view ) { return; diff --git a/readme.txt b/readme.txt index 19fe61a496..772f222cc3 100644 --- a/readme.txt +++ b/readme.txt @@ -32,6 +32,9 @@ Beautifully display your Gravity Forms entries. Learn more on [gravitykit.com](h * Fixed: The maximum number of files allowed in the File Upload field was not respected when editing an entry. * Fixed: Sorting the View by the Name field would yield incorrect results. +#### 💻 Developer Updates +* Added `gk/gravityview/view/entries/query/sorting-parameters` filter to modify the sorting parameters applied during the retrieval of View entries. + = 2.27.1 on August 14, 2024 = This release fixes an issue with adding fields in the View editor's Edit Entry layout when the Multiple Forms extension is enabled. From 6ad768ec4715586b0fe56cdf6f6519eafed28ccb Mon Sep 17 00:00:00 2001 From: Vlad Date: Tue, 27 Aug 2024 12:00:30 -0400 Subject: [PATCH 2/3] Trigger build From 0b6cc9892436e4c0060b3627c844aa177f16dedc Mon Sep 17 00:00:00 2001 From: Vlad Date: Wed, 28 Aug 2024 09:57:21 -0400 Subject: [PATCH 3/3] Refactor the sorting parameters code --- future/includes/class-gv-view.php | 38 ++++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/future/includes/class-gv-view.php b/future/includes/class-gv-view.php index 7d1a756ad5..faf5bf5bd4 100644 --- a/future/includes/class-gv-view.php +++ b/future/includes/class-gv-view.php @@ -1107,11 +1107,21 @@ public function get_entries( $request = null ) { $sorting_parameters = []; foreach ( $sort_field_ids as $key => $id ) { - $sorting_parameters[ $id ] = [ - 'id' => GravityView_frontend::_override_sorting_id_by_field_type( $id, $this->form->ID ), - 'type' => GVCommon::is_field_numeric( $this->form->ID, $id ) ? 'numeric' : 'string', - 'direction' => strtoupper( \GV\Utils::get( $sort_directions, $key, 'ASC' ) ), - ]; + // The original field ID can be overridden for certain fields, including the Name field + // where a single ID becomes multiple field input IDs joined by a pipe (e.g., "3.3|3.6"). + $id_overrides = explode( + '|', + GravityView_frontend::_override_sorting_id_by_field_type( $id, $this->form->ID ) + ); + + foreach ( $id_overrides as $id_override ) { + $sorting_parameters[] = [ + '_original_id' => $id, + 'id' => $id_override, + 'is_numeric' => GVCommon::is_field_numeric( $this->form->ID, $id ), + 'direction' => strtoupper( \GV\Utils::get( $sort_directions, $key, 'ASC' ) ), + ]; + } } /** @@ -1121,8 +1131,8 @@ public function get_entries( $request = null ) { * * @since TBD * - * @param array $sorting_parameters The array of sorting parameters, including field IDs, directions, and casting types. - * @param View $this The View instance. + * @param array $sorting_parameters The array of sorting parameters, including field ID, field type (direction, and casting types. + * @param View $this The View instance. */ $sorting_parameters = apply_filters( 'gk/gravityview/view/entries/query/sorting-parameters', $sorting_parameters, $this ); @@ -1131,17 +1141,13 @@ public function get_entries( $request = null ) { continue; } - $sort_field_ids = explode( '|', $field['id'] ); - - foreach ( $sort_field_ids as $field_id ) { - $order = new \GF_Query_Column( $field_id, $this->form->ID ); + $order = new \GF_Query_Column( $field['id'], $this->form->ID ); - if ( 'id' !== $field_id && 'numeric' === $field['type'] ) { - $order = \GF_Query_Call::CAST( $order, defined( 'GF_Query::TYPE_DECIMAL' ) ? \GF_Query::TYPE_DECIMAL : \GF_Query::TYPE_SIGNED ); - } - - $query->order( $order, $field['direction'] ); + if ( 'id' !== $field['id'] && (int) $field['is_numeric'] ) { + $order = \GF_Query_Call::CAST( $order, defined( 'GF_Query::TYPE_DECIMAL' ) ? \GF_Query::TYPE_DECIMAL : \GF_Query::TYPE_SIGNED ); } + + $query->order( $order, $field['direction'] ); } }