From 5d3fae4249bc2087529d069baef66b7d39399e4f Mon Sep 17 00:00:00 2001 From: "origami11@yandex.ru" Date: Mon, 1 Dec 2025 16:19:28 +0300 Subject: [PATCH] =?UTF-8?q?chore:=20=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=82=D0=B8=D0=BF=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Controller/Action.php | 2 +- src/Controller/Component.php | 9 ++--- src/Database.php | 8 ++++- src/Database/Manager.php | 70 ++++++++++++++++++++++++++++-------- src/Mail.php | 7 ++-- src/Primitive.php | 4 +-- src/Role/User.php | 5 ++- src/Session.php | 3 ++ src/Setup.php | 10 ++++-- src/Tools/Drawing.php | 2 +- src/Tools/Image.php | 5 ++- src/Tools/TemplateImage.php | 4 +-- src/Validator/Rule/Time.php | 1 + src/View/View.php | 30 ++++++++++++---- src/ZipFile.php | 7 ++-- 15 files changed, 125 insertions(+), 42 deletions(-) diff --git a/src/Controller/Action.php b/src/Controller/Action.php index 1c30a78..8c57a29 100644 --- a/src/Controller/Action.php +++ b/src/Controller/Action.php @@ -205,7 +205,7 @@ class Action implements ActionInterface /** * Выполнение действия * @param HttpRequest $request - * @return View|string + * @return View|string|false */ public function execute(HttpRequest $request) { diff --git a/src/Controller/Component.php b/src/Controller/Component.php index 85f54f2..a6916a5 100644 --- a/src/Controller/Component.php +++ b/src/Controller/Component.php @@ -96,11 +96,12 @@ class Component } $this->before(); - if (method_exists($this, $action)) { - return call_user_func([$this, $action], $crequest); - } else { - return $this->actionIndex($crequest); + $actionMethod = [$this, $action]; + if (is_callable($actionMethod)) { + return call_user_func($actionMethod, $crequest); } + + return $this->actionIndex($crequest); } /** diff --git a/src/Database.php b/src/Database.php index 8d7807d..a15b787 100644 --- a/src/Database.php +++ b/src/Database.php @@ -132,7 +132,7 @@ namespace ctiso { * Извлекает из базы все элементы по запросу (Для совместимости со старым представлением баз данных CIS) * @param string $query - запрос * @param ?array $values - значения - * @return list> + * @return array> */ public function fetchAllArray($query, $values = null) { @@ -212,6 +212,9 @@ namespace ctiso { return $result[$index]; } else { $result = $this->fetchOneArray("SELECT $index AS lastid FROM $table WHERE OID = last_insert_rowid()"); + if ($result === false) { + throw new \RuntimeException("Ошибка получения идентификатора"); + } return $result['lastid']; } } @@ -255,6 +258,9 @@ namespace ctiso { function getNextId($seq) { $result = $this->fetchOneArray("SELECT nextval('$seq')"); + if ($result === false) { + throw new \RuntimeException("Ошибка получения следующего идентификатора"); + } return $result['nextval']; } diff --git a/src/Database/Manager.php b/src/Database/Manager.php index 9f0fe05..19ed189 100644 --- a/src/Database/Manager.php +++ b/src/Database/Manager.php @@ -8,27 +8,67 @@ use ctiso\Path; use Exception; /** - * @phpstan-type Action array{ - * type:string, + * @phpstan-type DropAction array{ + * type:"dropTable", + * table_name:string + * } + * + * @phpstan-type CreateAction array{ + * type:"createTable", * table_name:string, - * table:string, - * fields:array, - * field: ColumnProps, * constraints:?array, - * references:?array, + * fields:array, + * } + * + * @phpstan-type AddColumnAction array{ + * type:"addColumn", + * table_name:string, + * column_name:string, + * field:ColumnProps + * } + * + * @phpstan-type AlterReferenceAction array{ + * type:"alterReference", + * table:string, + * column:string, + * refTable:string, + * refColumn:string + * } + * + * @phpstan-type RenameColumnAction array{ + * type:"renameColumn", + * table:string, + * old_name:string, + * new_name:string + * } + * + * @phpstan-type ExecuteFileAction array{ + * type:"executeFile", * source:string, - * pgsql?:string, - * old_name?:string, - * new_name?:string, - * column?:string, - * column_name?:string, - * refTable?:string, - * refColumn?:string, - * values:array, + * pgsql:?string + * } + * + * @phpstan-type CreateViewAction array{ + * type:"createView", * view:string, * select:string * } * + * @phpstan-type InsertAction array{ + * type:"insert", + * table_name:string, + * values:array + * } + * + * @phpstan-type Action DropAction + * | CreateAction + * | AddColumnAction + * | AlterReferenceAction + * | RenameColumnAction + * | ExecuteFileAction + * | CreateViewAction + * | InsertAction + * * @phpstan-type ColumnProps array{ * name:string, * type:string, @@ -266,7 +306,7 @@ class Manager * @example createTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']]) * @param string $table * @param array $fields - * @param array|string|null $constraints + * @param array{fields: array, type: string}|string|null $constraints */ public function createTableQuery($table, $fields, $constraints): void { diff --git a/src/Mail.php b/src/Mail.php index e965dfd..848c645 100644 --- a/src/Mail.php +++ b/src/Mail.php @@ -111,8 +111,11 @@ class Mail if (file_exists($filename)) { $file = fopen($filename, "rb"); if (is_resource($file)) { - $data = fread($file, filesize($filename)); - $this->attachment[] = ($name) ? [$data, $name] : [$data, basename($filename)]; + $size = filesize($filename); + if ($size !== false && $size > 0) { + $data = fread($file, $size); + $this->attachment[] = ($name) ? [$data, $name] : [$data, basename($filename)]; + } } } } diff --git a/src/Primitive.php b/src/Primitive.php index 746f868..ce1482a 100644 --- a/src/Primitive.php +++ b/src/Primitive.php @@ -81,7 +81,7 @@ class Primitive { if ($month != 0 && $day != 0 && $year != 0) { if (checkdate($month, $day, $year)) { - return mktime(0, 0, 0, $month, $day, $year); + return mktime(0, 0, 0, $month, $day, $year) ?: 0; } else { return 0; } @@ -102,7 +102,7 @@ class Primitive { $tmp = []; if (preg_match('/(\d+)-(\d+)-(\d+)T(\d+):(\d+)Z/', $value, $tmp)) { if (checkdate((int)$tmp[2], (int)$tmp[3], (int)$tmp[1])) { - $result = mktime((int)$tmp[4], (int)$tmp[5], 0, (int)$tmp[2], (int)$tmp[3], (int)$tmp[1]); + $result = mktime((int)$tmp[4], (int)$tmp[5], 0, (int)$tmp[2], (int)$tmp[3], (int)$tmp[1]) ?: 0; } } return $result; diff --git a/src/Role/User.php b/src/Role/User.php index 1cca467..fc96b8d 100644 --- a/src/Role/User.php +++ b/src/Role/User.php @@ -98,7 +98,7 @@ class User implements UserInterface * @param PDOStatement $result * @return PDOStatement|bool */ - function setSID(string $random, $result) + function setSID(string $random, $result) { return $this->db->executeQuery("UPDATE users SET sid = :sid, trie_count = 0 WHERE id_user = :user", [ 'user' => $result->getInt('id_user'), @@ -115,6 +115,9 @@ class User implements UserInterface function updateTries(string $login): void { $user = $this->db->fetchOneArray("SELECT id_user, trie_count FROM users WHERE login = :login", ['login' => $login]); + if ($user === false) { + return; + } $this->db->executeQuery( "UPDATE users SET trie_time = :cur_time, trie_count = :count WHERE id_user = :id_user", ['cur_time' => time(), 'count' => $user['trie_count']+1, 'id_user' => $user['id_user']] diff --git a/src/Session.php b/src/Session.php index bf17b0c..6085450 100644 --- a/src/Session.php +++ b/src/Session.php @@ -16,6 +16,9 @@ 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; } else { $_SESSION[$key] = $value; diff --git a/src/Setup.php b/src/Setup.php index 7f7874f..09a428f 100644 --- a/src/Setup.php +++ b/src/Setup.php @@ -59,7 +59,11 @@ class Setup public function __construct($file) { $this->file = $file; - $this->node = simplexml_load_file($file); + $node = simplexml_load_file($file); + if ($node === false) { + throw new \RuntimeException("Can't load file $file"); + } + $this->node = $node; $this->target = ''; $this->source = ''; @@ -127,7 +131,7 @@ class Setup /** * Заменяет переменные на их значения в строке - * @param list $match массив совпадения + * @param array $match массив совпадения * @return string */ function replaceVariable(array $match) @@ -147,7 +151,7 @@ class Setup { $result = []; foreach ($attributes as $key => $value) { - $result[$key] = preg_replace_callback("/\\\${(\w+)}/", [$this, 'replaceVariable'], $value); + $result[$key] = preg_replace_callback("/\\\${(\w+)}/", $this->replaceVariable(...), $value); } return $result; } diff --git a/src/Tools/Drawing.php b/src/Tools/Drawing.php index 75b2eab..9758044 100644 --- a/src/Tools/Drawing.php +++ b/src/Tools/Drawing.php @@ -144,7 +144,7 @@ class Drawing $temp_x = $x; for ($i = 0; $i < mb_strlen($text); $i++) { $bbox = imagettftext($image, $size, $angle, $temp_x, $y, $color, $font, $text[$i]); - $temp_x += $spacing + ($bbox[2] - $bbox[0]); + $temp_x += $spacing + ($bbox !== false ? ($bbox[2] - $bbox[0]) : 0); } } } diff --git a/src/Tools/Image.php b/src/Tools/Image.php index 646c7d9..ee04dcb 100644 --- a/src/Tools/Image.php +++ b/src/Tools/Image.php @@ -25,8 +25,11 @@ class Image { $width = imagesx($image); $height = imagesy($image); + $percent = min($prewidth / $width, $preheight / $height); - if ($percent > 1 && !$force) $percent = 1; + if ($percent > 1 && !$force) { + $percent = 1; + } $new_width = $width * $percent; $new_height = $height * $percent; diff --git a/src/Tools/TemplateImage.php b/src/Tools/TemplateImage.php index 66d5460..a076a02 100644 --- a/src/Tools/TemplateImage.php +++ b/src/Tools/TemplateImage.php @@ -89,8 +89,8 @@ class TemplateImage /** * Создает пустое изображение - * @param int $width - * @param int $height + * @param int<1, max> $width + * @param int<1, max> $height */ function setEmptyImage($width, $height): void { diff --git a/src/Validator/Rule/Time.php b/src/Validator/Rule/Time.php index 34534b9..6b20161 100644 --- a/src/Validator/Rule/Time.php +++ b/src/Validator/Rule/Time.php @@ -9,6 +9,7 @@ use ctiso\Validator\Rule\AbstractRule, class Time extends AbstractRule { + /** @var non-empty-string */ private string $split = ":"; public function getErrorMsg(): string diff --git a/src/View/View.php b/src/View/View.php index 45091a0..c4d4106 100644 --- a/src/View/View.php +++ b/src/View/View.php @@ -5,12 +5,13 @@ use Exception; class View extends \stdClass { - protected array $_section = []; // Вложенные шаблоны - // Блоки - /** @var string[] $_stylesheet */ - protected array $_stylesheet = []; // Массив стилей текущего шаблона - /** @var string[] $_script */ - protected array $_script = []; // Массив скриптов текущего шаблона + /** @var array Вложенные шаблоны */ + protected array $_section = []; + + /** @var string[] $_stylesheet Массив стилей текущего шаблона */ + protected array $_stylesheet = []; + /** @var string[] $_script Массив скриптов текущего шаблона */ + protected array $_script = []; /** @var string[] $_scriptstring */ public array $_scriptstring = []; /** @var string[] $_startup */ @@ -46,7 +47,7 @@ class View extends \stdClass */ public function setView($section, $view): void { - $this->_section [$section] = $view; + $this->_section[$section] = $view; if (is_object($view)) { $view->parent_view = $this; } @@ -122,6 +123,14 @@ class View extends \stdClass return $result; } + /* + function getTitleArray(): array { + return array_reduce($this->_section, fn ($result, $item) => + is_object($item) ? array_merge($result, $item->getTitleArray()) : $result, []); + } + */ + + /*abstract*/ public function set(string $key, mixed $value): void { } @@ -208,4 +217,11 @@ class View extends \stdClass } return $result; } + + /** + * @return View|string|false + */ + function execute() { + return ''; + } } diff --git a/src/ZipFile.php b/src/ZipFile.php index 99ae70b..b6ecdf6 100644 --- a/src/ZipFile.php +++ b/src/ZipFile.php @@ -26,12 +26,15 @@ class ZipFile extends ZipArchive // Read all Files in Dir $dir = opendir($location); + if (!$dir) { + throw new \RuntimeException("Enable to open dir '$dir'"); + } while (($file = readdir($dir)) !== false) { if (in_array($file, $this->ignore)) continue; // Rekursiv, If dir: FlxZipArchive::addDir(), else ::File(); - $call = (is_dir($location . $file)) ? 'addDir' : 'addFile'; - call_user_func([$this, $call], $location . $file, $name . $file); + $call = (is_dir($location . $file)) ? $this->addDir(...) : $this->addFile(...); + call_user_func($call, $location . $file, $name . $file); } }