chore: Аннотации к типам

This commit is contained in:
origami11@yandex.ru 2025-10-23 11:24:33 +03:00
parent e5713e9015
commit 530a3b931d
22 changed files with 388 additions and 131 deletions

View file

@ -78,7 +78,7 @@ class Collection implements \ArrayAccess
return (($result > 0) ? $result : $default); return (($result > 0) ? $result : $default);
} }
public function clear() public function clear(): void
{ {
$this->data = []; $this->data = [];
} }

View file

@ -4,26 +4,37 @@ namespace ctiso\Database;
use ctiso\Database; use ctiso\Database;
class IdGenerator { class IdGenerator {
/** @var Database */
private $db; private $db;
function __construct(Database $db) { function __construct(Database $db) {
$this->db = $db; $this->db = $db;
} }
/**
* @return bool
*/
function isBeforeInsert() { function isBeforeInsert() {
return false; return false;
}
function isAfterInsert() {
return true;
} }
/**
* @return bool
*/
function isAfterInsert() {
return true;
}
/**
* @param string $seq
* @return int
*/
function getId($seq) { function getId($seq) {
if ($this->db->isPostgres()) { if ($this->db->isPostgres()) {
$result = $this->db->fetchOneArray("SELECT nextval('$seq') AS nextval"); $result = $this->db->fetchOneArray("SELECT nextval('$seq') AS nextval");
} else { } else {
$result = $this->db->fetchOneArray("SELECT last_insert_rowid() AS nextval"); $result = $this->db->fetchOneArray("SELECT last_insert_rowid() AS nextval");
} }
return (int)$result['nextval']; return (int)$result['nextval'];
} }
} }

View file

@ -5,13 +5,20 @@ namespace ctiso\Database;
use ctiso\Database\Manager; use ctiso\Database\Manager;
class JsonInstall { class JsonInstall {
/** @var Manager */
public $db_manager; public $db_manager;
/** @var array */
public $serialColumns; public $serialColumns;
public function __construct(Manager $db_manager) { public function __construct(Manager $db_manager) {
$this->db_manager = $db_manager; $this->db_manager = $db_manager;
} }
/**
* Установить базу данных
* @param string $dbinit_path
* @param ?string $dbfill_path
*/
function install($dbinit_path, $dbfill_path = null) { function install($dbinit_path, $dbfill_path = null) {
$dbinit_file = file_get_contents($dbinit_path); $dbinit_file = file_get_contents($dbinit_path);
if (is_string($dbinit_file)) { if (is_string($dbinit_file)) {
@ -32,6 +39,11 @@ class JsonInstall {
$this->makeConstraints($initActions); $this->makeConstraints($initActions);
} }
/**
* Получить список таблиц, которые не существуют в базе данных
* @param array $tables
* @return array
*/
function missingTables($tables) { function missingTables($tables) {
$actual_tables = $this->db_manager->getAllTableNames(); $actual_tables = $this->db_manager->getAllTableNames();
$missingTables = []; $missingTables = [];
@ -42,7 +54,12 @@ class JsonInstall {
return $missingTables; return $missingTables;
} }
// Создать таблицы /**
* Создать таблицы
* @param array $initActions
* @param string $dbinit_path
* @return void
*/
function initDataBase(array $initActions, $dbinit_path) { function initDataBase(array $initActions, $dbinit_path) {
$pg = $this->db_manager->db->isPostgres(); $pg = $this->db_manager->db->isPostgres();
if (!$pg) { if (!$pg) {
@ -73,7 +90,7 @@ class JsonInstall {
} }
} }
if ($action["type"] != "alterReference") { if ($action["type"] != "alterReference") {
$this->db_manager->ExecuteAction($action, $dbinit_path); $this->db_manager->executeAction($action, $dbinit_path);
} }
} }
@ -95,7 +112,11 @@ class JsonInstall {
} }
} }
//Заполнить данными /**
* Заполнить данными
* @param string $dbfill_file_path
* @return void
*/
function fillDataBase($dbfill_file_path) { function fillDataBase($dbfill_file_path) {
$dbfill_file = file_get_contents($dbfill_file_path); $dbfill_file = file_get_contents($dbfill_file_path);
if (is_string($dbfill_file)) { if (is_string($dbfill_file)) {
@ -128,7 +149,11 @@ class JsonInstall {
} }
} }
//Обновить ключи serial и создать ограничения /**
* Обновить ключи serial и создать ограничения
* @param array $initActions
* @return void
*/
function makeConstraints($initActions) { function makeConstraints($initActions) {
$pg = $this->db_manager->db->isPostgres(); $pg = $this->db_manager->db->isPostgres();
if ($pg) { if ($pg) {

View file

@ -17,9 +17,15 @@ class Manager
$this->db = $db; $this->db = $db;
} }
public function executeAction(array $action, $db_file = "") /**
* Выполняет действие
* @param array $action
* @param string $db_file
* @throws Exception
*/
public function executeAction(array $action, $db_file = ""): void
{ {
switch($action["type"]) { switch ($action["type"]) {
case "dropTable": case "dropTable":
$this->dropTableQuery($action["table_name"], true); $this->dropTableQuery($action["table_name"], true);
break; break;
@ -56,59 +62,85 @@ class Manager
break; break;
default: default:
throw new Exception("unknown action ". $action["type"] . PHP_EOL); throw new Exception("unknown action " . $action["type"] . PHP_EOL);
} }
} }
//Дропает и создаёт SQL VIEW /**
public function recreateView($viewName, $selectStatement) * Дропает и создаёт SQL VIEW
* @param string $viewName
* @param string $selectStatement
*/
public function recreateView($viewName, $selectStatement): void
{ {
$this->db->query("DROP VIEW ".$viewName); $this->db->query("DROP VIEW " . $viewName);
$this->db->query("CREATE VIEW ".$viewName." AS ".$selectStatement); $this->db->query("CREATE VIEW " . $viewName . " AS " . $selectStatement);
} }
public function dropTableQuery($table, $cascade=false) /**
* Дропает таблицу
* @param string $table
* @param bool $cascade
*/
public function dropTableQuery($table, $cascade = false): void
{ {
$statement = "DROP TABLE IF EXISTS ".$table; $statement = "DROP TABLE IF EXISTS " . $table;
if ($this->db->isPostgres()&&$cascade) { if ($this->db->isPostgres() && $cascade) {
$statement .= " CASCADE"; $statement .= " CASCADE";
} }
$this->db->query($statement); $this->db->query($statement);
} }
public function alterReference($table, $column, $refTable, $refColumn) /**
* Добавляет ссылку на другую таблицу
* @param string $table
* @param string $column
* @param string $refTable
* @param string $refColumn
*/
public function alterReference($table, $column, $refTable, $refColumn): void
{ {
$this->db->query("ALTER TABLE ".$table." ADD CONSTRAINT ".$table."_".$column."fk"." FOREIGN KEY (".$column.") REFERENCES ".$refTable." (".$refColumn.")"); $this->db->query("ALTER TABLE " . $table . " ADD CONSTRAINT " . $table . "_" . $column . "fk" . " FOREIGN KEY (" . $column . ") REFERENCES " . $refTable . " (" . $refColumn . ") ON DELETE CASCADE ON UPDATE CASCADE");
} }
//Извлечение информации о полях таблицы /**
* Извлечение информации о полях таблицы
* @param string $table
* @return array{type:string,not_null:bool,constraint:?string}[]|null
*/
public function tableInfo($table) public function tableInfo($table)
{ {
$pg = $this->db->isPostgres(); $pg = $this->db->isPostgres();
if ($pg) { if ($pg) {
throw new Exception("Not implemented for postgres"); throw new Exception("Not implemented for postgres");
} else { } else {
$results = $this->db->fetchAllArray("PRAGMA table_info(".$table.");"); $results = $this->db->fetchAllArray("PRAGMA table_info(" . $table . ");");
if (empty($results)) { if (empty($results)) {
return null; return null;
} }
$fields = []; $fields = [];
foreach ($results as $result) { foreach ($results as $result) {
$fields[$result["name"]] = [ $fields[$result["name"]] = [
"type"=> $result["type"], "type" => $result["type"],
"not_null"=> boolval($result["notnull"]), "not_null" => boolval($result["notnull"]),
"constraint"=> ((bool) $result["pk"]) ? "PRIMARY KEY" : null "constraint" => ((bool) $result["pk"]) ? "PRIMARY KEY" : null
]; ];
} }
return $fields; return $fields;
} }
} }
public function renameColumn($table, $old_name, $new_name) /**
* Переименование столбца в таблице
* @param string $table
* @param string $old_name
* @param string $new_name
*/
public function renameColumn($table, $old_name, $new_name): void
{ {
$pg = $this->db->isPostgres(); $pg = $this->db->isPostgres();
if ($pg) { if ($pg) {
$this->db->query("ALTER TABLE ".$table." RENAME COLUMN ".$old_name." TO ".$new_name); $this->db->query("ALTER TABLE " . $table . " RENAME COLUMN " . $old_name . " TO " . $new_name);
} else { } else {
$tmp_table = "tmp_" . $table; $tmp_table = "tmp_" . $table;
$this->dropTableQuery($tmp_table); $this->dropTableQuery($tmp_table);
@ -120,7 +152,7 @@ class Manager
$data = $this->dumpTable($table); $data = $this->dumpTable($table);
$this->db->query("ALTER TABLE ".$table." RENAME TO ".$tmp_table.";"); $this->db->query("ALTER TABLE " . $table . " RENAME TO " . $tmp_table . ";");
$table_info[$new_name] = $table_info[$old_name]; $table_info[$new_name] = $table_info[$old_name];
unset($table_info[$old_name]); unset($table_info[$old_name]);
$this->createTableQuery($table, $table_info, null); $this->createTableQuery($table, $table_info, null);
@ -135,41 +167,63 @@ class Manager
} }
} }
//Обновление ключа serial после ручной вставки /**
public function updateSerial($table, $column) * Обновление ключа serial после ручной вставки
* @param string $table
* @param string $column
*/
public function updateSerial($table, $column): void
{ {
$this->db->query("SELECT setval(pg_get_serial_sequence('".$table."', '".$column."'), coalesce(max(".$column."),0) + 1, false) FROM ".$table); $this->db->query("SELECT setval(pg_get_serial_sequence('" . $table . "', '" . $column . "'), coalesce(max(" . $column . "),0) + 1, false) FROM " . $table);
} }
/**
* Возвращает определение столбца
* @param string $name
* @param array $data
* @param bool $pg
* @return string
*/
public function columnDefinition($name, $data, $pg) public function columnDefinition($name, $data, $pg)
{ {
$constraint = isset($data['constraint']) ? " ".$data['constraint'] : ""; $constraint = isset($data['constraint']) ? " " . $data['constraint'] : "";
$references = ""; $references = "";
if (isset($data['references'])) { if (isset($data['references'])) {
$references = " REFERENCES " . $data['references']['refTable'] . '(' .$data['references']['refColumn'] . ')'; $references = " REFERENCES " . $data['references']['refTable'] . '(' . $data['references']['refColumn'] . ')';
} }
if (isset($data["not_null"]) && $data["not_null"]) { if (isset($data["not_null"]) && $data["not_null"]) {
$constraint .=" NOT NULL"; $constraint .= " NOT NULL";
} }
$type = $data['type']; $type = $data['type'];
if (!$pg) { if (!$pg) {
if (strtolower($type)=="serial") { if (strtolower($type) == "serial") {
$type = "integer"; $type = "integer";
} }
//if (strtolower($type)=="boolean") //if (strtolower($type)=="boolean")
// $type = "integer"; // $type = "integer";
} }
return $name." ".$type.$references.$constraint; return $name . " " . $type . $references . $constraint;
} }
public function addColumn($table_name, $column_name, $field) /**
* Добавляет столбец в таблицу
* @param string $table_name
* @param string $column_name
* @param array $field
*/
public function addColumn($table_name, $column_name, $field): void
{ {
$pg = $this->db->isPostgres(); $pg = $this->db->isPostgres();
$q = "ALTER TABLE ".$table_name." ADD COLUMN ". $q = "ALTER TABLE " . $table_name . " ADD COLUMN " .
$this->columnDefinition($column_name, $field, $pg); $this->columnDefinition($column_name, $field, $pg);
$this->db->query($q); $this->db->query($q);
} }
/**
* Возвращает определение ограничения
* @param array{fields: string[], type: string} $c
* @return string
*/
public function getConstraintDef(array $c) public function getConstraintDef(array $c)
{ {
if ($c['type'] == 'unique') { if ($c['type'] == 'unique') {
@ -178,7 +232,14 @@ class Manager
return ""; return "";
} }
//CreateTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']])
/**
* Создает таблицу
* @example createTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']])
* @param string $table
* @param array $fields
* @param array|string|null $constraints
*/
public function createTableQuery($table, $fields, $constraints) public function createTableQuery($table, $fields, $constraints)
{ {
$pg = $this->db->isPostgres(); $pg = $this->db->isPostgres();
@ -198,12 +259,17 @@ class Manager
$this->db->query($statement); $this->db->query($statement);
} }
/**
* Возвращает дамп таблицы
* @param string $table_name
* @return array
*/
public function dumpTable($table_name) public function dumpTable($table_name)
{ {
$pg = $this->db->isPostgres(); $pg = $this->db->isPostgres();
$result = []; $result = [];
$data = $this->db->fetchAllArray("SELECT * FROM ".$table_name.";"); $data = $this->db->fetchAllArray("SELECT * FROM " . $table_name . ";");
if (!$pg) { if (!$pg) {
$table_fields = $this->tableInfo($table_name); $table_fields = $this->tableInfo($table_name);
@ -220,14 +286,18 @@ class Manager
} }
foreach ($data as $r) { foreach ($data as $r) {
$result[] = [ $result[] = [
"type" => "insert", "type" => "insert",
"table_name" => $table_name, "table_name" => $table_name,
"values" => $r "values" => $r
]; ];
} }
return $result; return $result;
} }
/**
* Возвращает все имена таблиц
* @return array
*/
public function getAllTableNames() public function getAllTableNames()
{ {
$result = []; $result = [];
@ -243,6 +313,10 @@ class Manager
return $result; return $result;
} }
/**
* Возвращает дамп всех таблиц
* @return array
*/
public function dumpInserts() public function dumpInserts()
{ {
$table_names = $this->getAllTableNames(); $table_names = $this->getAllTableNames();

View file

@ -32,29 +32,41 @@ class Statement
$this->conn = $conn; $this->conn = $conn;
} }
function setInt($n, $value) { /**
* @param int|string $n
* @param int $value
*/
function setInt($n, $value): void {
$this->binds [] = [$n, $value, PDO::PARAM_INT]; $this->binds [] = [$n, $value, PDO::PARAM_INT];
} }
function setString($n, $value) { /**
* @param int|string $n
* @param string $value
*/
function setString($n, $value): void {
$this->binds [] = [$n, $value, PDO::PARAM_STR]; $this->binds [] = [$n, $value, PDO::PARAM_STR];
} }
function setBlob($n, $value) { /**
* @param int|string $n
* @param mixed $value
*/
function setBlob($n, $value): void {
$this->binds [] = [$n, $value, PDO::PARAM_LOB]; $this->binds [] = [$n, $value, PDO::PARAM_LOB];
} }
/** /**
* @param int $limit * @param int $limit
*/ */
function setLimit($limit) { function setLimit($limit): void {
$this->limit = $limit; $this->limit = $limit;
} }
/** /**
* @param int $offset * @param int $offset
*/ */
function setOffset($offset) { function setOffset($offset): void {
$this->offset = $offset; $this->offset = $offset;
} }

View file

@ -7,7 +7,9 @@ class StatementIterator implements \Iterator
{ {
private $result; private $result;
/** @var int */
private $pos = 0; private $pos = 0;
/** @var int */
private $row_count; private $row_count;
/** /**
@ -37,15 +39,15 @@ class StatementIterator implements \Iterator
return $this->result->cache[$this->pos]; return $this->result->cache[$this->pos];
} }
function next(): void{ function next(): void {
$this->pos++; $this->pos++;
} }
function seek($index) { function seek($index): void {
$this->pos = $index; $this->pos = $index;
} }
function count() { function count(): int {
return $this->row_count; return $this->row_count;
} }
} }

View file

@ -4,15 +4,19 @@ namespace ctiso\Excel;
class DateTime class DateTime
{ {
/** @var int */
public $value; public $value;
function __construct($value) /**
* @param int $value
*/
function __construct($value)
{ {
$this->value = (int)$value; $this->value = (int)$value;
} }
function getString() function getString(): string
{ {
return date('Y-m-d\TH:i:s.u', $this->value); return date('Y-m-d\TH:i:s.u', $this->value);
} }
} }

View file

@ -202,6 +202,12 @@ class Table
return max(array_map([$this, 'getRowCells'], $this->rows)); return max(array_map([$this, 'getRowCells'], $this->rows));
} }
/**
* Кодирование строки
* @deprecated
* @param string $s Строка
* @return string
*/
function encode($s) function encode($s)
{ {
return $s; return $s;
@ -209,6 +215,11 @@ class Table
/** /**
* Генерация клетки таблицы (Переработать) * Генерация клетки таблицы (Переработать)
* @param TableCell $ncell Клетка таблицы
* @param XMLWriter $doc XMLWriter
* @param int $j Индекс клетки
* @param mixed $value Значение клетки
* @param bool $setIndex Устанавливать индекс клетки в атрибут ss:Index
*/ */
function createCell (TableCell $ncell, XMLWriter $doc, $j, mixed $value, $setIndex) { function createCell (TableCell $ncell, XMLWriter $doc, $j, mixed $value, $setIndex) {
$doc->startElement("Cell"); $doc->startElement("Cell");
@ -222,7 +233,7 @@ class Table
} }
if ($setIndex) { if ($setIndex) {
$doc->writeAttribute('ss:Index', $j); $doc->writeAttribute('ss:Index', (string)$j);
} }
$doc->startElement("Data"); $doc->startElement("Data");
@ -247,7 +258,7 @@ class Table
/** /**
* Генерация таблицы * Генерация таблицы
*/ */
public function createTable (XMLWriter $doc) { public function createTable (XMLWriter $doc): void {
$doc->startElement('Worksheet'); $doc->startElement('Worksheet');
$doc->writeAttribute('ss:Name', $this->name); $doc->writeAttribute('ss:Name', $this->name);
@ -295,7 +306,7 @@ class Table
$doc->endElement(); $doc->endElement();
} }
protected function splitPane (XMLWriter $doc) { protected function splitPane (XMLWriter $doc): void {
$doc->startElement('WorksheetOptions'); $doc->startElement('WorksheetOptions');
$doc->writeAttribute('xmlns', 'urn:schemas-microsoft-com:office:excel'); $doc->writeAttribute('xmlns', 'urn:schemas-microsoft-com:office:excel');

View file

@ -10,13 +10,14 @@ use ctiso\Filter\UserAccess,
class ActionAccess class ActionAccess
{ {
public $access = array(); public $access = [];
public $processor; public $processor;
/** @var User */ /** @var User */
public $user; public $user;
/** /**
* @param FilterInterface $processor * @param FilterInterface $processor
* @param User $user
*/ */
function __construct($processor, $user) { function __construct($processor, $user) {
$this->processor = $processor; $this->processor = $processor;
@ -27,6 +28,9 @@ class ActionAccess
* Проверка доступных действий для пользователя * Проверка доступных действий для пользователя
* !! Реализация класса проверки действий не должна быть внутри Контроллера!!! * !! Реализация класса проверки действий не должна быть внутри Контроллера!!!
* Информация о доступе может быть в файле, базе данных и т.д. * Информация о доступе может быть в файле, базе данных и т.д.
*
* @param string $action
* @return bool
*/ */
function checkAction($action) { function checkAction($action) {
// Импликация !! http://ru.wikipedia.org/wiki/Импликация // Импликация !! http://ru.wikipedia.org/wiki/Импликация

View file

@ -5,8 +5,8 @@
*/ */
namespace ctiso\Filter; namespace ctiso\Filter;
use ctiso\Controller\Action, use ctiso\Controller\Action;
ctiso\HttpRequest; use ctiso\HttpRequest;
class Filter implements \ctiso\Controller\ActionInterface class Filter implements \ctiso\Controller\ActionInterface
{ {

View file

@ -125,7 +125,7 @@ class Login extends Filter
return false; return false;
} }
private function enter($result) private function enter($result): void
{ {
$this->user = $result; $this->user = $result;
$random = rand(0, 1024 * 1024); $random = rand(0, 1024 * 1024);
@ -138,7 +138,7 @@ class Login extends Filter
$_SESSION["time"] = time(); $_SESSION["time"] = time();
} }
public function execute(HttpRequest $request) public function execute(HttpRequest $request): string
{ {
$logged = $this->isLoggin($request); $logged = $this->isLoggin($request);
if ($request->get('action') == 'user_access') { if ($request->get('action') == 'user_access') {
@ -187,7 +187,7 @@ class Login extends Filter
/** /**
* Проверка на попадание реквеста в белый список * Проверка на попадание реквеста в белый список
*/ */
public function requestIsWhite(Collection $request) { public function requestIsWhite(Collection $request): bool {
$module = $request->get('module'); $module = $request->get('module');
$action = $request->get('action'); $action = $request->get('action');

View file

@ -5,12 +5,12 @@
*/ */
namespace ctiso\Form; namespace ctiso\Form;
use ctiso\Form\Field,
ctiso\Form\Select, use ctiso\Form\Field;
ctiso\Form\Input, use ctiso\Form\Select;
ctiso\View\View, use ctiso\Form\Input;
ctiso\Validator\Validator, use ctiso\Validator\Validator;
ctiso\HttpRequest; use ctiso\HttpRequest;
/** /**
* Форма для ввода * Форма для ввода
@ -76,7 +76,7 @@ class Form {
} }
function getId() function getId(): string
{ {
return '_form_edit'; return '_form_edit';
} }
@ -85,18 +85,16 @@ class Form {
* Добавление конструкторя для поля формы * Добавление конструкторя для поля формы
* @param string $name Краткое название поля * @param string $name Краткое название поля
* @param class-string<Field> $class * @param class-string<Field> $class
* @return void
*/ */
public function addFieldClass($name, $class) public function addFieldClass($name, $class): void
{ {
$this->constructor [$name] = $class; $this->constructor [$name] = $class;
} }
/** /**
* Добавляет одно поле ввода на форму * Добавляет одно поле ввода на форму
* @return Field
*/ */
public function addField(array $init, $factory = null) public function addField(array $init, $factory = null): Field
{ {
assert(isset($init['type'])); assert(isset($init['type']));
assert(isset($init['name'])); assert(isset($init['name']));
@ -118,8 +116,7 @@ class Form {
/** /**
* Добавление fieldset на форму * Добавление fieldset на форму
*/ */
public function addFieldSet(array $fieldset): void
public function addFieldSet(array $fieldset)
{ {
$this->fieldsets[$fieldset['name']] = $fieldset; $this->fieldsets[$fieldset['name']] = $fieldset;
} }
@ -127,7 +124,7 @@ class Form {
/** /**
* Добавление массива fieldset на форму * Добавление массива fieldset на форму
*/ */
public function addFieldSetList(array $list) public function addFieldSetList(array $list): void
{ {
foreach ($list as $fieldset) { foreach ($list as $fieldset) {
$this->addFieldSet($fieldset); $this->addFieldSet($fieldset);
@ -138,7 +135,7 @@ class Form {
* Добавляет список полей для формы * Добавляет список полей для формы
* @param array $list * @param array $list
*/ */
public function addFieldList(array $list, $factory = null) public function addFieldList(array $list, $factory = null): void
{ {
foreach ($list as $init) { foreach ($list as $init) {
$this->addField($init, $factory); $this->addField($init, $factory);
@ -148,7 +145,7 @@ class Form {
/** /**
* Устанавливает ошибки после проверки * Устанавливает ошибки после проверки
*/ */
function setError(Validator $validator) function setError(Validator $validator): void
{ {
foreach ($validator->getErrorMsg() as $name => $error) foreach ($validator->getErrorMsg() as $name => $error)
{ {
@ -162,7 +159,7 @@ class Form {
* @param string $name * @param string $name
* @param string $message * @param string $message
*/ */
function setFieldError($name, $message) function setFieldError($name, $message): void
{ {
$this->field[$name]->error = true; $this->field[$name]->error = true;
$this->field[$name]->error_msg = $message; $this->field[$name]->error_msg = $message;
@ -171,7 +168,7 @@ class Form {
/** /**
* Устанавливает значения из масива * Устанавливает значения из масива
*/ */
function setValues(HttpRequest $request) { function setValues(HttpRequest $request): void {
foreach ($this->field as $key => $_) { foreach ($this->field as $key => $_) {
$value = $request->getRawData($this->method, $key); $value = $request->getRawData($this->method, $key);
$this->field[$key]->setValue($value); $this->field[$key]->setValue($value);
@ -183,7 +180,7 @@ class Form {
* @param object $data * @param object $data
* @param array $schema Связь между элементами формы и свойствами обьекта * @param array $schema Связь между элементами формы и свойствами обьекта
*/ */
public function fill($data, array $schema) public function fill($data, array $schema): void
{ {
foreach ($schema as $key => $conv) { foreach ($schema as $key => $conv) {
list($value, $type) = $conv; list($value, $type) = $conv;
@ -191,12 +188,12 @@ class Form {
} }
} }
public function set($name, $value) public function set($name, $value): void
{ {
$this->field[$name]->setValue($value); $this->field[$name]->setValue($value);
} }
function execute() function execute(): self
{ {
return $this; return $this;
} }

View file

@ -3,12 +3,16 @@
namespace ctiso\Form; namespace ctiso\Form;
use ctiso\Form\Field; use ctiso\Form\Field;
/**
* @phpstan-type Option = array{value: string, name: string, selected: bool, class?: string|false}
*/
class Select extends Field class Select extends Field
{ {
/** @var Option[] */
public $options = []; public $options = [];
/** /**
* @param array $input * @param array{ options?: Option[], 'options.pair'?: array } $input
* @param OptionsFactory $factory * @param OptionsFactory $factory
*/ */
public function __construct ($input, $factory) { public function __construct ($input, $factory) {
@ -28,6 +32,11 @@ class Select extends Field
} }
} }
/**
* @param string[] $list
* @param bool $selected
* @return Option[]
*/
public function optionsPair($list, $selected = false) { public function optionsPair($list, $selected = false) {
$result = []; $result = [];
foreach ($list as $key => $value) { foreach ($list as $key => $value) {

View file

@ -160,7 +160,7 @@ class Functions {
} }
/** /**
* @deprecated * @deprecated use fn and <=> operator
* @param array $a * @param array $a
* @param array $b * @param array $b
* @param $key * @param $key
@ -174,6 +174,14 @@ class Functions {
return ($a[$key] > $b[$key]) ? -1 : 1; return ($a[$key] > $b[$key]) ? -1 : 1;
} }
/**
* @deprecated use fn and <=> operator
* @param array $a
* @param array $b
* @param $key
*
* @return int
*/
static function __cmp_less($a, $b, $key) { static function __cmp_less($a, $b, $key) {
if ($a[$key] == $b[$key]) { if ($a[$key] == $b[$key]) {
return 0; return 0;
@ -224,6 +232,11 @@ class Functions {
return $result; return $result;
} }
/**
* @param string $key
* @param string $value
* @param array|\ArrayIterator $array
*/
static function assoc_key_values($key, $value, $array) { static function assoc_key_values($key, $value, $array) {
$result = []; $result = [];
foreach ($array as $item) { foreach ($array as $item) {
@ -232,6 +245,10 @@ class Functions {
return $result; return $result;
} }
/**
* @param string $key
* @param array|\ArrayIterator $array
*/
static function assoc_key($key, $array) { static function assoc_key($key, $array) {
$result = []; $result = [];
foreach ($array as $item) { foreach ($array as $item) {
@ -241,6 +258,7 @@ class Functions {
} }
/** /**
* Возвращает значение по ключу
* @param string $key * @param string $key
* @param mixed $value * @param mixed $value
* @param array $array * @param array $array
@ -248,14 +266,25 @@ class Functions {
*/ */
static function _get($key, $value, $array) { static function _get($key, $value, $array) {
foreach ($array as $item) { foreach ($array as $item) {
if ($item[$key] == $value) return $item; if ($item[$key] == $value) {
return $item;
}
} }
return null; return null;
} }
/**
* Возвращает ключ по значению
* @param string $key
* @param mixed $value
* @param array $array
* @return mixed
*/
static function _get_key($key, $value, $array) { static function _get_key($key, $value, $array) {
foreach ($array as $name => $item) { foreach ($array as $name => $item) {
if ($item[$key] == $value) return $name; if ($item[$key] == $value) {
return $name;
}
} }
return null; return null;
} }
@ -279,7 +308,6 @@ class Functions {
* @return mixed * @return mixed
*/ */
static function some(array $array, callable $callback) { static function some(array $array, callable $callback) {
foreach ($array as $key => $value) { foreach ($array as $key => $value) {
if (call_user_func($callback, $value) === true) { if (call_user_func($callback, $value) === true) {
return $key; return $key;
@ -288,8 +316,14 @@ class Functions {
return false; return false;
} }
/**
* Разбивает массив на массивы определенной длины
* @template T
* @param int $length Длина массива
* @param T[] $array Массив
* @return T[][]
*/
static function span(int $length, array $array) { static function span(int $length, array $array) {
$result = []; $result = [];
$count = count($array); $count = count($array);
for($i = 0; $i < $count; $i += $length) { for($i = 0; $i < $count; $i += $length) {
@ -298,12 +332,22 @@ class Functions {
return $result; return $result;
} }
/**
* Возвращает значение массива
* @param array $data Массив
* @param string|int $n Ключ
* @return mixed
*/
static function array_ref(array $data, string|int $n) { static function array_ref(array $data, string|int $n) {
return $data[$n]; return $data[$n];
} }
static function call() { /**
$args = func_get_args(); * Вызывает функцию с аргументами
* @param mixed ...$args Аргументы
* @return mixed
*/
static function call(...$args) {
$name = array_shift($args); $name = array_shift($args);
return call_user_func_array($name, $args); return call_user_func_array($name, $args);
} }

View file

@ -61,7 +61,7 @@ class HttpRequest extends Collection
return parent::get('data')->getString($key, $default); return parent::get('data')->getString($key, $default);
} }
function session(?Session $value = null) function session(?Session $value = null): ?Session
{ {
if ($value) { if ($value) {
$this->_session = $value; $this->_session = $value;
@ -69,7 +69,7 @@ class HttpRequest extends Collection
return $this->_session; return $this->_session;
} }
function set(string $key, mixed $value) function set(string $key, mixed $value): void
{ {
parent::get('data')->set($key, $value); parent::get('data')->set($key, $value);
} }
@ -79,9 +79,11 @@ class HttpRequest extends Collection
return parent::get($key)->export(); return parent::get($key)->export();
} }
function clear() function clear(): void
{ {
return parent::get('data')->clear(); /** @var Collection */
$collection = parent::get('data');
$collection->clear();
} }
/** /**

View file

@ -5,34 +5,34 @@
* Выбор оформления страницы осуществляется если было совпадение с каким либо условием * Выбор оформления страницы осуществляется если было совпадение с каким либо условием
*/ */
namespace ctiso\Layout; namespace ctiso\Layout;
use ctiso\Filter\Filter,
ctiso\Functions, use ctiso\Filter\Filter;
ctiso\HttpRequest; use ctiso\HttpRequest;
class Manager extends Filter class Manager extends Filter
{ {
// Массив условий с их макетами /**
protected $condition = array(); * Массив условий с их макетами
* @var list<array{callable, Filter}>
*/
protected $condition = [];
/** /**
* Функция которая добавляет условие для проверки параметров $_GET * Функция которая добавляет условие для проверки параметров $_GET
* @param $get array() | true Ассоциативный массив ключей и значений для $_GET * @param array|true $get Ассоциативный массив ключей и значений для $_GET
* * @param Filter $layout Макет
* @example
* addConditionGet(array('module' => 'personal'), 'personal')
* addConditionGet(array('module' => 'login'), 'login')
*/ */
public function addConditionGet($get, Filter $layout) public function addConditionGet($get, Filter $layout): void
{ {
$this->addCondition(Functions::rcurry([$this, 'checkGet'], $get), $layout); $this->addCondition(fn(HttpRequest $request) => $this->checkGet($request, $get), $layout);
} }
/** /**
* Условие для аякс запросов. Тоже самое что и addConditionGet но еще проверяется является ли запрос ajax * Условие для аякс запросов. Тоже самое что и addConditionGet но еще проверяется является ли запрос ajax
*/ */
public function addConditionXHR($get, Filter $layout) public function addConditionXHR($get, Filter $layout): void
{ {
$this->addCondition(Functions::rcurry([$this, 'checkXHR'], $get), $layout); $this->addCondition(fn(HttpRequest $request) => $this->checkXHR($request, $get), $layout);
} }
/** /**
@ -57,17 +57,17 @@ class Manager extends Filter
* @param array $get * @param array $get
* @return bool * @return bool
*/ */
public function checkXHR($request, $get) public function checkXHR($request, $get): bool
{ {
return $request->isAjax() && $this->checkGet($request, $get); return $request->isAjax() && $this->checkGet($request, $get);
} }
/** /**
* Добавляет условие в общем виде * Добавляет условие в общем виде
* @parma $get function(HttpRequest) Функция * @param callable $get Функция
* @parma $layout Layout Макет * @param Filter $layout Макет
*/ */
public function addCondition($get, Filter $layout) public function addCondition($get, Filter $layout): void
{ {
$this->condition [] = [$get, $layout]; $this->condition [] = [$get, $layout];
} }
@ -75,7 +75,7 @@ class Manager extends Filter
/** /**
* Выбирает и применяет макет для страницы * Выбирает и применяет макет для страницы
*/ */
public function execute(HttpRequest $request) public function execute(HttpRequest $request): string
{ {
foreach ($this->condition as $condition) { foreach ($this->condition as $condition) {
if (call_user_func($condition[0], $request)) { if (call_user_func($condition[0], $request)) {
@ -88,6 +88,7 @@ class Manager extends Filter
} }
} }
} }
return '';
} }
} }

View file

@ -8,8 +8,11 @@ use ctiso\Role\User;
class Factory class Factory
{ {
/** @var Database */
public $db; public $db;
/** @var ?Registry */
public $config; public $config;
/** @var ?User */
public $user; public $user;
public function __construct(Database $db, ?Registry $config = null, ?User $user = null) public function __construct(Database $db, ?Registry $config = null, ?User $user = null)

View file

@ -75,6 +75,12 @@ class Path
return pathinfo($fileName, PATHINFO_EXTENSION); return pathinfo($fileName, PATHINFO_EXTENSION);
} }
/**
* Проверяет расширение файла
* @param string $fileName Полное имя файла
* @param string|array $extension Расширение файла
* @return bool
*/
static function isType($fileName, $extension) static function isType($fileName, $extension)
{ {
if (is_array($extension)) { if (is_array($extension)) {
@ -101,7 +107,6 @@ class Path
* Возвращает имя файла без расширения * Возвращает имя файла без расширения
* *
* @param string $fileName Полное имя файла * @param string $fileName Полное имя файла
*
* @return string * @return string
*/ */
static function getFileName(string $fileName) static function getFileName(string $fileName)
@ -344,7 +349,6 @@ class Path
* Подбирает новое временное имя для файла * Подбирает новое временное имя для файла
* *
* @param string $dst Предпологаемое имя файла * @param string $dst Предпологаемое имя файла
*
* @return string Новое имя файла * @return string Новое имя файла
*/ */
static function resolveFile($dst) static function resolveFile($dst)

View file

@ -20,7 +20,7 @@ class Primitive {
} }
// int // int
public static function to_bool($value) public static function to_bool($value): bool
{ {
return filter_var($value, FILTER_VALIDATE_BOOLEAN);//(int)((bool) $value); return filter_var($value, FILTER_VALIDATE_BOOLEAN);//(int)((bool) $value);
} }
@ -41,8 +41,12 @@ class Primitive {
return ((string) $value); return ((string) $value);
} }
// date /**
public static function to_date($value) * Преобразование даты dd/mm/yy в unix timestamp
* @param string $value
* @return int
*/
public static function to_date($value): int
{ {
$result = 0; $result = 0;
$tmp = explode("/", $value ?? '', 3); $tmp = explode("/", $value ?? '', 3);
@ -66,7 +70,12 @@ class Primitive {
return $result; return $result;
} }
public static function to_datetime($value) /**
* Преобразование даты ISO 8601 в unix timestamp
* @param string $value
* @return int
*/
public static function to_datetime($value): int
{ {
$result = 0; $result = 0;
@ -79,7 +88,12 @@ class Primitive {
return $result; return $result;
} }
public static function from_date($value) /**
* Преобразование даты в формат dd/mm/yyyy
* @param int $value
* @return string
*/
public static function from_date($value): string
{ {
if ($value > 0) { if ($value > 0) {
return date("d/m/Y", $value); return date("d/m/Y", $value);
@ -87,7 +101,12 @@ class Primitive {
return ''; return '';
} }
public static function from_datetime($value) /**
* Преобразование даты в формат ISO 8601
* @param int $value
* @return string
*/
public static function from_datetime($value): string
{ {
if ($value > 0) { if ($value > 0) {
return date("Y-m-d\TH:i\Z", $value); return date("Y-m-d\TH:i\Z", $value);
@ -96,24 +115,45 @@ class Primitive {
} }
// secure /**
* @deprecated
* @template T
* @param T $value
* @return T
*/
public static function to_secure($value) public static function to_secure($value)
{ {
// Значение приабразуется во время сохранения в базе данных // Значение приабразуется во время сохранения в базе данных
return $value; return $value;
} }
/**
* @deprecated
* @template T
* @param T $value
* @return T
*/
public static function from_secure($value) public static function from_secure($value)
{ {
return $value; return $value;
} }
// array /**
* Преобразование значения в массив
* @param mixed $value
* @return array
*/
public static function to_array($value) public static function to_array($value)
{ {
return (is_array($value)) ? $value : []; return (is_array($value)) ? $value : [];
} }
/**
* @deprecated
* @template T
* @param T $value
* @return T
*/
public static function from_array($value) public static function from_array($value)
{ {
return $value; return $value;

View file

@ -7,6 +7,9 @@ class Url {
public array $parts = []; public array $parts = [];
public ?Url $parent; public ?Url $parent;
/**
* @param Url|null $parent
*/
function setParent($parent): void { function setParent($parent): void {
$this->parent = $parent; $this->parent = $parent;
} }

View file

@ -6,7 +6,11 @@
namespace ctiso; namespace ctiso;
class UserMessageException extends \Exception { class UserMessageException extends \Exception {
/** @var string */
public $userMessage; public $userMessage;
/**
* @param string $message
*/
public function __construct($message) { public function __construct($message) {
parent::__construct($message); parent::__construct($message);
$this->userMessage = $message; $this->userMessage = $message;

View file

@ -169,7 +169,11 @@ class View extends \stdClass
throw new Exception("file not found: $file"); throw new Exception("file not found: $file");
} }
// FIXME: Префикс, конфликтует с протоколом
/**
* FIXME: Префикс, конфликтует с протоколом
* @param string[]|string[][] $alias
*/
function resolveName($alias, string $file): string { function resolveName($alias, string $file): string {
list($type, $filename) = explode(":", $file, 2); list($type, $filename) = explode(":", $file, 2);
@ -185,6 +189,9 @@ class View extends \stdClass
return $file; return $file;
} }
/**
* @param string[][] $alias
*/
public function resolveAllNames($alias, array $list): array { public function resolveAllNames($alias, array $list): array {
$result = []; $result = [];
foreach($list as $item) { foreach($list as $item) {