diff --git a/extdbms/lib/Configs/App.php b/extdbms/lib/Configs/App.php
index 26c30a2..f52ae68 100644
--- a/extdbms/lib/Configs/App.php
+++ b/extdbms/lib/Configs/App.php
@@ -4,6 +4,7 @@ namespace lib\Configs;
use \lib\Core\App as Core;
use Dotenv\Dotenv;
+use lib\Database\DB;
class App extends Core
{
@@ -12,6 +13,7 @@ class App extends Core
// .env 파일 로드
$dotenv = Dotenv::createImmutable(ROOT_PATH);
$dotenv->load();
+ DB::init(); // ✅ 여기서 초기화
parent::__construct();
}
}
diff --git a/extdbms/lib/Configs/Route.php b/extdbms/lib/Configs/Route.php
index 59f5dc7..8da0d12 100644
--- a/extdbms/lib/Configs/Route.php
+++ b/extdbms/lib/Configs/Route.php
@@ -49,6 +49,19 @@ $router->group('dbms/client/onetime', function (Router $router) {
// // Response::view($result);
// });
});
+$router->group('dbms/client/payment', function (Router $router) {
+ $router->add('GET', 'billpaper', function ($params) {
+ $controller = new OnetimeController();
+ return $controller->billpaper($params);
+ // Response::view($result);
+ });
+ $router->add('GET', 'nonpayment', function ($params) {
+ $controller = new OnetimeController();
+ return $controller->nonpayment($params);
+ // Response::view($result);
+ });
+});
+
// 예제 라우트 그룹: dbms/dashboard/index 이후에 key/value 파라미터 허용
$router->group('dbms/dashboard', function (Router $router) {
diff --git a/extdbms/lib/Controllers/DBMS/Client/PaymentController.php b/extdbms/lib/Controllers/DBMS/Client/PaymentController.php
index 7db9237..3941ef9 100644
--- a/extdbms/lib/Controllers/DBMS/Client/PaymentController.php
+++ b/extdbms/lib/Controllers/DBMS/Client/PaymentController.php
@@ -2,7 +2,7 @@
namespace lib\Controllers\DBMS\Client;
-use lib\Services\ClientService;
+use lib\Utils\Pagination;
class PaymentController extends ClientController
{
@@ -11,4 +11,75 @@ class PaymentController extends ClientController
parent::__construct();
$this->getView()->setPath('payment');
} //
+
+ //청구서, depositbillpaper.php
+ //CLI 접속방법 : php index.php site/client/payment/billpaper
+ //WEB 접속방법 : http://localhostsite/client/payment/billpaper
+ public function billpaper(array $params): string
+ {
+ //사이트 정보 가져오기
+ if (!array_key_exists('sitekey', $params)) {
+ throw new \Exception("sitekey 값이 정의되지 않았습니다.");
+ }
+ $sitekey = $params['sitekey'];
+ $this->siteInfo = DBMS_SITEINFOS[$sitekey];
+ if (!array_key_exists($sitekey, DBMS_SITEINFOS)) {
+ throw new \Exception("[{$sitekey}]에 해당하는 사이트정보가 없습니다.");
+ }
+ //사용자정보가져오기
+ $client_code = $params['client_code'];
+ if (!array_key_exists('client_code', $params)) {
+ throw new \Exception("client_code 값이 정의되지 않았습니다.");
+ }
+ $client = $this->getClientService()->getEntityByCode($client_code);
+ if (!$client) {
+ throw new \Exception("[{$client_code}]에 해당하는 사이트정보가 없습니다.");
+ }
+ $this->client = $client;
+ return $this->render(__FUNCTION__);
+ }
+
+ //청구서, NonPaymentList.php
+ //CLI 접속방법 : php index.php site/client/payment/unpaid
+ //WEB 접속방법 : http://localhostsite/client/payment/unpaid
+ public function nonpayment(array $params): string
+ {
+ //사이트 정보 가져오기
+ if (!array_key_exists('sitekey', $params)) {
+ throw new \Exception("sitekey 값이 정의되지 않았습니다.");
+ }
+ $sitekey = $params['sitekey'];
+ $this->siteInfo = DBMS_SITEINFOS[$sitekey];
+ if (!array_key_exists($sitekey, DBMS_SITEINFOS)) {
+ throw new \Exception("[{$sitekey}]에 해당하는 사이트정보가 없습니다.");
+ }
+ //사용자정보가져오기
+ $client_code = $params['client_code'];
+ if (!array_key_exists('client_code', $params)) {
+ throw new \Exception("client_code 값이 정의되지 않았습니다.");
+ }
+ $client = $this->getClientService()->getEntityByCode($client_code);
+ if (!$client) {
+ throw new \Exception("[{$client_code}]에 해당하는 사이트정보가 없습니다.");
+ }
+ $this->client = $client;
+ //mode 당일,1일전,2일전,3일전,custom
+ $nonpaymentDay = 'all';
+ switch ($params['mode']) {
+ case '1day':
+ break;
+ case '2day':
+ break;
+ case '3day':
+ break;
+ case 'custom':
+ break;
+ default:
+ }
+ $total = count($temps);
+ $page = $parmas['page'] ?? 1;
+ $perPage = $parmas['perPage'] ?? 10;
+ $this->pagination = new Pagination($total, (int)$page, (int)$perPage);
+ return $this->render(path: __FUNCTION__);
+ }
} //Class
diff --git a/extdbms/lib/Core/Model.php b/extdbms/lib/Core/Model.php
index bf7e1c3..2541529 100644
--- a/extdbms/lib/Core/Model.php
+++ b/extdbms/lib/Core/Model.php
@@ -2,229 +2,70 @@
namespace lib\Core;
-use \PDO;
-use PDOException;
-use PDOStatement;
+use lib\Database\DB;
+use lib\Database\QueryBuilder;
abstract class Model
{
- private $_db = null;
- private $_debug = false;
- private $_reset = true;
- private $_querys = ['SELECT' => 'SELECT *', 'JOIN' => [], 'ORDERBY' => [], 'LIMIT' => ''];
- private $_wheres = [];
- private $_lastQuery = "";
- protected function __construct()
- {
- $this->init();
- } //
+
+ private bool $_debug = false;
+ protected static QueryBuilder $queryBuilder;
+ public function __construct() {} //
+
abstract public function getTable(): string;
abstract public function getPKField(): string;
abstract public function getTitleField(): string;
- final public function getConnect(): PDO
- {
- if ($this->_db === null) {
- $driver = $_ENV['DATABASE_DRIVER'] ?? $_SERVER['DATABASE_DRIVER'] ?? 'mysql';
- $host = $_ENV['DATABASE_HOST'] ?? $_SERVER['DATABASE_HOST'] ?? 'localhost';
- $dbname = $_ENV['DATABASE_DB'] ?? $_SERVER['DATABASE_DB'] ?? 'test';
- $charset = $_ENV['DATABASE_CHARSET'] ?? $_SERVER['DATABASE_CHARSET'] ?? 'utf8';
- $user = $_ENV['DATABASE_ID'] ?? $_SERVER['DATABASE_ID'] ?? 'root';
- $pass = $_ENV['DATABASE_PASSWORD'] ?? $_SERVER['DATABASE_PASSWORD'] ?? '';
- $dsn = sprintf("%s:host=%s;dbname=%s;charset=%s", $driver, $host, $dbname, $charset);
- try {
- $this->_db = new PDO($dsn, $user, $pass);
- $this->_db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
- $this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- } catch (PDOException $e) {
- throw new \Exception("❌ DB 연결 실패: " . $e->getMessage());
- }
- }
- $this->init();
- return $this->_db;
- }
- final public function setDebug($debug)
+ final public function setDebug(bool $debug): void
{
$this->_debug = $debug;
}
- final public function getDebug()
+ final public function getDebug(): bool
{
return $this->_debug;
}
- private function init(): void
+
+ public static function query(): QueryBuilder
{
- $debug = $_ENV['DATABASE_QUERY_DEBUG'] ?? $_SERVER['DATABASE_QUERY_DEBUG'] ?? 'false';
- if ($debug === "true") {
- $this->_debug = true;
+ if (!isset(self::$queryBuilder)) {
+ self::$queryBuilder = new QueryBuilder(pdo: DB::getPDO()); // Assuming DB::getPDO() gives PDO instance
}
- $this->_reset = true;
- $this->_querys = ['SELECT' => 'SELECT *', 'JOIN' => [], 'ORDERBY' => [], 'LIMIT' => ''];
- $this->_wheres = [];
- $this->_lastQuery = "";
- }
- final public function getLastQuery(): string
- {
- return $this->_lastQuery;
+ return self::$queryBuilder->table((new static())->getTable());
}
- //Where절관련
- private function getColumnValue(mixed $datas, $delimeter = ","): string
+ public static function all(): array
{
- $value = "";
- if ($datas === null) {
- return "";
- }
- if (is_array($datas)) {
- $temps = [];
- foreach ($datas as $data) {
- $data = trim($data);
- $temps[] = is_string($data) ? "'{$data}'" : $data;
- }
- $value = implode($delimeter, $temps);
- } else {
- $value = is_string($datas) ? "='{$datas}'" : $datas;
- }
- return $value;
+ return self::query()->get();
}
- private function getColumnData(mixed $columns, mixed $datas = null, string $delimeter): string
+ public static function find($id): ?array
{
- $temps = [];
- if (is_array($columns)) {
- //복합배열형태로 들어온 경우
- foreach ($columns as $column => $data) {
- $value = $this->getColumnValue($data);
- $temps[] = " {$column}{$value} ";
- }
- } else {
- $value = $this->getColumnValue($datas);
- $temps[] = " {$columns}{$value} ";
- }
- // throw new \Exception("DATA:" . $columns . $value === null ? "NULL" : $value);
- return implode($delimeter, $temps);
+ return self::query()->where((new static())->getPKField(), '=', $id)->first();
}
- final public function getWhere(): string
+ public static function where(string $column, string $operator = "", mixed $value = ""): QueryBuilder
{
- return count($this->_wheres) ? "WHERE " . implode(" ", $this->_wheres) : "";
+ return self::query()->where($column, $operator, $value);
}
-
- final public function where(mixed $columns, mixed $values = null, string $delimeter = "AND"): void
+ public static function whereNotIn(string $column, array $values): QueryBuilder
{
- $query = $this->getColumnData($columns, $values, $delimeter);
- $this->_wheres[] = count($this->_wheres) ? "{$delimeter} {$query}" : $query;
+ return self::query()->whereNotIn($column, $values);
}
- final public function orWhere(mixed $columns, mixed $values = null, string $delimeter = "OR"): void
+ public static function orWhereIn(string $column, array $values): QueryBuilder
{
- $this->where($columns, $values, $delimeter);
+ return self::query()->orWhereIn($column, $values);
}
- final public function whereLike(string $column, string $value, string $option = "both", string $delimeter = "AND"): void
+ public static function count(): int
{
- switch ($option) {
- case 'before':
- $value = "%{$value}";
- break;
- case 'after':
- $value = "{$value}%";
- break;
- default:
- $value = "%{$value}%";
- break;
- }
- $this->where("{$column} LIKE '{$value}'", null, $delimeter);
+ return self::query()->count();
}
- final public function orWhereLike(string $column, string $value, string $option = "both", string $delimeter = "OR"): void
+ public static function insert(array $data): bool
{
- $this->whereLike($column, $value, $option, $delimeter);
+ return self::query()->insert($data);
}
- final public function whereIn(string $column, array $values, string $delimeter = "AND", $range = "IN")
+ public static function updateById($id, array $data): bool
{
- $query = " {$column} {$range} (" . $this->getColumnValue($values) . ")";
- $this->_wheres[] = count($this->_wheres) ? $delimeter . " " . $query : $query;
+ return self::query()->where((new static())->getPKField(), '=', $id)->update($data);
}
- final public function whereNotIn(string $column, array $values, string $delimeter = "AND", $range = "NOT IN")
+ public static function deleteById($id): bool
{
- $this->whereIn($column, $values, $delimeter, $range);
+ return self::query()->where((new static())->getPKField(), '=', $id)->delete();
}
-
- final public function execute(string $query): bool|PDOStatement
- {
- if ($this->_debug) {
- echo "\n
Query:" . $query . "\n
";
- }
- $this->_lastQuery = $query;
- $stmt = $this->getConnect()->prepare($query);
- $stmt->execute();
- if ($this->_reset) {
- $this->init();
- }
- return $stmt;
- }
-
- //CURD문
- final protected function create_process(mixed $columns, mixed $values = null): bool|PDOStatement
- {
- $this->where($columns, $values);
- $query = sprintf("INSERT INTO %s VALUES(%s) %s", $this->getTable(), $this->getColumnData($columns, $values, ","), $this->getWhere());
- return $this->execute($query);
- } //
- final protected function modify_process(mixed $columns, mixed $values = null): bool|PDOStatement
- {
- $query = sprintf("UPDATE %s SET %s %s", $this->getTable(), $this->getColumnData($columns, $values, ","), $this->getWhere());
- return $this->execute($query);
- } //
- final protected function delete_process(): bool|PDOStatement
- {
- $query = sprintf("DELETE FROM %s %s", $this->getTable(), $this->getWhere());
- return $this->execute($query);
- } //
- public function select(mixed $columns = "*"): void
- {
- $columns = is_array($columns) ? implode(",", $columns) : $columns;
- $this->_querys["SELECT"] = "SELECT {$columns}";
- }
- //join_type : LEFT, RIGHT, INNER, OUTER
- final public function join(string $table, mixed $match = null, $join_type = ""): void
- {
- $this->_querys['JOIN'][] = " {$join_type} JOIN {$table} ON {$match}";
- }
- final public function orderBy(mixed $columns, string $default_direction = ""): void
- {
- if (is_array($columns)) {
- foreach ($columns as $column => $direction) {
- $this->orderBy($column, $direction ?? $default_direction);
- }
- } else {
- $this->_querys['ORDERBY'][] = "{$columns} {$default_direction}";
- }
- }
- final public function limit(int $start, int $offset = 0): void
- {
- $offset = $offset > 0 ? ",{$offset}" : "";
- $this->_querys["LIMIT"] = " LIMIT {$start} {$offset}";
- }
-
- //Result
- private function getResultQuery(string $head, string $tail = ""): string
- {
- $join = count($this->_querys['JOIN']) ? implode(",", $this->_querys['JOIN']) : "";
- $where = $this->getWhere();
- $orderby = count($this->_querys['ORDERBY']) ? "ORDER BY " . implode(",", $this->_querys['ORDERBY']) : "";
- return "{$head} FROM {$this->getTable()} {$join} {$where} {$tail} {$orderby} {$this->_querys['LIMIT']}";
- }
- public function getResult($mode = PDO::FETCH_ASSOC): mixed
- {
- $stmt = $this->execute($this->getResultQuery($this->_querys['SELECT']));
- return $stmt->fetch($mode);
- }
- public function getResults($mode = PDO::FETCH_ASSOC): mixed
- {
- $stmt = $this->execute($this->getResultQuery($this->_querys['SELECT']));
- return $stmt->fetchAll($mode);
- }
- final public function countAllResults(string $column = "*", $reset = true): int
- {
- $this->_reset = $reset;
- $stmt = $this->execute($this->getResultQuery("SELECT COUNT({$column})"));
- $count = $stmt->fetchColumn(0);
- $this->_reset = true;
- return $count;
- }
-} //Class
\ No newline at end of file
+}
diff --git a/extdbms/lib/Database/DB.php b/extdbms/lib/Database/DB.php
new file mode 100644
index 0000000..ecd2108
--- /dev/null
+++ b/extdbms/lib/Database/DB.php
@@ -0,0 +1,32 @@
+setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ }
+
+ public static function getPDO(): PDO
+ {
+ if (!isset(self::$pdo)) {
+ throw new \Exception("PDO not initialized. Call DB::init() first.");
+ }
+ return self::$pdo;
+ }
+}
diff --git a/extdbms/lib/Database/QueryBuilder.php b/extdbms/lib/Database/QueryBuilder.php
new file mode 100644
index 0000000..c92967e
--- /dev/null
+++ b/extdbms/lib/Database/QueryBuilder.php
@@ -0,0 +1,265 @@
+pdo = $pdo;
+ }
+
+ public function table(string $table): static
+ {
+ $this->table = $table;
+ return $this;
+ }
+
+ public function select(array|string $columns): static
+ {
+ $this->select = is_array($columns) ? $columns : explode(',', $columns);
+ return $this;
+ }
+
+ public function where(string $column, string $operator = "", mixed $value = ""): static
+ {
+ $placeholder = ':w_' . count($this->bindings);
+ $this->where[] = "$column $operator $placeholder";
+ $this->bindings[$placeholder] = $value;
+ return $this;
+ }
+
+ public function orderBy(string $column, string $direction = 'ASC'): static
+ {
+ $this->order[] = "$column $direction";
+ return $this;
+ }
+
+ public function limit(int $limit): static
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+
+ public function offset(int $offset): static
+ {
+ $this->offset = $offset;
+ return $this;
+ }
+
+ public function when(bool $condition, callable $callback): static
+ {
+ if ($condition) {
+ $callback($this);
+ }
+ return $this;
+ }
+
+ public function rawWhere(string $expression, array $bindings = []): static
+ {
+ $this->where[] = "($expression)";
+ foreach ($bindings as $key => $value) {
+ $this->bindings[":raw_" . $key] = $value;
+ }
+ return $this;
+ }
+
+ public function get(): array
+ {
+ $sql = "SELECT " . implode(', ', $this->select) . " FROM {$this->table}";
+
+ if (!empty($this->where)) {
+ $sql .= " WHERE " . implode(' AND ', $this->where);
+ }
+
+ if (!empty($this->order)) {
+ $sql .= " ORDER BY " . implode(', ', $this->order);
+ }
+
+ if (!is_null($this->limit)) {
+ $sql .= " LIMIT :__limit";
+ $this->bindings[':__limit'] = $this->limit;
+ }
+
+ if (!is_null($this->offset)) {
+ $sql .= " OFFSET :__offset";
+ $this->bindings[':__offset'] = $this->offset;
+ }
+
+ $stmt = $this->pdo->prepare($sql);
+ foreach ($this->bindings as $placeholder => $value) {
+ $stmt->bindValue($placeholder, $value);
+ }
+
+ $stmt->execute();
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+
+ public function first(): ?array
+ {
+ $this->limit(1);
+ $rows = $this->get();
+ return $rows[0] ?? null;
+ }
+
+ public function count(): int
+ {
+ $this->select = ['COUNT(*) AS cnt'];
+ $results = $this->get();
+ return (int)($results[0]['cnt'] ?? 0);
+ }
+
+ public function exists(): bool
+ {
+ return $this->count() > 0;
+ }
+
+ public function insert(array $data): bool
+ {
+ $columns = array_keys($data);
+ $placeholders = array_map(fn($col) => ':' . $col, $columns);
+
+ $sql = "INSERT INTO {$this->table} (" . implode(', ', $columns) . ") VALUES (" . implode(', ', $placeholders) . ")";
+ $stmt = $this->pdo->prepare($sql);
+
+ foreach ($data as $col => $value) {
+ $stmt->bindValue(':' . $col, $value);
+ }
+
+ return $stmt->execute();
+ }
+
+ public function update(array $data): bool
+ {
+ if (empty($this->where)) {
+ throw new \Exception("Update without WHERE is not allowed.");
+ }
+
+ $setClauses = [];
+ foreach ($data as $col => $val) {
+ $placeholder = ':u_' . $col;
+ $setClauses[] = "$col = $placeholder";
+ $this->bindings[$placeholder] = $val;
+ }
+
+ $sql = "UPDATE {$this->table} SET " . implode(', ', $setClauses);
+
+ if (!empty($this->where)) {
+ $sql .= " WHERE " . implode(' AND ', $this->where);
+ }
+
+ $stmt = $this->pdo->prepare($sql);
+ foreach ($this->bindings as $placeholder => $value) {
+ $stmt->bindValue($placeholder, $value);
+ }
+
+ return $stmt->execute();
+ }
+
+ public function delete(): bool
+ {
+ if (empty($this->where)) {
+ throw new \Exception("Delete without WHERE is not allowed.");
+ }
+
+ $sql = "DELETE FROM {$this->table} WHERE " . implode(' AND ', $this->where);
+ $stmt = $this->pdo->prepare($sql);
+ foreach ($this->bindings as $placeholder => $value) {
+ $stmt->bindValue($placeholder, $value);
+ }
+
+ return $stmt->execute();
+ }
+
+ public function whereIn(string $column, array $values, string $boolean = 'AND'): static
+ {
+ if (empty($values)) {
+ throw new \InvalidArgumentException("whereIn: values 배열이 비어있을 수 없습니다.");
+ }
+
+ $placeholders = implode(', ', array_fill(0, count($values), '?'));
+ $this->where[] = "$column IN ($placeholders)";
+ $this->bindings = array_merge($this->bindings, $values);
+
+ return $this;
+ }
+
+ public function whereNotIn(string $column, array $values, string $boolean = 'AND'): static
+ {
+ if (empty($values)) {
+ throw new \InvalidArgumentException("whereNotIn: values 배열이 비어있을 수 없습니다.");
+ }
+
+ $placeholders = implode(', ', array_fill(0, count($values), '?'));
+ $this->where[] = "$column NOT IN ($placeholders)";
+ $this->bindings = array_merge($this->bindings, $values);
+
+ return $this;
+ }
+
+ public function orWhereIn(string $column, array $values): static
+ {
+ return $this->whereIn($column, $values, 'OR');
+ }
+
+ public function orWhere(string $column, string $operator, mixed $value): static
+ {
+ $placeholder = ':w_' . count($this->bindings);
+ $condition = "$column $operator $placeholder";
+
+ if (empty($this->where)) {
+ $this->where[] = $condition;
+ } else {
+ $last = array_pop($this->where);
+ $this->where[] = "($last OR $condition)";
+ }
+
+ $this->bindings[$placeholder] = $value;
+ return $this;
+ }
+
+ public function join(string $table, string $on, string $type = 'INNER'): static
+ {
+ $this->joins[] = strtoupper($type) . " JOIN $table ON $on";
+ return $this;
+ }
+
+ public function raw(string $sql, array $bindings = []): array
+ {
+ $stmt = $this->pdo->prepare($sql);
+ foreach ($bindings as $key => $value) {
+ $stmt->bindValue(is_int($key) ? $key + 1 : $key, $value);
+ }
+ $stmt->execute();
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+
+ public function beginTransaction(): void
+ {
+ $this->pdo->beginTransaction();
+ }
+
+ public function commit(): void
+ {
+ $this->pdo->commit();
+ }
+
+ public function rollBack(): void
+ {
+ if ($this->pdo->inTransaction()) {
+ $this->pdo->rollBack();
+ }
+ }
+}
diff --git a/extdbms/lib/Services/ServiceService.php b/extdbms/lib/Services/ServiceService.php
index e371b60..cd8b80e 100644
--- a/extdbms/lib/Services/ServiceService.php
+++ b/extdbms/lib/Services/ServiceService.php
@@ -39,7 +39,7 @@ class ServiceService extends CommonService
$this->getModel()->where("service_open_date > DATE_ADD(now(), INTERVAL -{$day} DAY)");
$this->getModel()->where("service_status", 'o');
$this->getModel()->whereNotIn("service_line", $excepts);
- $count = $this->getModel()->countAllResults();
+ $count = $this->getModel()->count();
// echo __FUNCTION__ . ":" . $this->getModel()->getLastQuery();
return $count;
}
@@ -49,7 +49,7 @@ class ServiceService extends CommonService
$this->getModel()->where("service_payment_date > now()");
$this->getModel()->where("service_status", 'o');
$this->getModel()->whereNotIn("service_line", $excepts);
- $count = $this->getModel()->countAllResults();
+ $count = $this->getModel()->count();
// echo __FUNCTION__ . ":" . $this->getModel()->getLastQuery();
return $count;
}
diff --git a/extdbms/lib/Utils/Pagination.php b/extdbms/lib/Utils/Pagination.php
new file mode 100644
index 0000000..5e5efac
--- /dev/null
+++ b/extdbms/lib/Utils/Pagination.php
@@ -0,0 +1,112 @@
+totalItems = $totalItems;
+ $this->perPage = $perPage;
+ $this->currentPage = max(1, $currentPage);
+ $this->totalPages = (int)ceil($totalItems / $perPage);
+
+ $this->start = ($this->currentPage - 1) * $perPage;
+ $this->end = min($this->start + $perPage, $totalItems);
+ }
+
+ public function hasPrevious(): bool
+ {
+ return $this->currentPage > 1;
+ }
+
+ public function hasNext(): bool
+ {
+ return $this->currentPage < $this->totalPages;
+ }
+
+ public function previousPage(): int
+ {
+ return max(1, $this->currentPage - 1);
+ }
+
+ public function nextPage(): int
+ {
+ return min($this->totalPages, $this->currentPage + 1);
+ }
+
+ public function getOffset(): int
+ {
+ return $this->start;
+ }
+
+ public function getLimit(): int
+ {
+ return $this->perPage;
+ }
+
+ public function toArray(): array
+ {
+ return [
+ 'current_page' => $this->currentPage,
+ 'per_page' => $this->perPage,
+ 'total_items' => $this->totalItems,
+ 'total_pages' => $this->totalPages,
+ 'has_previous' => $this->hasPrevious(),
+ 'has_next' => $this->hasNext(),
+ 'previous_page' => $this->previousPage(),
+ 'next_page' => $this->nextPage(),
+ 'offset' => $this->getOffset(),
+ 'limit' => $this->getLimit(),
+ ];
+ }
+
+ public function render(string $baseUrl = '', array $query = []): string
+ {
+ if ($this->totalPages <= 1) {
+ return ''; // 페이지가 1개 이하면 렌더링 생략
+ }
+
+ $html = '';
+ return $html;
+ }
+
+ private function pageLink(int $page, string $label, string $baseUrl, array $query): string
+ {
+ $query['page'] = $page;
+ $url = $baseUrl . '?' . http_build_query($query);
+ return '
| 고객명 | +종류 | +장비명 | +IP | +결제일 | +서비스 가격 | +과금상태 | +미납과금 | + +비고 | +
|---|---|---|---|---|---|---|---|---|
| = $data[Client_Name] ?> | += $data[adddb_case] ?> | += $data[server_code] ?> | += $data[service_ip] ?> | + + += $data[service_payment_date] ?> | += $data[service_amount] ?> | + += $data[adddb_accountStatus] ?> | += $data[adddb_nonpayment] ?> | + + += $data[service_note] ?> | + +