From 5170ed8ed5a78c05a0f575a011a830b092b8a827 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Wed, 3 Dec 2025 17:12:40 +0300 Subject: [PATCH 01/14] feat: FakeTemplate -> JsonView --- src/Controller/Component.php | 6 +++--- src/View/{FakeTemplate.php => JsonView.php} | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) rename src/View/{FakeTemplate.php => JsonView.php} (73%) diff --git a/src/Controller/Component.php b/src/Controller/Component.php index a6916a5..fbf04b7 100644 --- a/src/Controller/Component.php +++ b/src/Controller/Component.php @@ -16,7 +16,7 @@ use ctiso\Controller\SiteInterface; use ctiso\Database\PDOStatement; use PHPTAL; use PHPTAL_PreFilter_Normalize; -use ctiso\View\FakeTemplate; +use ctiso\View\JsonView; /** * Класс компонента @@ -117,12 +117,12 @@ class Component /** * Получить шаблон * @param string $name - * @return PHPTAL|FakeTemplate + * @return PHPTAL|JsonView */ public function getView($name) { if ($this->output === 'json') { - return new FakeTemplate($name); + return new JsonView($name); } /** @var Registry $config */ diff --git a/src/View/FakeTemplate.php b/src/View/JsonView.php similarity index 73% rename from src/View/FakeTemplate.php rename to src/View/JsonView.php index 223fa46..3ba8fd4 100644 --- a/src/View/FakeTemplate.php +++ b/src/View/JsonView.php @@ -2,7 +2,7 @@ namespace ctiso\View; -class FakeTemplate extends \stdClass { +class JsonView extends \stdClass { /** @var array */ public $_data = []; /** @var string */ @@ -15,6 +15,14 @@ class FakeTemplate extends \stdClass { $this->_name = $name; } + /** + * @param string $key + * @param mixed $value + */ + function set($key, $value): void { + $this->_data[$key] = $value; + } + /** * @param string $key * @param mixed $value From 74aa44bdc02c161469f9dc37e62598cd090c8249 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Wed, 3 Dec 2025 18:32:21 +0300 Subject: [PATCH 02/14] =?UTF-8?q?feat:=20=D0=A1=D1=82=D1=80=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=82=D0=B8=D0=BF=D1=8B=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?HttpRequest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Collection.php | 2 +- src/HttpRequest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Collection.php b/src/Collection.php index cf8b814..8e5328d 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -58,7 +58,7 @@ class Collection implements \ArrayAccess /** * @param string $key - * @param int $default + * @param int $default * @return int */ public function getInt($key, $default = 0) diff --git a/src/HttpRequest.php b/src/HttpRequest.php index da5c547..e688fe5 100644 --- a/src/HttpRequest.php +++ b/src/HttpRequest.php @@ -55,7 +55,7 @@ class HttpRequest extends Collection /** * @param string $key * @param mixed $default - * @return mixed + * @return null|string|array */ function get($key, $default = null) { From aa667d248942524d894a4cd9ee1748ea5bfd21c8 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Wed, 3 Dec 2025 20:58:24 +0300 Subject: [PATCH 03/14] fix: HttpRequest --- src/Collection.php | 4 ++-- src/HttpRequest.php | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Collection.php b/src/Collection.php index 8e5328d..85428ad 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -61,7 +61,7 @@ class Collection implements \ArrayAccess * @param int $default * @return int */ - public function getInt($key, $default = 0) + public function getInt(string $key, int $default = 0): int { return (int)$this->get($key, $default); } @@ -81,7 +81,7 @@ class Collection implements \ArrayAccess * @param int $default * @return int */ - public function getNat($key, $default = 1) + public function getNat(string $key, int $default = 1): int { $result = (int)$this->get($key, $default); return (($result > 0) ? $result : $default); diff --git a/src/HttpRequest.php b/src/HttpRequest.php index e688fe5..55b9bcc 100644 --- a/src/HttpRequest.php +++ b/src/HttpRequest.php @@ -67,6 +67,16 @@ class HttpRequest extends Collection return parent::get('data')->getString($key, $default); } + function getInt(string $key, int $default = 0): int + { + return parent::get('data')->getInt($key, $default); + } + + function getNat(string $key, int $default = 1): int + { + return parent::get('data')->getNat($key, $default); + } + function session(?Session $value = null): ?Session { if ($value) { From 088610946787007a73add55b8cb32cc7336172bd Mon Sep 17 00:00:00 2001 From: Wizard Date: Thu, 4 Dec 2025 00:46:30 +0300 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20getArray=20=D0=B4=D0=BB=D1=8F=20H?= =?UTF-8?q?ttpRequest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HttpRequest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/HttpRequest.php b/src/HttpRequest.php index 55b9bcc..7192c09 100644 --- a/src/HttpRequest.php +++ b/src/HttpRequest.php @@ -85,6 +85,14 @@ class HttpRequest extends Collection return $this->_session; } + function getArray($key, $default = []) { + $result = parent::get('data')->get($key, $default); + if (is_array($result)) { + return $result; + } + return $default; + } + function set(string $key, mixed $value): void { parent::get('data')->set($key, $value); From 3169ea2032208efa8db608a69166160f65c99627 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Thu, 4 Dec 2025 13:43:22 +0300 Subject: [PATCH 05/14] =?UTF-8?q?chore:=20=D0=90=D0=BD=D0=BD=D0=BE=D1=82?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D1=82=D0=B8=D0=BF=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Controller/Service.php | 1 + src/HttpRequest.php | 2 +- src/Model/BaseMapper.php | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Controller/Service.php b/src/Controller/Service.php index 7e00a06..e4d7fb9 100644 --- a/src/Controller/Service.php +++ b/src/Controller/Service.php @@ -55,6 +55,7 @@ class Service */ public function getModel($modelName) { + /** @var BaseMapper */ $model = new $modelName(); $model->db = $this->db; return $model; diff --git a/src/HttpRequest.php b/src/HttpRequest.php index 7192c09..62d024e 100644 --- a/src/HttpRequest.php +++ b/src/HttpRequest.php @@ -85,7 +85,7 @@ class HttpRequest extends Collection return $this->_session; } - function getArray($key, $default = []) { + function getArray(string $key, array $default = []): array { $result = parent::get('data')->get($key, $default); if (is_array($result)) { return $result; diff --git a/src/Model/BaseMapper.php b/src/Model/BaseMapper.php index 7e55e72..37831a0 100644 --- a/src/Model/BaseMapper.php +++ b/src/Model/BaseMapper.php @@ -2,6 +2,9 @@ namespace ctiso\Model; +/** + * @property \ctiso\Database $db + */ abstract class BaseMapper { function getAllAsOptions(): array { return []; From 08defbd046663fdc0bb42fe1a44040ef35be16d9 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Thu, 4 Dec 2025 16:39:24 +0300 Subject: [PATCH 06/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Connection/HttpResponse.php | 2 +- src/Controller/Component.php | 2 +- src/Controller/Front.php | 2 +- src/Database.php | 6 ++++++ src/Filter/Login.php | 6 +++--- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Connection/HttpResponse.php b/src/Connection/HttpResponse.php index 9f0fe69..a16120b 100644 --- a/src/Connection/HttpResponse.php +++ b/src/Connection/HttpResponse.php @@ -47,7 +47,7 @@ class HttpResponse if (isset($this->param['Transfer-Encoding']) && $this->param['Transfer-Encoding'] == 'chunked') { //$this->data = substr($this->response, $this->offset); - $index = hexdec($this->getLine()); + $index = (int)hexdec($this->getLine()); $chunk = []; while ($index > 0) { $chunk [] = substr($this->response, $this->offset, $index); diff --git a/src/Controller/Component.php b/src/Controller/Component.php index fbf04b7..124d4e5 100644 --- a/src/Controller/Component.php +++ b/src/Controller/Component.php @@ -135,7 +135,7 @@ class Component foreach ($this->viewPath as $index => $viewPath) { // Загружать шаблон по умолчанию если не найден текущий $dir = Path::join($this->viewPath[$index], 'templates', $template); - if(is_dir($dir)) { + if (is_dir($dir)) { $tpl = new PHPTAL(Path::join($this->viewPath[$index], 'templates', $template, $name)); $tpl->setPhpCodeDestination(PHPTAL_PHP_CODE_DESTINATION); $selected = $index; diff --git a/src/Controller/Front.php b/src/Controller/Front.php index 1a64a65..b799f40 100644 --- a/src/Controller/Front.php +++ b/src/Controller/Front.php @@ -111,7 +111,7 @@ class Front extends Action public function execute(HttpRequest $request) { - $name = $request->get('module', $this->default); + $name = $request->getString('module', $this->default); try { return $this->loadModule($name, $request); } catch (UserMessageException $ex) { //Исключение с понятным пользователю сообщением diff --git a/src/Database.php b/src/Database.php index a15b787..ab2a233 100644 --- a/src/Database.php +++ b/src/Database.php @@ -53,6 +53,12 @@ namespace ctiso { return $result; } + function query($query, $fetchMode = PDO::FETCH_INTO, mixed $_arg1 = null, mixed $_arg2 = null): PDOStatement { + /** @var PDOStatement */ + $result = parent::query($query, $fetchMode); + return $result; + } + /** * Возвращает DSN * @return DSN diff --git a/src/Filter/Login.php b/src/Filter/Login.php index 93df732..2df43b7 100644 --- a/src/Filter/Login.php +++ b/src/Filter/Login.php @@ -41,7 +41,7 @@ class Login extends Filter /** * Проверка авторизации * @param HttpRequest $request - * @return Boolean Авторизовани пользователь или нет + * @return bool Авторизовани пользователь или нет */ public function isLoggin(HttpRequest $request) { @@ -50,8 +50,8 @@ class Login extends Filter switch ($request->getAction()) { // Авторизация по постоянному паролю case 'login': - $login = $request->get('login', '') ; - $password = $request->get('password'); + $login = $request->getString('login', '') ; + $password = $request->getString('password'); $result = $this->role->getUserByLogin($login); // Поиск по логину if ($result) { From b782af55a58e2668e8c3f01473e547165fa96cda Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Thu, 4 Dec 2025 19:44:02 +0300 Subject: [PATCH 07/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Filter/Login.php | 10 +++++----- src/Path.php | 6 +++--- src/Session.php | 5 +---- src/Setup.php | 3 ++- src/Tools/StringUtil.php | 6 +++--- src/Tools/TemplateImage.php | 8 ++++++-- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Filter/Login.php b/src/Filter/Login.php index 2df43b7..78ac4b1 100644 --- a/src/Filter/Login.php +++ b/src/Filter/Login.php @@ -81,7 +81,7 @@ class Login extends Filter $request->set('timeout_error', true); break; } else { - $this->role->resetTries($request->get('login')); + $this->role->resetTries($request->getString('login')); } } // Извлечнеие пользователя из родительской CMS, для проверки пароля @@ -154,7 +154,7 @@ class Login extends Filter public function execute(HttpRequest $request): mixed { $logged = $this->isLoggin($request); - if ($request->get('action') == 'user_access') { + if ($request->getString('action') == 'user_access') { if ($logged) { $result = []; $result['fullname'] = $this->user->getString('patronymic') . " " . $this->user->getString('firstname'); @@ -166,7 +166,7 @@ class Login extends Filter } } - if ($request->get('action') == 'relogin') { + if ($request->getString('action') == 'relogin') { if ($logged) { return json_encode(['result' => 'ok', 'message' => "Авторизация успешна"]); } else { @@ -177,7 +177,7 @@ class Login extends Filter if (!$logged) { // Параметры при неправильной авторизации // Действия по умолчанию !! Возможно переход на форму регистрации - if ($request->get('mode') == 'ajax') { + if ($request->getString('mode') == 'ajax') { if (!$this->requestIsWhite($request)) { return json_encode(['result' => 'fail', 'message' =>"NOT_AUTHORIZED"]); } @@ -188,7 +188,7 @@ class Login extends Filter } else if (isset($_SERVER['HTTP_REFERER'])) { $arr = []; parse_str(parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_QUERY) ?? '', $arr); - if (isset($arr['back_page']) && $request->get('mode') != 'ajax') { + if (isset($arr['back_page']) && $request->getString('mode') != 'ajax') { $request->redirect($arr['back_page']); } } diff --git a/src/Path.php b/src/Path.php index b9b386a..d9381ee 100644 --- a/src/Path.php +++ b/src/Path.php @@ -120,12 +120,12 @@ class Path * Преобразует строку пути в массив * * @param string $path Путь - * @return list|false + * @return list */ - public static function listFromString(string $path): array|false + public static function listFromString(string $path): array { $list = preg_split('#\\\\|/#s', $path); - return $list; + return $list ?: []; } /** diff --git a/src/Session.php b/src/Session.php index 6085450..ff2bba6 100644 --- a/src/Session.php +++ b/src/Session.php @@ -16,10 +16,7 @@ class Session { if (is_array($key)) { $className = get_class($key[0]); - /*if ($className === false) { - throw new \RuntimeException("Invalid class name " . $className); - }*/ - $_SESSION[strtolower($className)][$key[1]] = $value; + $_SESSION[strtolower($className ?: '')][$key[1]] = $value; } else { $_SESSION[$key] = $value; } diff --git a/src/Setup.php b/src/Setup.php index 09a428f..e3538be 100644 --- a/src/Setup.php +++ b/src/Setup.php @@ -10,6 +10,7 @@ namespace ctiso; use ctiso\Tools\SQLStatementExtractor; use ctiso\Path; +use ctiso\File; use SimpleXMLElement; class FakeZipArchive { @@ -26,7 +27,7 @@ class FakeZipArchive { * @return string */ function getFromName($file) { - return file_get_contents(Path::join($this->base, $file)); + return File::getContents(Path::join($this->base, $file)); } } diff --git a/src/Tools/StringUtil.php b/src/Tools/StringUtil.php index aba87c3..a5a37ce 100644 --- a/src/Tools/StringUtil.php +++ b/src/Tools/StringUtil.php @@ -96,11 +96,11 @@ class StringUtil /** * Разбивает строку на массив символов * @param string $str - * @return array|false + * @return array */ - static function mb_str_split(string $str): array|false + static function mb_str_split(string $str): array { - return preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY); + return preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY) ?: []; } /** diff --git a/src/Tools/TemplateImage.php b/src/Tools/TemplateImage.php index 690a4a4..cb0ad0d 100644 --- a/src/Tools/TemplateImage.php +++ b/src/Tools/TemplateImage.php @@ -196,12 +196,16 @@ class TemplateImage return $text; } - function setSize(int $new_width, int $new_height): void + /** + * @param int<1,max> $new_width + * @param ?int<1,max> $new_height + */ + function setSize(int $new_width, ?int $new_height = null): void { $width = imagesx($this->image); $height = imagesy($this->image); if ($new_height == null) { - $new_height = ceil($height * $new_width / $width); + $new_height = max(1, (int)ceil($height * $new_width / $width)); } // Resample From fbe5eb878e7de494ade163feaf02659db40c28a5 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Tue, 9 Dec 2025 17:05:00 +0300 Subject: [PATCH 08/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Filter/Login.php | 7 +++++-- src/Form/Select.php | 2 +- src/Functions.php | 4 ++-- src/Validator/Validator.php | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Filter/Login.php b/src/Filter/Login.php index 78ac4b1..50475ee 100644 --- a/src/Filter/Login.php +++ b/src/Filter/Login.php @@ -187,8 +187,11 @@ class Login extends Filter } } else if (isset($_SERVER['HTTP_REFERER'])) { $arr = []; - parse_str(parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_QUERY) ?? '', $arr); - if (isset($arr['back_page']) && $request->getString('mode') != 'ajax') { + parse_str(parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_QUERY) ?: '', $arr); + if (isset($arr['back_page']) + && is_string($arr['back_page']) + && $request->getString('mode') != 'ajax') + { $request->redirect($arr['back_page']); } } diff --git a/src/Form/Select.php b/src/Form/Select.php index 333691a..89ea70d 100644 --- a/src/Form/Select.php +++ b/src/Form/Select.php @@ -4,7 +4,7 @@ namespace ctiso\Form; use ctiso\Form\Field; /** - * @phpstan-type Option = array{value: string, name: string, selected: bool, class?: string|false} + * @phpstan-type Option = array{value: string, name: string, selected?: bool, class?: string|false} */ class Select extends Field { diff --git a/src/Functions.php b/src/Functions.php index 1d7dd87..fa4391b 100644 --- a/src/Functions.php +++ b/src/Functions.php @@ -268,7 +268,7 @@ class Functions { /** * @param string $key - * @param list|\ArrayIterator $array + * @param array|\ArrayIterator $array * @return array */ static function key_values_object($key, $array) { @@ -283,7 +283,7 @@ class Functions { /** * @param string $key * @param string $value - * @param list>|\ArrayIterator $array + * @param array>|\ArrayIterator $array * @return array */ static function assoc_key_values($key, $value, $array) { diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 7576ca8..2404d6a 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -10,7 +10,7 @@ use Exception, /** * @phpstan-type Rule array{ - * validate:string, // Описание правила см. формат правила ниже + * validate?:string, // Описание правила см. формат правила ниже * name:string, // Имя переменой для проверки * context?:object * } From 3d34ae4b84cd74d5afb31c525f740c98a33e6298 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Tue, 9 Dec 2025 19:46:55 +0300 Subject: [PATCH 09/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Connection/HttpResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Connection/HttpResponse.php b/src/Connection/HttpResponse.php index a16120b..fad35ab 100644 --- a/src/Connection/HttpResponse.php +++ b/src/Connection/HttpResponse.php @@ -52,7 +52,7 @@ class HttpResponse while ($index > 0) { $chunk [] = substr($this->response, $this->offset, $index); $this->offset += $index; - $index = hexdec($this->getLine()); + $index = (int)hexdec($this->getLine()); } $this->data = implode("", $chunk); From f4d829119b0223ae440622fe789685feeaafd692 Mon Sep 17 00:00:00 2001 From: Wizard Date: Tue, 9 Dec 2025 23:25:13 +0300 Subject: [PATCH 10/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Path.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Path.php b/src/Path.php index d9381ee..b169d92 100644 --- a/src/Path.php +++ b/src/Path.php @@ -60,7 +60,7 @@ class Path */ public static function basename($path) { - $list = preg_split('#\\\\|/#s', $path); + $list = preg_split('#\\\\|/#s', $path) ?: ['']; return end($list); } @@ -96,7 +96,7 @@ class Path static function skipExtension(string $fileName): string { $path = pathinfo($fileName); - if ($path['dirname'] === ".") { + if (!isset($path['dirname']) || $path['dirname'] === ".") { return $path['filename']; } else { return self::join($path['dirname'], $path['filename']); From 233749f1ea5ba4d7afe160599f7f7d51e7e4d29e Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Wed, 10 Dec 2025 17:46:56 +0300 Subject: [PATCH 11/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Collection.php | 59 +++++++++++++++++++++++++++++++++++++-- src/Controller/Action.php | 2 +- src/HttpRequest.php | 25 +++++++++-------- src/Path.php | 22 +++++++-------- 4 files changed, 82 insertions(+), 26 deletions(-) diff --git a/src/Collection.php b/src/Collection.php index 85428ad..430cc69 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -63,7 +63,18 @@ class Collection implements \ArrayAccess */ public function getInt(string $key, int $default = 0): int { - return (int)$this->get($key, $default); + $value = $this->get($key); + + // Фильтруем как целое число + if (is_numeric($value)) { + // Приводим к int, но сначала проверим, что не float с дробной частью + $floatVal = (float)$value; + if (is_finite($floatVal) && floor($floatVal) === $floatVal) { + return (int)$floatVal; + } + } + + return $default; } /** @@ -73,9 +84,53 @@ class Collection implements \ArrayAccess */ public function getString(string $key, string $default = ''): string { - return (string)$this->get($key, $default); + $value = $this->get($key); + + if (is_string($value)) { + return $value; + } + + if (is_numeric($value)) { + return (string)$value; + } + + return $default; } + /** + * Получает булево значение + * Поддерживает: 1, '1', 'true', 'on', 'yes' → true + * Иначе → false + */ + public function getBool(string $key, bool $default = false): bool + { + $value = $this->get($key); + + if (is_bool($value)) { + return $value; + } + + if (is_string($value)) { + $value = strtolower(trim($value)); + return in_array($value, ['1', 'true', 'on', 'yes'], true); + } + + if (is_numeric($value)) { + return (bool)$value; + } + + return $default; + } + + function getArray(string $key, array $default = []): array { + $result = $this->get($key); + if (is_array($result)) { + return $result; + } + return $default; + } + + /** * @param string $key * @param int $default diff --git a/src/Controller/Action.php b/src/Controller/Action.php index fab01da..84cf844 100644 --- a/src/Controller/Action.php +++ b/src/Controller/Action.php @@ -231,7 +231,7 @@ class Action implements ActionInterface /** * Страница по умолчанию * @param HttpRequest $request - * @return View|string + * @return string|false */ public function actionIndex(HttpRequest $request) { return ""; diff --git a/src/HttpRequest.php b/src/HttpRequest.php index 62d024e..a24e60f 100644 --- a/src/HttpRequest.php +++ b/src/HttpRequest.php @@ -5,8 +5,7 @@ */ namespace ctiso; -use Exception; -use ArrayAccess; + use ctiso\Collection; use ctiso\Session; @@ -69,12 +68,22 @@ class HttpRequest extends Collection function getInt(string $key, int $default = 0): int { - return parent::get('data')->getInt($key, $default); + return parent::get('data')->getInt($key, $default); } function getNat(string $key, int $default = 1): int { - return parent::get('data')->getNat($key, $default); + return parent::get('data')->getNat($key, $default); + } + + function getBool(string $key, bool $default = false): bool + { + return parent::get('data')->getBool($key, $default); + } + + function getArray(string $key, array $default = []): array + { + return parent::get('data')->getArray($key, $default); } function session(?Session $value = null): ?Session @@ -85,14 +94,6 @@ class HttpRequest extends Collection return $this->_session; } - function getArray(string $key, array $default = []): array { - $result = parent::get('data')->get($key, $default); - if (is_array($result)) { - return $result; - } - return $default; - } - function set(string $key, mixed $value): void { parent::get('data')->set($key, $value); diff --git a/src/Path.php b/src/Path.php index b169d92..55a0022 100644 --- a/src/Path.php +++ b/src/Path.php @@ -21,7 +21,7 @@ class Path */ public function __construct($path = '') { - $this->url = parse_url($path); + $this->url = parse_url($path) ?: []; if (isset($this->url['path'])) { $path = $this->url['path']; @@ -174,17 +174,17 @@ class Path */ public static function makeUrl($path): string { - $slash = (isset($path['host']) && (strlen($path['path']) > 0) && ($path['path'][0] != '/')) ? '/' : ''; + $slash = (isset($path['host']) && isset($path['path']) && (strlen($path['path']) > 0) && ($path['path'][0] != '/')) ? '/' : ''; + $scheme = isset($path['scheme']) ? $path['scheme'] . ':/' : ''; + $user = isset($path['user']) ? $path['user'] . (isset($path['pass']) ? ':' . $path['pass'] : '') . '@' : ''; - return (isset($path['scheme']) ? $path['scheme'] . ':/' : '') - . (isset($path['host']) ? ('/' - . (isset($path['user']) ? $path['user'] . (isset($path['pass']) ? ':' . $path['pass'] : '') . '@' : '') - . $path['host'] - . (isset($path['port']) ? ':' . $path['port'] : '')) : '') - . $slash - . ($path['path'] ?? '') - . (isset($path['query']) ? '?' . $path['query'] : '') - . (isset($path['fragment']) ? '#' . $path['fragment'] : ''); + $port = isset($path['port']) ? ':' . $path['port'] : ''; + $host = isset($path['host']) ? ('/' . $user . $path['host'] . $port) : ''; + + $query = isset($path['query']) ? '?' . $path['query'] : ''; + $fragment = isset($path['fragment']) ? '#' . $path['fragment'] : ''; + + return $scheme . $host . $slash . ($path['path'] ?? '') . $query . $fragment; } /** From 1b6630e5f5766bd7d8760cae01ca1a29414b5e38 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Wed, 10 Dec 2025 19:50:04 +0300 Subject: [PATCH 12/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Database/Manager.php | 4 ++-- src/Functions.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Database/Manager.php b/src/Database/Manager.php index 19ed189..ff8211e 100644 --- a/src/Database/Manager.php +++ b/src/Database/Manager.php @@ -16,7 +16,7 @@ use Exception; * @phpstan-type CreateAction array{ * type:"createTable", * table_name:string, - * constraints:?array, + * constraints?:array{fields: array, type: string}|string, * fields:array, * } * @@ -277,7 +277,7 @@ class Manager * Добавляет столбец в таблицу * @param string $table_name * @param string $column_name - * @param array $field + * @param ColumnProps $field */ public function addColumn($table_name, $column_name, $field): void { diff --git a/src/Functions.php b/src/Functions.php index fa4391b..bd7fead 100644 --- a/src/Functions.php +++ b/src/Functions.php @@ -296,7 +296,7 @@ class Functions { /** * @param string $key - * @param list>|\ArrayIterator $array + * @param array>|\ArrayIterator $array * @return array */ static function assoc_key($key, $array) { From 481f76add4aa9b5916eb17421dcc93c6e802519f Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Thu, 11 Dec 2025 13:27:11 +0300 Subject: [PATCH 13/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Validator/Rule/AbstractRule.php | 5 +++-- src/Validator/Rule/Alpha.php | 5 +++-- src/Validator/Rule/RuleContext.php | 10 ++++++++++ src/Validator/Rule/Unique.php | 7 ++++--- src/Validator/Validator.php | 9 +++++---- 5 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 src/Validator/Rule/RuleContext.php diff --git a/src/Validator/Rule/AbstractRule.php b/src/Validator/Rule/AbstractRule.php index fac4aad..706d8b6 100644 --- a/src/Validator/Rule/AbstractRule.php +++ b/src/Validator/Rule/AbstractRule.php @@ -1,13 +1,14 @@ ctx->isUnique($container->get($this->field), $status, $container); + return $this->ctx->isUnique($container->getString($this->field), $status, $container); } } diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 2404d6a..2225479 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -4,15 +4,16 @@ * Проверка коллекции */ namespace ctiso\Validator; -use Exception, - ctiso\Validator\Rule\AbstractRule, - ctiso\Collection; +use Exception; +use ctiso\Validator\Rule\AbstractRule; +use ctiso\Validator\Rule\RuleContext; +use ctiso\Collection; /** * @phpstan-type Rule array{ * validate?:string, // Описание правила см. формат правила ниже * name:string, // Имя переменой для проверки - * context?:object + * context?:RuleContext * } */ class Validator From 5988eca22b65841af866e13c4a80b9badc440c08 Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Thu, 11 Dec 2025 16:08:16 +0300 Subject: [PATCH 14/14] =?UTF-8?q?chore:=20=D0=A2=D0=B8=D0=BF=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Role/User.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Role/User.php b/src/Role/User.php index fc96b8d..78f2923 100644 --- a/src/Role/User.php +++ b/src/Role/User.php @@ -74,7 +74,9 @@ class User implements UserInterface if ($result) { $time = time(); $id = $this->id; - $this->db->executeQuery("UPDATE users SET lasttime = $time WHERE id_user = $id"); // Время входа + $this->db->executeQuery( + "UPDATE users SET lasttime = :time WHERE id_user = :id", + ['time' => $time, 'id' => $id]); // Время входа } return $result; }