diff --git a/public/components/Pagination.php b/public/components/Pagination.php new file mode 100644 index 0000000000000000000000000000000000000000..87965a8a75e027293beefd66f006d399ef4eb008 --- /dev/null +++ b/public/components/Pagination.php @@ -0,0 +1,45 @@ +<?php +// PREREKUISIT UNTUK PAKE FUNGSI INI: +// 1. Redirect user ke /page 1 kalo di query ga ada page nummber +// 2. Di controller sebelum render page, query total count dari database simpan di variabel $_count. +// 3. Pastiin di service/repo ada fungsi buat ngurusin order by, limit, dst. +// For more information, refer to GET /cats di cats controller. +function generatePaginationLinks($currentPage, $totalPages) +{ + $html = '<div class="pagination">'; + + // Previous button + if ($currentPage > 1) { + $html .= '<a href="?pageNo=' . ($currentPage - 1) . '&pageSize=10" class="prev-page">Previous</a>'; + } + + for ($i = 1; $i <= $totalPages; $i++) { + if ($i === $currentPage) { + $html .= '<span class="current-page">' . $i . '</span>'; + } else { + $html .= '<a href="?pageNo=' . $i . '&pageSize=10">' . $i . '</a>'; + } + } + + // Next button + if ($currentPage < $totalPages) { + $html .= '<a href="?pageNo=' . ($currentPage + 1) . '&pageSize=10" class="next-page">Next</a>'; + } + + $html .= '</div>'; + return $html; +} + +$totalCount = $_count; // Total number of cats +$pageSize = 10; // Number of cats per page +$totalPages = ceil($totalCount / $pageSize); +$currentPage = isset($_GET['pageNo']) ? intval($_GET['pageNo']) : 1; + +$paginationHtml = generatePaginationLinks($currentPage, $totalPages); + +?> + + +<div class="pagination-container"> + <?php echo $paginationHtml; ?> +</div> \ No newline at end of file diff --git a/public/css/styles.css b/public/css/styles.css index 28485548e491495d1d611bc4f79aed32dac7e441..51ac1b4fedfc3f40cdcba55758e4e576869f6891 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -345,3 +345,54 @@ button[type="submit"] { font-weight: bold; } +/* Pagination styles */ +.pagination { + text-align: center; + margin-top: 20px; +} + +.pagination a, +.pagination .current-page { + display: inline-block; + padding: 5px 10px; + margin: 2px; + border: 1px solid #ccc; + text-decoration: none; + color: #333; + background-color: #fff; + border-radius: 4px; + font-weight: bold; +} + +.pagination a:hover { + background-color: #eee; +} + +.pagination .current-page { + background-color: #007BFF; + color: #fff; +} + +.pagination .prev-page, +.pagination .next-page { + padding: 5px 10px; + margin: 2px; + border: 1px solid #007BFF; + background-color: #007BFF; + color: #fff; + border-radius: 4px; + font-weight: bold; + text-decoration: none; +} + +.pagination .prev-page:hover, +.pagination .next-page:hover { + background-color: #0056b3; +} + +.pagination-container { + display: flex; + justify-content: center; + align-items: center; + margin-top: 20px; +} \ No newline at end of file diff --git a/public/view/cats.php b/public/view/cats.php index ebc936e8961b499e4ead8bf7aeab9cbfdce3730e..af45f9985078056293b7a4ae487c5e2668d7b45d 100644 --- a/public/view/cats.php +++ b/public/view/cats.php @@ -54,8 +54,8 @@ </div> <?php endforeach; ?> </div> + <?php require_once(PROJECT_ROOT_PATH . '/public/components/Pagination.php'); ?> <div> - <div id="edit-cat-modal" class="modal"> <div class="modal-content"> <span class="close" onclick="closeEditCatModal()">×</span> diff --git a/src/bases/BaseRepository.php b/src/bases/BaseRepository.php index 03f2f7a04fc51d11f35020d9bfc0ffa057047b93..32c1ac290c011e6c452bcf1471a00a96ec589930 100644 --- a/src/bases/BaseRepository.php +++ b/src/bases/BaseRepository.php @@ -4,86 +4,75 @@ require_once PROJECT_ROOT_PATH . "/src/db/DBConnection.php"; abstract class BaseRepository { - protected static $instance; - protected $pdo; - protected $tableName = ''; - - protected function __construct() - { - $this->pdo = DBConnection::getInstance()->getPDO(); - } - - public static function getInstance() - { - if (!isset(self::$instance)) { - self::$instance = new static(); + protected static $instance; + protected $pdo; + protected $tableName = ''; + + protected function __construct() + { + $this->pdo = DBConnection::getInstance()->getPDO(); } - return self::$instance; - } - public function getPDO() - { - return $this->pdo; - } + public static function getInstance() + { + if (!isset(self::$instance)) { + self::$instance = new static(); + } + return self::$instance; + } + + public function getPDO() + { + return $this->pdo; + } - public function insert($data, $paramTypes) { + public function insert($data, $paramTypes) + { // Filter the $data array to include only the keys present in $paramTypes $filteredData = array_intersect_key($data, $paramTypes); - // Prepare the SQL statement $columns = implode(', ', array_keys($filteredData)); $placeholders = ':' . implode(', :', array_keys($filteredData)); $sql = "INSERT INTO $this->tableName ($columns) VALUES ($placeholders)"; - // Prepare the PDO statement $stmt = $this->pdo->prepare($sql); - // Bind parameters with data types foreach ($filteredData as $key => $value) { $stmt->bindValue(':' . $key, $value, $paramTypes[$key]); } - // Execute the query if ($stmt->execute()) { return $this->pdo->lastInsertId(); } else { - return false; // Insert failed + return false; } } - public function selectOne($columns = "*", $where = []) + public function selectOne($columns = "*", $where = []) { - // Start building the query $query = "SELECT $columns FROM $this->tableName"; - // Add WHERE clause if provided if (!empty($where)) { $query .= " WHERE " . implode(" AND ", $where); } $query .= ";"; -// echo $query; - // Prepare and execute the query $stmt = $this->pdo->prepare($query); $stmt->execute(); - // Fetch and return the results return $stmt->fetch(); } public function select($columns = "*", $where = [], $orderBy = [], $page = 1, $perPage = 10, $isDesc = false) { - // Start building the query $query = "SELECT $columns FROM $this->tableName"; - // Add WHERE clause if provided if (!empty($where)) { $query .= " WHERE " . implode(" AND ", $where); } - // Add ORDER BY clause if provided if (!empty($orderBy)) { $query .= " ORDER BY " . implode(", ", $orderBy); if (!empty($isDesc)) { @@ -91,55 +80,54 @@ abstract class BaseRepository } } - if(!empty($perPage)) { - // Add LIMIT and OFFSET for pagination - $offset = ($page - 1) * $perPage; - $query .= " LIMIT $perPage OFFSET $offset"; + if (!empty($perPage)) { + $offset = ($page - 1) * $perPage; + $query .= " LIMIT $perPage OFFSET $offset"; } echo $query; - // Prepare and execute the query $stmt = $this->pdo->prepare($query); $stmt->execute(); - // Fetch and return the results return $stmt->fetchAll(PDO::FETCH_ASSOC); } public function update($id_col, $id, $data, $paramTypes) { - // Filter the data array to include only the keys present in $paramTypes - $filteredData = array_intersect_key($data, $paramTypes); - - // Prepare the SET clause for the update query - $setClause = implode(', ', array_map(function ($key) { - return "$key = :$key"; - }, array_keys($filteredData))); - - // Prepare the SQL statement - $sql = "UPDATE $this->tableName SET $setClause WHERE $id_col = $id"; - - // Bind parameters with data types - $stmt = $this->pdo->prepare($sql); - foreach ($filteredData as $key => $value) { - echo $value; - $stmt->bindValue(':' . $key, $value, $paramTypes[$key]); - } + $filteredData = array_intersect_key($data, $paramTypes); - // Execute the query - return $stmt->execute(); + $setClause = implode(', ', array_map(function ($key) { + return "$key = :$key"; + }, array_keys($filteredData))); + + $sql = "UPDATE $this->tableName SET $setClause WHERE $id_col = $id"; + + $stmt = $this->pdo->prepare($sql); + foreach ($filteredData as $key => $value) { + echo $value; + $stmt->bindValue(':' . $key, $value, $paramTypes[$key]); + } + + return $stmt->execute(); } public function delete($id_col, $id) { - // Prepare the SQL statement - $sql = "DELETE FROM $this->tableName WHERE $id_col = $id"; + $sql = "DELETE FROM $this->tableName WHERE $id_col = $id"; - // Bind the ID parameter - $stmt = $this->pdo->prepare($sql); + $stmt = $this->pdo->prepare($sql); + + return $stmt->execute(); + } + + public function count() + { + $query = "SELECT count(*) FROM $this->tableName"; + $stmt = $this->pdo->prepare($query); + $stmt->execute(); + + return $stmt->fetch(); - // Execute the query - return $stmt->execute(); } } \ No newline at end of file diff --git a/src/controllers/cat/CatController.php b/src/controllers/cat/CatController.php index a9042578145339d5bde5da17877c39751193395d..567619907ca256a4500aa88c5e6c4fef63b8aeb5 100644 --- a/src/controllers/cat/CatController.php +++ b/src/controllers/cat/CatController.php @@ -26,6 +26,9 @@ class CatController extends BaseController public function get($urlParams) { if (!$urlParams) { + if (!$_GET["pageNo"] || !$_GET["pageSize"]) { + header("Location: /cat?pageNo=1&pageSize=10"); + } $cats = $this->srv->getAll([ "search" => $_GET['search'] ?? null, "gender" => $_GET['gender'] ?? null, @@ -35,6 +38,7 @@ class CatController extends BaseController "pageSize" => $_GET['pageSize'] ?? null, "isDesc" => $_GET['isDesc'] ?? null ]); + $_count = $this->srv->countCats()[0]; $responseCats = array_map(function ($cat) { return $cat->toResponse(); diff --git a/src/services/CatSrv.php b/src/services/CatSrv.php index 40dd6a017924d4a347d05abdd42a52c999e43e46..275829aaae4ff40d04bf960febce9ab7267ed5fa 100644 --- a/src/services/CatSrv.php +++ b/src/services/CatSrv.php @@ -24,6 +24,11 @@ class CatSrv extends BaseSrv return self::$instance; } + public function countCats() + { + return $this->repository->count(); + } + public function getAll($config) { $search = $config['search']; @@ -45,8 +50,8 @@ class CatSrv extends BaseSrv $catsResult = $this->repository->select('*', $where, $order, $config["pageNo"], $config['pageSize'], $config['isDesc']); $cats = []; foreach ($catsResult as $catResult) { - $cat = new CatModel(); - $cats[] = $cat->constructFromArray($catResult); + $cat = new CatModel(); + $cats[] = $cat->constructFromArray($catResult); } return $cats; } @@ -93,4 +98,4 @@ class CatSrv extends BaseSrv $this->repository->delete("cat_id", $catId); return $cat; } -} +} \ No newline at end of file