From 5d07953def22327815c0caab94cf17d07eacc57b Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Sun, 13 Feb 2022 13:02:47 +0100 Subject: Remember filter settings when paginating. This patch does changes quite a bit of how things work under the hood. It changes the filter settings from using POST to using query args in a GET request instead. This has some challenges: 1. The query args from the form will overwrite any query args in the original URL, so we have to keep the query args that was passed in as hidden fields in the form. 2. Since we try to keep the passed in query args, we need to filter out the query args that we expect to set in the form, otherwise query args that are dropped by the form will still be present as hidden args. Not too happy about how this works tbh, but at least it seems to work reasonably well for now. I've also renamed the args set by the form to make the URL a bit nicer, i.e "city" instead of "selectcity" etc for the query arg keys. I've also refactored quite a bit to make the code more manageable. Like using the view helper to create the month selector, so it's consistent with the others, and remembers it's selection. (I also simplified it to simply list the months from jan to dec, instead of starting at the current month. If it's important to keep the old behaviour I'll change it back.) There's a few problems still with this implementation. 1. It only works in the admin-section for now. Not sure why. Probably because shortcodes... 2. In the admin section it gains the `cid` and `pid` query args that should not be there. Not sure why. 3. If we change the filters while being on a page larger than the total number of pages after the filter change, we stay on the page even if it's not a valid page after the filter change. This should be trivial to fix. --- includes/admin/views/_concerts_table.php | 93 ++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 33 deletions(-) diff --git a/includes/admin/views/_concerts_table.php b/includes/admin/views/_concerts_table.php index 7edb1df..86c1bf3 100644 --- a/includes/admin/views/_concerts_table.php +++ b/includes/admin/views/_concerts_table.php @@ -17,10 +17,18 @@ if (!class_exists("GiglogAdmin_ConcertsTable")) 'Rejected' ]; + const FILTER_KEYS = [ + 'city', + 'venue', + 'month', + 'only_mine' + ]; + private string $username; public function __construct() { $this->username = wp_get_current_user()->user_login; + $this->get_args(); } public function render(): string @@ -51,29 +59,28 @@ if (!class_exists("GiglogAdmin_ConcertsTable")) return $content; } - private function get_concerts() : ?array + private function get_args() : void { - $total_records_per_page = 15; - $filter = []; + $this->filter = []; // Use the submitted "city" if any. Otherwise, use the default/static value. - $cty = filter_input( INPUT_POST, 'selectcity', FILTER_SANITIZE_SPECIAL_CHARS ); + $cty = filter_input( INPUT_GET, 'city', FILTER_SANITIZE_SPECIAL_CHARS ); if ($cty) { - $filter['city'] = $cty; + $this->filter['city'] = $cty; } - $venue = filter_input( INPUT_POST, 'selectvenue', FILTER_SANITIZE_SPECIAL_CHARS ); + $venue = filter_input( INPUT_GET, 'venue', FILTER_SANITIZE_SPECIAL_CHARS ); if ($venue) { - $filter['venue_id'] = $venue; + $this->filter['venue_id'] = $venue; } - $smonth = filter_input( INPUT_POST, 'selectmonth', FILTER_SANITIZE_SPECIAL_CHARS ); + $smonth = filter_input( INPUT_GET, 'month', FILTER_SANITIZE_SPECIAL_CHARS ); if ($smonth) { - $filter['month'] = $smonth; + $this->filter['month'] = $smonth; } - if(isset($_POST['ownconcerts']) && $_POST['ownconcerts'] == '1') { - $filter['currentuser'] = wp_get_current_user()->user_login; + if(isset($_GET['only_mine']) && $_GET['only_mone'] == '1') { + $this->filter['currentuser'] = $this->username; } if (isset($_GET['page_no']) && $_GET['page_no'] != "" && is_numeric($_GET['page_no'])) { @@ -81,8 +88,13 @@ if (!class_exists("GiglogAdmin_ConcertsTable")) } else { $this->page_no = 1; } + } - $total_concerts = GiglogAdmin_Concert::count( $filter ); + private function get_concerts() : ?array + { + $total_records_per_page = 15; + + $total_concerts = GiglogAdmin_Concert::count( $this->filter ); $this->total_no_of_pages = ceil( $total_concerts / $total_records_per_page ); //calculate OFFSET Value and SET other Variables @@ -90,10 +102,15 @@ if (!class_exists("GiglogAdmin_ConcertsTable")) $this->previous_page = $this->page_no - 1; $this->next_page = $this->page_no + 1; - $filter['offset'] = $offset; - $filter['recperpage'] = $total_records_per_page; + $this->filter['offset'] = $offset; + $this->filter['recperpage'] = $total_records_per_page; + + return GiglogAdmin_Concert::find_concerts($this->filter); + } - return GiglogAdmin_Concert::find_concerts($filter); + private function get_filter(string $f) : ?string + { + return isset( $this->filter[$f] ) ? $this->filter[$f] : null; } private function render_pagination() : string @@ -115,9 +132,7 @@ if (!class_exists("GiglogAdmin_ConcertsTable")) $content .= '' . '' - // . '
' . 'Page ' . $this->page_no . ' of ' . $this->total_no_of_pages . '' - //. '
' . '
'; $content .= ''; @@ -210,11 +225,23 @@ if (!class_exists("GiglogAdmin_ConcertsTable")) private function render_filters() : string { - $cty = filter_input(INPUT_POST, 'selectcity', FILTER_SANITIZE_SPECIAL_CHARS); + global $wp_locale; - $select = '

FILTER DATA: ' - . \EternalTerror\ViewHelpers\select_field( - "selectcity", + $select = '

FILTER DATA: '; + + foreach( $_GET as $name => $val ) { + if ( in_array( $name, self::FILTER_KEYS ) ) { + continue; + } + + $select .= ''; + } + + $cty = $this->get_filter('city'); + + $select .= \EternalTerror\ViewHelpers\select_field( + "city", array_map(fn($city) => [$city, $city], GiglogAdmin_Venue::all_cities()), $cty, "Select city..."); @@ -223,30 +250,30 @@ if (!class_exists("GiglogAdmin_ConcertsTable")) if ( !empty($cty) ) { //second drop down for venue $select .= \EternalTerror\ViewHelpers\select_field( - "selectvenue", + "venue", array_map( fn($venue) => [$venue->id(), $venue->name()], GiglogAdmin_Venue::venues_in_city($cty) ), - filter_input(INPUT_POST, 'selectvenue', FILTER_SANITIZE_SPECIAL_CHARS), + $this->get_filter('venue_id'), "Select venue..."); } - $select.=' Filter by month: '; - $select.= ''; if(is_admin()) { //option to select own concerts only - $select .= 'get_filter( 'current_user' ) ) . '>'; } -- cgit v1.2.3