diff options
author | Harald Eilertsen <haraldei@anduin.net> | 2022-02-13 13:02:47 +0100 |
---|---|---|
committer | Harald Eilertsen <haraldei@anduin.net> | 2022-02-13 13:02:47 +0100 |
commit | 5d07953def22327815c0caab94cf17d07eacc57b (patch) | |
tree | 84d15a29ddd18c2a5bf53c67f46942b4cd924548 | |
parent | 2fa078eaea0c0ca39fd4547cd34c9560cd56c540 (diff) | |
download | gigologadmin-5d07953def22327815c0caab94cf17d07eacc57b.tar.gz gigologadmin-5d07953def22327815c0caab94cf17d07eacc57b.tar.bz2 gigologadmin-5d07953def22327815c0caab94cf17d07eacc57b.zip |
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.
-rw-r--r-- | includes/admin/views/_concerts_table.php | 93 |
1 files 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 .= '</span>' . '<span class="aligncenter" style="text-align:center;flex:auto">' - // . '<div style="padding: 10px 20px 0px; border-top: dotted 1px #CCC;">' . '<strong>Page ' . $this->page_no . ' of ' . $this->total_no_of_pages . '</strong>' - //. '</div>' . '</span>'; $content .= '<span class="alignright" style="text-align:right;flex:auto;float:none">'; @@ -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 = '<p><form method="POST" action="" class="filterclass">FILTER DATA: ' - . \EternalTerror\ViewHelpers\select_field( - "selectcity", + $select = '<p><form method="GET" action="" class="filterclass">FILTER DATA: '; + + foreach( $_GET as $name => $val ) { + if ( in_array( $name, self::FILTER_KEYS ) ) { + continue; + } + + $select .= '<input type="hidden" name="' . esc_attr( $name ) + . '" value="' . esc_attr( $val ) . '">'; + } + + $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.= '<select name="selectmonth" size="1"><option value="0" selected="selected">- - All - -</option>'; - for ($i = 0; $i < 12; $i++) { - $time = strtotime(sprintf('%d months', $i)); - $label = date('F', $time); - $value = date('n', $time); - $select.= "<option value='$value'>$label</option>"; - } + $select .= \EternalTerror\ViewHelpers\select_field( + "month", + array_map( + fn($m) => [ $m, $wp_locale->get_month( $m ) ], + range( 1, 12 ) + ), + $this->get_filter('month'), + "Select month..."); $select.='</select>'; if(is_admin()) { //option to select own concerts only - $select .= '<input name="ownconcerts" class="ownconc" type="checkbox" value="1"' - . checked(isset($_POST['ownconcerts']) ? $_POST['ownconcerts'] : false) + $select .= '<input name="only_mine" class="ownconc" type="checkbox" value="1"' + . checked( $this->get_filter( 'current_user' ) ) . '><label for="ownconcerts">Show own concerts only</label>'; } |