diff --git a/controllers/ManageAlbums.php b/controllers/ManageAlbums.php index 662714b..aa48f20 100644 --- a/controllers/ManageAlbums.php +++ b/controllers/ManageAlbums.php @@ -54,27 +54,19 @@ class ManageAlbums extends HTMLController 'value' => 'count', ], ], - 'start' => !empty($_GET['start']) ? (int) $_GET['start'] : 0, - 'sort_order' => !empty($_GET['order']) ? $_GET['order'] : null, - 'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : null, + 'default_sort_order' => 'tag', + 'default_sort_direction' => 'up', + 'start' => $_GET['start'] ?? 0, + 'sort_order' => $_GET['order'] ?? '', + 'sort_direction' => $_GET['dir'] ?? '', 'title' => 'Manage albums', 'no_items_label' => 'No albums meet the requirements of the current filter.', 'items_per_page' => 9999, 'index_class' => 'col-md-6', 'base_url' => BASEURL . '/managealbums/', - 'get_data' => function($offset = 0, $limit = 9999, $order = '', $direction = 'up') { - if (!in_array($order, ['id_tag', 'tag', 'slug', 'count'])) - $order = 'tag'; - if (!in_array($direction, ['up', 'down'])) - $direction = 'up'; - - $rows = PhotoAlbum::getHierarchy($order, $direction); - - return [ - 'rows' => $rows, - 'order' => $order, - 'direction' => ($direction == 'up' ? 'up' : 'down'), - ]; + 'get_data' => function($offset, $limit, $order, $direction) { + assert(in_array($order, ['id_tag', 'tag', 'slug', 'count'])); + return PhotoAlbum::getHierarchy($order, $direction); }, 'get_count' => function() { return 9999; diff --git a/controllers/ManageAssets.php b/controllers/ManageAssets.php index 5ae3597..88d9c46 100644 --- a/controllers/ManageAssets.php +++ b/controllers/ManageAssets.php @@ -121,19 +121,20 @@ class ManageAssets extends HTMLController ], ], ], - 'start' => !empty($_GET['start']) ? (int) $_GET['start'] : 0, - 'sort_order' => !empty($_GET['order']) ? $_GET['order'] : '', - 'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : '', + 'default_sort_order' => 'id_asset', + 'default_sort_direction' => 'down', + 'start' => $_GET['start'] ?? 0, + 'sort_order' => $_GET['order'] ?? '', + 'sort_direction' => $_GET['dir'] ?? '', 'title' => 'Manage assets', 'no_items_label' => 'No assets meet the requirements of the current filter.', 'items_per_page' => 30, 'index_class' => 'col-md-6', 'base_url' => BASEURL . '/manageassets/', - 'get_data' => function($offset = 0, $limit = 30, $order = '', $direction = 'down') { - if (!in_array($order, ['id_asset', 'id_user_uploaded', 'title', 'subdir', 'filename'])) - $order = 'id_asset'; + 'get_data' => function($offset, $limit, $order, $direction) { + assert(in_array($order, ['id_asset', 'id_user_uploaded', 'title', 'subdir', 'filename'])); - $data = Registry::get('db')->queryAssocs(' + return Registry::get('db')->queryAssocs(' SELECT a.id_asset, a.subdir, a.filename, a.image_width, a.image_height, a.mimetype, u.id_user, u.first_name, u.surname @@ -146,12 +147,6 @@ class ManageAssets extends HTMLController 'offset' => $offset, 'limit' => $limit, ]); - - return [ - 'rows' => $data, - 'order' => $order, - 'direction' => $direction, - ]; }, 'get_count' => 'Asset::getCount', ]; diff --git a/controllers/ManageErrors.php b/controllers/ManageErrors.php index f510c7b..a3c7628 100644 --- a/controllers/ManageErrors.php +++ b/controllers/ManageErrors.php @@ -14,8 +14,8 @@ class ManageErrors extends HTMLController if (!Registry::get('user')->isAdmin()) throw new NotAllowedException(); - // Flushing, are we? - if (isset($_POST['flush']) && Session::validateSession('get')) + // Clearing, are we? + if (isset($_POST['clear']) && Session::validateSession('get')) { ErrorLog::flush(); header('Location: ' . BASEURL . '/manageerrors/'); @@ -31,7 +31,7 @@ class ManageErrors extends HTMLController 'method' => 'post', 'class' => 'col-md-6 text-end', 'buttons' => [ - 'flush' => [ + 'clear' => [ 'type' => 'submit', 'caption' => 'Delete all', 'class' => 'btn-danger', @@ -39,7 +39,7 @@ class ManageErrors extends HTMLController ], ], 'columns' => [ - 'id' => [ + 'id_entry' => [ 'value' => 'id_entry', 'header' => '#', 'is_sortable' => true, @@ -95,19 +95,20 @@ class ManageErrors extends HTMLController ], ], ], - 'start' => !empty($_GET['start']) ? (int) $_GET['start'] : 0, - 'sort_order' => !empty($_GET['order']) ? $_GET['order'] : '', - 'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : '', + 'default_sort_order' => 'id_entry', + 'default_sort_direction' => 'down', + 'start' => $_GET['start'] ?? 0, + 'sort_order' => $_GET['order'] ?? '', + 'sort_direction' => $_GET['dir'] ?? '', 'no_items_label' => "No errors to display -- we're all good!", 'items_per_page' => 20, 'index_class' => 'col-md-6', 'base_url' => BASEURL . '/manageerrors/', 'get_count' => 'ErrorLog::getCount', - 'get_data' => function($offset = 0, $limit = 20, $order = '', $direction = 'down') { - if (!in_array($order, ['id_entry', 'file', 'line', 'time', 'ipaddress', 'id_user'])) - $order = 'id_entry'; + 'get_data' => function($offset, $limit, $order, $direction) { + assert(in_array($order, ['id_entry', 'file', 'line', 'time', 'ipaddress', 'id_user'])); - $data = Registry::get('db')->queryAssocs(' + return Registry::get('db')->queryAssocs(' SELECT * FROM log_errors ORDER BY {raw:order} @@ -117,12 +118,6 @@ class ManageErrors extends HTMLController 'offset' => $offset, 'limit' => $limit, ]); - - return [ - 'rows' => $data, - 'order' => $order, - 'direction' => $direction, - ]; }, ]; diff --git a/controllers/ManageTags.php b/controllers/ManageTags.php index ec12de0..34431c9 100644 --- a/controllers/ManageTags.php +++ b/controllers/ManageTags.php @@ -70,21 +70,20 @@ class ManageTags extends HTMLController 'value' => 'count', ], ], - 'start' => !empty($_GET['start']) ? (int) $_GET['start'] : 0, - 'sort_order' => !empty($_GET['order']) ? $_GET['order'] : null, - 'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : null, + 'default_sort_order' => 'tag', + 'default_sort_direction' => 'up', + 'start' => $_GET['start'] ?? 0, + 'sort_order' => $_GET['order'] ?? '', + 'sort_direction' => $_GET['dir'] ?? '', 'title' => 'Manage tags', 'no_items_label' => 'No tags meet the requirements of the current filter.', 'items_per_page' => 30, 'index_class' => 'col-md-6', 'base_url' => BASEURL . '/managetags/', - 'get_data' => function($offset = 0, $limit = 30, $order = '', $direction = 'up') { - if (!in_array($order, ['id_tag', 'tag', 'slug', 'kind', 'count'])) - $order = 'tag'; - if (!in_array($direction, ['up', 'down'])) - $direction = 'up'; + 'get_data' => function($offset, $limit, $order, $direction) { + assert(in_array($order, ['id_tag', 'tag', 'slug', 'count'])); - $data = Registry::get('db')->queryAssocs(' + return Registry::get('db')->queryAssocs(' SELECT t.*, u.id_user, u.first_name, u.surname FROM tags AS t LEFT JOIN users AS u ON t.id_user_owner = u.id_user @@ -97,12 +96,6 @@ class ManageTags extends HTMLController 'limit' => $limit, 'album' => 'Album', ]); - - return [ - 'rows' => $data, - 'order' => $order, - 'direction' => ($direction == 'up' ? 'up' : 'down'), - ]; }, 'get_count' => function() { return Registry::get('db')->queryValue(' diff --git a/controllers/ManageUsers.php b/controllers/ManageUsers.php index 1be66a5..7f43b88 100644 --- a/controllers/ManageUsers.php +++ b/controllers/ManageUsers.php @@ -90,19 +90,20 @@ class ManageUsers extends HTMLController ], ], ], - 'start' => !empty($_GET['start']) ? (int) $_GET['start'] : 0, - 'sort_order' => !empty($_GET['order']) ? $_GET['order'] : '', - 'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : '', + 'default_sort_order' => 'id_user', + 'default_sort_direction' => 'down', + 'start' => $_GET['start'] ?? 0, + 'sort_order' => $_GET['order'] ?? '', + 'sort_direction' => $_GET['dir'] ?? '', 'title' => 'Manage users', 'no_items_label' => 'No users meet the requirements of the current filter.', 'items_per_page' => 30, 'index_class' => 'col-md-6', 'base_url' => BASEURL . '/manageusers/', - 'get_data' => function($offset = 0, $limit = 30, $order = '', $direction = 'down') { - if (!in_array($order, ['id_user', 'surname', 'first_name', 'slug', 'emailaddress', 'last_action_time', 'ip_address', 'is_admin'])) - $order = 'id_user'; + 'get_data' => function($offset, $limit, $order, $direction) { + assert(in_array($order, ['id_user', 'surname', 'first_name', 'slug', 'emailaddress', 'last_action_time', 'ip_address', 'is_admin'])); - $data = Registry::get('db')->queryAssocs(' + return Registry::get('db')->queryAssocs(' SELECT * FROM users ORDER BY {raw:order} @@ -112,18 +113,8 @@ class ManageUsers extends HTMLController 'offset' => $offset, 'limit' => $limit, ]); - - return [ - 'rows' => $data, - 'order' => $order, - 'direction' => $direction, - ]; }, - 'get_count' => function() { - return Registry::get('db')->queryValue(' - SELECT COUNT(*) - FROM users'); - } + 'get_count' => 'Member::getCount', ]; $table = new GenericTable($options); diff --git a/models/GenericTable.php b/models/GenericTable.php index b63df32..df48c83 100644 --- a/models/GenericTable.php +++ b/models/GenericTable.php @@ -28,53 +28,22 @@ class GenericTable public function __construct($options) { - // Make sure we're actually sorting on something sortable. - if (!isset($options['sort_order']) || (!empty($options['sort_order']) && empty($options['columns'][$options['sort_order']]['is_sortable']))) - $options['sort_order'] = ''; + $this->initOrder($options); + $this->initPagination($options); - // Order in which direction? - if (!empty($options['sort_direction']) && !in_array($options['sort_direction'], ['up', 'down'])) - $options['sort_direction'] = 'up'; - - // How much data do we have? - $this->recordCount = $options['get_count'](); - - // How much data do we need to retrieve? - $this->items_per_page = !empty($options['items_per_page']) ? $options['items_per_page'] : 30; - - // Figure out where to start. - $this->start = empty($options['start']) || !is_numeric($options['start']) || $options['start'] < 0 || $options['start'] > $this->recordCount ? 0 : $options['start']; - - // Figure out where we are on the whole, too. - $numPages = max(1, ceil($this->recordCount / $this->items_per_page)); - $this->currentPage = min(ceil($this->start / $this->items_per_page) + 1, $numPages); - - // Let's bear a few things in mind... - $this->base_url = $options['base_url']; - - // Gather parameters for the data gather function first. - $parameters = [$this->start, $this->items_per_page, $options['sort_order'], $options['sort_direction']]; - - // Okay, let's fetch the data! - $data = $options['get_data'](...$parameters); - - // Extract data into local variables. - $rawRowData = $data['rows']; - $this->sort_order = $data['order']; - $this->sort_direction = $data['direction']; - unset($data); + $data = $options['get_data']($this->start, $this->items_per_page, + $this->sort_order, $this->sort_direction); // Okay, now for the column headers... $this->generateColumnHeaders($options); // Should we create a page index? - $needsPageIndex = !empty($this->items_per_page) && $this->recordCount > $this->items_per_page; - if ($needsPageIndex) + if ($this->recordCount > $this->items_per_page) $this->generatePageIndex($options); // Process the data to be shown into rows. - if (!empty($rawRowData)) - $this->processAllRows($rawRowData, $options); + if (!empty($data)) + $this->processAllRows($data, $options); else $this->body = $options['no_items_label'] ?? ''; @@ -89,6 +58,38 @@ class GenericTable $this->form_below = $options['form_below'] ?? $options['form'] ?? null; } + private function initOrder($options) + { + assert(isset($options['default_sort_order'])); + assert(isset($options['default_sort_direction'])); + + // Validate sort order (column) + $this->sort_order = $options['sort_order']; + if (empty($this->sort_order) || empty($options['columns'][$this->sort_order]['is_sortable'])) + $this->sort_order = $options['default_sort_order']; + + // Validate sort direction + $this->sort_direction = $options['sort_direction']; + if (empty($this->sort_direction) || !in_array($this->sort_direction, ['up', 'down'])) + $this->sort_direction = $options['default_sort_direction']; + } + + private function initPagination(array $options) + { + assert(isset($options['base_url'])); + assert(isset($options['items_per_page'])); + + $this->base_url = $options['base_url']; + + $this->recordCount = $options['get_count'](); + $this->items_per_page = !empty($options['items_per_page']) ? $options['items_per_page'] : 30; + + $this->start = empty($options['start']) || !is_numeric($options['start']) || $options['start'] < 0 || $options['start'] > $this->recordCount ? 0 : $options['start']; + + $numPages = max(1, ceil($this->recordCount / $this->items_per_page)); + $this->currentPage = min(ceil($this->start / $this->items_per_page) + 1, $numPages); + } + private function generateColumnHeaders($options) { foreach ($options['columns'] as $key => $column) @@ -218,7 +219,7 @@ class GenericTable { // Basic option: simply take a use a particular data property. case 'value': - $value = htmlspecialchars($rowData[$options['data']]); + $value = htmlspecialchars($rowData[$options['data']] ?? ''); break; // Processing via a lambda function.