From 15bf6674a36582d2ae736bfec651239884b9cab5 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Sat, 4 Sep 2021 20:56:59 +0200 Subject: Move the concerts table and edit form out of AdminPage. Currently the AdminPage is still responsible for updating changes to any of the concerts, but I'd like to get that into their respective classes too. That way the AdminPage will just be a simple class to handle the layout of the page, while all the specific functionality is in their own classes. This is also the first step to be able to reuse the concerts table on the public end of the site. --- includes/admin/views/_concerts_table.php | 199 +++++++++++++++++++++ includes/admin/views/_edit_concert_form.php | 82 +++++++++ includes/admin/views/giglog_admin_page.php | 258 ++-------------------------- 3 files changed, 291 insertions(+), 248 deletions(-) create mode 100644 includes/admin/views/_concerts_table.php create mode 100644 includes/admin/views/_edit_concert_form.php diff --git a/includes/admin/views/_concerts_table.php b/includes/admin/views/_concerts_table.php new file mode 100644 index 0000000..37459a3 --- /dev/null +++ b/includes/admin/views/_concerts_table.php @@ -0,0 +1,199 @@ + +// SPDX-FileCopyrightText: 2021 Harald Eilertsen +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +if (!class_exists("GiglogAdmin_ConcertsTable")) +{ + class GiglogAdmin_ConcertsTable + { + const STATUS_LABELS = [ + '', + 'Accred Requested', + 'Photo Approved', + 'Text Approved', + 'Photo and Text Approved', + 'Rejected' + ]; + + private string $username; + + public function __construct() { + $this->username = wp_get_current_user()->user_login; + } + + public function render(): string + { + return $this->render_filters() + . $this->render_concerts_table(); + } + + private function render_concerts_table() : string + { + $content = ''; + // $content .= ''; + + $content .= ' + + + '; + if (current_user_can('administrator')) + $content .= ''; + $content .= ''; + + $filter = []; + + // Use the submitted "city" if any. Otherwise, use the default/static value. + $cty = filter_input( INPUT_POST, 'selectcity', FILTER_SANITIZE_SPECIAL_CHARS ); + if ($cty) $filter['city'] = $cty; + + $venue = filter_input( INPUT_POST, 'selectvenue', FILTER_SANITIZE_SPECIAL_CHARS ); + if ($venue) $filter['venue_id'] = $venue; + + $concerts = GiglogAdmin_Concert::find_concerts($filter); + + $lastType = ''; + + foreach ( $concerts AS $concert ) { + $content .= ''; + + if ($lastType != '' && $lastType != $concert->venue()->city()) { + $content .= ''; + } + + if ($lastType == '' ) { + $content .= ''; + } + // Modify these to match the database structure + // $content .= ''; + $content .= ''; + $content .= ''; + $content .= ''; + $fdate = strtotime($concert->cdate()); + $newformat = date('d.M.Y',$fdate); + + //$content .= DATE_FORMAT($fdate,'%d.%b.%Y'); + $content .= ''; + $content .= ''; + + $content .= ''; + $content .= ''; + $content .= ''; + $content .= ''; + + $content .= ''; + + if (current_user_can('administrator')) { + $content .= + ''; + } + $content .= ''; + $lastType = $concert->venue()->city(); + } + $content .= '
CITYIDBANDVENUEDATE
CITYNAMEVENUEDATE PHOTO1PHOTO2TEXT1TEXT2STATUSAdminOptions
' . $concert->city() . '
' . $concert->venue()->city() . '
' . $row->id. '' . $concert->cname() . '' . $concert->venue()->name() . '' . $newformat . '' . $this->mark_new_concert($concert) . '' . $this->assign_role_for_user_form('photo1', $concert) . '' . $this->assign_role_for_user_form('photo2', $concert) . '' . $this->assign_role_for_user_form('rev1', $concert) . '' . $this->assign_role_for_user_form('rev2', $concert) . '' . self::STATUS_LABELS[$concert->status()] . '' + . $this->adminactions($concert) + . '
'; + + // return the table + return $content; + } + + private function render_filters() : string + { + $cty = filter_input(INPUT_POST, 'selectcity', FILTER_SANITIZE_SPECIAL_CHARS); + + $select = '
FILTER DATA:'; + $select .= \EternalTerror\ViewHelpers\select_field( + "selectcity", + array_map(fn($city) => [$city, $city], GiglogAdmin_Venue::all_cities()), + $cty, + "Select city..."); + + + if ( !empty($cty) ) { + //second drop down for venue + $select .= \EternalTerror\ViewHelpers\select_field( + "selectvenue", + array_map( + fn($venue) => [$venue->id(), $venue->name()], + GiglogAdmin_Venue::venues_in_city($cty) + ), + filter_input(INPUT_POST, 'selectvenue', FILTER_SANITIZE_SPECIAL_CHARS), + "Select venue..."); + } + //option to select own concerts only + $select .= '' + . '' + . \EternalTerror\ViewHelpers\select_field( + 'selectstatus', + array_map(fn($i) => [ $i, self::STATUS_LABELS[$i] ], range(1, count(self::STATUS_LABELS) - 1)), + $concert->status()) + . '' + . '' + . '
'; + } + + /** + * Display a mark on the concert if it is new. + * I.e. imported/created within the last ten days. + * + * @return null|string + */ + private function mark_new_concert(GiglogAdmin_Concert $concert) : string + { + $now = new DateTime(); + $new_entry = $now->diff($concert->created())->days <= 10; + if ($new_entry) { + return 'NEW'; + } + else { + return ''; + } + } + + private function assign_role_for_user_form(string $role, GiglogAdmin_Concert $concert) : ?string + { + $roles = $concert->roles(); + $assigned_user = array_key_exists($role, $roles) ? $roles[$role] : NULL; + + //first check if current slot is taken by current user + if ( $assigned_user == $this->username ) { + $f = '
' + . ' ' + . ' ' + . ' ' + . '
'; + } + elseif ( $assigned_user ) { //check if slot is taken by another user + $f = 'Taken' + . '
Taken by ' . $assigned_user . '
'; + } + elseif ( array_search($this->username, $roles) ) { + // other slots for this concert are taken by user + $f = '-'; + } + else { //not taken by anyone + $f = '
' + . ' ' + . ' ' + . ' ' + . '
'; + } + + return $f; + } + } +} diff --git a/includes/admin/views/_edit_concert_form.php b/includes/admin/views/_edit_concert_form.php new file mode 100644 index 0000000..32ca762 --- /dev/null +++ b/includes/admin/views/_edit_concert_form.php @@ -0,0 +1,82 @@ + +// SPDX-FileCopyrightText: 2021 Harald Eilertsen +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +if (!class_exists("GiglogAdmin_EditConcertForm")) +{ + class GiglogAdmin_EditConcertForm + { + private function get_venue_selector( ?GiglogAdmin_Venue $invenue ): string + { + return \EternalTerror\ViewHelpers\select_field( + "selectvenueadmin", + array_map(fn($venue) => [$venue->id(), $venue->name()], GiglogAdmin_Venue::all_venues()), + $invenue ? $invenue->id() : null); + } + + + private function user_dropdown_for_role( GiglogAdmin_Concert $concert, string $role): string + { + $users = array_map( + fn($usr) => $usr->user_login, + get_users( array( 'fields' => array( 'user_login' ) ) ) ); + + $roles = $concert->roles(); + + $current_user = array_key_exists($role, $roles) ? $roles[$role] : NULL; + + return \EternalTerror\ViewHelpers\select_field( + $role, + array_map( fn($user) => [ $user, $user ], $users ), + $current_user); + } + + + + public function render() : string + { + $cid = filter_input(INPUT_POST, "cid"); + $editing = filter_input(INPUT_POST, "edit") == "EDIT"; + + if ($editing && !empty($cid)) //A bit overdoing with the checks if concert ID is empty both here and in find_cid. But based on that, things are NULL or not. Better ideas? + $c = GiglogAdmin_Concert::get($cid); + else + $c = new GiglogAdmin_Concert((object)[]); + + $content='

Form to create/edit concerts and venues


'; + $content.='
' + .'
CONCERT DETAILS

' + .'' + .'
' + .'' . $this->get_venue_selector($c->venue()) . '
' + .'
' + .'
' + .'
' + .'
'; + // actions differ if we update or create a concert, hence two buttons needed + if ($editing) + $content.='

'; + else + $content.='

'; + + $content.='
'; + + $content.='
ASSIGNMENT DETAILS

' + .''.$this->user_dropdown_for_role($c,'photo1').'
' + .''.$this->user_dropdown_for_role($c,'photo2').'
' + .''.$this->user_dropdown_for_role($c,'rev1').'
' + .''.$this->user_dropdown_for_role($c,'rev2').'
'; + + $content.='
'; + $content.='
VENUE DETAILS

' + .'

' + .'
' + .'

' + .'
'; + $content.='
'; + return $content; + } + } +} diff --git a/includes/admin/views/giglog_admin_page.php b/includes/admin/views/giglog_admin_page.php index dfea3fd..89ca490 100644 --- a/includes/admin/views/giglog_admin_page.php +++ b/includes/admin/views/giglog_admin_page.php @@ -7,10 +7,11 @@ if ( !class_exists( 'GiglogAdmin_AdminPage' ) ) { require_once __DIR__ . '/../../venue.php'; + require_once __DIR__ . '/_concerts_table.php'; + require_once __DIR__ . '/_edit_concert_form.php'; - class GiglogAdmin_AdminPage { - private string $username; - + class GiglogAdmin_AdminPage + { const STATUS_LABELS = [ '', 'Accred Requested', @@ -20,19 +21,15 @@ if ( !class_exists( 'GiglogAdmin_AdminPage' ) ) { 'Rejected' ]; - public function __construct() - { - $this->username = wp_get_current_user()->user_login; - } - public static function render_html() : void { $page = new self(); $page->render_page(); } - public function render_page() : void + private function render_page() : void { + $concerts = new GiglogAdmin_ConcertsTable(); ?>

Giglog Admin

@@ -51,219 +48,15 @@ if ( !class_exists( 'GiglogAdmin_AdminPage' ) ) { what the accreditation status is. You will get personal message if this is really close to the concert date.

-

get_filters() ?>

-

get_concerts() ?>

+

render() ?>

[$venue->id(), $venue->name()], GiglogAdmin_Venue::all_venues()), - $invenue ? $invenue->id() : null); - } - - - private function user_dropdown_for_role( GiglogAdmin_Concert $concert, string $role): string - { - $users = array_map( - fn($usr) => $usr->user_login, - get_users( array( 'fields' => array( 'user_login' ) ) ) ); - - $roles = $concert->roles(); - - $current_user = array_key_exists($role, $roles) ? $roles[$role] : NULL; - - return \EternalTerror\ViewHelpers\select_field( - $role, - array_map( fn($user) => [ $user, $user ], $users ), - $current_user); - } - - - private function get_filters() : string - { - $cty = filter_input(INPUT_POST, 'selectcity', FILTER_SANITIZE_SPECIAL_CHARS); - - $select = '
FILTER DATA:'; - $select .= \EternalTerror\ViewHelpers\select_field( - "selectcity", - array_map(fn($city) => [$city, $city], GiglogAdmin_Venue::all_cities()), - $cty, - "Select city..."); - - - if ( !empty($cty) ) { - //second drop down for venue - $select .= \EternalTerror\ViewHelpers\select_field( - "selectvenue", - array_map( - fn($venue) => [$venue->id(), $venue->name()], - GiglogAdmin_Venue::venues_in_city($cty) - ), - filter_input(INPUT_POST, 'selectvenue', FILTER_SANITIZE_SPECIAL_CHARS), - "Select venue..."); + if (current_user_can('administrator')) { + $form = new GiglogAdmin_EditConcertForm(); + echo $form->render(); } - //option to select own concerts only - $select .= 'CONCERT DETAILS

' - .'' - .'
' - .'' . $this->get_venue_selector($c->venue()) . '
' - .'
' - .'
' - .'
' - .'
'; - // actions differ if we update or create a concert, hence two buttons needed - if ($editing) - $content.='

'; - else - $content.='

'; - - $content.=''; - - $content.='
ASSIGNMENT DETAILS

' - .''.$this->user_dropdown_for_role($c,'photo1').'
' - .''.$this->user_dropdown_for_role($c,'photo2').'
' - .''.$this->user_dropdown_for_role($c,'rev1').'
' - .''.$this->user_dropdown_for_role($c,'rev2').'
'; - - $content.='
'; - $content.='
VENUE DETAILS

' - .'

' - .'
' - .'

' - .'
'; - $content.=''; - return $content; - } - - private function adminactions( GiglogAdmin_Concert $concert ) : string - { - return - '
' - . '' - . \EternalTerror\ViewHelpers\select_field( - 'selectstatus', - array_map(fn($i) => [ $i, self::STATUS_LABELS[$i] ], range(1, count(self::STATUS_LABELS) - 1)), - $concert->status()) - . '' - . '' - . '
'; - } - - //function to calculate if the concert has been added in the past 10 days or before that and show a green NEW for the newest rows - /** - * @return null|string - */ - private function getpublishstatus(GiglogAdmin_Concert $concert) : string - { - $now = new DateTime(); - $new_entry = $now->diff($concert->created())->days <= 10; - if ($new_entry) { - return 'NEW'; - } - else { - return ''; - } - } - - - private function get_concerts(): string - { - $content = ''; - // $content .= ''; - - $content .= ' - - - '; - if (current_user_can('administrator')) - $content .= ''; - $content .= ''; - - $filter = []; - - // Use the submitted "city" if any. Otherwise, use the default/static value. - $cty = filter_input( INPUT_POST, 'selectcity', FILTER_SANITIZE_SPECIAL_CHARS ); - if ($cty) $filter['city'] = $cty; - - $venue = filter_input( INPUT_POST, 'selectvenue', FILTER_SANITIZE_SPECIAL_CHARS ); - if ($venue) $filter['venue_id'] = $venue; - - $concerts = GiglogAdmin_Concert::find_concerts($filter); - - $lastType = ''; - - foreach ( $concerts AS $concert ) { - $content .= ''; - - if ($lastType != '' && $lastType != $concert->venue()->city()) { - $content .= ''; - } - - if ($lastType == '' ) { - $content .= ''; - } - // Modify these to match the database structure - // $content .= ''; - $content .= ''; - $content .= ''; - $content .= ''; - $fdate = strtotime($concert->cdate()); - $newformat = date('d.M.Y',$fdate); - - //$content .= DATE_FORMAT($fdate,'%d.%b.%Y'); - $content .= ''; - $content .= ''; - - $content .= ''; - $content .= ''; - $content .= ''; - $content .= ''; - - $content .= ''; - - if (current_user_can('administrator')) { - $content .= - ''; - } - $content .= ''; - $lastType = $concert->venue()->city(); - } - $content .= '
CITYIDBANDVENUEDATE
CITYNAMEVENUEDATE PHOTO1PHOTO2TEXT1TEXT2STATUSAdminOptions
' . $concert->city() . '
' . $concert->venue()->city() . '
' . $row->id. '' . $concert->cname() . '' . $concert->venue()->name() . '' . $newformat . '' . $this->getpublishstatus($concert) . '' . $this->assign_role_for_user_form('photo1', $concert) . '' . $this->assign_role_for_user_form('photo2', $concert) . '' . $this->assign_role_for_user_form('rev1', $concert) . '' . $this->assign_role_for_user_form('rev2', $concert) . '' . self::STATUS_LABELS[$concert->status()] . '' - . $this->adminactions($concert) - . '
'; - - // return the table - return $content; - } - - /** * @return void */ @@ -397,37 +190,6 @@ if ( !class_exists( 'GiglogAdmin_AdminPage' ) ) { wp_mail( $to, $subject, $body, $headers ); } - private function assign_role_for_user_form(string $role, GiglogAdmin_Concert $concert) : ?string - { - $roles = $concert->roles(); - $assigned_user = array_key_exists($role, $roles) ? $roles[$role] : NULL; - - //first check if current slot is taken by current user - if ( $assigned_user == $this->username ) { - $f = '
' - . ' ' - . ' ' - . ' ' - . '
'; - } - elseif ( $assigned_user ) { //check if slot is taken by another user - $f = 'Taken' - . '
Taken by ' . $assigned_user . '
'; - } - elseif ( array_search($this->username, $roles) ) { - // other slots for this concert are taken by user - $f = '-'; - } - else { //not taken by anyone - $f = '
' - . ' ' - . ' ' - . ' ' - . '
'; - } - - return $f; - } } } ?> -- cgit v1.2.3 From 20a05190275d3dce43061fad1d30f3d4847c8f1f Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Sat, 4 Sep 2021 21:00:28 +0200 Subject: Drop extra query for venue_id in concert queries. It's not required since the id is in the concerts table too. That's what links them together. --- includes/concert.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/concert.php b/includes/concert.php index a533679..29de015 100644 --- a/includes/concert.php +++ b/includes/concert.php @@ -31,7 +31,7 @@ if ( !class_exists('GiglogAdmin_Concert') ) { public const STATUS_REJECTED = 5; private const BASE_QUERY = - 'SELECT wpg_concerts.*, wpg_venues.id as venue_id, wpg_venues.wpgvenue_name wpg_venues_wpgvenue_city ' + 'SELECT wpg_concerts.*, wpg_venues.wpgvenue_name wpg_venues_wpgvenue_city ' . 'FROM wpg_concerts ' . 'LEFT JOIN wpg_venues ON wpg_concerts.venue = wpg_venues.id '; -- cgit v1.2.3