diff --git a/src/Adapter.php b/src/Adapter.php index 6ab0934..2ba68f9 100644 --- a/src/Adapter.php +++ b/src/Adapter.php @@ -8,21 +8,12 @@ namespace ctiso; */ class Adapter { - /** @var array|object */ protected $adaptee; - - /** - * @param array|object $adaptee - */ public function __construct ($adaptee) { $this->adaptee = $adaptee; } - /** - * @param string $name - * @return mixed - */ public function get($name) { if (is_array ($this->adaptee)) { diff --git a/src/Arr.php b/src/Arr.php index 2fa9187..38cbb35 100644 --- a/src/Arr.php +++ b/src/Arr.php @@ -4,12 +4,6 @@ namespace ctiso; class Arr { - /** - * @param array $data - * @param string|int $key - * @param mixed $default - * @return mixed - */ static function get($data, $key, $default = null) { return $data[$key] ?? $default; } diff --git a/src/Collection.php b/src/Collection.php index 430cc69..2f7cea3 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -3,18 +3,21 @@ namespace ctiso; /** * Коллекция - * @implements \ArrayAccess + * */ class Collection implements \ArrayAccess { - /** @var array */ - protected $data = []; + /** + * Holds collective request data + * + * @var array + */ + protected $data = array(); /** * Преобразование массива в коллекцию * * @param array $data - * @return bool */ public function import(array $data) { @@ -24,8 +27,6 @@ class Collection implements \ArrayAccess /** * Преобразование коллекции в массив - * - * @return array */ public function export() { @@ -33,13 +34,14 @@ class Collection implements \ArrayAccess } /** - + * Store "request data" in GPC order. + * * @param string $key * @param mixed $value * * @return void */ - public function set(string $key, mixed $value) + public function set($key/*: string*/, $value/*: any*/) { $this->data[$key] = $value; } @@ -48,7 +50,7 @@ class Collection implements \ArrayAccess * Read stored "request data" by referencing a key. * * @param string $key - * @param mixed $default + * * @return mixed */ public function get($key, $default = null) @@ -56,93 +58,23 @@ class Collection implements \ArrayAccess return isset($this->data[$key]) && $this->data[$key] != '' ? $this->data[$key] : $default; } - /** - * @param string $key - * @param int $default - * @return int - */ - public function getInt(string $key, int $default = 0): int + public function getInt($key, $default = 0) { - $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; + return (int)$this->get($key, $default); } - /** - * @param string $key - * @param string $default - * @return string - */ - public function getString(string $key, string $default = ''): string + public function getString($key, $default = '') { - $value = $this->get($key); - - if (is_string($value)) { - return $value; - } - - if (is_numeric($value)) { - return (string)$value; - } - - return $default; + return (string)$this->get($key, $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 - * @return int - */ - public function getNat(string $key, int $default = 1): int + public function getNat($key, $default = 1) { $result = (int)$this->get($key, $default); return (($result > 0) ? $result : $default); } - public function clear(): void + public function clear() { $this->data = []; } diff --git a/src/ComponentRequest.php b/src/ComponentRequest.php index 378c375..6bc7dbc 100644 --- a/src/ComponentRequest.php +++ b/src/ComponentRequest.php @@ -2,31 +2,19 @@ namespace ctiso; -use ctiso\HttpRequest; -use ctiso\Arr; +use ctiso\HttpRequest, + ctiso\Arr; class ComponentRequest { - /** @var int */ public $component_id; - /** @var string */ public $component_title; - /** @var HttpRequest */ public $r; - /** - * @param int $c - * @param HttpRequest $r - */ function __construct($c, HttpRequest $r) { $this->component_id = $c; $this->r = $r; } - /** - * @param string $key - * @param mixed $default - * @return mixed - */ function get($key, $default = null) { if ($key == 'active_page') { return $this->r->get($key); @@ -42,9 +30,6 @@ class ComponentRequest { return $default; } - /** - * @return string - */ function getAction() { return $this->r->getAction(); } diff --git a/src/Connection/HttpRequest.php b/src/Connection/HttpRequest.php index 368feda..006cc63 100644 --- a/src/Connection/HttpRequest.php +++ b/src/Connection/HttpRequest.php @@ -3,37 +3,27 @@ namespace ctiso\Connection; use ctiso\File; -class HttpRequest +class HttpRequest { const POST = "POST"; const GET = "GET"; - /** @var array Параметры запроса */ - private $param = []; - /** @var string Содержание */ - public $data = null; - /** @var string Адресс */ - public $url; - /** @var string Метод */ - public $method; - /** @var int */ + private $param = array(); // Параметры запроса + public $data = null; // Содержание + public $url; // Адресс + public $method; // Метод public $port = 80; - /** @var string */ public $host = ""; - /** @var ?string */ public $proxy_host = null; - /** @var ?int */ public $proxy_port = null; - /** @var string */ public $http_version = 'HTTP/1.1'; function __construct() { $this->method = self::GET; } - + /** * Возвращает заголовок соединения - * @return string */ public function getHeader() { @@ -46,58 +36,47 @@ class HttpRequest $result .= $this->data; return $result; } - + /** * Установка параметров запроса - * @param string $name - * @param string $value + * @parma string $name + * @parma string $value */ - public function setParameter($name, $value): void + public function setParameter($name, $value) { $this->param[$name] = $value; } /** * Метод запроса GET или POST - * @param string $method */ - public function setMethod($method): void + public function setMethod($method) { $this->method = $method; } - /** - * Установка URL - * @param string $url - */ - public function setUrl($url): void + public function setUrl($url) { $this->url = $url; - $host = parse_url($this->url, PHP_URL_HOST); - if (!$host) { - throw new \RuntimeException("Не удалось получить хост"); - } - $this->host = $host; + $this->host = parse_url($this->url, PHP_URL_HOST); } - public function getUrl(): string + public function getUrl() { return $this->url; } /** * Содержание запроса - * @param string $data */ - public function setContent($data): void + public function setContent($data) { - $this->setParameter("Content-length", (string)strlen($data)); + $this->setParameter ("Content-length", strlen($data)); $this->data = $data; } /** * Посылает запрос и возвращает страницу - * @return string|null */ public function getPage() { @@ -110,7 +89,7 @@ class HttpRequest $header = $this->getHeader(); fwrite($socket, $header); - $result = ''; + $result = null; while (! feof($socket)) { $result .= fgets($socket, 128); } @@ -120,12 +99,6 @@ class HttpRequest return null; } - /** - * Получение JSON - * @param string $url - * @param array $data - * @return array - */ static function getJSON($url, $data) { $query = http_build_query($data); $q = $url . '?' . $query; diff --git a/src/Connection/HttpResponse.php b/src/Connection/HttpResponse.php index fad35ab..1da2036 100644 --- a/src/Connection/HttpResponse.php +++ b/src/Connection/HttpResponse.php @@ -7,39 +7,30 @@ namespace ctiso\Connection; class HttpResponse { - /** @var int */ private $offset; - /** @var array */ - private $param = []; - /** @var int */ + private $param = array (); private $code; - /** @var string */ public $response; - /** @var string */ public $version; - /** @var string */ public $data; - /** - * @param string $response HTTP ответ - */ public function __construct($response) { $this->offset = 0; $this->response = $response; $this->parseMessage(); - } + } /** * Обработка HTTP ответа */ - private function parseMessage(): void + private function parseMessage() { $http = explode(" ", $this->getLine()); $this->version = $http[0]; - $this->code = (int)$http[1]; + $this->code = $http[1]; - $line = $this->getLine(); + $line = $this->getLine(); while ($offset = strpos($line, ":")) { $this->param[substr($line, 0, $offset)] = trim(substr($line, $offset + 1)); $line = $this->getLine(); @@ -47,12 +38,12 @@ class HttpResponse if (isset($this->param['Transfer-Encoding']) && $this->param['Transfer-Encoding'] == 'chunked') { //$this->data = substr($this->response, $this->offset); - $index = (int)hexdec($this->getLine()); + $index = hexdec($this->getLine()); $chunk = []; while ($index > 0) { $chunk [] = substr($this->response, $this->offset, $index); $this->offset += $index; - $index = (int)hexdec($this->getLine()); + $index = hexdec($this->getLine()); } $this->data = implode("", $chunk); @@ -64,33 +55,32 @@ class HttpResponse /** * Обработка строки HTTP ответа */ - private function getLine(): string + private function getLine() { $begin = $this->offset; $offset = strpos($this->response, "\r\n", $this->offset); - $result = substr($this->response, $begin, $offset - $begin); + $result = substr($this->response, $begin, $offset - $begin); $this->offset = $offset + 2; return $result; } /** * Значение параметра HTTP ответа - * @param string $name Имя параметра */ - public function getParameter($name): string + public function getParameter($name) { return $this->param[$name]; } - public function getData(): string + public function getData() { return $this->data; } /** - * Состояние + * Состояние */ - public function getCode(): int + public function getCode() { return $this->code; } diff --git a/src/Controller/Action.php b/src/Controller/Action.php index 84cf844..4393ab7 100644 --- a/src/Controller/Action.php +++ b/src/Controller/Action.php @@ -1,69 +1,63 @@ part = new Url(); } - public function setUp(): void { + public function setUp() { } - /** - * Загрузка файла настроек - * @param string $name - * @return array - */ public function loadConfig($name) { $basePath = $this->config->get('site', 'path'); @@ -77,40 +71,25 @@ class Action implements ActionInterface return $settings; } - public function getConnection(): Database + public function getConnection() { return $this->db; } - /** - * Путь к установке модуля - * @param string $name - * @return string - */ public function installPath($name) { $basePath = $this->config->get('system', 'path'); return Path::join($basePath, "modules", $name); } - /** - * Добавляет подсказки - * @param View $view - * @param string $name - */ - public function addSuggest(View $view, $name): void { + public function addSuggest(View $view, $name) { + $suggest = []; $file = Path::join($this->modulePath, 'help', $name . '.suggest'); if (file_exists($file)) { $view->suggestions = include($file); } } - /** - * Поиск иконки - * @param string $icon - * @param int $size - * @return string Путь к иконке - */ function findIcon($icon, $size) { $webPath = $this->config->get('site', 'web'); return Path::join($webPath, 'icons', $size . 'x' . $size, $icon . '.png'); @@ -130,8 +109,7 @@ class Action implements ActionInterface $webPath = $this->config->get('system', 'web'); $list = [ - Path::join($this->modulePath, 'templates', $this->viewPathPrefix) - => Path::join($webPath, "modules", $this->name, 'templates', $this->viewPathPrefix), + Path::join($this->modulePath, 'templates', $this->viewPathPrefix) => Path::join($webPath, "modules", $this->name, 'templates', $this->viewPathPrefix), Path::join($basePath, "templates") => Path::join($webPath, "templates") ]; @@ -186,7 +164,6 @@ class Action implements ActionInterface * 1. Можно переопределить действия * 2. Использовать наследование чтобы добавить к старому обработчику новое поведение * @param HttpRequest $request запроса - * @return View|string */ public function preProcess(HttpRequest $request) { @@ -202,47 +179,29 @@ class Action implements ActionInterface return $view; } - /** - * Выполнение действия - * @param HttpRequest $request - * @return View|string|false - */ public function execute(HttpRequest $request) { $result = $this->preProcess($request); - return $result; + if (!empty($result)) { + $this->view = $result; + } + $text = $this->render(); + return $text; } - /** - * Перенаправление на другой контроллер - * @param string $action - * @param HttpRequest $args - * @return mixed - */ public function forward($action, HttpRequest $args) { - $actionFn = [$this, $action]; - if (!is_callable($actionFn)) { - return false; - } - $value = call_user_func($actionFn, $args); + $value = call_user_func([$this, $action], $args); return $value; } /** * Страница по умолчанию - * @param HttpRequest $request - * @return string|false */ public function actionIndex(HttpRequest $request) { return ""; } - /** - * Добавление части ссылки - * @param string $key - * @param string $value - */ - public function addUrlPart($key, $value): void { + public function addUrlPart($key, $value) { $this->part->addQueryParam($key, $value); } @@ -255,9 +214,10 @@ class Action implements ActionInterface */ public function nUrl($actionName, array $param = []) { - $access = $this->access; + $access/*: ActionAccess*/ = $this->access; $url = new Url(); + //print_r([$name, $param]); if ($access == null || $access->checkAction($actionName)) { $moduleName = explode("\\", strtolower(get_class($this))); if (count($moduleName) > 2) { @@ -278,7 +238,7 @@ class Action implements ActionInterface /** * Генерация ссылки на действие контроллера * Ajax определяется автоматически mode = ajax используется для смены layout - * @param string $name + * @param $name * @param array $param * @return Url|null * @@ -290,13 +250,31 @@ class Action implements ActionInterface return $this->nUrl($name, array_merge(['mode' => 'ajax'], $param)); } + /** + * Добавление помошника контроллера + */ + public function addHelper($class) + { + $this->helpers [] = $class; + } + + /** + * Вызов помошников контроллера + */ + public function callHelpers(HttpRequest $request) + { + $action = self::ACTION_PREFIX . $request->getAction(); + foreach ($this->helpers as $helper) { + if (method_exists($helper, $action)) { + return call_user_func([$helper, $action], $request, $this); + } else { + return $helper->actionIndex($request, $this); // Вместо return response ??? + } + } + } + /** * Загрузка файла класса - * @deprecated Веместо его нужно использовать автозагрузку - * @param string $path - * @param mixed $setup - * @param string $prefix - * @return mixed */ public function loadClass($path, $setup = null, $prefix = '') { @@ -308,11 +286,6 @@ class Action implements ActionInterface throw new Exception("NO CLASS $path"); } - /** - * Загрузка настроек - * @param string $path - * @return array - */ public function loadSettings($path) { $result = new Settings($path); @@ -320,21 +293,69 @@ class Action implements ActionInterface return $result->export(); } + public function setView($name) + { + $this->view = $this->getView($name); + } + /** - * Установка идентификатора страницы - * @return int + * Установка заголовка для отображения */ + public function setTitle($title) + { + $this->view->setTitle($title); + } + + /** + * Добавление widget к отображению + */ + public function addChild($section, $node) + { + $this->childNodes[$section] = $node; + } + + public function setValue($name, $value) + { + $this->ctrlValues[$name] = $value; + } + + /** + * Добавление дочернего отображения к текущему отображению + */ + public function addView($section, $node) + { + $this->childViews[$section] = $node; + } + + /** + * Генерация содержания + * Путаница c execute и render + */ + public function render() + { + $view = $this->view; + if ($view instanceof View) { + $this->view->assignValues($this->ctrlValues); + + $node/*: Composite*/ = null; + foreach ($this->childNodes as $name => $node) { + $node->make($this); + $this->view->setView($name, $node->view); + } + + foreach ($this->childViews as $name => $node) { + $this->view->setView($name, $node); + } + } + return $this->view; + } + function getPageId(HttpRequest $request) { $pageId = time(); $request->session()->set('page', $pageId); return $pageId; } - /** - * Проверка идентификатора страницы - * @param int $page Идентификатор страницы - * @return bool - */ function checkPageId(HttpRequest $request, $page) { if ($request->get('__forced__')) { @@ -346,14 +367,16 @@ class Action implements ActionInterface return $result; } - /** - * @return State - */ function _getActionPath() { return new State('index'); } - function redirect(string $action): void { + // Тоже убрать в метод Controller_Model + function getActionPath(HttpRequest $request, $action = null) { + $this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction()); + } + + function redirect($action/*: string*/) { header('location: ' . $action); exit(); } diff --git a/src/Controller/ActionInterface.php b/src/Controller/ActionInterface.php deleted file mode 100644 index 4c8dbf6..0000000 --- a/src/Controller/ActionInterface.php +++ /dev/null @@ -1,28 +0,0 @@ - $class - * @return \ctiso\View\View - */ - function getView($name, $class); - /** - * @param string $key - * @param string $value - */ - function addUrlPart($key, $value): void; -} \ No newline at end of file diff --git a/src/Controller/Component.php b/src/Controller/Component.php index 124d4e5..6beb987 100644 --- a/src/Controller/Component.php +++ b/src/Controller/Component.php @@ -1,90 +1,79 @@ _name = $name; + } + + function __set($key, $value) { + $this->_data[$key] = $value; + } + + function execute() { + return json_encode($this->_data); + } +} /** * Класс компонента */ class Component { - /** @var string[] */ - public $viewPath = []; - /** @var string[] */ - public $webPath = []; + public $viewPath = array(); + public $webPath = array(); - /** @var ?string */ public $template = null; - public string $templatePath; + public $templatePath; - /** @var int */ public $component_id; - /** @var string */ public $component_title; - /** @var string */ + public $COMPONENTS_WEB; public Registry $config; public Database $db; public Collection $parameter; - /** @var string */ public $output = 'html'; - /** @var string */ public $module; - /** @var string */ public $item_module; /** - * @var SiteInterface $site + * @var \App\Controller\Site */ public $site; - function before(): void { + function before() { } - /** - * @param string $match - * @return string - */ static function replaceContent($match) { return \ctiso\Tales::phptal_component(htmlspecialchars_decode($match[3])); } - /** - * @param string $text - * @return string - */ static function applyComponents($text) { - $callback = fn($x) => self::replaceContent($x); - return preg_replace_callback('/<(\w+)(\s+[a-zA-Z\-]+=\"[^\"]*\")*\s+tal:replace="structure\s+component:([^\"]*)"[^>]*>/u', - $callback, $text); + return preg_replace_callback('/<(\w+)(\s+[a-zA-Z\-]+=\"[^\"]*\")*\s+tal:replace="structure\s+component:([^\"]*)"[^>]*>/u', 'ctiso\\Controller\\Component::replaceContent', $text); } - /** - * Выполняет запрос компонента и возвращает результат - * Результат может быть строкой или View для обычных компонентов, или массивом для использования в сервисах - * - * @param HttpRequest $request - * @param bool $has_id - * @return mixed - */ function execute(HttpRequest $request, $has_id = true) { $crequest = new ComponentRequest($this->component_id, $request); @@ -96,36 +85,25 @@ class Component } $this->before(); - $actionMethod = [$this, $action]; - if (is_callable($actionMethod)) { - return call_user_func($actionMethod, $crequest); + if (method_exists($this, $action)) { + return call_user_func([$this, $action], $crequest); + } else { + return $this->actionIndex($crequest); } - - return $this->actionIndex($crequest); } - /** - * Получить имя шаблона - * @param Registry $_registry - * @return string - */ - public function getTemplateName($_registry) { + public function getTemplateName($_registry/*: \ctiso\Settings*/) { return (isset($_COOKIE['with_template']) && preg_match('/^[\w\d-]{3,20}$/', $_COOKIE['with_template'])) ? $_COOKIE['with_template'] : ($_registry ? $_registry->get('site', 'template') : 'modern'); } - /** - * Получить шаблон - * @param string $name - * @return PHPTAL|JsonView - */ public function getView($name) { if ($this->output === 'json') { - return new JsonView($name); + return new FakeTemplate($name); } - /** @var Registry $config */ + /* @var Registry $config */ $config = $this->config; $default = $config->get('site', 'template'); $template = ($this->template) ? $this->template : $this->getTemplateName($config); @@ -135,7 +113,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; @@ -170,19 +148,10 @@ class Component return $tpl; } - /** - * Возвращает путь к шаблону по умолчанию - * @return string - */ function _getDefaultPath() { return $this->viewPath[count($this->viewPath) - 1]; } - /** - * Возвращает путь к шаблону - * @param string $name - * @return string - */ public function getTemplatePath($name) { $registry = $this->config; // Брать настройки из куков если есть @@ -196,10 +165,6 @@ class Component return Path::join($this->viewPath[count($this->viewPath) - 1], 'templates', 'modern', $name); } - /** - * Возвращает путь к шаблонам - * @return string - */ public function getTemplateWebPath() { return Path::join($this->webPath[count($this->webPath) - 1], 'templates', 'modern'); @@ -207,26 +172,19 @@ class Component /** * Создает модель - * - * @template T - * @param class-string $modelName - * @return T + * @param string $name + * @return mixed */ - public function getModel($modelName) + public function getModel($name) { + $modelName = "App\\Mapper\\" . $name; $model = new $modelName(); $model->config = $this->config; $model->db = $this->db; return $model; } - /** - * @param string $key - * @param string $val - * @param PDOStatement $res - * @return array{value: string, name: string}[] - */ - public function options(string $key, string $val, $res) { + public function options($key, $val, $res/*: PDOStatement*/) { $result = []; while($res->next()) { $result[] = ['value' => $res->getString($key), 'name' => $res->getString($val)]; @@ -234,12 +192,7 @@ class Component return $result; } - /** - * @param array $list - * @param bool $selected - * @return array{value: string, name: string, selected: bool}[] - */ - public function optionsPair(array $list, $selected = false) { + public function optionsPair($list, $selected = false) { $result = []; foreach ($list as $key => $value) { $result [] = ['value' => $key, 'name' => $value, 'selected' => $key == $selected]; @@ -247,13 +200,7 @@ class Component return $result; } - /** - * Найти файл по пути - * @param string[] $pathList - * @param string $name - * @return string|null - */ - function findFile(array $pathList, string $name) { + function findFile($pathList, $name) { foreach($pathList as $item) { $filename = Path::join($item, $name); if (file_exists($filename)) { @@ -263,10 +210,6 @@ class Component return null; } - /** - * Получить информацию о параметрах - * @return array - */ function getInfo() { $filename = Path::join($this->viewPath[count($this->viewPath) - 1], 'install.json'); if (file_exists($filename)) { @@ -280,10 +223,8 @@ class Component /** * Генерация интерфейса для выбора галлереи фотографии - * @param Composite $view - * @param ?\ctiso\Form\OptionsFactory $options */ - public function setParameters(Composite $view, $options = null): void + public function setParameters(Composite $view, $options = null) { $form = new Form(); @@ -295,26 +236,19 @@ class Component $view->component_title = $settings['title']; } - /** - * @param \ctiso\Form\OptionsFactory $options - * @return array - */ public function getFields($options = null) { $form = new Form(); - $settings = $this->getInfo(); - $form->addFieldList($settings['parameter'], $options); + $form->addFieldList($this->getInfo()['parameter'], $options); return $form->field; } /** * Обьеденить с ComponentFactory - * @param string $expression - * @param SiteInterface $site - * @return Component */ - static function loadComponent(string $expression, $site) + static function loadComponent($expression, $site/*: SiteInterface*/) { + $expression = htmlspecialchars_decode($expression); $offset = strpos($expression, '?'); $url = parse_url($expression); @@ -327,21 +261,16 @@ class Component parse_str($query, $arguments); } $name = $path; - $config = $site->getConfig(); - - // FIXME: Если имя для компонента не задано то возвращаем пустой компонент - // Нужно дополнительно проверить и файл или в autoloader просто не найдет файл копонента - if (!$name) { - return new Component(); - } + $config = $site->config; $filename = ucfirst($name); $path = Path::join ($config->get('site', 'components'), $name, $filename . '.php'); $className = implode("\\", ['Components', ucfirst($name), $filename]); - $component = null; + $component/*: Component*/ = null; + if (file_exists($path)) { - /** @var Component $component */ + // require_once ($path); $component = new $className(); $component->viewPath = [$config->get('site', 'components') . '/' . $name . '/']; @@ -349,9 +278,8 @@ class Component $component->COMPONENTS_WEB = $config->get('site', 'web') . '/components/'; } else { - /** @var Component $component */ $component = new $className(); - $template = $component->getTemplateName($site->getConfig()); + $template = $component->getTemplateName($site->config); $component->viewPath = [ // Сначало ищем локально @@ -380,7 +308,7 @@ class Component $db = $site->getDatabase(); $component->db = $db; - $component->config = $site->getConfig(); + $component->config = $site->config; $component->site = $site; $stmt = $db->prepareStatement("SELECT * FROM component WHERE code = ?"); @@ -416,29 +344,22 @@ class Component $editor = $component->getEditUrl(); if ($editor) { - $site->addComponentConfig($editor); + $site->componentsConfig[] = $editor; } return $component; } - /** - * @return ?array{name: string, url: string} - */ function getEditUrl() { return null; } - /** - * @param ComponentRequest $request - * @return array - */ - function raw_query($request) + function raw_query($request/*: ComponentRequest*/) { $arr = $request->r->export('get'); $param = []; - $parameter = $this->parameter; + $parameter/*: Collection*/ = $this->parameter; foreach($parameter->export() as $key => $value) { $param[$key] = $value; } @@ -456,12 +377,7 @@ class Component } - /** - * @param ComponentRequest $request - * @param array $list - * @return string - */ - function query($request, $list) + function query($request/*: ComponentRequest*/, $list) { $arr = $request->r->export('get'); @@ -473,28 +389,10 @@ class Component return '?' . http_build_query($arr); } - /** - * @param string $name - * @param string $path - * @param array $shim - */ - function addRequireJsPath($name, $path, $shim = null): void { + function addRequireJsPath($name, $path, $shim = null) { $this->site->addRequireJsPath($name, $path, $shim); } - /** - * @param ComponentRequest $request - * @return mixed - */ - function actionIndex($request) { - return ""; - } - - /** - * @param HttpRequest $request - * @return array - */ - function getDefaultPageEnvironment($request) { - return []; + function actionIndex($request/*: ComponentRequest*/) { } } diff --git a/src/Controller/Front.php b/src/Controller/Front.php index b799f40..d1bc119 100644 --- a/src/Controller/Front.php +++ b/src/Controller/Front.php @@ -5,37 +5,25 @@ * @package system.controller */ namespace ctiso\Controller; - -use ctiso\Controller\Action; -use ctiso\Registry; -use ctiso\Database; -use ctiso\Filter\ActionAccess; -use ctiso\Filter\ActionLogger; -use ctiso\Path; -use ctiso\UserMessageException; -use ctiso\HttpRequest; -use ctiso\Role\User; +use ctiso\Controller\Action, + ctiso\Registry, + ctiso\Database, + ctiso\Collection, + ctiso\Filter\ActionAccess, + ctiso\Filter\ActionLogger, + ctiso\Path, + ctiso\UserMessageException, + ctiso\HttpRequest, + ctiso\Role\User; class Front extends Action { - /** - * Параметр по которому выбирается модуль - * @var string - */ - protected $_param; - /** - * Значение параметра по умолчанию - * @var string - */ - protected $default; + protected $_param; // Параметр по которому выбирается модуль + protected $default; // Значение параметра по умолчанию - /** @var array */ - protected $modules = []; + protected $modules = array(); - /** - * @param string $default - */ public function __construct(Database $db, Registry $config, User $user, $default) { parent::__construct(); $this->config = $config; @@ -44,13 +32,7 @@ class Front extends Action $this->default = $default; } - /** - * Проверяет загружен ли модуль - * @param string $name Имя модуля - * @return bool - */ - public function isLoaded($name): bool - { + public function isLoaded($name) { return isset($this->modules[$name]); } @@ -81,7 +63,6 @@ class Front extends Action $ucpart = ucfirst($second); $moduleClass = "Modules\\$ucname\\$ucpart"; - /** @var Action $module */ $module = new $moduleClass(); // Инициализация модуля @@ -111,7 +92,7 @@ class Front extends Action public function execute(HttpRequest $request) { - $name = $request->getString('module', $this->default); + $name = $request->get('module', $this->default); try { return $this->loadModule($name, $request); } catch (UserMessageException $ex) { //Исключение с понятным пользователю сообщением diff --git a/src/Controller/Installer.php b/src/Controller/Installer.php deleted file mode 100644 index 79b08f2..0000000 --- a/src/Controller/Installer.php +++ /dev/null @@ -1,171 +0,0 @@ -_registry = $_registry; - } - - /** - * Устанавливает параметры - * @param Manager $db_manager - * @param callable $installPath - */ - public function setUp($db_manager, $installPath): void - { - $this->db_manager = $db_manager; - $this->installPath = $installPath; - } - - /** - * Получение пути к файлу install.json - * @param string $name - * @return string - */ - function getSetupFile($name) - { - $setup = Path::join(call_user_func($this->installPath, $name), "install.json"); - return $setup; - } - - /** - * Получение пути к файлу unisntall.json - * @param string $name - * @return string - */ - function getUninstallFile($name) - { - return Path::join(call_user_func($this->installPath, $name), "sql", "uninstall.json"); - } - - /** - * Проверка версии обновления - * @param string $name - * @return bool - */ - function isChanged($name) // Информация о модулях - { - $item = $this->_registry->get($name); - if ($item) { - $setup = $this->getSetupFile($name); - if (file_exists($setup) && (filemtime($setup) > $item['time'])) { - return true; - } - return false; - } - return true; - } - - /** - * Устанавливает SQL - * @param array $sql - * @param string $version_new - * @param string $version_old - * @param string $name - * @return array - */ - function installSQL(array $sql, $version_new, $version_old, $name) - { - $result = []; - $json_installer = new JsonInstall($this->db_manager); - foreach ($sql as $version => $install) { - if (version_compare($version, $version_new, "<=") && version_compare($version, $version_old, ">")) { - $file = Path::join(call_user_func($this->installPath, $name), "sql", $install); - $json_installer->install($file, null); - $result[] = $version; - } - } - return $result; - } - - /** - * @param string $name - * @return void - */ - function uninstall($name): void - { - $uninstall = $this->getUninstallFile($name); - if (file_exists($uninstall)) { - $json_installer = new JsonInstall($this->db_manager); - $json_installer->install($uninstall, null); - } - $this->_registry->removeKey($name); - $this->_registry->write(); - } - - /** - * Устанавливает обновления если есть - * @param string $name - * @param bool $force - * @return array - */ - function doUpdates($name, $force = false) - { - $result = []; - $setup = $this->getSetupFile($name); - - if (file_exists($setup) && ($this->isChanged($name) || $force)) { - $registry = $this->_registry; - - $settings = new Settings($setup); - $settings->read(); - - $item = $registry->get($name); - - $version_new = $settings->get('version'); - if ($item) { - $version_old = $item['version']; - } else { - $version_old = "0.0"; - $registry->writeKey([$name], []); - } - if (version_compare($version_old, $settings->get('version'), "!=")) { - $sql = $settings->get('sql'); - if (is_array($sql)) { - $res = $this->installSQL($sql, $version_new, $version_old, $name); - if ($res) { - $result[] = $res; - } - } - } - - // Обновление версии меню - $registry->removeKey($name); - $registry->set($name, [ - 'version' => $version_new, - 'time' => filemtime($setup) - ]); - // $registry->writeKey([$name], $settings->export()); - - $registry->write(); - } - return $result; - } - - /** - * Устанавливает базу данных - * @param string $dbinit_path - * @param string|null $dbfill_path - */ - function install($dbinit_path, $dbfill_path = null): void - { - $json_installer = new JsonInstall($this->db_manager); - $json_installer->install($dbinit_path, $dbfill_path); - } -} diff --git a/src/Controller/Request.php b/src/Controller/Request.php index 4a4293e..fb2d950 100644 --- a/src/Controller/Request.php +++ b/src/Controller/Request.php @@ -4,25 +4,14 @@ namespace ctiso\Controller; use ctiso\HttpRequest; class Request { - /** @var HttpRequest */ public $r; - /** @var string */ public $id; - /** - * @param HttpRequest $request - * @param string $id - */ - function __construct($request, $id) { + function __construct($request/*: HttpRequest*/, $id) { $this->r = $request; $this->id = $id; } - /** - * @param string $name - * @param mixed $def - * @return mixed - */ function get($name, $def = null) { $v = $this->r->get($name); $id = $this->id; diff --git a/src/Controller/Service.php b/src/Controller/Service.php index e4d7fb9..331475d 100644 --- a/src/Controller/Service.php +++ b/src/Controller/Service.php @@ -4,70 +4,56 @@ * Класс сервиса = Упрощенный компонент */ namespace ctiso\Controller; - -use ctiso\Path; -use ctiso\Model\BaseMapper; -use ctiso\File; -use ctiso\Registry; -use ctiso\Database\PDOStatement; -use ctiso\Database; +use ctiso\Path, + ctiso\Model\BaseMapper, + ctiso\File, + ctiso\Registry, + ctiso\Database\PDOStatement; class Service { - /** @var array */ public $viewPath = []; - /** @var array */ public $webPath = []; - /** @var Registry */ - public $config; - /** @var string */ + public $config/*: Registry*/; public $template; - /** @var string */ public $templatePath; - /** @var string */ public $COMPONENTS_WEB; - /** @var Database */ + public $db; - /** - * Возвращает путь к шаблонам - * @param string $name Имя шаблона - * @return string - */ public function getTemplatePath($name) { return Path::join($this->viewPath[0], 'templates', 'modern', $name); } - /** - * Возвращает путь к шаблонам - * @return string - */ public function getTemplateWebPath() { return Path::join($this->webPath[0], strtolower(get_class($this)), 'templates', 'modern'); } + /** + * @param string $name Имя модели + */ + private function getModelPath($name) + { + return Path::join ($this->config->get('system', 'path'), "model", $name . ".php"); + } + /** * Создает модель - * @param class-string $modelName + * @param string $name * @return BaseMapper */ - public function getModel($modelName) + public function getModel($name) { - /** @var BaseMapper */ - $model = new $modelName(); + require_once ($this->getModelPath ($name)); + $modelName = $name . "Mapper"; + $model = new $modelName (); $model->db = $this->db; return $model; } - /** - * @param string $key - * @param string $val - * @param PDOStatement $res - * @return array - */ - public function options($key, $val, $res) { + public function options($key, $val, $res/*: PDOStatement*/) { $result = []; while($res->next()) { $result[] = ['value' => $res->getInt($key), 'name' => $res->getString($val)]; @@ -75,11 +61,6 @@ class Service return $result; } - /** - * @param array $list - * @param bool $selected - * @return array - */ public function optionsPair($list, $selected = false) { $result = []; foreach ($list as $key => $value) { @@ -87,10 +68,7 @@ class Service } return $result; } - - /** - * @return array - */ + function getInfo() { $filename = Path::join($this->viewPath[0], 'install.json'); if (file_exists($filename)) { diff --git a/src/Controller/SiteInterface.php b/src/Controller/SiteInterface.php index 92c06a5..1125601 100644 --- a/src/Controller/SiteInterface.php +++ b/src/Controller/SiteInterface.php @@ -3,39 +3,10 @@ namespace ctiso\Controller; interface SiteInterface { - /** - * FIXME: Возвращает ресурс (но его тип опрделяется в App) - * @return mixed - */ function getResource(); - /** - * @return \ctiso\Database - */ + function loadComponent($expression); function getDatabase(); - /** - * @return \ctiso\Registry - */ function getConfig(); - /** - * @return \ctiso\Settings - */ - function getTheme(); - /** - * @param array $config - */ - function addComponentConfig($config): void; - function addRequireJsPath(string $name, string $path, ?array $shim = null): void; - function addStyleSheet(string $url): void; - - /** - * @param string $expression - * @return ?Component - */ - function loadComponent(string $expression); - /** - * @return array{string, string, string} - */ - function findTemplate(string $name); - function replaceImg(string $src, int $width, int $height): string; - function updatePageTime(int $time): void; + function setComponentConfig($config); + function addRequireJsPath($name, $path, $schim = null); } diff --git a/src/Database.php b/src/Database.php index ab2a233..c967d6d 100644 --- a/src/Database.php +++ b/src/Database.php @@ -1,10 +1,6 @@ setAttribute(PDO::ATTR_STATEMENT_CLASS, [PDOStatement::class, []]); } - /** - * prepare возвращает только PDOStatement т.к установлен PDO::ERRMODE_EXCEPTION - */ - function prepare(string $sql, array $options = []): PDOStatement + function prepare(string $sql, array $options = []): PDOStatement|false { - /** @var PDOStatement */ - $result = parent::prepare($sql, $options); + $result/*: PDOStatement*/ = parent::prepare($sql, $options); 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 - */ public function getDSN() { return $this->dsn; } - - /** - * Возвращает true, если база данных Postgres - * @return bool - */ public function isPostgres() { return ($this->dsn["phptype"] == "pgsql"); } /** * Создает соединение с базой данных - * @param array $dsn - DSN - * @return Database|null */ static function getConnection(array $dsn) { - /** @var ?Database */ $connection = null; if ($dsn['phptype'] == 'pgsql' || $dsn['phptype'] == 'mysql') { $port = (isset($dsn['port'])) ? "port={$dsn['port']};" : ""; - $connection = new self("{$dsn['phptype']}:host={$dsn['hostspec']}; $port dbname={$dsn['database']}", $dsn['username'], $dsn['password']); + $connection/*: Database*/ = new self("{$dsn['phptype']}:host={$dsn['hostspec']}; $port dbname={$dsn['database']}", $dsn['username'], $dsn['password']); if ($dsn['phptype'] == 'pgsql') { $connection->query('SET client_encoding="UTF-8"'); } @@ -100,9 +64,9 @@ namespace ctiso { $connection = new self("{$dsn['phptype']}:"); $connection->sqliteCreateFunction('LOWER', 'sqliteLower', 1); } elseif ($dsn['phptype'] == 'sqlite') { - $connection = new self("{$dsn['phptype']}:{$dsn['database']}"); + $connection/*: Database*/ = new self("{$dsn['phptype']}:{$dsn['database']}"); $connection->setAttribute(PDO::ATTR_TIMEOUT, 5); - $mode = defined('SQLITE_JOURNAL_MODE') ? \SQLITE_JOURNAL_MODE : 'WAL'; + $mode = defined('SQLITE_JOURNAL_MODE') ? SQLITE_JOURNAL_MODE : 'WAL'; $connection->query("PRAGMA journal_mode=$mode"); $connection->sqliteCreateFunction('LOWER', 'sqliteLower', 1); } @@ -110,12 +74,7 @@ namespace ctiso { return $connection; } - /** - * Выполняет запрос к базе данных - * @param string $query - запрос - * @param ?array $values - значения - */ - public function executeQuery($query, $values = null): PDOStatement + public function executeQuery($query, $values = null): PDOStatement|bool { $stmt = $this->prepare($query); @@ -124,21 +83,14 @@ namespace ctiso { return $stmt; } - /** - * Создает подготовленный запрос - * @param string $query - запрос - * @return Statement - */ public function prepareStatement($query) { return new Statement($query, $this); } + // Для совместимости со старым представлением баз данных CIS /** - * Извлекает из базы все элементы по запросу (Для совместимости со старым представлением баз данных CIS) - * @param string $query - запрос - * @param ?array $values - значения - * @return array> + * Извлекает из базы все элементы по запросу */ public function fetchAllArray($query, $values = null) { @@ -150,9 +102,6 @@ namespace ctiso { /** * Извлекает из базы первый элемент по запросу - * @param string $query - запрос - * @param ?array $values - значения - * @return array|false */ public function fetchOneArray($query, $values = null) { @@ -162,11 +111,6 @@ namespace ctiso { return $sth->fetch(PDO::FETCH_ASSOC); } - /** - * Преобразует значения в подготовленные значения - * @param array $values - значения - * @return ?array - */ private function prepareValues($values) { if (!$values) { @@ -189,14 +133,8 @@ namespace ctiso { } return $prep; } - /** * Создает INSERT запрос - * @param string $table - таблица - * @param array $values - значения - * @param bool $return_id - возвращать id - * @param string $index - индекс - * @return int|null */ function insertQuery($table, array $values, $return_id = false, $index = null) { @@ -218,22 +156,15 @@ 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']; } } - return null; } /** * Создает UPDATE запрос - * @param string $table - таблица - * @param array $values - значения - * @param string $cond - условие */ - function updateQuery($table, array $values, $cond): void + function updateQuery($table, array $values, $cond) { $prep = $this->prepareValues($values); $sql = "UPDATE $table SET " . implode( @@ -247,10 +178,6 @@ namespace ctiso { $stmt->execute($prep); } - /** - * Создает генератор идентификаторов - * @return IdGenerator - */ function getIdGenerator() { return new IdGenerator($this); @@ -264,17 +191,12 @@ namespace ctiso { function getNextId($seq) { $result = $this->fetchOneArray("SELECT nextval('$seq')"); - if ($result === false) { - throw new \RuntimeException("Ошибка получения следующего идентификатора"); - } return $result['nextval']; } - /** - * Закрывает соединение с базой данных - */ - function close(): void + function close() { + return null; } } } diff --git a/src/Database/IdGenerator.php b/src/Database/IdGenerator.php index 6cad31a..5ae4664 100644 --- a/src/Database/IdGenerator.php +++ b/src/Database/IdGenerator.php @@ -4,40 +4,26 @@ namespace ctiso\Database; use ctiso\Database; class IdGenerator { - /** @var Database */ private $db; function __construct(Database $db) { $this->db = $db; } - /** - * @return bool - */ function isBeforeInsert() { - return false; - } + return false; + } - /** - * @return bool - */ function isAfterInsert() { - return true; + return true; } - - /** - * @param string $seq - * @return int - */ + function getId($seq) { if ($this->db->isPostgres()) { $result = $this->db->fetchOneArray("SELECT nextval('$seq') AS nextval"); } else { $result = $this->db->fetchOneArray("SELECT last_insert_rowid() AS nextval"); - } - if (!$result) { - throw new \Exception("nextval failed"); - } + } return (int)$result['nextval']; } } diff --git a/src/Database/JsonInstall.php b/src/Database/JsonInstall.php index f7842fb..253cd39 100644 --- a/src/Database/JsonInstall.php +++ b/src/Database/JsonInstall.php @@ -3,24 +3,21 @@ namespace ctiso\Database; use ctiso\Database\Manager; +use App\DbMigrate\DataBaseInfo; +use App\DbMigrate\DiffPatch; +/** + * Уcтсановить базу данных из json файла. + */ class JsonInstall { - /** @var Manager */ - public $db_manager; - /** @var array */ + public Manager $db_manager; public $serialColumns; public function __construct(Manager $db_manager) { $this->db_manager = $db_manager; } - /** - * Установить базу данных - * @param string $dbinit_path - * @param ?string $dbfill_path - * @return int - */ - function install($dbinit_path, $dbfill_path = null) { + public function install(string $dbinit_path, ?string $dbfill_path = null) { $dbinit_file = file_get_contents($dbinit_path); if (is_string($dbinit_file)) { $initActions = json_decode($dbinit_file, true); @@ -38,15 +35,9 @@ class JsonInstall { $this->fillDataBase($dbfill_path); } $this->makeConstraints($initActions); - return 1; } - /** - * Получить список таблиц, которые не существуют в базе данных - * @param array $tables - * @return array - */ - function missingTables($tables) { + protected function missingTables(array $tables) { $actual_tables = $this->db_manager->getAllTableNames(); $missingTables = []; foreach ($tables as $table) { @@ -58,19 +49,17 @@ class JsonInstall { /** * Создать таблицы - * @param array $initActions - * @param string $dbinit_path - * @return void */ - function initDataBase(array $initActions, $dbinit_path) { + function initDataBase(array $initActions, string $dbinit_path): void { $pg = $this->db_manager->db->isPostgres(); if (!$pg) { $refs = []; //В sqlite нет alter reference. Референсы надо создавать при создании таблицы. foreach ($initActions as $action) { if ($action["type"] == "alterReference") { - if (!isset($refs[$action["table"]])) + if (!isset($refs[$action["table"]])) { $refs[$action["table"]] = []; + } $refs[$action["table"]][]=$action;//добавить к списку референсов для таблицы } } @@ -116,16 +105,13 @@ class JsonInstall { /** * Заполнить данными - * @param string $dbfill_file_path - * @return void */ - function fillDataBase($dbfill_file_path) { + function fillDataBase(string $dbfill_file_path): void { $dbfill_file = file_get_contents($dbfill_file_path); if (is_string($dbfill_file)) { $actions = json_decode($dbfill_file,true); if ($actions) { - - //Проверка что упоминаемые в списке действий таблицы уже есть в базе + // Проверка что упоминаемые в списке действий таблицы уже есть в базе $affected_tables = []; foreach ($actions as $action) { if ($action["table_name"]) { @@ -153,17 +139,14 @@ class JsonInstall { /** * Обновить ключи serial и создать ограничения - * @param array $initActions - * @return void */ - function makeConstraints($initActions) { + protected function makeConstraints(array $initActions) { $pg = $this->db_manager->db->isPostgres(); if ($pg) { foreach ($this->serialColumns as $serialColumn) { $this->db_manager->updateSerial($serialColumn["table"], $serialColumn["column"]); } - foreach ($initActions as $action) { if ($action["type"] == "alterReference") { $this->db_manager->executeAction($action); @@ -172,4 +155,18 @@ class JsonInstall { } } + /** + * Обновить базу данных + */ + function update(array $patches): void { + $db = $this->db_manager->db; + $dbi = new DataBaseInfo(); + $diff = new DiffPatch($db); + $diff->readPatches($dbi, $patches); + + // Применяем изменения + $db->beginTransaction(); + $diff->patchDatabase($diff->getCurrentSchema(), $dbi); + $db->commit(); + } } \ No newline at end of file diff --git a/src/Database/Manager.php b/src/Database/Manager.php index ff8211e..7783739 100644 --- a/src/Database/Manager.php +++ b/src/Database/Manager.php @@ -7,95 +7,16 @@ use ctiso\Tools\SQLStatementExtractor; use ctiso\Path; use Exception; -/** - * @phpstan-type DropAction array{ - * type:"dropTable", - * table_name:string - * } - * - * @phpstan-type CreateAction array{ - * type:"createTable", - * table_name:string, - * constraints?:array{fields: array, type: string}|string, - * 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 - * } - * - * @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, - * not_null:bool, - * default:?string, - * references:?array{refTable:string,refColumn:string} - * } - */ class Manager { - /** @var Database */ - public $db; + public Database $db; - public function __construct(Database $db) - { + public function __construct(Database $db) { $this->db = $db; } - /** - * Выполняет действие - * @param Action $action - * @param string $db_file - * @throws Exception - */ - public function executeAction(array $action, $db_file = ""): void - { - switch ($action["type"]) { + public function executeAction(array $action, string $db_file = ""): void { + switch($action["type"]) { case "dropTable": $this->dropTableQuery($action["table_name"], true); break; @@ -132,85 +53,60 @@ class Manager break; default: - throw new Exception("unknown action " . $action["type"] . PHP_EOL); + throw new Exception("unknown action ". $action["type"] . PHP_EOL); } } /** * Дропает и создаёт SQL VIEW - * @param string $viewName - * @param string $selectStatement */ - public function recreateView($viewName, $selectStatement): void - { - $this->db->query("DROP VIEW " . $viewName); - $this->db->query("CREATE VIEW " . $viewName . " AS " . $selectStatement); + public function recreateView($viewName, $selectStatement) { + $this->db->query("DROP VIEW ".$viewName); + $this->db->query("CREATE VIEW ".$viewName." AS ".$selectStatement); } - /** - * Дропает таблицу - * @param string $table - * @param bool $cascade - */ - public function dropTableQuery($table, $cascade = false): void + public function dropTableQuery($table, $cascade=false) { - $statement = "DROP TABLE IF EXISTS " . $table; - if ($this->db->isPostgres() && $cascade) { + $statement = "DROP TABLE IF EXISTS ".$table; + if ($this->db->isPostgres()&&$cascade) { $statement .= " CASCADE"; } $this->db->query($statement); } - /** - * Добавляет ссылку на другую таблицу - * @param string $table - * @param string $column - * @param string $refTable - * @param string $refColumn - */ - public function alterReference($table, $column, $refTable, $refColumn): void + public function alterReference($table, $column, $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"); + $this->db->query("ALTER TABLE ".$table." ADD CONSTRAINT ".$table."_".$column."fk"." FOREIGN KEY (".$column.") REFERENCES ".$refTable." (".$refColumn.")"); } - /** - * Извлечение информации о полях таблицы - * @param string $table - * @return array{type:string,not_null:bool,constraint:?string}[]|null - */ + //Извлечение информации о полях таблицы public function tableInfo($table) { $pg = $this->db->isPostgres(); if ($pg) { throw new Exception("Not implemented for postgres"); } else { - $results = $this->db->fetchAllArray("PRAGMA table_info(" . $table . ");"); + $results = $this->db->fetchAllArray("PRAGMA table_info(".$table.");"); if (empty($results)) { return null; } $fields = []; foreach ($results as $result) { $fields[$result["name"]] = [ - "type" => $result["type"], - "not_null" => boolval($result["notnull"]), - "constraint" => ((bool) $result["pk"]) ? "PRIMARY KEY" : null + "type"=> $result["type"], + "nullable"=> !boolval($result["notnull"]), + "constraint"=> ((bool) $result["pk"]) ? "PRIMARY KEY" : null ]; } return $fields; } } - /** - * Переименование столбца в таблице - * @param string $table - * @param string $old_name - * @param string $new_name - */ - public function renameColumn($table, $old_name, $new_name): void + public function renameColumn(string $table, string $old_name, string $new_name): void { $pg = $this->db->isPostgres(); 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 { $tmp_table = "tmp_" . $table; $this->dropTableQuery($tmp_table); @@ -222,7 +118,7 @@ class Manager $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]; unset($table_info[$old_name]); $this->createTableQuery($table, $table_info, null); @@ -239,59 +135,40 @@ class Manager /** * Обновление ключа 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 ColumnProps $data - * @param bool $pg - * @return string - */ - public function columnDefinition($name, $data, $pg) + public function columnDefinition(string $name, $data, $pg): string { - $constraint = isset($data['constraint']) ? " " . $data['constraint'] : ""; + $constraint = isset($data['constraint']) ? " ".$data['constraint'] : ""; $references = ""; if (isset($data['references'])) { - $references = " REFERENCES " . $data['references']['refTable'] . '(' . $data['references']['refColumn'] . ')'; + $references = " REFERENCES " . $data['references']['table'] . '(' .$data['references']['column'] . ')'; } - if (isset($data["not_null"]) && $data["not_null"]) { - $constraint .= " NOT NULL"; + if (isset($data["nullable"]) && $data["nullable"] === false) { + $constraint .=" NOT NULL"; } $type = $data['type']; if (!$pg) { - if (strtolower($type) == "serial") { + if (strtolower($type)=="serial") { $type = "integer"; } } - return $name . " " . $type . $references . $constraint; + return $name." ".$type.$references.$constraint; } - /** - * Добавляет столбец в таблицу - * @param string $table_name - * @param string $column_name - * @param ColumnProps $field - */ - public function addColumn($table_name, $column_name, $field): void + public function addColumn(string $table_name, string $column_name, $field): void { $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->db->query($q); } - /** - * Возвращает определение ограничения - * @param array{fields: string[], type: string} $c - * @return string - */ public function getConstraintDef(array $c) { if ($c['type'] == 'unique') { @@ -300,15 +177,8 @@ class Manager return ""; } - - /** - * Создает таблицу - * @example createTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']]) - * @param string $table - * @param array $fields - * @param array{fields: array, type: string}|string|null $constraints - */ - public function createTableQuery($table, $fields, $constraints): void + //CreateTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']]) + public function createTableQuery(string $table, array $fields, $constraints): void { $pg = $this->db->isPostgres(); if ($constraints) { @@ -327,17 +197,12 @@ class Manager $this->db->query($statement); } - /** - * Возвращает дамп таблицы - * @param string $table_name - * @return array - */ - public function dumpTable($table_name) + public function dumpTable(string $table_name): array { $pg = $this->db->isPostgres(); $result = []; - $data = $this->db->fetchAllArray("SELECT * FROM " . $table_name . ";"); + $data = $this->db->fetchAllArray("SELECT * FROM ".$table_name.";"); if (!$pg) { $table_fields = $this->tableInfo($table_name); @@ -354,19 +219,15 @@ class Manager } foreach ($data as $r) { $result[] = [ - "type" => "insert", - "table_name" => $table_name, - "values" => $r + "type" => "insert", + "table_name" => $table_name, + "values" => $r ]; } return $result; } - /** - * Возвращает все имена таблиц - * @return list - */ - public function getAllTableNames() + public function getAllTableNames(): array { $result = []; if ($this->db->isPostgres()) { @@ -381,11 +242,7 @@ class Manager return $result; } - /** - * Возвращает дамп всех таблиц - * @return array - */ - public function dumpInserts() + public function dumpInserts(): array { $table_names = $this->getAllTableNames(); $result = []; diff --git a/src/Database/PDOStatement.php b/src/Database/PDOStatement.php index 69a1c49..2a6a834 100644 --- a/src/Database/PDOStatement.php +++ b/src/Database/PDOStatement.php @@ -7,16 +7,10 @@ use ctiso\Database\StatementIterator, PDO; use TheSeer\Tokenizer\Exception; -/** - * @implements \IteratorAggregate - */ class PDOStatement extends \PDOStatement implements \IteratorAggregate { - /** @var int */ protected $cursorPos = 0; - /** @var array */ - public $cache = []; - /** @var ?array */ + public $cache = array(); public $fields; function getIterator(): \Iterator { @@ -26,15 +20,11 @@ class PDOStatement extends \PDOStatement implements \IteratorAggregate protected function __construct() { } - function rewind(): void { + function rewind() { $this->cursorPos = 0; } - /** - * @param int $rownum - * @return bool - */ - public function seek($rownum): bool { + public function seek($rownum) { if ($rownum < 0) { return false; } @@ -45,19 +35,17 @@ class PDOStatement extends \PDOStatement implements \IteratorAggregate return true; } - function valid(): bool { + function valid() { return true; } - /** - * @return bool - */ + public function first() { - if ($this->cursorPos !== 0) { $this->seek(0); } + if($this->cursorPos !== 0) { $this->seek(0); } return $this->next(); } - function next(): bool{ + function next() { if ($this->getRecordCount() > $this->cursorPos) { if (!isset($this->cache[$this->cursorPos])) { $this->cache[$this->cursorPos] = $this->fetch(PDO::FETCH_ASSOC); @@ -72,86 +60,49 @@ class PDOStatement extends \PDOStatement implements \IteratorAggregate } } - function key(): int { + function key() { return $this->cursorPos; } - /** - * @return mixed - */ function current() { return $this->cache[$this->cursorPos]; } - /** - * @return array|null - */ function getRow() { return $this->fields; } - /** - * @param string $name - * @return int - */ - function getInt($name): int { + function getInt($name) { if (!$this->fields) { throw new \Exception('no fields'); } return (int)$this->fields[$name]; } - /** - * @param string $name - * @return string - */ function getBlob($name) { return $this->fields[$name]; } - /** - * @param string $name - * @return string - */ function getString($name) { return $this->fields[$name] ?? null; } - /** - * @param string $name - * @return bool - */ function getBoolean($name) { return (bool)$this->fields[$name]; } - /** - * @param string $name - * @return mixed - */ function get($name) { return $this->fields[$name]; } - /** - * @param string $name - * @return array - */ function getArray($name) { return StringUtil::strToArray($this->fields[$name]); } - /** - * @return int - */ function getRecordCount() { return count($this->cache); } - /** - * @param array $args - * @return bool - */ function execute($args = null): bool { $result = parent::execute($args); return $result; diff --git a/src/Database/Statement.php b/src/Database/Statement.php index e270822..b0f6ebd 100644 --- a/src/Database/Statement.php +++ b/src/Database/Statement.php @@ -4,80 +4,48 @@ * Класс оболочка для PDOStatement для замены Creole */ namespace ctiso\Database; - -use PDO; -use ctiso\Database; +use PDO, + ctiso\Database; class Statement { - /** @var ?int */ protected $limit = null; - /** @var ?int */ protected $offset = null; - /** @var never */ protected $statement = null; - /** @var array{int|string, mixed, int}[] */ - protected $binds = []; - /** @var Database */ + protected $binds = array(); protected $conn; - /** @var string */ protected $query; - /** - * @param string $query - * @param Database $conn - */ - function __construct($query, $conn) { + function __construct($query, $conn/*: Database*/) { $this->query = $query; $this->conn = $conn; } - /** - * @param int|string $n - * @param int $value - */ - function setInt($n, $value): void { + function setInt($n, $value) { $this->binds [] = [$n, $value, PDO::PARAM_INT]; } - /** - * @param int|string $n - * @param string $value - */ - function setString($n, $value): void { + function setString($n, $value) { $this->binds [] = [$n, $value, PDO::PARAM_STR]; } - /** - * @param int|string $n - * @param mixed $value - */ - function setBlob($n, $value): void { + function setBlob($n, $value) { $this->binds [] = [$n, $value, PDO::PARAM_LOB]; } - /** - * @param int $limit - */ - function setLimit($limit): void { + function setLimit($limit) { $this->limit = $limit; } - /** - * @param int $offset - */ - function setOffset($offset): void { + function setOffset($offset) { $this->offset = $offset; } - /** - * @return PDOStatement - */ function executeQuery() { if ($this->limit) { $this->query .= " LIMIT {$this->limit} OFFSET {$this->offset}"; } - $stmt = $this->conn->prepare($this->query); + $stmt/*: PDOStatement*/ = $this->conn->prepare($this->query); foreach ($this->binds as $bind) { list($n, $value, $type) = $bind; $stmt->bindValue($n, $value, (int) $type); diff --git a/src/Database/StatementIterator.php b/src/Database/StatementIterator.php index 43f82e9..f767408 100644 --- a/src/Database/StatementIterator.php +++ b/src/Database/StatementIterator.php @@ -3,22 +3,14 @@ namespace ctiso\Database; use PDO; -/** - * @implements \Iterator - */ class StatementIterator implements \Iterator { - /** @var PDOStatement */ + private $result; - /** @var int */ private $pos = 0; - /** @var int */ private $row_count; - /** - * @param PDOStatement $rs - */ - public function __construct($rs) { + public function __construct($rs/*: PDOStatement*/) { $this->result = $rs; $this->row_count = $rs->getRecordCount(); } @@ -42,18 +34,15 @@ class StatementIterator implements \Iterator return $this->result->cache[$this->pos]; } - function next(): void { + function next(): void{ $this->pos++; } - /** - * @param int $index - */ - function seek($index): void { + function seek($index) { $this->pos = $index; } - function count(): int { + function count() { return $this->row_count; } } diff --git a/src/Excel/DataTime.php b/src/Excel/DataTime.php index 7a910df..877546d 100644 --- a/src/Excel/DataTime.php +++ b/src/Excel/DataTime.php @@ -4,19 +4,15 @@ namespace ctiso\Excel; class DateTime { - /** @var int */ public $value; - /** - * @param int $value - */ - function __construct($value) + function __construct($value) { $this->value = (int)$value; } - function getString(): string + function getString() { return date('Y-m-d\TH:i:s.u', $this->value); - } + } } diff --git a/src/Excel/Document.php b/src/Excel/Document.php index 4a9480c..d4d033e 100644 --- a/src/Excel/Document.php +++ b/src/Excel/Document.php @@ -8,18 +8,11 @@ use XMLWriter, Exception; class Document { - /** @var string */ static $ns = "urn:schemas-microsoft-com:office:spreadsheet"; - /** @var list */ - private $table = []; - /** @var array */ - protected $styles = []; + private $table = array (); + protected $styles = array(); - /** - * Добавление таблицы в документ - * @param Table|callable $table Таблица или функция, возвращающая таблицу - */ - function addTable($table): void { + function addTable($table) { $this->table [] = $table; } @@ -29,7 +22,7 @@ class Document { * @param array $values array Параметры стиля * @param string $type Тип стиля */ - function setStyle ($name, array $values, $type = 'Interior'): void + function setStyle ($name, array $values, $type = 'Interior') { if(!isset($this->styles[$name])) { $this->styles[$name] = []; @@ -40,8 +33,7 @@ class Document { /** * Генерация стилей */ - private function createStyles (XMLWriter $doc): void - { + private function createStyles (XMLWriter $doc) { $doc->startElement('Styles'); foreach ($this->styles as $name => $sn) { $doc->startElement('Style'); @@ -73,22 +65,18 @@ class Document { /** * Преобразует переводы строки в спец символы - * @param string $s - * @return string */ function clean ($s) { + assert(is_string($s)); + return strtr($s, ["\n" => " "]); } /** * Сохраняет таблицу в формате Office 2003 XML * http://en.wikipedia.org/wiki/Microsoft_Office_XML_formats - * - * @param string $filename - * @throws Exception - * @return void */ - function save($filename): void + function save($filename) { $doc = new XMLWriter(); if (!$doc->openUri($filename)) { diff --git a/src/Excel/Number.php b/src/Excel/Number.php index 3df78bb..8ed12b4 100644 --- a/src/Excel/Number.php +++ b/src/Excel/Number.php @@ -4,20 +4,16 @@ namespace ctiso\Excel; class Number { - /** @var int */ public $value; - /** - * @param int|float $value - */ - function __construct($value) + function __construct($value) { $this->value = (int)($value); } - function getString(): string + function getString() { - return (string) $this->value; - } + return $this->value; + } } diff --git a/src/Excel/Table.php b/src/Excel/Table.php index 395253e..ea28a2e 100644 --- a/src/Excel/Table.php +++ b/src/Excel/Table.php @@ -10,16 +10,10 @@ use XMLWriter, class TableCell { - /** @var string|false */ public $style = false; - /** @var string */ public $value; - /** @var bool */ public $merge = false; - /** - * @param string $value Значение клетки - */ function __construct ($value) { $this->value = $value; @@ -31,29 +25,16 @@ class TableCell */ class TableRow { - /** @var string|false */ public $style = false; - /** @var TableCell[] */ - public $cells = []; - /** @var int|false */ + public $cells = array(); public $height = false; - /** - * Устанавливает значение для клетки - * @param int $y Номер столбца - * @param string $value Значение клетки - */ - function setCell($y, $value): void + function setCell($y, $value) { $this->cells[$y] = new TableCell($value); } - /** - * Устанавливает стиль для клетки - * @param int $y Номер столбца - * @param string $name Имя стиля - */ - function setCellStyle($y, $name): void + function setCellStyle($y, $name) { $this->cells[$y]->style = $name; } @@ -64,16 +45,12 @@ class TableRow */ class Table { - /** @var int */ static $index; - /** @var string */ private $name; - /** @var TableRow[] */ - protected $rows = []; + private $style; + protected $rows = array(); - /** @var int|false */ protected $_splitVertical = false; - /** @var int|false */ protected $_splitHorizontal = false; function __construct() @@ -83,30 +60,26 @@ class Table /** * Записать значение в клетку с заданными координатами - * @param int $x Номер ряда - * @param int $y Номер столбца - * @param string $value Значение клетки */ - function setCell(int $x, int $y, $value): void + function setCell($x, $y, $value) { - assert($x > 0); - assert($y > 0); + assert(is_numeric($x) && $x > 0); + assert(is_numeric($y) && $y > 0); if(! isset($this->rows[$x])) { $this->rows[$x] = new TableRow(); } - - $row = $this->rows[$x]; + $row/*: TableRow*/ = $this->rows[$x]; $row->setCell($y, $value); } /** * Заполняет ряд начиная с указанного столбца значениями из массива */ - function setRow(int $row, int $index, array $data): void + function setRow($row, $index, array $data) { - assert($index > 0); - assert($row > 0); + assert(is_numeric($index) && $index > 0); + assert(is_numeric($row) && $row > 0); reset($data); for ($i = $index; $i < $index + count($data); $i++) { @@ -117,40 +90,40 @@ class Table /** * Устанавливает высоту ряда - * @param int $row Номер ряда - * @param int $value Высота ряда + * @param $row integer Номер ряда + * @parma $value real Высота ряда */ - function setRowHeight (int $row, $value): void + function setRowHeight ($row, $value) { - assert($row > 0); + assert(is_numeric($row) && $row > 0); $this->rows[$row]->height = $value; } /** * Устанавливает стиль ряда - * @param int $row Номер ряда - * @param string $name Имя стиля + * @param $row integer Номер ряда + * @parma $name string Имя стиля */ - function setRowStyle(int $row, $name): void + function setRowStyle ($row, $name) { - assert($row > 0); + assert(is_numeric($row) && $row > 0); $this->rows[$row]->style = $name; } /** * Обьединяет клетки в строке - * @param int $x Номер ряда - * @param int $cell Номер столбца - * @param bool $merge Количество клеток для обьединения + * @param $row Номер ряда + * @param $cell Номер столбца + * @param $merge Количество клеток для обьединения */ - function setCellMerge(int $x, int $cell, $merge): void + function setCellMerge($x, $cell, $merge) { - assert($x > 0); - assert($cell > 0); + assert(is_numeric($x) && $x > 0); + assert(is_numeric($cell) && $cell > 0); - $row = $this->rows[$x]; + $row/*: TableRow*/ = $this->rows[$x]; $row->cells[$cell]->merge = $merge; } @@ -160,20 +133,18 @@ class Table * @param int $y Номер столбца * @param string $name Имя стиля */ - function setCellStyle ($row, $y, $name): void + function setCellStyle ($row, $y, $name) { - if (isset($this->rows[$row])) { + if (isset($this->rows[$row])) $this->rows[$row]->setCellStyle($y, $name); - } } /** * Добавляет строку к таблице - * @return int Номер добавленной строки */ - function addRow(int $index = 1, array $data = [""]) + function addRow($index = 1, array $data = [""]) { - assert($index > 0); + assert(is_numeric($index) && $index > 0); $offset = $this->getRows() + 1; $this->setRow($offset, $index, $data); @@ -187,9 +158,8 @@ class Table */ function getRows() { - // Высчитываем максимальный индекс, массив может быть разрежен поэтому используем array_keys - $keys = array_keys($this->rows); - return $keys === [] ? 0 : max($keys); + $keys/*: array*/ = array_keys($this->rows); + return max($keys); } /** @@ -199,15 +169,15 @@ class Table */ function getRowCells(TableRow $row) { - $keys = array_keys($row->cells); - return $keys === [] ? 0 :max($keys); + $keys/*: array*/ = array_keys($row->cells); + return max($keys); } /** * Разделяет таблицу на две части по вертикали * @param int $n Количество столбцов слева */ - function splitVertical($n): void { + function splitVertical($n) { $this->_splitVertical = $n; } @@ -215,7 +185,7 @@ class Table * Разделяет таблицу на две части по горизонтали * @param int $n Количество столбцов сверху */ - function splitHorizontal($n): void { + function splitHorizontal($n) { $this->_splitHorizontal = $n; } @@ -226,16 +196,9 @@ class Table * @return int */ function getColumns() { - $columns = array_map($this->getRowCells(...), $this->rows); - return $columns === [] ? 0 : max($columns); + return max(array_map([$this, 'getRowCells'], $this->rows)); } - /** - * Кодирование строки - * @deprecated Можно заменить на значение - * @param string $s Строка - * @return string - */ function encode($s) { return $s; @@ -243,13 +206,8 @@ 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): void { + function createCell (TableCell $ncell, XMLWriter $doc, $j, $value/*: any*/, $setIndex) { $doc->startElement("Cell"); if ($ncell->style) { @@ -257,11 +215,11 @@ class Table } if ($ncell->merge) { - $doc->writeAttribute('ss:MergeAcross', (string)$ncell->merge); + $doc->writeAttribute('ss:MergeAcross', $ncell->merge); } if ($setIndex) { - $doc->writeAttribute('ss:Index', (string)$j); + $doc->writeAttribute('ss:Index', $j); } $doc->startElement("Data"); @@ -277,7 +235,7 @@ class Table } else { $doc->writeAttribute('ss:Type', "Number"); } - $doc->writeCdata($value); + $doc->writeCdata($this->encode($value)); } $doc->endElement(); $doc->endElement(); @@ -286,7 +244,7 @@ class Table /** * Генерация таблицы */ - public function createTable (XMLWriter $doc): void { + public function createTable (XMLWriter $doc) { $doc->startElement('Worksheet'); $doc->writeAttribute('ss:Name', $this->name); @@ -306,10 +264,10 @@ class Table } if ($this->rows[$i]->height) { - $doc->writeAttribute('ss:Height', (string)$this->rows[$i]->height); + $doc->writeAttribute('ss:Height', $this->rows[$i]->height); } - /** @var TableRow $nrow */ - $nrow = $this->rows[$i]; + + $nrow/*: TableRow*/ = $this->rows[$i]; // Флаг индикатор подстановки номера столбца $setIndex = false; for ($j = 1; $j <= $columns; $j++) { @@ -334,23 +292,23 @@ class Table $doc->endElement(); } - protected function splitPane (XMLWriter $doc): void { + protected function splitPane (XMLWriter $doc) { $doc->startElement('WorksheetOptions'); $doc->writeAttribute('xmlns', 'urn:schemas-microsoft-com:office:excel'); $doc->writeElement('FrozenNoSplit'); if ($this->_splitVertical) { - $doc->writeElement('SplitVertical', (string) $this->_splitVertical); - $doc->writeElement('LeftColumnRightPane', (string) $this->_splitVertical); + $doc->writeElement('SplitVertical', $this->_splitVertical); + $doc->writeElement('LeftColumnRightPane', $this->_splitVertical); } if ($this->_splitHorizontal) { - $doc->writeElement('SplitHorizontal', (string) $this->_splitHorizontal); - $doc->writeElement('TopRowBottomPane', (string) $this->_splitHorizontal); + $doc->writeElement('SplitHorizontal', $this->_splitHorizontal); + $doc->writeElement('TopRowBottomPane', $this->_splitHorizontal); } if ($this->_splitHorizontal && $this->_splitVertical) { - $doc->writeElement('ActivePane', (string) 0); + $doc->writeElement('ActivePane', (string)0); } else if($this->_splitHorizontal) { - $doc->writeElement('ActivePane', (string) 2); + $doc->writeElement('ActivePane', (string)2); } $doc->endElement(); } diff --git a/src/File.php b/src/File.php index 8ee2eae..c523cf6 100644 --- a/src/File.php +++ b/src/File.php @@ -4,11 +4,6 @@ namespace ctiso; use Exception; class File { - /** - * @param string $filename - * @return string - * @throws Exception - */ static function getContents($filename) { $buffer = @file_get_contents($filename); if ($buffer !== false) { diff --git a/src/Filter/ActionAccess.php b/src/Filter/ActionAccess.php index 6dd44c3..4fabc60 100644 --- a/src/Filter/ActionAccess.php +++ b/src/Filter/ActionAccess.php @@ -1,27 +1,20 @@ processor = $processor; $this->user = $user; } @@ -30,19 +23,12 @@ class ActionAccess * Проверка доступных действий для пользователя * !! Реализация класса проверки действий не должна быть внутри Контроллера!!! * Информация о доступе может быть в файле, базе данных и т.д. - * - * @param string $action - * @return bool */ function checkAction($action) { // Импликация !! http://ru.wikipedia.org/wiki/Импликация return (!isset($this->access[$action]) || in_array($this->user->access, $this->access[$action])); } - /** - * @param HttpRequest $request - * @return mixed - */ function execute(HttpRequest $request) { $action = $request->getAction(); if(! $this->checkAction($action)) { diff --git a/src/Filter/ActionLogger.php b/src/Filter/ActionLogger.php index ee94839..b2b02ff 100644 --- a/src/Filter/ActionLogger.php +++ b/src/Filter/ActionLogger.php @@ -5,25 +5,15 @@ use ctiso\Role\UserInterface, ctiso\HttpRequest; /* Переделать формат Логов на список json */ -class ActionLogger implements FilterInterface -{ - /** @var array */ - public $before = []; - /** @var resource */ +class ActionLogger +{ + public $before = array(); public $file; - /** @var UserInterface */ public $user; - /** @var string */ public $action; - /** @var \ctiso\Controller\ActionInterface */ public $processor; - /** - * @param \ctiso\Controller\ActionInterface $processor - * @param string $logPath - * @param UserInterface $user - */ - function __construct($processor, $logPath, $user) { + function __construct($processor/*: Filter*/, $logPath, $user/*: UserInterface*/) { $this->processor = $processor; $this->user = $user; diff --git a/src/Filter/Authorization.php b/src/Filter/Authorization.php index 2421212..8510433 100644 --- a/src/Filter/Authorization.php +++ b/src/Filter/Authorization.php @@ -5,20 +5,13 @@ namespace ctiso\Filter; class Authorization { const SESSION_BROWSER_SIGN_SECRET = '@w3dsju45Msk#'; const SESSION_BROWSER_SIGN_KEYNAME = 'session.app.browser.sign'; - /** @var string */ public $group; - /** - * @param string $group - */ function __construct($group) { $this->group = $group; } - /** - * @param string $group - */ - static function isLogged($group = 'access'): bool { + static function isLogged($group = 'access') { // echo session_status(); if (session_status() == PHP_SESSION_NONE) { session_start(); @@ -36,11 +29,7 @@ class Authorization { return false; } - /** - * @param int $id - * @param string $group - */ - static function enter($id, $group = 'access'): void { + static function enter($id, $group = 'access') { // $db->executeQuery("UPDATE visitor SET sid = '' WHERE id_visitor = " . $result->getInt('id_user')); // session_register("access"); // session_register("time"); @@ -51,7 +40,7 @@ class Authorization { $_SESSION ["time"] = time(); } - static function getRawSign(): string + static function getRawSign() { $rawSign = self::SESSION_BROWSER_SIGN_SECRET; $signParts = ['HTTP_USER_AGENT']; @@ -59,16 +48,17 @@ class Authorization { foreach ($signParts as $signPart) { $rawSign .= '::' . ($_SERVER[$signPart] ?? 'none'); } - + return $rawSign; } - static function getBrowserSign(): string + static function getBrowserSign() { + return md5(self::getRawSign()); } - function logout(): void { + function logout() { session_destroy(); } } diff --git a/src/Filter/Filter.php b/src/Filter/Filter.php index 57d8e7c..156d4e0 100644 --- a/src/Filter/Filter.php +++ b/src/Filter/Filter.php @@ -5,44 +5,29 @@ */ namespace ctiso\Filter; -use ctiso\Database; -use ctiso\HttpRequest; -use ctiso\Controller\ActionInterface; +use ctiso\Controller\Action, + ctiso\HttpRequest; -class Filter implements ActionInterface +class Filter { - /** @var ActionInterface */ public $processor; - - /** - * @param ActionInterface $processor - */ - public function __construct($processor) + public function __construct($processor/*: Action*/) { $this->processor = $processor; } - + public function execute(HttpRequest $request) { return $this->processor->execute($request); } - /** - * @param string $name - * @param class-string<\ctiso\View\View> $class - * @return \ctiso\View\View - */ - public function getView($name, $class = \ctiso\View\Top::class) + public function getView($name, $class = 'ctiso\\View\\Top') { return $this->processor->getView($name, $class); } - public function getConnection(): Database + public function getConnection() { return $this->processor->getConnection(); } - - public function addUrlPart($key, $value): void { - $this->processor->addUrlPart($key, $value); - } } diff --git a/src/Filter/FilterInterface.php b/src/Filter/FilterInterface.php deleted file mode 100644 index aee34a9..0000000 --- a/src/Filter/FilterInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -getAction()) { // Авторизация по постоянному паролю case 'login': - $login = $request->getString('login', '') ; - $password = $request->getString('password'); + $login = $request->get('login'); + $password = $request->get('password'); $result = $this->role->getUserByLogin($login); // Поиск по логину if ($result) { @@ -63,9 +60,6 @@ class Login extends Filter $db = Database::getConnection($dsn); $user = $db->fetchOneArray("SELECT * FROM users WHERE login = :login", ['login' => $login]); - if ($user === false) { - return false; - } $userPassword = $user['password']; } /*else if (time() - $result->getInt('lastupdate') > 60*60*24*60) { // Проверить давность пароля, 60 дней @@ -73,7 +67,7 @@ class Login extends Filter $request->set('lastupdate', true); return false; }*/ - // Проверка на количества попыток авторизации + // Проверка на количества попыток авторизации $lastAttempt = $result; if ($lastAttempt->get('trie_count') >= self::AUTH_MAX_ATTEMPT /*&& time() - $lastAttempt['trie_time'] < self::AUTH_LAST_ATTEMPT_TIMER*/) { @@ -81,7 +75,7 @@ class Login extends Filter $request->set('timeout_error', true); break; } else { - $this->role->resetTries($request->getString('login')); + $this->role->resetTries($request->get('login')); } } // Извлечнеие пользователя из родительской CMS, для проверки пароля @@ -106,7 +100,7 @@ class Login extends Filter $result = $this->role->getUserByLogin($login); // Поиск по логину if ($result) { $temp = md5($result->getString('password') . $result->getString('login') . $result->getString('sid')); - if ($password == $temp) { + if ($password == $temp) { $this->enter($result); return true; } @@ -131,15 +125,11 @@ class Login extends Filter return false; } - /** - * Вход в систему - * @param PDOStatement $result - */ - private function enter($result): void + private function enter($result) { $this->user = $result; $random = rand(0, 1024 * 1024); - $this->role->setSID((string)$random, $result); + $this->role->setSID($random, $result); $_SESSION["group"] = $result->getInt('access'); $_SESSION["access"] = $result->getInt('id_user'); // id_user @@ -148,13 +138,10 @@ class Login extends Filter $_SESSION["time"] = time(); } - /** - * @return mixed - */ - public function execute(HttpRequest $request): mixed + public function execute(HttpRequest $request) { $logged = $this->isLoggin($request); - if ($request->getString('action') == 'user_access') { + if ($request->get('action') == 'user_access') { if ($logged) { $result = []; $result['fullname'] = $this->user->getString('patronymic') . " " . $this->user->getString('firstname'); @@ -166,7 +153,7 @@ class Login extends Filter } } - if ($request->getString('action') == 'relogin') { + if ($request->get('action') == 'relogin') { if ($logged) { return json_encode(['result' => 'ok', 'message' => "Авторизация успешна"]); } else { @@ -177,7 +164,7 @@ class Login extends Filter if (!$logged) { // Параметры при неправильной авторизации // Действия по умолчанию !! Возможно переход на форму регистрации - if ($request->getString('mode') == 'ajax') { + if ($request->get('mode') == 'ajax') { if (!$this->requestIsWhite($request)) { return json_encode(['result' => 'fail', 'message' =>"NOT_AUTHORIZED"]); } @@ -187,11 +174,8 @@ 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']) - && is_string($arr['back_page']) - && $request->getString('mode') != 'ajax') - { + parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY) ?? '', $arr); + if (isset($arr['back_page']) && $request->get('mode') != 'ajax') { $request->redirect($arr['back_page']); } } @@ -200,23 +184,19 @@ class Login extends Filter return $text; } - /** + /* --------------------- * Проверка на попадание реквеста в белый список - */ - public function requestIsWhite(Collection $request): bool { + */ + public function requestIsWhite(Collection $request) { $module = $request->get('module'); $action = $request->get('action'); $moduleDir = explode('\\',$module)[0]; - // TODO: Параметр для белого списка перенести в install.json $file = Path::join($this->config->get('system', 'path'), 'modules', $moduleDir, 'filters', 'white.json'); if (file_exists($file)) { - $text = file_get_contents($file); - if (!$text) { - return false; - } - $whiteList = json_decode($text, true); - if (is_array($whiteList) && in_array($action, $whiteList, true)) { + $whiteList = json_decode(file_get_contents($file), true); + + if (in_array($action, $whiteList)) { return true; } } diff --git a/src/Form/CheckBox.php b/src/Form/CheckBox.php index fd1fa2a..6eb1619 100644 --- a/src/Form/CheckBox.php +++ b/src/Form/CheckBox.php @@ -5,9 +5,8 @@ use ctiso\Form\Field; class CheckBox extends Field { - /** @var bool */ public $checked = false; - function setValue($value): void + function setValue($value) { $this->value = $value; $this->checked = $value; diff --git a/src/Form/Field.php b/src/Form/Field.php index 098003e..c3df594 100644 --- a/src/Form/Field.php +++ b/src/Form/Field.php @@ -4,51 +4,28 @@ */ namespace ctiso\Form; -use ctiso\Form\OptionsFactory; - class Field { - /** @var bool */ public $hidden = false; - /** @var string */ public $name; - /** @var string */ public $label; // Метка поля - - /** @var mixed */ public $value; // Значение поля - /** @var string */ public $type = ""; // Каждому типу элемента соответствует макрос TAL - /** @var ?string */ - public $error_msg = null; - /** @var ?mixed */ - public $default = null; - /** @var bool */ - public $error = false; - /** @var bool */ + public $error_msg = null; + public $default = null; + public $error = false; public $require = false; - /** @var ?string */ public $hint = null; - /** @var ?int */ public $maxlength = null; - /** @var ?string */ public $fieldset = null; // Блоки (Убрать в отдельный класс!!!) - /** @var array */ - public $_title = []; - /** @var string */ + public $_title = array(); public $description = ""; - /** @var array */ - public $alias = []; - - - /** - * @param array $input - * @param OptionsFactory|null $factory - * @phpstan-ignore-next-line - */ + public $alias = array(); + + /** @phpstan-ignore-next-line */ public function __construct ($input = [], $factory = null) - { + { $this->default = null; if (isset($input['validate'])) { $this->require = strpos($input['validate'], 'require') !== false; @@ -64,15 +41,12 @@ class Field } } - /** - * @param mixed $value - */ - function setValue($value): void + function setValue($value/*: any*/) { $this->value = $value; } - function getId(): string + function getId() { return $this->name . '_label'; } diff --git a/src/Form/Form.php b/src/Form/Form.php index a425af1..b634115 100644 --- a/src/Form/Form.php +++ b/src/Form/Form.php @@ -5,40 +5,30 @@ */ namespace ctiso\Form; - -use ctiso\Form\Field; -use ctiso\Form\Select; -use ctiso\Form\Input; -use ctiso\Validator\Validator; -use ctiso\HttpRequest; +use ctiso\Form\Field, + ctiso\Form\Select, + ctiso\Form\Input, + ctiso\View\View, + ctiso\Validator\Validator, + ctiso\HttpRequest; /** * Форма для ввода */ class Form { - /** @var array */ - public $field = []; //Поля формы - /** @var array */ - public $fieldsets = []; //Группы полей (fieldset). Некоторые поля могут не принадлежать никаким группам + public $field = array(); //Поля формы + public $fieldsets = array(); //Группы полей (fieldset). Некоторые поля могут не принадлежать никаким группам - /** @var string */ public $action = ""; - /** @var string */ public $method = 'post'; - /** @var string */ public $header; - /** @var array */ protected $replace; - /** @var array */ protected $before; - /** @var array */ - public $_title = []; - /** @var array */ - public $alias = []; - /** @var class-string[] */ - private $constructor = []; + public $_title = array(); + public $alias = array(); + private $constructor = array(); /** * Строим форму по ее структуре. Каждому типу соответствует определенный класс. @@ -49,6 +39,7 @@ class Form { 'input' => Input::class, // input с проверкой на заполненность 'inputreq' => Input::class, + 'date' => Date::class, 'datereq' => Date::class, 'datetime' => DateTime::class, @@ -77,7 +68,7 @@ class Form { } - function getId(): string + function getId() { return '_form_edit'; } @@ -86,18 +77,18 @@ class Form { * Добавление конструкторя для поля формы * @param string $name Краткое название поля * @param class-string $class + * @return void */ - public function addFieldClass($name, $class): void + public function addFieldClass($name, $class) { $this->constructor [$name] = $class; } /** * Добавляет одно поле ввода на форму - * @param array{ type: string, name: string, hint?: string } $init - * @param OptionsFactory|null $factory + * @return Field */ - public function addField(array $init, $factory = null): Field + public function addField(array $init, $factory = null) { assert(isset($init['type'])); assert(isset($init['name'])); @@ -119,7 +110,8 @@ class Form { /** * Добавление fieldset на форму */ - public function addFieldSet(array $fieldset): void + + public function addFieldSet(array $fieldset) { $this->fieldsets[$fieldset['name']] = $fieldset; } @@ -127,7 +119,8 @@ class Form { /** * Добавление массива fieldset на форму */ - public function addFieldSetList(array $list): void + + public function addFieldSetList(array $list) { foreach ($list as $fieldset) { $this->addFieldSet($fieldset); @@ -137,9 +130,8 @@ class Form { /** * Добавляет список полей для формы * @param array $list - * @param OptionsFactory|null $factory */ - public function addFieldList(array $list, $factory = null): void + public function addFieldList(array $list, $factory = null) { foreach ($list as $init) { $this->addField($init, $factory); @@ -149,7 +141,7 @@ class Form { /** * Устанавливает ошибки после проверки */ - function setError(Validator $validator): void + function setError(Validator $validator) { foreach ($validator->getErrorMsg() as $name => $error) { @@ -158,12 +150,7 @@ class Form { } } - /** - * Устанавливает ошибку для поля - * @param string $name - * @param string $message - */ - function setFieldError($name, $message): void + function setFieldError($name, $message) { $this->field[$name]->error = true; $this->field[$name]->error_msg = $message; @@ -172,7 +159,7 @@ class Form { /** * Устанавливает значения из масива */ - function setValues(HttpRequest $request): void { + function setValues(HttpRequest $request) { foreach ($this->field as $key => $_) { $value = $request->getRawData($this->method, $key); $this->field[$key]->setValue($value); @@ -184,28 +171,20 @@ class Form { * @param object $data * @param array $schema Связь между элементами формы и свойствами обьекта */ - public function fill($data, array $schema): void + public function fill($data, array $schema) { foreach ($schema as $key => $conv) { list($value, $type) = $conv; - $convertFn = [\ctiso\Primitive::class, 'from_' . $type]; - if (!is_callable($convertFn)) { - throw new \Exception('Не найден метод преобразования ' . $type); - } - $this->field[$key]->setValue(call_user_func($convertFn, $data->$value)); + $this->field [$key]->setValue(call_user_func([\ctiso\Primitive::class, 'from_' . $type], $data->$value)); } } - /** - * @param string $name - * @param mixed $value - */ - public function set($name, $value): void + public function set($name, $value) { $this->field[$name]->setValue($value); } - - function execute(): self + + function execute() { return $this; } diff --git a/src/Form/Hidden.php b/src/Form/Hidden.php index 6e3df61..535e21b 100644 --- a/src/Form/Hidden.php +++ b/src/Form/Hidden.php @@ -4,6 +4,5 @@ namespace ctiso\Form; use ctiso\Form\Input; class Hidden extends Input { - /** @var bool */ public $hidden = true; } diff --git a/src/Form/OptionsFactory.php b/src/Form/OptionsFactory.php deleted file mode 100644 index 79be2e0..0000000 --- a/src/Form/OptionsFactory.php +++ /dev/null @@ -1,7 +0,0 @@ -value = $value; diff --git a/src/Form/Select.php b/src/Form/Select.php index 89ea70d..4b00b0a 100644 --- a/src/Form/Select.php +++ b/src/Form/Select.php @@ -3,18 +3,10 @@ namespace ctiso\Form; use ctiso\Form\Field; -/** - * @phpstan-type Option = array{value: string, name: string, selected?: bool, class?: string|false} - */ class Select extends Field { - /** @var Option[] */ - public $options = []; + public $options = array(); - /** - * @param array{ options?: Option[], 'options.pair'?: array } $input - * @param OptionsFactory $factory - */ public function __construct ($input, $factory) { parent::__construct($input); @@ -32,11 +24,6 @@ class Select extends Field } } - /** - * @param string[] $list - * @param bool $selected - * @return Option[] - */ public function optionsPair($list, $selected = false) { $result = []; foreach ($list as $key => $value) { diff --git a/src/Form/SelectMany.php b/src/Form/SelectMany.php index 9ca752d..86f4295 100644 --- a/src/Form/SelectMany.php +++ b/src/Form/SelectMany.php @@ -5,7 +5,7 @@ use ctiso\Form\Select; class SelectMany extends Select { - function setValue(mixed $value): void + function setValue($value) { // Установить selected у options if (!is_array($value)) { $value = [$value]; } diff --git a/src/Form/SelectOne.php b/src/Form/SelectOne.php index d631d81..d2dc842 100644 --- a/src/Form/SelectOne.php +++ b/src/Form/SelectOne.php @@ -8,7 +8,7 @@ use ctiso\Form\Select; class SelectOne extends Select { - function setValue($value): void + function setValue($value) { // Установить selected у options $this->value = $value; diff --git a/src/Form/TextArea.php b/src/Form/TextArea.php index 01e60e0..50ce417 100644 --- a/src/Form/TextArea.php +++ b/src/Form/TextArea.php @@ -1,13 +1,13 @@ value = $value; } diff --git a/src/Form/ViewState.php b/src/Form/ViewState.php index b315e6d..c9c6831 100644 --- a/src/Form/ViewState.php +++ b/src/Form/ViewState.php @@ -1,6 +1,6 @@ values[$name] = $value; } - /** - * Возвращает значение - * @param string ...$args - * @return mixed - */ - function get(...$args) + function get($_rest) { + $args = func_get_args(); $result = $this->values; foreach ($args as $name) { if (!isset($result[$name])) { @@ -38,28 +28,16 @@ class ViewState // extends Collection return $result; } - /** - * Сохраняет состояние - * @return string - */ - function saveState(): string + function saveState() { return base64_encode(serialize($this->values)); } - /** - * Восстанавливает состояние - * @param string $value - */ - function restoreState($value): void + function restoreState($value) { $this->values = unserialize(base64_decode($value)); } - /** - * Возвращает состояние - * @return array - */ function export() { return $this->values; diff --git a/src/Functions.php b/src/Functions.php index bd7fead..b547974 100644 --- a/src/Functions.php +++ b/src/Functions.php @@ -1,55 +1,42 @@ */ - protected $params; - /** @var callable */ - protected $fn; +namespace ctiso; - /** - * @param array $params - */ +class right { + protected $params; + protected $fn; + public function __construct($params) { $this->fn = array_shift($params); $this->params = $params; } - - /** - * Применение функции - * @param mixed ...$params - * @return mixed - */ - function apply(...$params) { + + function apply() { + $params = func_get_args(); array_splice($params, count($params), 0, $this->params); return call_user_func_array($this->fn, $params); - } + } } class left { - /** @var array */ - protected $params; - /** @var callable */ + protected $params; protected $fn; - - /** - * @param array $params - */ + public function __construct($params) { $this->fn = array_shift($params); $this->params = $params; } - /** - * Применение функции - * @param mixed ...$params - * @return mixed - */ - function apply(...$params) { + function apply() { + $params = func_get_args(); array_splice ($params, 0, 0, $this->params); return call_user_func_array ($this->fn, $params); } @@ -57,25 +44,16 @@ class left { define('__', '_ARGUMENT_PLACE_'); class partial { - /** @var array */ - protected $params; - /** @var callable */ + protected $params; protected $fn; - - /** - * @param array $params - */ + public function __construct($params) { $this->fn = array_shift($params); $this->params = $params; } - /** - * Применение функции - * @param mixed ...$params - * @return mixed - */ - function apply(...$params) { + function apply() { + $params = func_get_args(); $result = []; $count = count($this->params); for($i = 0, $j = 0; $i < $count; $i++) { @@ -88,28 +66,19 @@ class partial { } return call_user_func_array ($this->fn, $result); } -} +} /** * Композиция функций */ class compose { - /** @var array */ protected $fns; - - /** - * @param array $list - */ function __construct($list) { $this->fns = array_reverse($list); } - /** - * Применение функций - * @param mixed ...$params - * @return mixed - */ - function apply (...$params) { + function apply () { + $params = func_get_args (); $result = call_user_func_array($this->fns[0], $params); $count = count($this->fns); for ($i = 1; $i < $count; $i++) { @@ -121,53 +90,48 @@ class compose { class Functions { - /** - * Частичное применение функции - * @param mixed ...$args - * @return mixed - */ - static function partial(...$args) { - $closure = new partial($args); + static function partial($_rest) { + $closure = new partial(func_get_args()); return [$closure, 'apply']; } /** * Композиция функций - * @param mixed ...$args - * @return mixed + * @param array $_rest + * @return mixed */ - static function compose(...$args) { - $closure = new compose($args); + static function compose($_rest) { + $closure = new compose(func_get_args()); return [$closure, 'apply']; } /** * Карирование справа - * @param mixed ...$args - * @return mixed + * + * @return mixed */ - static function rcurry(...$args) { - $closure = new right($args); + static function rcurry($_rest) { + $closure = new right(func_get_args ()); return [$closure, 'apply']; } /** * Карирование слева - * @param mixed ...$args - * @return mixed + * + * @return mixed */ - static function lcurry(...$args) { - $closure = new left($args); + static function lcurry($_rest) { + $closure = new left(func_get_args ()); return [$closure, 'apply']; } /** * Разделение массива на два по условию * @param mixed $pred Условие по которому разделяется массив - * @param array $lst + * @param array $lst * - * @return mixed + * @return mixed */ static function partition($pred, $lst) { $left = []; @@ -183,33 +147,25 @@ class Functions { } /** - * @deprecated - * @param array $value - * @param string $name + * @param array $value + * @param string $name * * @return mixed */ static function __key($value, $name) { return $value[$name]; } - - /** - * @deprecated - * @param mixed $value - * - * @return mixed - */ + static function identity($value) { return $value; } - + /** - * @deprecated use fn and <=> operator * @param array $a * @param array $b - * @param string|int $key + * @param $key * - * @return int + * @return int */ static function __cmp($a, $b, $key) { if ($a[$key] == $b[$key]) { @@ -217,75 +173,75 @@ class Functions { } return ($a[$key] > $b[$key]) ? -1 : 1; } - - /** - * @deprecated use fn and <=> operator - * @param array $a - * @param array $b - * @param string|int $key - * - * @return int - */ + static function __cmp_less($a, $b, $key) { if ($a[$key] == $b[$key]) { return 0; } return ($a[$key] < $b[$key]) ? -1 : 1; } - - /** - * @param string ...$args - * @return string - */ - static function concat(...$args) { + + // Сравнение по ключу массиве + static function __index($n, $key, $row) { + return ($row[$key] == $n); + } + + static function __div($x, $y) { + return $x / $y; + } + + static function __self($name, $o) { + return call_user_func([$o, $name]); + } + + static function concat(/* $args ...*/) { + $args = func_get_args(); return implode("", $args); } - - /** - * @param mixed $x - * @return bool - */ + static function __empty($x) { return empty($x); } - + + // Отрицание + static function __not($x) { + return !$x; + } + + // Не равно + static function __neq($x, $y) { + return $x != $y; + } + + // Равно + static function __eq($x, $y) { + return $x == $y; + } + /** * Извлекает из многомерого массива значения с определенным ключом * @example key_values('a', array(1 => array('a' => 1, 'b' => 2))) => array(1) * - * @param string $key - * @param list|\ArrayIterator $array * @return mixed */ - static function key_values($key, $array) { + static function key_values($key, $array/*: array|ArrayIterator*/) { $result = []; - + foreach($array as $item) { $result[] = $item[$key]; } return $result; } - - /** - * @param string $key - * @param array|\ArrayIterator $array - * @return array - */ - static function key_values_object($key, $array) { + + static function key_values_object($key, $array/*: array|ArrayIterator*/) { $result = []; - + foreach($array as $item) { $result[] = $item->{$key}; } return $result; } - - /** - * @param string $key - * @param string $value - * @param array>|\ArrayIterator $array - * @return array - */ + static function assoc_key_values($key, $value, $array) { $result = []; foreach ($array as $item) { @@ -293,12 +249,7 @@ class Functions { } return $result; } - - /** - * @param string $key - * @param array>|\ArrayIterator $array - * @return array - */ + static function assoc_key($key, $array) { $result = []; foreach ($array as $item) { @@ -306,44 +257,24 @@ class Functions { } return $result; } - - /** - * Возвращает значение по ключу - * @param string $key - * @param mixed $value - * @param array $array - * @return mixed - */ - static function _get($key, $value, $array) { + + static function _get($key, $value/*: any*/, $array/*: array*/) { 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) { foreach ($array as $name => $item) { - if ($item[$key] == $value) { - return $name; - } + if ($item[$key] == $value) return $name; } - return null; + return null; } - - + + /** * Логическа операция && ко всем элементам массива - * @param array $array Массив - * @param callable $callback Функция * @return bool */ static function every(array $array, $callback) { @@ -354,14 +285,17 @@ class Functions { } return true; } - + /** * Логическа операция || ко всем элементам массива - * @param array $array Массив - * @param callable $callback Функция + * @param array $array + * @param mixed $callback + * * @return mixed */ - static function some(array $array, callable $callback) { + static function some(array $array, $callback) { + assert(is_callable($callback)); + foreach ($array as $key => $value) { if (call_user_func($callback, $value) === true) { return $key; @@ -369,15 +303,10 @@ class Functions { } return false; } - - /** - * Разбивает массив на массивы определенной длины - * @template T - * @param int $length Длина массива - * @param T[] $array Массив - * @return T[][] - */ - static function span(int $length, array $array) { + + static function span($length, array $array) { + assert(is_int($length)); + $result = []; $count = count($array); for($i = 0; $i < $count; $i += $length) { @@ -385,70 +314,54 @@ class Functions { } return $result; } - - /** - * Возвращает значение массива - * @param array $data Массив - * @param string|int $n Ключ - * @return mixed - */ - static function array_ref(array $data, string|int $n) { + + static function array_ref($data, $n) { return $data[$n]; } - - /** - * Вызывает функцию с аргументами - * @param mixed ...$args Аргументы - * @return mixed - */ - static function call(...$args) { + + static function call() { + $args = func_get_args(); $name = array_shift($args); return call_user_func_array($name, $args); } - + /** * Поиск элемента в массиве - * @param callable $cb сравнение с элементом массива + * @param mixed $cb сравнение с элементом массива * @param array $hs массив в котором ищется значение - * @param bool $strict * * @return int|string|null ключ найденого элемента в массиве */ static function array_usearch($cb, array $hs, $strict = false) { foreach($hs as $key => $value) { - if (call_user_func_array($cb, [$value, $key, $strict])) { - return $key; - } + if (call_user_func_array($cb, [$value, $key, $strict])) return $key; } return null; - } - + } + /** * Выбирает все сроки из таблицы с уникальными значениями ключа - * @example - * key_unique_values ('name', array (array ('name' => 1), array ('name' => 2), array ('name' => 1))) - * => array (1, 2) - * * @param string $name Имя ключа * @param array $table Двухмерный массив - * @return array Массив с уникальными значениями ключа + * @example + * key_unique_values ('name', array (array ('name' => 1), array ('name' => 2), array ('name' => 1))) + => array (1, 2) + * @end example */ static function key_unique_values ($name, $table) { - // Ищем уникальные значения для заданного ключа + // Ищем уникальные значения для заданного ключа $keys = []; foreach ($table as $row) { - if (!in_array ($row[$name], $keys)) { + if (!in_array ($row[$name], $keys)) $keys[] = $row[$name]; - } } return $keys; } - + /** * Сортировка двумерного массива по заданному ключу * @param array $array Массив * @param string $key Имя ключа по значению которого будет идти сравнение - * @param callable $fn Функция сравнения * @return array Отсортированный массив */ static function sortOn($array, $key, $fn = '\\ctiso\\Functions::__cmp') { @@ -458,18 +371,16 @@ class Functions { } /** - * Преобразует ключи элементов для многомерного массива - * @param string $key_name Имя ключа - * @param array $array Многомерный массив + * Преобразует ключи элементов для многомерного массива * @return mixed */ - static function hash_key ($key_name, $array) { + static function hash_key ($key_name,$array/*: array */) { $result = []; foreach($array as $value) { - $result[$value[$key_name]] = $value; + $result[$value[$key_name]] = $value; } - return $result; + return $result; } } diff --git a/src/HttpRequest.php b/src/HttpRequest.php index a24e60f..c8c0f7c 100644 --- a/src/HttpRequest.php +++ b/src/HttpRequest.php @@ -4,19 +4,18 @@ * Неверный запрос */ namespace ctiso; - - -use ctiso\Collection; -use ctiso\Session; +use Exception, + ArrayAccess, + ctiso\Collection, + ctiso\Session; /** - * @template T=mixed + * @template T */ class HttpRequest extends Collection { - /** @var Session */ - public $_session; + public $_session; /** * Constructor * Stores "request data" in GPC order. @@ -42,51 +41,21 @@ class HttpRequest extends Collection parent::set('files', $data); } - /** - * @param string $key - * @return Collection - */ function _get($key) { return parent::get($key); } /** - * @param string $key - * @param mixed $default - * @return null|string|array + * @param T $key + * @return mixed */ function get($key, $default = null) { return parent::get('data')->get($key, $default); } - function getString(string $key, string $default = ''): string - { - 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 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 + function session(Session $value = null) { if ($value) { $this->_session = $value; @@ -94,25 +63,19 @@ class HttpRequest extends Collection return $this->_session; } - function set(string $key, mixed $value): void + function set($key, $value/*: any*/) { parent::get('data')->set($key, $value); } - /** - * @param string $key - * @return array - */ - function export(string $key = 'data') + function export($key = 'data') { return parent::get($key)->export(); } - function clear(): void + function clear() { - /** @var Collection */ - $collection = parent::get('data'); - $collection->clear(); + return parent::get('data')->clear(); } /** @@ -122,7 +85,7 @@ class HttpRequest extends Collection * @param string $key * @return mixed */ - public function getRawData(string $var, $key) + public function getRawData($var, $key) { $data = parent::get(strtolower($var)); if ($data) { @@ -131,12 +94,6 @@ class HttpRequest extends Collection return null; } - /** - * @param string $var - * @param string $key - * @param mixed $val - * @return mixed - */ public function setRawData($var, $key, $val) { $data = parent::get(strtolower($var)); @@ -145,34 +102,28 @@ class HttpRequest extends Collection } } - /** - * @param string $name - */ - public function setAction($name): void + public function setAction($name) { $this->setRawData('get', 'action', $name); } - public function getAction(): string + public function getAction() { $result = $this->getRawData('get', 'action'); return ($result) ? $result : 'index'; } - public function isAjax(): bool + public function isAjax() { return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'); } - /** - * @param string $url - */ - public function redirect($url): void { + public function redirect($url) { header('location: ' . $url); exit(); } - static function getProtocol(): string { + static function getProtocol() { return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; } } diff --git a/src/Layout/Blank.php b/src/Layout/Blank.php index 8a0d0ff..f731df3 100644 --- a/src/Layout/Blank.php +++ b/src/Layout/Blank.php @@ -9,9 +9,6 @@ use ctiso\Filter\Filter, class Blank extends Filter { - /** - * @return mixed - */ function execute(HttpRequest $request) { $text = $this->processor->execute($request); diff --git a/src/Layout/Manager.php b/src/Layout/Manager.php index 26537b0..78a4686 100644 --- a/src/Layout/Manager.php +++ b/src/Layout/Manager.php @@ -5,44 +5,37 @@ * Выбор оформления страницы осуществляется если было совпадение с каким либо условием */ namespace ctiso\Layout; - -use ctiso\Filter\Filter; -use ctiso\HttpRequest; +use ctiso\Filter\Filter, + ctiso\Functions, + ctiso\HttpRequest; class Manager extends Filter { - /** - * Массив условий с их макетами - * @var list - */ - protected $condition = []; + // Массив условий с их макетами + protected $condition = array(); /** * Функция которая добавляет условие для проверки параметров $_GET - * @param array|true $get Ассоциативный массив ключей и значений для $_GET - * @param Filter $layout Макет + * @param $get array() | true Ассоциативный массив ключей и значений для $_GET + * + * @example + * addConditionGet(array('module' => 'personal'), 'personal') + * addConditionGet(array('module' => 'login'), 'login') */ - public function addConditionGet($get, Filter $layout): void + public function addConditionGet($get, Filter $layout) { - $this->addCondition(fn(HttpRequest $request) => $this->checkGet($request, $get), $layout); + $this->addCondition(Functions::rcurry([$this, 'checkGet'], $get), $layout); } /** - * Условие для аякс запросов. Тоже самое что и addConditionGet но еще проверяется является ли запрос ajax - * @param array|true $get Ассоциативный массив ключей и значений для $_GET - * @param Filter $layout Макет + * Условие для аякс запросов. Тоже самое что и addConditionGet но еще проверяется является ли запрос ajax */ - public function addConditionXHR($get, Filter $layout): void + public function addConditionXHR($get, Filter $layout) { - $this->addCondition(fn(HttpRequest $request) => $this->checkXHR($request, $get), $layout); + $this->addCondition(Functions::rcurry([$this, 'checkXHR'], $get), $layout); } - /** - * @param HttpRequest $request - * @param array|true $get - * @return bool - */ - public function checkGet($request, $get) + public function checkGet($request/*: HttpRequest*/, $get) { if (is_array($get)) { foreach ($get as $key => $value) { @@ -54,44 +47,37 @@ class Manager extends Filter return true; } - /** - * @param HttpRequest $request - * @param array|true $get - * @return bool - */ - public function checkXHR($request, $get): bool + public function checkXHR($request/*: HttpRequest*/, $get) { return $request->isAjax() && $this->checkGet($request, $get); } /** * Добавляет условие в общем виде - * @param callable $get Функция - * @param Filter $layout Макет + * @parma $get function(HttpRequest) Функция + * @parma $layout Layout Макет */ - public function addCondition($get, Filter $layout): void - { + public function addCondition($get, Filter $layout) + { $this->condition [] = [$get, $layout]; } /** * Выбирает и применяет макет для страницы - * @return mixed */ - public function execute(HttpRequest $request): mixed + public function execute(HttpRequest $request) { foreach ($this->condition as $condition) { if (call_user_func($condition[0], $request)) { $layout = $condition[1]; $view = $layout->execute($request); if (is_object($view)) { - return $view->execute(); + return $view->render(); } else { return $view; } } } - return ''; } } diff --git a/src/Mail.php b/src/Mail.php index 848c645..7f3930d 100644 --- a/src/Mail.php +++ b/src/Mail.php @@ -4,39 +4,26 @@ * Класс для работы с почтой * http://en.wikipedia.org/wiki/MIME */ - namespace ctiso; - use ctiso\Path, Exception; class Mail { - /** @var string */ public $_from; - /** @var string */ public $_to; - /** @var string */ public $_subject; - /** @var string */ public $content; - /** @var string */ public $copy; - /** @var string */ - private $encoding; - /** @var string */ + private $encoding; private $_notify = null; - /** @var array */ - protected $attachment = array(); - /** @var string */ + protected $attachment = array (); protected $uniqid; - /** @var string */ protected $type = "text/plain"; - function __construct() - { + function __construct() { $this->setEncoding("UTF-8"); $this->uniqid = strtoupper(uniqid((string)time())); // Идентефикатор разделителя } @@ -44,35 +31,32 @@ class Mail /** * Установка отправителя */ - function from(string $name): void + function from($name) { - // filter_var($name, FILTER_VALIDATE_EMAIL); $this->_from = $name; - } + } /** * Установка получателя */ - function to(string $name): void + function to($name) // recipient { $this->_to = $name; } - /** - * @param string $name - */ - function replyTo($name): void - {} + function replyTo($name) // recipient + { + } /** * Установка получателей копии */ - function copy(string $name): void + function copy($name) // recipient cc { $this->copy = $name; } - - function notify(string $notify): void + + function notify($notify) { $this->_notify = $notify; } @@ -80,70 +64,59 @@ class Mail /** * Тема письма */ - function subject(string $subject): void + function subject($subject) { - $this->_subject = $subject; + $this->_subject = $subject; } /** * Текст письма */ - function setContent(string $text): void + function setContent($text) { $this->content = $text; } - + /** * Кодировка текста в письме */ - function setEncoding(string $encoding): void + function setEncoding($encoding) { $this->encoding = $encoding; } /** * Добавление вложения из файла - * @param string $filename - * @param string|false $name */ - function addAttachment(string $filename, $name = false): void + function addAttachment($filename, $name = false) { - if (file_exists($filename)) { + assert(is_string($filename)); + + if(file_exists($filename)) { // assert ?? $file = fopen($filename, "rb"); if (is_resource($file)) { - $size = filesize($filename); - if ($size !== false && $size > 0) { - $data = fread($file, $size); - $this->attachment[] = ($name) ? [$data, $name] : [$data, basename($filename)]; - } + $data = fread($file, filesize($filename)); + $this->attachment [] = ($name) ? [$data, $name] : [$data, basename($filename)]; } } } - /** - * Установка типа содержимого - * @param string $type - */ - function setType($type): void + function setType($type) { $this->type = $type; } /** * Добавление вложения из строки с указанием имени файла - * @param string $data - * @param string $name */ - function addAttachmentRaw($data, string $name): void + function addAttachmentRaw($data, $name) { - $this->attachment[] = [$data, $name]; + assert(is_string($name)); + + $this->attachment [] = [$data, $name]; } - /** - * @param string $var - * @param string $val - */ - function quote($var, $val): string + function quote($var, $val) { return ";" . PHP_EOL . "\t" . $var . "=\"" . $val . "\""; } @@ -151,40 +124,36 @@ class Mail /** * Общий формат тегов MIME * @see http://tools.ietf.org/html/rfc2045 - * - * @param string $name - * @param string $value - * @param array $args */ - function mimeTag($name, $value, array $args = []): string + function mimeTag($name, $value, array $args = []) { - assert(is_string($name)); - assert(is_string($value)); + assert (is_string($name)); + assert (is_string($value)); - return $name . ": " . $value . implode("", array_map([$this, 'quote'], array_keys($args), array_values($args))) . PHP_EOL; + return $name . ": " . $value . implode("", array_map([$this, 'quote'], array_keys($args), array_values($args))) . PHP_EOL; } /** - * - * @see http://tools.ietf.org/html/rfc2047 + * + * @see http://tools.ietf.org/html/rfc2047 */ - function encodedWord(string $text, string $encoding = 'B'): string + function encodedWord($text, $encoding = 'B') { - return "=?{$this->encoding}?$encoding?" . base64_encode($text) . "?="; + return "=?{$this->encoding}?$encoding?".base64_encode($text)."?="; } /** * Тело сообщения */ - function getMessage(): string + function getMessage() { - $message = "--" . $this->uniqid . PHP_EOL; + $message = "--".$this->uniqid . PHP_EOL; $message .= $this->mimeTag("Content-Type", $this->type, ['charset' => $this->encoding]); $message .= $this->mimeTag("Content-Transfer-Encoding", "8bit"); $message .= PHP_EOL . $this->content . PHP_EOL . PHP_EOL; /* - * Вложения + * Вложения * http://tools.ietf.org/html/rfc2046#section-5.1.3 */ foreach ($this->attachment as $value) { @@ -202,7 +171,7 @@ class Mail /** * Заголовок сообщения */ - function getHeader(): string + function getHeader() { $head = $this->mimeTag("MIME-Version", "1.0"); $head .= $this->mimeTag("From", $this->_from); @@ -219,7 +188,7 @@ class Mail return $head; } - function getSubject(): string + function getSubject() { return $this->encodedWord($this->_subject); } @@ -227,28 +196,27 @@ class Mail /** * Вывод строки для сохранения в формате .eml */ - function eml(): string + function eml() { return "To: " . $this->_to . PHP_EOL . "Subject: {$this->getSubject()}" . PHP_EOL . $this->getHeader() . $this->getMessage(); } /** - * Отправка почты + * Отправка почты */ - function send(): bool + function send() { $result = mail($this->_to, $this->getSubject(), $this->getMessage(), $this->getHeader()); - if (! $result) { + if(! $result) { file_put_contents(Path::resolveFile("send.eml"), $this->eml()); - throw new Exception('Невозможно отправить почту'); + throw new Exception('Невозможно отправить почту'); } return $result; } - function clear(): void - { + function clear() { foreach ($this->attachment as $key => &$value) { - unset($this->attachment[$key]); + unset($this->attachment[$key]); } $this->attachment = []; } diff --git a/src/MailAlt.php b/src/MailAlt.php index c9cae8a..7a42a7a 100644 --- a/src/MailAlt.php +++ b/src/MailAlt.php @@ -5,11 +5,8 @@ use PHPMailer\PHPMailer\PHPMailer; class MailAlt { - /** @var PHPMailer */ public $mailer; - /** @var string */ public $_notify; - /** @var string */ public $encoding; function __construct() { @@ -20,65 +17,62 @@ class MailAlt /** * Установка отправителя */ - function from(string $name): void + function from($name) { $this->mailer->setFrom($name); - } + } /** * Установка получателя */ - function to(string $name): void // recipient + function to($name) // recipient { $this->mailer->addAddress($name); } - function replyTo(string $name): void // recipient + function replyTo($name) // recipient { - $this->mailer->addReplyTo($name); + $this->mailer->AddReplyTo($name); } /** * Установка получателей копии - * @param string $name */ - function copy(string $name): void // recipient cc + function copy($name) // recipient cc { $this->mailer->addCC($name); } - - function notify(string $notify): void + + function notify($notify) { $this->_notify = $notify; } /** * Тема письма - * @param string $subject */ - function subject(string $subject): void + function subject($subject/*: string*/) { - $this->mailer->Subject = $subject; + $this->mailer->Subject = $subject; } /** * Текст письма - * @param string $text */ - function setContent(string $text): void + function setContent($text) { $this->mailer->Body = $text; } - function setType(string $text): void + function setType($text) { $this->mailer->isHTML($text == 'text/html'); } - + /** * Кодировка текста в письме */ - function setEncoding(string $encoding): void + function setEncoding($encoding) { $this->encoding = $encoding; } @@ -86,20 +80,20 @@ class MailAlt /** * Добавление вложения из файла */ - function addAttachment(string $filename, ?string $name = null): void + function addAttachment($filename, $name = null) { $this->mailer->addAttachment($filename, $name); } /** - * Отправка почты + * Отправка почты */ - function send(): bool + function send() { return $this->mailer->send(); } - function eml(): string { + function eml() { return $this->mailer->getSentMIMEMessage(); } } diff --git a/src/Model/BaseMapper.php b/src/Model/BaseMapper.php index 37831a0..7e55e72 100644 --- a/src/Model/BaseMapper.php +++ b/src/Model/BaseMapper.php @@ -2,9 +2,6 @@ namespace ctiso\Model; -/** - * @property \ctiso\Database $db - */ abstract class BaseMapper { function getAllAsOptions(): array { return []; diff --git a/src/Model/Factory.php b/src/Model/Factory.php index 6f6e840..ab560e3 100644 --- a/src/Model/Factory.php +++ b/src/Model/Factory.php @@ -1,21 +1,17 @@ db = $db; $this->config = $config; diff --git a/src/Numbers.php b/src/Numbers.php index 5d92be2..2494706 100644 --- a/src/Numbers.php +++ b/src/Numbers.php @@ -4,27 +4,24 @@ namespace ctiso; class Numbers { - static function roman(float $i): float + static function roman($i) { return 0; } - static function decimal(float $i): float + static function decimal($i) { return $i; } - /** - * @param array $array - * @return array - */ - static function prefix(callable $prefix, array $array) + static function prefix($prefix, array $array, $key = false) { $result = []; $count = count($array); for ($i = 0; $i < $count; $i++) { - $result [] = call_user_func($prefix, $i + 1) . '. ' . $array[$i]; + $result [] = call_user_func($prefix, $i + 1) . '. ' . $array[$i]; } return $result; } } + diff --git a/src/Path.php b/src/Path.php index 55a0022..e9d3c6b 100644 --- a/src/Path.php +++ b/src/Path.php @@ -12,16 +12,14 @@ class Path { const SEPARATOR = "/"; - protected array $path = []; - protected array $url = []; - protected bool $absolute = false; + protected $path = array(); + protected $url = array(); + protected $absolute = false; - /** - * @param string $path Путь (Тип указан в doccomments т.к откудато приходит null) - */ public function __construct($path = '') { - $this->url = parse_url($path) ?: []; + //assert(is_string($path)); + $this->url = parse_url($path ?? ''); if (isset($this->url['path'])) { $path = $this->url['path']; @@ -38,16 +36,16 @@ class Path } } - static function factory(string $path): Path { + static function factory($path) { return new Path($path); } - public function getParts(): array + public function getParts() { return $this->path; } - public static function normalize(string $pathName): string + public static function normalize($pathName) { $path = new Path($pathName); return $path->__toString(); @@ -55,12 +53,12 @@ class Path /** * Базовое имя - * @param string $path - * @return string + * @param $path + * @return mixed */ public static function basename($path) { - $list = preg_split('#\\\\|/#s', $path) ?: ['']; + $list = preg_split('#\\\\|/#s', $path); return end($list); } @@ -75,12 +73,6 @@ class Path return pathinfo($fileName, PATHINFO_EXTENSION); } - /** - * Проверяет расширение файла - * @param string $fileName Полное имя файла - * @param string|array $extension Расширение файла - * @return bool - */ static function isType($fileName, $extension) { if (is_array($extension)) { @@ -92,11 +84,17 @@ class Path /** * Полное имя файла без расширения + * + * @param string $fileName Имя файла + * + * @return string */ - static function skipExtension(string $fileName): string + static function skipExtension($fileName) { + assert(is_string($fileName)); + $path = pathinfo($fileName); - if (!isset($path['dirname']) || $path['dirname'] === ".") { + if ($path['dirname'] === ".") { return $path['filename']; } else { return self::join($path['dirname'], $path['filename']); @@ -107,10 +105,13 @@ class Path * Возвращает имя файла без расширения * * @param string $fileName Полное имя файла + * * @return string */ - static function getFileName(string $fileName) + static function getFileName($fileName) { + assert(is_string($fileName)); + return pathinfo($fileName, PATHINFO_FILENAME); } @@ -120,18 +121,20 @@ class Path * Преобразует строку пути в массив * * @param string $path Путь - * @return list + * + * @return array */ - public static function listFromString(string $path): array + public static function listFromString($path) { + assert(is_string($path)); + $list = preg_split('#\\\\|/#s', $path); - return $list ?: []; + + return $list; } /** * Преобразует относительный путь в абсолютный - * @param array $path Путь - * @return array */ public static function optimize($path) // { @@ -151,10 +154,8 @@ class Path return $result; } - /** - * Сравнение двух путей на равентство - */ - public function equal(Path $path): bool + // Сравнение двух путей на равентство + public function equal($path/*: Path*/) { $count = count($this->path); if ($count == count($path->path)) { @@ -168,29 +169,27 @@ class Path return false; } - /** - * Преобразует путь в строку - * @param array{ host?: string, path?: string, query?: string, fragment?: string, scheme?: string, user?: string, pass?: string, port?: int} $path Путь - */ - public static function makeUrl($path): string + public static function makeUrl($path) { - $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'] : '') . '@' : ''; + $slash = (isset($path['host']) && (strlen($path['path']) > 0) && ($path['path'][0] != '/')) ? '/' : ''; - $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; + 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'] : ''); } /** * Преобразует путь в строку + * + * @return string */ - public function __toString(): string + public function __toString() { $result = (($this->absolute) ? '/' : '') . implode(self::SEPARATOR, $this->path); $this->url['path'] = $result; @@ -200,9 +199,11 @@ class Path /** * Проверяет является ли папка родительской для другой папки * - * @param Path $path + * @parma Path $path + * + * @return boolean */ - public function isParent($path): bool + public function isParent($path/*: Path*/) { if (isset($this->url['host']) && isset($path->url['host']) && ($this->url['host'] != $path->url['host'])) return false; @@ -219,7 +220,7 @@ class Path return false; } - public static function _isParent(string $path1, string $path2): bool + public static function _isParent($path1, $path2) { $path = new Path($path1); return $path->isParent(new Path($path2)); @@ -229,6 +230,7 @@ class Path * Находит путь относительно текущего путя * * @param string $name Полный путь к файлу + * * @return string Относительный путь к файлу */ public function relPath($name) @@ -243,12 +245,7 @@ class Path return $path->__toString(); } - /** - * Вычисляет относительный путь в виде строки - * @param string $rpath Путь относительно которого вычисляется относительный путь - * @param string $lpath Путь к которому вычисляется относительный путь - * @return string Относительный путь - */ + // Вычисляет относительный путь в виде строки static function relative($rpath, $lpath) { // Нужно проверять диск!! $self = new Path($rpath); @@ -274,10 +271,6 @@ class Path return implode("/", $result); } - /** - * @param string $path - * @return string - */ public function append($path) { $base = $this->__toString(); @@ -287,10 +280,11 @@ class Path /** * Обьединяет строки в Path соединяя необходимым разделителем * fixme не обрабатывает параметры урла, решение Path::join(SITE_WWW_PATH) . '?param=pampam' - * @param string ...$args * @return string */ - static function fromJoin(...$args) { + static function fromJoin($_rest) { + $args = func_get_args(); + $result = []; $parts0 = new Path(array_shift($args)); $result [] = $parts0->getParts(); @@ -308,30 +302,29 @@ class Path /** * Обьединяет строки в строку пути соединяя необходимым разделителем * fixme не обрабатывает параметры урла, решение Path::join(SITE_WWW_PATH) . '?param=pampam' - * @param string ...$args * @return string */ - static function join(...$args) + static function join($_rest) { + $args = func_get_args(); $path = call_user_func_array([self::class, "fromJoin"], $args); return self::makeUrl($path->url); } // Проверка структуры имени файла - static function checkName(string $name, string $extension): bool + static function checkName($name, $extension) { return (strlen(pathinfo($name, PATHINFO_FILENAME)) > 0) && (pathinfo($name, PATHINFO_EXTENSION) == $extension); } - static function isCharName(string $char): bool + static function isCharName($char) { $ch = ord($char); return ((($ch >= ord('a')) && ($ch <= ord('z'))) || (strpos('-._', $char) !== false) || (($ch >= ord('0')) && ($ch <= ord('9')))); } // Проверка имени файла - static function isName(string $name): bool - { + static function isName($name) { if (strlen(trim($name)) == 0) { return false; } @@ -343,7 +336,7 @@ class Path return true; } - public function isAbsolute(): bool + public function isAbsolute() { return $this->absolute; } @@ -352,6 +345,7 @@ class Path * Подбирает новое временное имя для файла * * @param string $dst Предпологаемое имя файла + * * @return string Новое имя файла */ static function resolveFile($dst) @@ -371,12 +365,12 @@ class Path /** * Список файлов в директории * - * @param ?string[] $allow массив расширений для файлов - * @param string[] $ignore массив имен пааок которые не нужно обрабатывать + * @param array $allow массив расширений для файлов + * @param array $ignore массив имен пааок которые не нужно обрабатывать * - * @return string[] + * @returnarray */ - public function getContent(?array $allow = null, array $ignore = []) + public function getContent($allow = null, $ignore = []) { $ignore = array_merge([".", ".."], $ignore); return self::fileList($this->__toString(), $allow, $ignore); @@ -385,12 +379,12 @@ class Path /** * Обьединяет строки в путь соединяя необходимым разделителем * - * @param ?string[] $allow массив расширений разрешеных для файлов - * @param string[] $ignore массив имен папок которые не нужно обрабатывать + * @param array $allow массив расширений разрешеных для файлов + * @param array $ignore массив имен пааок которые не нужно обрабатывать * - * @return string[] + * @return array */ - function getContentRec(?array $allow = null, array $ignore = []) + function getContentRec($allow = null, $ignore = []) { $result = []; $ignore = array_merge([".", ".."], $ignore); @@ -398,16 +392,8 @@ class Path return $result; } - /** - * Список файлов в директории - * - * @param string $base Базовый путь - * @param ?string[] $allow массив расширений для файлов - * @param string[] $ignore массив имен папок которые не нужно обрабатывать - * - * @return string[] - */ - protected static function fileList(string $base, ?array &$allow, array &$ignore): array + // Использовать SPL ??? + protected static function fileList($base, &$allow, &$ignore) { if ($base == '') $base = '.'; $result = []; @@ -432,7 +418,7 @@ class Path return $result; } - protected static function fileListAll(array &$result, string $base, ?array &$allow, array &$ignore): void + protected static function fileListAll(&$result, $base, &$allow, &$ignore) { $files = self::fileList($base, $allow, $ignore); foreach ($files as $name) { @@ -452,7 +438,7 @@ class Path * * @return void */ - static function prepare(string $dst, bool $filename = true) + static function prepare($dst, $filename = true) { if ($filename) { $path_dst = pathinfo($dst, PATHINFO_DIRNAME); @@ -473,7 +459,7 @@ class Path * * @return string */ - static function updateRelativePathOnFileMove(string $relativePath, string $srcFile, string $dstFile) { + static function updateRelativePathOnFileMove($relativePath, $srcFile, $dstFile) { $srcToDst = self::relative($srcFile, $dstFile); return self::normalize(self::join($srcToDst, $relativePath)); } @@ -488,7 +474,7 @@ class Path * * @return string */ - static function updateRelativePathOnDirectoryMove(string $relativePath, string $fileDir, string $srcDir, string $dstDir) { + static function updateRelativePathOnDirectoryMove($relativePath, $fileDir, $srcDir, $dstDir) { $relativePath = self::normalize($relativePath); $fileDir = self::normalize($fileDir); $srcDir = self::normalize($srcDir); diff --git a/src/Primitive.php b/src/Primitive.php index ce1482a..283d7e1 100644 --- a/src/Primitive.php +++ b/src/Primitive.php @@ -3,74 +3,51 @@ /** * Преобразование типов !!! Пересмотреть использование классов!! * Класс преобразования типа значения поля класса в тип поля таблицы + * @package system */ namespace ctiso; class Primitive { - /** - * @param mixed $value - */ - public static function to_varchar($value): string + // varchar + public static function to_varchar($value) { return ((string) $value); } - /** - * @param mixed $value - * @return mixed - */ public static function from_varchar($value) { return $value; } - /** - * @param mixed $value - */ - public static function to_bool($value): bool + // int + public static function to_bool($value) { - return filter_var($value, FILTER_VALIDATE_BOOLEAN); + return filter_var($value, FILTER_VALIDATE_BOOLEAN);//(int)((bool) $value); } - /** - * Преобразование значения в булевое значение - * @param string $value - * @return bool - */ - public static function from_bool($value): bool + public static function from_bool($value) { return ((bool) $value); } - /** - * Преобразование значения в целое число - * @param string $value - * @return int - */ - public static function to_int($value): int + // int + public static function to_int($value) { return ((int) $value); } - /** - * @param mixed $value - */ - public static function from_int($value): string + public static function from_int($value) { return ((string) $value); } - - /** - * Преобразование даты dd/mm/yy в unix timestamp - * @param string $value - * @return int - */ - public static function to_date($value): int + + // date + public static function to_date($value) { $result = 0; $tmp = explode("/", $value ?? '', 3); - + if (count($tmp) != 3) { return $result; } @@ -81,39 +58,29 @@ class Primitive { if ($month != 0 && $day != 0 && $year != 0) { if (checkdate($month, $day, $year)) { - return mktime(0, 0, 0, $month, $day, $year) ?: 0; + return mktime(0, 0, 0, $month, $day, $year); } else { return 0; } } - + return $result; } - /** - * Преобразование даты ISO 8601 в unix timestamp - * @param string $value - * @return int - */ - public static function to_datetime($value): int + public static function to_datetime($value) { $result = 0; $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]) ?: 0; + $result = mktime((int)$tmp[4], (int)$tmp[5], 0, (int)$tmp[2], (int)$tmp[3], (int)$tmp[1]); } } return $result; } - /** - * Преобразование даты в формат dd/mm/yyyy - * @param int $value - * @return string - */ - public static function from_date($value): string + public static function from_date($value) { if ($value > 0) { return date("d/m/Y", $value); @@ -121,12 +88,7 @@ class Primitive { return ''; } - /** - * Преобразование даты в формат ISO 8601 - * @param int $value - * @return string - */ - public static function from_datetime($value): string + public static function from_datetime($value) { if ($value > 0) { return date("Y-m-d\TH:i\Z", $value); @@ -135,45 +97,24 @@ class Primitive { } - /** - * @deprecated - * @template T - * @param T $value - * @return T - */ + // secure public static function to_secure($value) { // Значение приабразуется во время сохранения в базе данных return $value; } - /** - * @deprecated - * @template T - * @param T $value - * @return T - */ public static function from_secure($value) { return $value; } - /** - * Преобразование значения в массив - * @param mixed $value - * @return array - */ - public static function to_array($value) + // array + public static function to_array($value) { return (is_array($value)) ? $value : []; } - /** - * @deprecated - * @template T - * @param T $value - * @return T - */ public static function from_array($value) { return $value; diff --git a/src/Process.php b/src/Process.php index ce1c177..a1728f5 100644 --- a/src/Process.php +++ b/src/Process.php @@ -2,46 +2,28 @@ namespace ctiso; -/** - * str_getcsv - * @param string $input - * @param string $delimiter - * @param string $enclosure - * @param string $escape - * @return array|false - */ -function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") -{ - $fiveMBs = 1024; - $fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+'); - $data = []; - if (is_resource($fp)) { - fputs($fp, $input); - rewind($fp); - $data = fgetcsv($fp, 1000, $delimiter, $enclosure); - fclose($fp); - } - return $data; +if (!function_exists('str_getcsv')) { + function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") { + $fiveMBs = 1024; + $fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+'); + $data = ''; + if (is_resource($fp)) { + fputs($fp, $input); + rewind($fp); + $data = fgetcsv($fp, 1000, $delimiter, $enclosure); + fclose($fp); + } + return $data; + } } - -/** - * process_exists - * @param int $pid - * @return bool - */ -function process_exists($pid) -{ +function process_exists($pid) { if (PHP_OS == 'WINNT') { - $content = shell_exec("tasklist.exe /NH /FO CSV"); - if (!$content) { - return false; - } - $processes = explode("\n", $content); - foreach ($processes as $process) { + $processes = explode("\n", shell_exec("tasklist.exe /NH /FO CSV")); + foreach($processes as $process) { if ($process != "") { $csv = str_getcsv($process); - if ($csv && $pid == $csv[1]) return true; + if ($pid == $csv[1]) return true; } } return false; @@ -50,19 +32,13 @@ function process_exists($pid) } } -/** - * create_single_proces - * @param string $fpid - * @param callable $fn - * @return int - */ -function create_single_process($fpid, $fn) -{ +function create_single_proces($fpid, $fn) { if (file_exists($fpid)) { - if (process_exists((int)file_get_contents($fpid))) { - return 1; + print_r(realpath($fpid)); + if (process_exists(file_get_contents($fpid))) { + return 1; } - } + } call_user_func($fn); return 0; } diff --git a/src/Registry.php b/src/Registry.php index 5eda214..21e08eb 100644 --- a/src/Registry.php +++ b/src/Registry.php @@ -5,58 +5,47 @@ use ctiso\File, Exception; class Registry { - /** @var array */ - private array $namespace = []; + public $namespace = []; + public $data; - function importFile(string $namespace, ?string $filePath = null): void { + function importFile($namespace, $filePath = null) { $data = json_decode(File::getContents($filePath), true); $data['_file'] = $filePath; $this->namespace[$namespace] = [ 'path' => $filePath, 'data' => $data - ]; + ]; } - function importArray(string $namespace, array $data = []): void { + function importArray($namespace, $data = []) { if (isset($this->namespace[$namespace])) { $data = array_merge($this->namespace[$namespace]['data'], $data); - } + } $this->namespace[$namespace] = [ 'path' => null, 'data' => $data - ]; + ]; } - /** - * @param string $ns - * @param string $key - * @return mixed - * @throws Exception - */ - public function get(string $ns, string $key) { + public function get($ns, $key) { if (isset($this->namespace[$ns]['data'][$key])) { return $this->namespace[$ns]['data'][$key]; } throw new Exception('Unknown key ' . $ns . '::' . $key); } - /** - * @param string $ns - * @param string $key - * @return mixed|null - */ - public function getOpt(string $ns, string $key) { + public function getOpt($ns, $key) { if (isset($this->namespace[$ns]['data'][$key])) { return $this->namespace[$ns]['data'][$key]; } return null; } - public function has(string $ns, string $key): bool { + public function has($ns, $key) { return isset($this->namespace[$ns]['data'][$key]); } - function set(string $ns, string $key, mixed $value): void { + function set($ns, $key, $value) { $this->namespace[$ns]['data'][$key] = $value; } } diff --git a/src/Role/User.php b/src/Role/User.php index 78f2923..3f5728e 100644 --- a/src/Role/User.php +++ b/src/Role/User.php @@ -1,47 +1,41 @@ db = $db; $this->groups = $groups; } - public function setDB(Database $db): void { + public function setDB(Database $db) { $this->db = $db; } - public function getName(): string { + public function getName() { return $this->name; } - /** - * @return bool - */ function isLogged() { return \ctiso\Filter\Authorization::isLogged(); } - public function getUserByQuery(Statement $stmt): ?PDOStatement + + public function getUserByQuery(Statement $stmt) { $result = $stmt->executeQuery(); if ($result->next()) { @@ -50,38 +44,32 @@ class User implements UserInterface $this->id = $result->getInt('id_user'); $this->password = $result->getString('password'); $this->fullname = implode(' ', [ - $result->getString('surname'), - $result->getString('firstname'), + $result->getString('surname'), + $result->getString('firstname'), $result->getString('patronymic')]); return $result; } return null; } - /** - * @param PDOStatement $result - * @return string - */ function getUserPassword($result) { return $result->get('password'); } - public function getUserByLogin(string $login): ?PDOStatement + public function getUserByLogin($login) { $stmt = $this->db->prepareStatement("SELECT * FROM users WHERE login = ?"); $stmt->setString(1, $login); $result = $this->getUserByQuery($stmt); - if ($result) { + if ($result) { $time = time(); $id = $this->id; - $this->db->executeQuery( - "UPDATE users SET lasttime = :time WHERE id_user = :id", - ['time' => $time, 'id' => $id]); // Время входа + $this->db->executeQuery("UPDATE users SET lasttime = $time WHERE id_user = $id"); // Время входа } return $result; } - public function getUserById(int $id): ?PDOStatement + public function getUserById($id) { $stmt = $this->db->prepareStatement("SELECT * FROM users WHERE id_user = ?"); $stmt->setInt(1, $_SESSION ['access']); @@ -89,37 +77,25 @@ class User implements UserInterface if ($result) { $lasttime = $result->getInt('lasttime'); $time = time(); - if ($time - $lasttime > self::LIFE_TIME) return null; // Вышло время сессии + if ($time - $lasttime > self::LIFE_TIME) return null; // Вышло время сессии $id = $this->id; } return $result; } - /** - * @param string $random - * @param PDOStatement $result - * @return PDOStatement|bool - */ - 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'), - 'sid' => $random - ]); + function setSID($random, $result) { + return $this->db->executeQuery("UPDATE users SET sid = '$random', trie_count = 0 WHERE id_user = " . $result->getInt('id_user')); } - function resetTries(string $login): void { + function resetTries($login) { $this->db->executeQuery( "UPDATE users SET trie_count = :count WHERE login = :login", ['count' => 0, 'login' => $login] ); } - function updateTries(string $login): void { + function updateTries($login) { $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/Role/UserInterface.php b/src/Role/UserInterface.php index a69d9b7..295e4ca 100644 --- a/src/Role/UserInterface.php +++ b/src/Role/UserInterface.php @@ -2,18 +2,11 @@ namespace ctiso\Role; use ctiso\Database\Statement; -use ctiso\Database\PDOStatement; interface UserInterface { - function getUserByQuery(Statement $stmt): ?PDOStatement; - function getUserByLogin(string $login): ?PDOStatement; - function getUserById(int $id): ?PDOStatement; - function getName(): string; - - /** - * @param string $random - * @param PDOStatement $result - * @return PDOStatement|bool - */ - function setSID(string $random, $result); + function getUserByQuery(Statement $stmt); + function getUserByLogin($login); + function getUserById($id); + function getName(); + function setSID($random, $result); } \ No newline at end of file diff --git a/src/Security.php b/src/Security.php index fa9bea0..ea25461 100644 --- a/src/Security.php +++ b/src/Security.php @@ -3,7 +3,7 @@ namespace ctiso; class Security { - static function generatePassword(int $length = 9, int $strength = 0): string { + static function generatePassword($length = 9, $strength = 0) { $vowels = 'aeuy'; $consonants = 'bdghjmnpqrstvz'; if ($strength & 1) { @@ -18,7 +18,7 @@ class Security { if ($strength & 8) { $consonants .= '@#$%'; } - + $password = ''; $alt = time() % 2; for ($i = 0; $i < $length; $i++) { diff --git a/src/Session.php b/src/Session.php index ff2bba6..6eab118 100644 --- a/src/Session.php +++ b/src/Session.php @@ -2,9 +2,9 @@ namespace ctiso; -class Session +class Session { - function get(string $key): mixed + function get($key) { if (isset($_SESSION[$key])) { return $_SESSION[$key]; @@ -12,27 +12,26 @@ class Session return null; } - function set(string|array $key, mixed $value): void + function set($key, $value) { if (is_array($key)) { - $className = get_class($key[0]); - $_SESSION[strtolower($className ?: '')][$key[1]] = $value; + $_SESSION[strtolower(get_class($key[0]))][$key[1]] = $value; } else { $_SESSION[$key] = $value; } } - function clean(string $key): void + function clean($key) { unset($_SESSION[$key]); } - function start(): void + function start() { @session_start(); } - function stop(): void + function stop() { session_destroy(); } diff --git a/src/Settings.php b/src/Settings.php index d6958c3..1f38299 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -5,30 +5,21 @@ use ctiso\File, Exception; /** - * Класс реестра + * Класс реестра * Реестр организован как ассоциативный многомерный массив * array( 'name1' => parameters1, 'name2' => parameters1, ... ) * - * name1, name2 ... - Имена модулей + * name1, name2 ... - Имена модулей * parameters1, parameters1 - Массивы с параметрами модуля * Имя необходимо чтобы потом легко было удалить ненужные ветки дерева */ class Settings { - /** @var array */ public $data = []; - /** @var string */ protected $file; - /** @var string */ protected $format = 'php'; - /** @var bool */ protected $is_read = false; - /** - * Конструктор - * @param string $file Путь к файлу - * @param 'php'|'json'|false $format Формат файла - */ public function __construct ($file = null, $format = false) { $fileFormat = ['theme' => 'json']; @@ -42,7 +33,7 @@ class Settings * Чтение настроек из файла * @return Boolean */ - public function read(): bool + public function read() { if (!file_exists ($this->file)) { $this->is_read = true; @@ -67,19 +58,18 @@ class Settings /** * Запись ключа в реестр (Реестр это многомерный массив) - * @param array $key Путь к значению ключа - * @param mixed $value Значение - * @return void */ - public function writeKey(array $key, $value) + public function writeKey(array $key, $value) { +// assert(count($key) >= 1); $data = &$this->data; while (count($key) > 1) { $name = array_shift($key); $data = &$data[$name]; - } - + } + +// assert(count($key) == 1); $name = array_shift($key); if (is_array($value)) { if (!isset($data[$name])) { @@ -93,10 +83,8 @@ class Settings /** * Обновляет массив в соответствии со значением - * @param array $data Массив - * @param mixed $value Значение */ - protected function merge(array &$data, $value): void + protected function merge(array &$data, $value) { foreach ($value as $key => $subvalue) { if (is_array($subvalue)) { @@ -109,23 +97,17 @@ class Settings } /** - * Чтение ключа из реестра + * Чтение ключа из реестра * @param array $key Путь к значению ключа - * @return mixed */ public function readKey(array $key) { return $this->readKeyData($key, $this->data); } - /** - * Чтение ключа из реестра - * @param array $key Путь к значению ключа - * @param array $data - * @return mixed - */ protected function readKeyData(array $key, $data) { +// assert(count($key) >= 1); while (count($key) > 1) { $name = array_shift($key); if (isset($data[$name])) { @@ -133,8 +115,9 @@ class Settings } else { return null; } - } - + } + +// assert(count($key) == 1); $name = array_shift($key); if (isset($data[$name])) { return $data[$name]; @@ -146,10 +129,9 @@ class Settings /** * Чтение ключа из реестра (Собирает все ключи с определенным значением во всех модулях) * @param mixed $key Путь к значению ключа внутри модуля - * @return array */ public function readKeyList(...$key) - { + { $result = []; foreach ($this->data as $name => $value) { $output = $this->readKeyData($key, $value); @@ -160,17 +142,13 @@ class Settings return $result; } - /** - * Удаление ключа из реестра - * @param string $name Имя ключа - */ - public function removeKey($name): void + public function removeKey($name) { unset($this->data[$name]); } - public function removeNode(array $key): void + public function removeNode(array $key) { $data = &$this->data; while (count($key) > 1) { @@ -180,11 +158,11 @@ class Settings $name = array_shift($key); unset($data[$name]); } - + /** * Запись настроек в файл (Может переименовать в store) * - * @param string $file + * @param File $file * @return void */ public function write($file = null) @@ -199,49 +177,28 @@ class Settings $result = var_export($this->data, true); $result = ""; } - file_put_contents(($file) ? $file : $this->file, $result); + file_put_contents (($file) ? $file : $this->file, $result); } - /** - * Установка значения ключа - * @param string $key Ключ - * @param mixed $value Значение - */ - public function set($key, $value): void { + public function set($key, $value) { $this->data[$key] = $value; } - /** - * Получение значения ключа - * @param string $key Ключ - * @param mixed $default Значение по умолчанию - * @return mixed - */ public function get($key, $default = null) { return isset($this->data[$key]) && $this->data[$key] != '' ? $this->data[$key] : $default; } - /** - * Получение всех данных - * @return array - */ function export() { return $this->data; } - /** - * Импорт данных - * @param array $data Данные - * @return void - */ function import($data) { $this->data = $data; } /** - * Список модулей/ключей - * @return array + * Список модулей/ключей */ public function getKeys() { @@ -250,8 +207,6 @@ class Settings /** * Проверка наличия ключа - * @param string $name Ключ - * @return bool */ public function hasKey($name) { diff --git a/src/Setup.php b/src/Setup.php index e3538be..1aef431 100644 --- a/src/Setup.php +++ b/src/Setup.php @@ -6,65 +6,40 @@ * $setup->set('target', 'dst'); * $setup->executeActions('install'); * - */ + */ namespace ctiso; use ctiso\Tools\SQLStatementExtractor; use ctiso\Path; -use ctiso\File; -use SimpleXMLElement; class FakeZipArchive { - /** @var string */ public $base; - - function open(string $path): void { + function open($path) { $this->base = $path; } - /** - * Возвращает содержимое файла - * @param string $file - * @return string - */ function getFromName($file) { - return File::getContents(Path::join($this->base, $file)); + return file_get_contents(Path::join($this->base, $file)); } } -class Setup +class Setup { - /** @var array */ - protected $actions = []; - /** @var array */ - public $context = []; - /** @var string */ + protected $actions = array(); + public $context = array(); protected $file; - /** @var string */ protected $action; - /** @var SimpleXMLElement */ protected $node; - /** @var array */ - protected $stack = []; - - /** @var FakeZipArchive */ + protected $stack = array(); + public $zip; - /** @var string */ public $target; - /** @var string */ public $source; - /** - * @param string $file - */ public function __construct($file) { $this->file = $file; - $node = simplexml_load_file($file); - if ($node === false) { - throw new \RuntimeException("Can't load file $file"); - } - $this->node = $node; + $this->node = simplexml_load_file($file); $this->target = ''; $this->source = ''; @@ -81,29 +56,22 @@ class Setup } /** - * Регистрация новых действия для установки - * @param string $name - * @param callable $action + * Регистрация новых действия для установки */ - public function registerAction(string $name, $action): void + public function registerAction($name, $action) { $this->actions[$name] = $action; } /** * Установка переменных для шаблона - * @param string $name - * @param mixed $value */ - public function set(string $name, $value): void + public function set($name, $value) { $this->context[$name] = $value; } - /** - * @return string - */ - function replaceFn(array $matches) { + function replaceFn($matches) { if (isset($this->context[$matches[2]])) { $v = $this->context[$matches[2]]; } else { @@ -116,14 +84,14 @@ class Setup return $v; } - public function fileContent(string $file, array $tpl): string - { + public function fileContent($file, array $tpl) + { $result = $this->zip->getFromName($file); $result = preg_replace_callback('/\{\{\s*(\*?)(\w+)\s*\}\}/', [$this, 'replaceFn'], $result); return $result; } - function callAction(string $name, array $attributes): void + function callAction($name, array $attributes) { if(isset($this->actions[$name])) { call_user_func_array($this->actions[$name], $attributes); @@ -132,8 +100,6 @@ class Setup /** * Заменяет переменные на их значения в строке - * @param array $match массив совпадения - * @return string */ function replaceVariable(array $match) { @@ -145,55 +111,50 @@ class Setup /** * Для всех аттрибутов заменяет переменные на их значения - * @param SimpleXMLElement $attributes аттрибуты - * @return array */ - function resolve(SimpleXMLElement $attributes): array - { + function resolve($attributes) + { $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; } - + /** * Выполняет список действий если для действия не указан аттрибут when то оно выполняется всегда - * + * * @param string $action специальное действие - * @return void */ function executeActions($action = "install") { - $this->action = $action; + $this->action = $action; if ($this->stack[count($this->stack) - 1] === false) { return; } - /** @var \SimpleXMLElement */ - $item = $this->stack[count($this->stack) - 1]; + $item/*: \SimpleXMLElement*/ = $this->stack[count($this->stack) - 1]; $root = $item->children(); foreach ($root as $node) - { + { $attributes = $node->attributes(); array_push($this->stack, $node); $this->callAction($node->getName(), [$this->resolve($attributes)]); array_pop($this->stack); } - } - + } + /** - * Копирования файла + * Копирования файла * preserve - Не переписывать файл если он существует * template Файл является шаблоном подставить параметры до копирования * src Исходный файл * dst Новый файл - * + * * @param array{preserve?: string, template: string, src: string, dst: string} $attributes - * @return void */ public function copyFile(array $attributes) - { + { $path = $this->targetPath($attributes['dst']); if (!(file_exists($path) && isset($attributes['preserve']))) { @@ -203,9 +164,9 @@ class Setup /** * Создает символическую ссылку на папку/файл - * @param array{target: string, link: string} $attributes + * @param array{target: string, link: string} $attributes */ - public function makeLink(array $attributes): void + public function makeLink(array $attributes) { if (function_exists('symlink')) { symlink($attributes['target'], $attributes['link']); @@ -213,37 +174,37 @@ class Setup } /** - * Подключение файла установки + * Подключение файла установки * @param array{file: string} $attributes Имя подключаемого файла */ - public function includeFile(array $attributes): void + public function includeFile(array $attributes) { $file = basename($this->file) . "/" . $attributes['file']; $setup = new Setup($file); - $setup->context = $this->context; + $setup->context = $this->context; $setup->executeActions(); } - function targetPath(string $s): string { + function targetPath($s) { return $this->target . '/' . $s; } /** * Создает новую папку - * dst Имя папки - * - * @param array{dst:string} $attributes + * dst Имя папки + * + * @param array{dst:string} $attributes */ - public function makeDirectory(array $attributes): void + public function makeDirectory(array $attributes) { $path = $this->targetPath($attributes['dst']); if (!file_exists($path)) { mkdir($path); } - } + } - function testWhen(array $attributes): void + function testWhen(array $attributes) { if (!isset($attributes['test']) || $attributes['test'] == $this->action) { $this->executeActions($this->action); @@ -251,11 +212,9 @@ class Setup } /** - * Выполнение Списка SQL команд из ZIP файла - * @param Database $conn - * @param string $file - */ - function batchSQLZip($conn, $file): void + * Выполнение Списка SQL команд + */ + function batchSQLZip($conn/*: Database*/, $file) { $stmtList = SQLStatementExtractor::extract($this->zip->getFromName($file)); foreach ($stmtList as $stmt) { @@ -263,12 +222,7 @@ class Setup } } - /** - * Выполнение Списка SQL команд - * @param Database $conn - * @param string $file - */ - static function batchSQL($conn, $file): void + static function batchSQL($conn/*: Database*/, $file) { $stmtList = SQLStatementExtractor::extractFile($file); foreach ($stmtList as $stmt) { diff --git a/src/SortRecord.php b/src/SortRecord.php index 84604ea..3c4fe48 100644 --- a/src/SortRecord.php +++ b/src/SortRecord.php @@ -2,23 +2,20 @@ namespace ctiso; -class SortRecord +class SortRecord { - public string $key; - public int $order; + public $key; + public $mode; + public $order; - function __construct(string $key, bool $order) - { + function __construct($key, $mode, $order) + { $this->key = $key; $this->order = ((boolean)($order) === false) ? 1 : -1; + $this->mode = $mode; } - /** - * @template T - * @param array $a - * @param array $b - */ - function compare(array $a, array $b): int + function compare($a, $b) { if($a[$this->key] == $b[$this->key]) { return 0; @@ -26,7 +23,7 @@ class SortRecord return ($a[$this->key] > $b[$this->key]) ? $this->order : -$this->order; } - function compareKeys(object $a, object $b): int + function compareKeys($a, $b) { if($a->{$this->key} == $b->{$this->key}) { return 0; @@ -34,17 +31,17 @@ class SortRecord return ($a->{$this->key} > $b->{$this->key}) ? $this->order : -$this->order; } - function sort(array &$list): bool + function sort(&$list) { return usort($list, [$this, 'compare']); } - function sortKeys(array &$list): bool + function sortKeys(&$list) { return usort($list, [$this, 'compareKeys']); } - function group(array &$list, string $key, array $types): void + function group(&$list, $key, $types) { $groups = []; foreach ($types as $name) { @@ -62,6 +59,6 @@ class SortRecord foreach ($groups as $value) { $result = array_merge($result, $value); } - $list = $result; + $list = $result; } } diff --git a/src/TableTree.php b/src/TableTree.php index d09eac3..ba0ec60 100644 --- a/src/TableTree.php +++ b/src/TableTree.php @@ -4,29 +4,26 @@ * Преобразование дерева из модели Plain в массив массивов (Adjacency List) */ +/** + * Обходит таблицу как дерево + * $fn ($name, $index, $rows, $cc) + * $name Ключ уровня + * $index Значение ключа уровня + * $rows Все столбцы текущго уровня + * $cc Столбцы более низкого уровня + * + * @param Array $level Уровни вложенности + * @param array $table Таблица + * @param Function $fn Функция которая применяется к каждой ветке дерева + */ namespace ctiso; use ctiso\Functions; class TableTree { - /** - * Обходит таблицу как дерево - * $fn ($name, $index, $rows, $cc) - * $name Ключ уровня - * $index Значение ключа уровня - * $rows Все столбцы текущго уровня - * $cc Столбцы более низкого уровня - * - * @param array $level Уровни вложенности - * @param array $table Таблица - * @param callable $fn Функция которая применяется к каждой ветке дерева - * @return array - */ static function walk($level, $table, $fn) { - if (empty ($level)) { - return $table; - } + if (empty ($level)) return $table; $name = array_shift ($level); - + $keys = Functions::key_unique_values($name, $table); $data = []; foreach ($keys as $index) { diff --git a/src/Tales.php b/src/Tales.php index 2e3529f..6538d86 100644 --- a/src/Tales.php +++ b/src/Tales.php @@ -4,30 +4,27 @@ * Расширения для PHPTAL для отображения времени и даты */ namespace ctiso; - -use PHPTAL_Php_TalesInternal; -use ctiso\Controller\SiteInterface; -use ctiso\Controller\Component; -use ctiso\HttpRequest; -use PHPTAL_Tales; -use PHPTAL_TalesRegistry; +use PHPTAL_Php_TalesInternal, + ctiso\Controller\SiteInterface, + ctiso\Controller\Component, + ctiso\HttpRequest, + PHPTAL_Tales, + PHPTAL_TalesRegistry; class Tales_DateTime implements PHPTAL_Tales { - static public function date(string $expression, bool $nothrow = false): string - { + static public function date($expression, $nothrow = false) { return "ctiso\\Tales::phptal_date(".PHPTAL_Php_TalesInternal::path($expression).")"; } - static public function time(string $expression, bool $nothrow = false): string - { + static public function time($expression, $nothrow = false) { return "ctiso\\Tales::phptal_time(".PHPTAL_Php_TalesInternal::path($expression).")"; } } class Tales_Component implements PHPTAL_Tales { - static public function component(string $expression, bool $nothrow = false): string + static public function component($expression, $nothrow = false) { $s = PHPTAL_Php_TalesInternal::string($expression); return "ctiso\\Tales::phptal_component(" . $s . ")"; @@ -36,7 +33,7 @@ class Tales_Component implements PHPTAL_Tales class Tales_Assets implements PHPTAL_Tales { - static public function assets(string $expression, bool $nothrow = false): string + static public function assets($expression, $nothrow = false) { $s = PHPTAL_Php_TalesInternal::string($expression); return "ctiso\\Tales::phptal_asset(" . $s . ")"; @@ -44,47 +41,45 @@ class Tales_Assets implements PHPTAL_Tales } class Tales { - /** @var ?SiteInterface */ - static $site; + static $site/*: SiteInterface*/; - static function phptal_date (int $e): string { + static function phptal_date ($e) { return date("d.m.Y", $e); } - static function phptal_time (int $e): string { + static function phptal_time ($e) { return date("H:i", $e); } - static function phptal_asset(string $s): string { + static function phptal_asset($s) { self::$site->addStyleSheet($s); return ""; } /** * Функция подключения компонента - * @param string $expression - * @return string */ - static function phptal_component($expression): string { + static function phptal_component($expression) { $begin = floatval(microtime(true)); - /** @var Component */ + $component/*: Component*/ = null; + $component = self::$site->loadComponent($expression); - $req = new HttpRequest(); + $req = new HttpRequest(); $result = $component->execute($req); - + echo ""; return $result; } - static function register(?SiteInterface $site): void { + static function register($site) { self::$site = $site; /* Регистрация нового префикса для подключения компонента */ $tales = PHPTAL_TalesRegistry::getInstance(); - $tales->registerPrefix('component', [\ctiso\Tales_Component::class, 'component']); - $tales->registerPrefix('date', [\ctiso\Tales_DateTime::class, 'date']); - $tales->registerPrefix('time', [\ctiso\Tales_DateTime::class, 'time']); - $tales->registerPrefix('assets', [\ctiso\Tales_Assets::class, 'assets']); + $tales->registerPrefix('component', ['ctiso\\Tales_Component', 'component']); + $tales->registerPrefix('date', ['ctiso\\Tales_DateTime', 'date']); + $tales->registerPrefix('time', ['ctiso\\Tales_DateTime', 'time']); + $tales->registerPrefix('assets', ['ctiso\\Tales_Assets', 'assets']); } } diff --git a/src/Tools/Drawing.php b/src/Tools/Drawing.php index 8a7568e..306d914 100644 --- a/src/Tools/Drawing.php +++ b/src/Tools/Drawing.php @@ -2,8 +2,6 @@ namespace ctiso\Tools; -use GdImage; - class Drawing { const ALIGN_LEFT = "left"; @@ -12,61 +10,26 @@ class Drawing const ALIGN_CENTER = "center"; const ALIGN_RIGHT = "right"; - /** - * @param GdImage $image - * @param int $left - * @param int $top - * @param int $width - * @param int $height - * @param list> $rgb - */ - static function drawRectangle(GdImage &$image, int $left, int $top, int $width, int $height, array $rgb): void + static function drawrectnagle(&$image, $left, $top, $width, $height, $rgb) { $color = imagecolorallocate($image, $rgb[0], $rgb[1], $rgb[2]); - if ($color === false) { - throw new \RuntimeException("Can't allocate color"); - } $right = $left + $width; $bottom = $top + $height; - imageline($image, $left, $top, $right, $top, $color); - imageline($image, $right, $top, $right, $bottom, $color); + imageline($image, $left, $top, $right, $top, $color); + imageline($image, $right,$top, $right, $bottom, $color); imageline($image, $left, $bottom, $right, $bottom, $color); - imageline($image, $left, $top, $left, $bottom, $color); + imageline($image, $left, $top, $left, $bottom, $color); } /** * http://ru2.php.net/imagettftext - * - * @param GdImage $image - * @param int $size - * @param float $angle - * @param int $left - * @param int $top - * @param int $color - * @param string $font - * @param string $text - * @param int $max_width - * @param int $max_height - * @param string $align - * @param string $valign */ - static function imagettftextbox( - GdImage &$image, - int $size, - float $angle, - $left, - $top, - $color, - $font, - $text, - $max_width, - $max_height, - $align, - $valign - ): float { - // echo $left,"\n", $top, "\n"; - // echo $max_width,"\n", $max_height, "\n"; - // self::drawrectnagle($image, $left, $top, $max_width, $max_height, array(0xFF,0,0)); + static function imagettftextbox(&$image, $size, $angle, $left, $top, $color, $font, $text, + $max_width, $max_height, $align, $valign) + { +// echo $left,"\n", $top, "\n"; +// echo $max_width,"\n", $max_height, "\n"; +// self::drawrectnagle($image, $left, $top, $max_width, $max_height, array(0xFF,0,0)); $text_lines = explode("\n", $text); // Supports manual line breaks! $lines = []; @@ -84,9 +47,6 @@ class Drawing for ($i = 0; $i < $count; $i++) { $item = $words[$i]; $dimensions = imagettfbbox($size, $angle, $font, $current_line . ($first_word ? '' : ' ') . $item); - if ($dimensions === false) { - continue; - } $line_width = $dimensions[2] - $dimensions[0]; $line_height = $dimensions[1] - $dimensions[7]; @@ -142,15 +102,20 @@ class Drawing return $largest_line_height * count($lines); } - function imagettftextSp(GdImage $image, float $size, float $angle, int $x, int $y, int $color, string $font, string $text, int $spacing = 0): void + + function imagettftextSp($image, $size, $angle, $x, $y, $color, $font, $text, $spacing = 0) { - if ($spacing == 0) { + if ($spacing == 0) + { imagettftext($image, $size, $angle, $x, $y, $color, $font, $text); - } else { + } + else + { $temp_x = $x; - for ($i = 0; $i < mb_strlen($text); $i++) { + for ($i = 0; $i < mb_strlen($text); $i++) + { $bbox = imagettftext($image, $size, $angle, $temp_x, $y, $color, $font, $text[$i]); - $temp_x += $spacing + ($bbox !== false ? ($bbox[2] - $bbox[0]) : 0); + $temp_x += $spacing + ($bbox[2] - $bbox[0]); } } } diff --git a/src/Tools/Image.php b/src/Tools/Image.php index dd3ebd4..a59642f 100644 --- a/src/Tools/Image.php +++ b/src/Tools/Image.php @@ -2,15 +2,9 @@ namespace ctiso\Tools; -use GdImage; - class Image -{ - /** - * @param string $uri - * @return GdImage|false - */ - static function load($uri): GdImage|false +{ + static function load($uri) { $e = strtolower(pathinfo($uri, PATHINFO_EXTENSION)); switch ($e) { @@ -18,32 +12,24 @@ class Image case 'jpeg': case 'jpg': return imagecreatefromjpeg($uri); case 'gif': return imagecreatefromgif($uri); } - return false; } - static function fit(GdImage $image, int $prewidth, int $preheight, bool $force = true): GdImage|false + static function fit($image, $prewidth, $preheight, $force = true) { $width = imagesx($image); $height = imagesy($image); - $percent = min($prewidth / $width, $preheight / $height); - if ($percent > 1 && !$force) { - $percent = 1; - } - $new_width = max(1, (int)($width * $percent)); - $new_height = max(1, (int)($height * $percent)); + if ($percent > 1 && !$force) $percent = 1; + $new_width = $width * $percent; + $new_height = $height * $percent; + $image_p = imagecreatetruecolor($new_width, $new_height); imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); return $image_p; } - /** - * @param GdImage $image - * @param string $uri - * @return bool - */ - static function save($image, $uri): bool + static function save($image, $uri) { $e = strtolower(pathinfo($uri, PATHINFO_EXTENSION)); switch ($e) { @@ -51,6 +37,5 @@ class Image case 'png': imagepng($image, $uri); break; case 'gif': imagegif($image, $uri); break; } - return false; } } \ No newline at end of file diff --git a/src/Tools/SQLStatementExtractor.php b/src/Tools/SQLStatementExtractor.php index 5041e69..771b52b 100644 --- a/src/Tools/SQLStatementExtractor.php +++ b/src/Tools/SQLStatementExtractor.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information please see * . */ - + /** * Static class for extracting SQL statements from a string or file. * @@ -26,157 +26,142 @@ * @version $Revision: 1.5 $ * @package creole.util.sql */ - namespace ctiso\Tools; - use Exception; -class SQLStatementExtractor -{ - - /** @var string */ +class SQLStatementExtractor { + protected static $delimiter = ';'; - + /** * Get SQL statements from file. - * + * * @param string $filename Path to file to read. * @return array SQL statements */ - public static function extractFile($filename) - { + public static function extractFile($filename) { $buffer = file_get_contents($filename); if ($buffer !== false) { - return self::extractStatements(self::getLines($buffer)); + return self::extractStatements(self::getLines($buffer)); } throw new Exception("Unable to read file: " . $filename); } - + /** * Extract statements from string. - * + * * @param string $buffer * @return array */ - public static function extract($buffer) - { + public static function extract($buffer) { return self::extractStatements(self::getLines($buffer)); } - + /** * Extract SQL statements from array of lines. * - * @param string[] $lines Lines of the read-in file. - * @return string[] SQL statements + * @param array $lines Lines of the read-in file. + * @return array */ - protected static function extractStatements($lines) - { - + protected static function extractStatements($lines) { + $statements = []; $sql = ""; + + foreach($lines as $line) { + + $line = trim($line); + + if (self::startsWith("//", $line) || + self::startsWith("--", $line) || + self::startsWith("#", $line)) { + continue; + } + + if (strlen($line) > 4 && strtoupper(substr($line,0, 4)) == "REM ") { + continue; + } - foreach ($lines as $line) { - $line = trim($line); + $sql .= " " . $line; + $sql = trim($sql); - if ( - self::startsWith("//", $line) || - self::startsWith("--", $line) || - self::startsWith("#", $line) - ) { - continue; + // SQL defines "--" as a comment to EOL + // and in Oracle it may contain a hint + // so we cannot just remove it, instead we must end it + if (strpos($line, "--") !== false) { + $sql .= "\n"; + } + + if (self::endsWith(self::$delimiter, $sql)) { + $statements[] = self::substring($sql, 0, strlen($sql)-1 - strlen(self::$delimiter)); + $sql = ""; + } } - - if (strlen($line) > 4 && strtoupper(substr($line, 0, 4)) == "REM ") { - continue; - } - - $sql .= " " . $line; - $sql = trim($sql); - - // SQL defines "--" as a comment to EOL - // and in Oracle it may contain a hint - // so we cannot just remove it, instead we must end it - if (strpos($line, "--") !== false) { - $sql .= "\n"; - } - - if (self::endsWith(self::$delimiter, $sql)) { - $statements[] = self::substring($sql, 0, strlen($sql) - 1 - strlen(self::$delimiter)); - $sql = ""; - } - } - return $statements; + return $statements; } - + // // Some string helper methods - // - + // + /** * Tests if a string starts with a given string. * @param string $check The substring to check. * @param string $string The string to check in (haystack). * @return boolean True if $string starts with $check, or they are equal, or $check is empty. */ - protected static function startsWith($check, $string) - { + protected static function startsWith($check, $string) { if ($check === "" || $check === $string) { return true; } else { return (strpos($string, $check) === 0); } } - + /** * Tests if a string ends with a given string. * @param string $check The substring to check. * @param string $string The string to check in (haystack). * @return boolean True if $string ends with $check, or they are equal, or $check is empty. */ - protected static function endsWith(string $check, string $string) - { + protected static function endsWith($check/*: string*/, $string) { if ($check === "" || $check === $string) { return true; } else { return (strpos(strrev($string), strrev($check)) === 0); } - } + } /** * a natural way of getting a subtring, php's circular string buffer and strange - * return values suck if you want to program strict as of C or friends - * @param string $string The string to get the substring from. - * @param int $startpos The start position of the substring. - * @param int $endpos The end position of the substring. - * @return string The substring. + * return values suck if you want to program strict as of C or friends */ - protected static function substring(string $string, int $startpos, int $endpos = -1) - { + protected static function substring($string, $startpos, $endpos = -1) { $len = strlen($string); - $endpos = (int) (($endpos === -1) ? $len - 1 : $endpos); - if ($startpos > $len - 1 || $startpos < 0) { + $endpos = (int) (($endpos === -1) ? $len-1 : $endpos); + if ($startpos > $len-1 || $startpos < 0) { trigger_error("substring(), Startindex out of bounds must be 0 $len - 1 || $endpos < $startpos) { - trigger_error("substring(), Endindex out of bounds must be $startpos $len-1 || $endpos < $startpos) { + trigger_error("substring(), Endindex out of bounds must be $startpos 0) { // already in sub-array? $subarr[$in_subarr][] = $tok; if ('}' === substr($tok, -1, 1)) { // check to see if we just added last component @@ -27,7 +21,7 @@ class StringUtil $in_subarr--; } } elseif ($tok[0] === '{') { // we're inside a new sub-array - if ('}' !== substr($tok, -1, 1)) { + if ('}' !== substr($tok, -1, 1)) { $in_subarr++; // if sub-array has more than one element $subarr[$in_subarr] = []; @@ -38,131 +32,81 @@ class StringUtil } else { // not sub-array $val = trim($tok, '"'); // remove " (surrounding strings) // perform type castng here? - $res[] = $val; + $res[] = $val; } } return $res; } - /** - * Нормализация строк на русском - * @param string $str - * @return string - */ - static function normalizeRussian(string $str): string - { - $result = preg_replace('/\s+/', ' ', $str); + //Нормализация строк на русском + static function normalizeRussian($str) { + $result = preg_replace('/\s+/',' ', $str); if (is_string($result)) { $result = trim($result); //Замена длинных пробелов на одинарные, пробелы по краям $result = mb_strtolower($result); - $result = preg_replace('/ё/', 'е', $str); //е на ё + $result = preg_replace('/ё/','е', $str); //е на ё } return $result; } - /** - * Проверка равенства двух строк на русском языке. - * @param string $str1 - * @param string $str2 - * @return bool - */ - static function equalRussianCheck($str1, $str2): bool - { + //Проверка равенства двух строк на русском языке. + static function equalRussianCheck($str1,$str2) { return self::normalizeRussian($str1) == self::normalizeRussian($str2); } + /** * Попадает ли строка в список вариантов * input: $str="foo1" $variants="foo1|foo2|foo3" * output: true * input: $str="foo" $variants="foo1|foo2|foo3" * output: false - * - * @param string $str - * @param string $variants - * @return bool - */ - static function compare_string_to_variants($str, string $variants) - { +*/ + static function compare_string_to_variants($str, $variants){ $variants_array = explode('|', $variants); $founded = false; foreach ($variants_array as $variant) { - $founded = $founded || self::equalRussianCheck($variant, $str); + $founded = $founded || self::equalRussianCheck($variant, $str); } return $founded; } - /** - * Разбивает строку на массив символов - * @param string $str - * @return array - */ - static function mb_str_split(string $str): array - { - return preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY) ?: []; + static function mb_str_split($str) { + return preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY); } - /** - * Заменяет символы в строке на символы из другой строки - * @param string $str - * @param string $from - * @param string $to - * @return string - */ - static function mb_strtr($str, $from, $to) - { + static function mb_strtr($str, $from, $to) { return str_replace(self::mb_str_split($from), self::mb_str_split($to), $str); } - static function encodestring(string $st): string - { - $st = self::mb_strtr($st, "абвгдеёзийклмнопрстуфхъыэ !+()", "abvgdeeziyklmnoprstufh_ie_____"); - $st = self::mb_strtr($st, "АБВГДЕЁЗИЙКЛМНОПРСТУФХЪЫЭ", "ABVGDEEZIYKLMNOPRSTUFH_IE"); + static function encodestring($st) { + $st = self::mb_strtr($st,"абвгдеёзийклмнопрстуфхъыэ !+()", "abvgdeeziyklmnoprstufh_ie_____"); + $st = self::mb_strtr($st,"АБВГДЕЁЗИЙКЛМНОПРСТУФХЪЫЭ", "ABVGDEEZIYKLMNOPRSTUFH_IE"); $st = strtr($st, [ - " " => '_', - "." => '_', - "," => '_', - "?" => '_', - "\"" => '_', - "'" => '_', - "/" => '_', - "\\" => '_', - "%" => '_', - "#" => '_', - "*" => '_', - "ж" => "zh", - "ц" => "ts", - "ч" => "ch", - "ш" => "sh", - "щ" => "shch", - "ь" => "", - "ю" => "yu", - "я" => "ya", - "Ж" => "ZH", - "Ц" => "TS", - "Ч" => "CH", - "Ш" => "SH", - "Щ" => "SHCH", - "Ь" => "", - "Ю" => "YU", - "Я" => "YA", - "Й" => "i", - "й" => "ie", - "ё" => "Ye", - "№" => "N" - ]); + " " => '_', + "." => '_', + "," => '_', + "?" => '_', + "\"" => '_', + "'" => '_', + "/" => '_', + "\\" => '_', + "%" => '_', + "#" => '_', + "*" => '_', + "ж"=>"zh", "ц"=>"ts", "ч"=>"ch", "ш"=>"sh", + "щ"=>"shch","ь"=>"", "ю"=>"yu", "я"=>"ya", + "Ж"=>"ZH", "Ц"=>"TS", "Ч"=>"CH", "Ш"=>"SH", + "Щ"=>"SHCH","Ь"=>"", "Ю"=>"YU", "Я"=>"YA", + "Й"=>"i", "й"=>"ie", "ё"=>"Ye", + "№"=>"N" + ]); return strtolower($st); } - /** - * Проверяет, является ли строка кодированной - * @param string $st - * @return int|false - */ - static function validate_encoded_string(string $st): int|false - { + static function validate_encoded_string($st) { $enc_st = self::encodestring($st); return preg_match('/^[\w_-]+(\.[\w_-]+)?$/', $enc_st); } -} +} \ No newline at end of file diff --git a/src/Tools/TemplateImage.php b/src/Tools/TemplateImage.php index cb0ad0d..ad9d8f0 100644 --- a/src/Tools/TemplateImage.php +++ b/src/Tools/TemplateImage.php @@ -3,18 +3,13 @@ /** * Формат для композиции изображений */ - namespace ctiso\Tools; - use ctiso\Tools\Drawing; -use GdImage; class TemplateImage { - /** @var array */ - static array $listfiles = array('jpg' => 'jpeg', 'gif' => 'gif', 'png' => 'png', 'bmp' => 'wbmp'); - /** @var array */ - static array $listfonts = array( + static $listfiles = array('jpg' => 'jpeg', 'gif' => 'gif', 'png' => 'png', 'bmp' => 'wbmp'); + static $listfonts = array( 'georgia' => 'georgia.ttf', 'georgiabd' => 'georgiab.ttf', 'georgiaz' => 'georgiaz.ttf', @@ -29,28 +24,26 @@ class TemplateImage '' => 'arial.ttf', 'dejavu' => 'DejaVuCondensedSerif.ttf', 'dejavubd' => 'DejaVuCondensedSerifBold.ttf', - 'dejavuz' => 'DejaVuCondensedSerifBoldItalic.ttf', + 'dejavuz' =>'DejaVuCondensedSerifBoldItalic.ttf', 'dejavui' => 'DejaVuCondensedSerifItalic.ttf', 'miriad' => 'MyriadPro-Cond.ttf', 'miriadbd' => 'MyriadPro-BoldCond.ttf' ); - /** @var string */ protected $src; - protected array $context = []; - protected array $data = []; - protected string $base = "c:\\windows\\fonts\\"; - protected GdImage $image; - /** @var bool */ + protected $context = array(); + protected $data = array(); + protected $base = "c:\\windows\\fonts\\"; + protected $image; protected $_prepare = true; - /** @var bool */ public $debug = false; - public string $resource; - public string $filename; + public $resource; + public $filename; - function __construct(?array $template = null) + function __construct ($template = null) { +// assert(is_string($src)); if ($template) { $this->data = $template; } @@ -59,165 +52,131 @@ class TemplateImage /** * Путь к изображению */ - function resourcePath(string $path): void + function resourcePath($path) { + assert(is_string($path)); + $this->resource = $path; } /** * Путь у шрифтам */ - function fontPath(string $path): void + function fontPath($path) { + assert(is_string($path)); + $this->base = $path; } - /** - * @param string $name - * @param mixed $value - */ - function set(string $name, $value): void + function set($name, $value) { - $this->context['[' . $name . ']'] = $value; + assert(is_string($name)); + + $this->context['['.$name.']'] = $this->encode($value); } - function setImage(string $name): void + function setImage($name) { $this->filename = $name; $this->image = $this->imagefromfile($name); } - /** - * Создает пустое изображение - * @param int<1, max> $width - * @param int<1, max> $height - */ - function setEmptyImage($width, $height): void + function setEmptyImage($width, $height) { $this->image = imagecreatetruecolor($width, $height); } /** * Создает изображение из файла - * @param string $file - * @return GdImage|null */ - function imagefromfile(string $file) + function imagefromfile($file) { + assert(is_string($file)); + $suffix = pathinfo($file, PATHINFO_EXTENSION); if (array_key_exists($suffix, self::$listfiles)) { - $imageFn = 'imagecreatefrom' . self::$listfiles[$suffix]; - if (!is_callable($imageFn)) { - return null; - } - return call_user_func($imageFn, $file); + return call_user_func('imagecreatefrom' . self::$listfiles[$suffix], $file); } return null; } - function getFontFile(string $name): string + function getFontFile($name) { - if (array_key_exists(strtolower($name), self::$listfonts)) { + assert(is_string($name)); + + if(array_key_exists(strtolower($name), self::$listfonts)) { return $this->base . self::$listfonts[$name]; } return $this->base . 'arial.ttf'; } - function fontSuffix(array $style): string + function fontSuffix($style) { - if ($style[0] && $style[1]) return "z"; + if($style[0] && $style[1]) return "z"; - if ($style[0]) return "bd"; - if ($style[1]) return "i"; + if($style[0]) return "bd"; + if($style[1]) return "i"; return ""; } - /** - * @param string $text - * @param object{ - * fontFamily: string, - * fontSize: int, - * fontStyle: array{string, string}, - * color: string, - * align: array, - * valign: array, - * left: int, - * top: int, - * width: int, - * height: int - * } $value - */ - function imageText(string $text, object $value): void + function imageText($text, $value/*: \stdClass*/) { + assert(is_string($text)); + $text = strtr($text, $this->context); $size = $value->fontSize; $fontfile = $this->getFontFile($value->fontFamily . $this->fontSuffix($value->fontStyle)); $color = intval(substr($value->color, 1), 16); - if ($value->align[0]) { + if ($value->align[0]) { $align = Drawing::ALIGN_LEFT; - } elseif ($value->align[2]) { + } elseif ($value->align[2]) { $align = Drawing::ALIGN_RIGHT; } else { $align = Drawing::ALIGN_CENTER; } - if ($value->valign[0]) { + if ($value->valign[0]) { $valign = Drawing::ALIGN_TOP; - } elseif ($value->valign[1]) { + } elseif ($value->valign[1]) { $valign = Drawing::ALIGN_CENTER; } else { $valign = Drawing::ALIGN_BOTTOM; } - Drawing::imagettftextbox( - $this->image, - $size, - 0, - $value->left, - $value->top, - $color, - $fontfile, - $text, - $value->width, - $value->height, - $align, - $valign - ); + Drawing::imagettftextbox($this->image, $size, 0, $value->left, $value->top, $color, $fontfile, $text, + $value->width, $value->height, + $align, $valign); } /** * Перекодировка текста - * @deprecated Можно заменить encode($x) -> $x */ - function encode(string $text): string + function encode($text) { - return $text; + assert(is_string($text)); + return $text; //iconv("WINDOWS-1251", "UTF-8", $text); } - /** - * @param int<1,max> $new_width - * @param ?int<1,max> $new_height - */ - function setSize(int $new_width, ?int $new_height = null): void + function setSize($new_width, $new_height) { $width = imagesx($this->image); $height = imagesy($this->image); if ($new_height == null) { - $new_height = max(1, (int)ceil($height * $new_width / $width)); + $new_height = ceil($height * $new_width / $width); } // Resample $image_p = imagecreatetruecolor($new_width, $new_height); imagecopyresampled($image_p, $this->image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); - // imagecopyresized($image_p, $this->image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); +// imagecopyresized($image_p, $this->image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); $this->image = $image_p; } - function prepare(): void - { - if ($this->_prepare) { + function prepare() { + if($this->_prepare) { $this->_prepare = false; foreach ($this->data as $value) { $this->imageText($value->text, $value); // break; @@ -228,8 +187,10 @@ class TemplateImage /** * Генерирует изображение из шаблона */ - function render(?string $file = null): string|bool + function render($file = null) { + assert(is_string($file) || is_null($file)); + $this->prepare(); if ($file == null) { diff --git a/src/UTF8.php b/src/UTF8.php index 4eab203..5eb93a0 100644 --- a/src/UTF8.php +++ b/src/UTF8.php @@ -2,20 +2,13 @@ namespace ctiso; -class UTF8 -{ - /** - * @param string $str - * @param int $split_length - * @return list - */ - static function str_split(string $str, int $split_length = 1): array - { - $split_length = (int) $split_length; - +class UTF8 { + static function str_split($str, $split_length = 1) { + $split_length = (int) $split_length; + $matches = []; - preg_match_all('/.{' . $split_length . '}|[^\x00]{1,' . $split_length . '}$/us', $str, $matches); - - return $matches[0]; + preg_match_all('/.{'.$split_length.'}|[^\x00]{1,'.$split_length.'}$/us', $str, $matches); + + return $matches[0]; } -} +} \ No newline at end of file diff --git a/src/Url.php b/src/Url.php index 83ce86b..f4393b0 100644 --- a/src/Url.php +++ b/src/Url.php @@ -3,29 +3,25 @@ namespace ctiso; class Url { - /** @var array */ - public array $parts = []; - public ?Url $parent; + public $parts = []; + public $parent/*: Url*/; - /** - * @param Url|null $parent - */ - function setParent($parent): void { + function __construct() { + } + + function setParent($parent) { $this->parent = $parent; } - /** - * @param string[] $parts - */ - function setQuery(array $parts): void { + function setQuery($parts) { $this->parts = $parts; } - function addQueryParam(string $key, ?string $value): void { + function addQueryParam($key, $value) { $this->parts[$key] = $value; } - function toString(): string { + function toString() { return '?' . http_build_query(array_merge($this->parts, $this->parent ? $this->parent->parts : [])); - } + } } \ No newline at end of file diff --git a/src/UserMessageException.php b/src/UserMessageException.php index 1638288..226eb75 100644 --- a/src/UserMessageException.php +++ b/src/UserMessageException.php @@ -6,11 +6,7 @@ namespace ctiso; class UserMessageException extends \Exception { - /** @var string */ public $userMessage; - /** - * @param string $message - */ public function __construct($message) { parent::__construct($message); $this->userMessage = $message; diff --git a/src/Validator/Rule/AbstractRule.php b/src/Validator/Rule/AbstractRule.php index 706d8b6..4ab8307 100644 --- a/src/Validator/Rule/AbstractRule.php +++ b/src/Validator/Rule/AbstractRule.php @@ -1,57 +1,47 @@ field = $field; $this->errorMsg = $errorMsg; } - - public function setName(string $field): self + + public function setName($field) { $this->field = $field; return $this; } - public function setErrorMsg(?string $errorMsg): self + public function setErrorMsg($errorMsg) { $this->errorMsg = $errorMsg; return $this; } - public function getErrorMsg(): string - { + public function getErrorMsg() + { return $this->errorMsg; } - /** - * @param Collection $container - * @param bool|null $status - * @return bool - */ - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { return true; } - function skipEmpty(): bool { + function skipEmpty() { return true; } - /** - * @param RuleContext $ctx - */ - public function setContext($ctx): void + public function setContext($ctx) { $this->ctx = $ctx; } diff --git a/src/Validator/Rule/Alpha.php b/src/Validator/Rule/Alpha.php index 2f13230..06793fd 100644 --- a/src/Validator/Rule/Alpha.php +++ b/src/Validator/Rule/Alpha.php @@ -4,18 +4,17 @@ * Проверка на число */ namespace ctiso\Validator\Rule; - -use ctiso\Validator\Rule\AbstractRule; -use ctiso\Collection; +use ctiso\Validator\Rule\AbstractRule, + ctiso\Collection; class Alpha extends AbstractRule { - public function getErrorMsg(): string - { + public function getErrorMsg() + { return "Поле должно содержать только буквы"; } - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { return ctype_alpha($container->get($this->field)); } diff --git a/src/Validator/Rule/Code.php b/src/Validator/Rule/Code.php index 30f6e5e..1102766 100644 --- a/src/Validator/Rule/Code.php +++ b/src/Validator/Rule/Code.php @@ -13,7 +13,7 @@ class Code extends AbstractRule return "Неправильно указан персональный код"; } - function checkCode(array $code): bool { + function checkCode($code): bool { foreach($code as $c) { if (empty($c)) { return false; diff --git a/src/Validator/Rule/Count.php b/src/Validator/Rule/Count.php index fa650a8..c346892 100644 --- a/src/Validator/Rule/Count.php +++ b/src/Validator/Rule/Count.php @@ -9,30 +9,26 @@ use ctiso\Validator\Rule\AbstractRule, class Count extends AbstractRule { - public int $size = 1; - public ?int $max = null; + public $size = 1; + public $max = null; - public function getErrorMsg(): string - { + public function getErrorMsg() + { return "Количество записей должно быть не менне {$this->size} и не более {$this->max}"; } - /** - * @param string $s - * @return bool - */ - function notEmpty($s): bool { + function not_empty($s) { return $s != ""; } - - public function isValid(Collection $container, $status = null): bool + + public function isValid(Collection $container, $status = null) { if (!$this->max) { $this->max = $this->size; - } - $count = count(array_filter(array_map('trim', - explode(";", $container->get($this->field))), [$this, 'notEmpty'])); + } + $count = count(array_filter(array_map('trim', + explode(";", $container->get($this->field))), [$this, 'not_empty'])); return $count >= $this->size && $count <= ((int)$this->max); } diff --git a/src/Validator/Rule/Date.php b/src/Validator/Rule/Date.php index a53975d..fdfff71 100644 --- a/src/Validator/Rule/Date.php +++ b/src/Validator/Rule/Date.php @@ -9,16 +9,16 @@ use ctiso\Validator\Rule\AbstractRule, class Date extends AbstractRule { - public function getErrorMsg(): string - { + public function getErrorMsg() + { return "Неверный формат даты"; } - - public function isValid(Collection $container, $status = null): bool + + public function isValid(Collection $container, $status = null) { $pattern = "/^([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{4})$/"; $matches = []; - return (preg_match($pattern, $container->get($this->field), $matches) + return (preg_match($pattern, $container->get($this->field), $matches) && checkdate((int)$matches[2], (int)$matches[1], (int)$matches[3])); } } diff --git a/src/Validator/Rule/Email.php b/src/Validator/Rule/Email.php index ebbdc17..22c1287 100644 --- a/src/Validator/Rule/Email.php +++ b/src/Validator/Rule/Email.php @@ -9,12 +9,12 @@ use ctiso\Validator\Rule\AbstractRule, class Email extends AbstractRule { - public function getErrorMsg(): string + public function getErrorMsg() { return "Неверный формат электронной почты"; } - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { $emails = explode(",", $container->get($this->field)); foreach ($emails as $email) { diff --git a/src/Validator/Rule/EmailList.php b/src/Validator/Rule/EmailList.php index 068becf..2132d0b 100644 --- a/src/Validator/Rule/EmailList.php +++ b/src/Validator/Rule/EmailList.php @@ -9,14 +9,20 @@ use ctiso\Validator\Rule\AbstractRule, class EmailList extends AbstractRule { - public function getErrorMsg(): string - { + public function getErrorMsg() + { return "Неверный формат электронной почты"; } - public function isValid(Collection $container, $status = null): bool { + public function isValid(Collection $container, $status = null) { + $user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\|\{\}~\']+'; + $doIsValid = '(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]\.?)+'; + $ipv4 = '[0-9]{1,3}(\.[0-9]{1,3}){3}'; + $ipv6 = '[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7}'; + $emails = $container->get($this->field); foreach ($emails as $email) { +// if (! preg_match("/^$user@($doIsValid|(\[($ipv4|$ipv6)\]))$/", $email)) return false; if (! filter_var($email, FILTER_VALIDATE_EMAIL)) return false; } return true; diff --git a/src/Validator/Rule/FileName.php b/src/Validator/Rule/FileName.php index 5f4410f..d45d1f8 100644 --- a/src/Validator/Rule/FileName.php +++ b/src/Validator/Rule/FileName.php @@ -7,12 +7,12 @@ use ctiso\Validator\Rule\AbstractRule, class FileName extends AbstractRule { - public function getErrorMsg(): string + public function getErrorMsg() { return 'Название файла может содержать только символы латиницы в нижнем регистре и цифры'; } - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { return Path::isName($container->get($this->field)); } diff --git a/src/Validator/Rule/IsFile.php b/src/Validator/Rule/IsFile.php index 37115f8..5304718 100644 --- a/src/Validator/Rule/IsFile.php +++ b/src/Validator/Rule/IsFile.php @@ -9,42 +9,42 @@ use ctiso\Validator\Rule\AbstractRule, class IsFile extends AbstractRule { - private array $type = []; - private int $maxsize = 1024; + private $type = array(); + private $maxsize = 1024; - function skipEmpty(): bool { + function skipEmpty() { return false; } - function setSize(int $size): void { + function setSize($size) { $this->maxsize = $size; } - function setType(array $type): void { + function setType(array $type) { $this->type = $type; } - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { if (!isset($_FILES[$this->field]) || $_FILES[$this->field]['error'] == UPLOAD_ERR_NO_FILE) { $this->setErrorMsg('Файл не загружен'); - return false; + return false; } if ($_FILES[$this->field]['error'] == UPLOAD_ERR_INI_SIZE) { $this->setErrorMsg('Превышен размер файла'); - return false; + return false; } $tmp = $_FILES[$this->field]; if (!in_array($tmp['type'], $this->type)) { $this->setErrorMsg('Неверный формат файла'); - return false; + return false; } if (((int)$tmp['size']) > $this->maxsize*1024) { $this->setErrorMsg('Неверный размер файла'); - return false; + return false; } return true; diff --git a/src/Validator/Rule/MatchRule.php b/src/Validator/Rule/MatchRule.php index b0db64b..d54f448 100644 --- a/src/Validator/Rule/MatchRule.php +++ b/src/Validator/Rule/MatchRule.php @@ -9,16 +9,14 @@ use ctiso\Validator\Rule\AbstractRule, class MatchRule extends AbstractRule { - /** @var string */ public $same; - public function getErrorMsg(): string - { + public function getErrorMsg() + { return "Поля не совпадают"; } - public function isValid(Collection $container, $status = null): bool - { + public function isValid(Collection $container, $status = null) { return (strcmp($container->get($this->field), $container->get($this->same)) == 0); } } diff --git a/src/Validator/Rule/Notnull.php b/src/Validator/Rule/Notnull.php index 2a146e2..d9130da 100644 --- a/src/Validator/Rule/Notnull.php +++ b/src/Validator/Rule/Notnull.php @@ -6,16 +6,16 @@ use ctiso\Validator\Rule\AbstractRule, class Notnull extends AbstractRule { - function skipEmpty(): bool { + function skipEmpty() { return false; } - public function getErrorMsg(): string - { + public function getErrorMsg() + { return "Поле не должно быть пустым"; } - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { $data = $container->get($this->field); if (is_array($data)) { diff --git a/src/Validator/Rule/Numeric.php b/src/Validator/Rule/Numeric.php index 1fe5b0d..a3c6a5a 100644 --- a/src/Validator/Rule/Numeric.php +++ b/src/Validator/Rule/Numeric.php @@ -9,12 +9,12 @@ use ctiso\Validator\Rule\AbstractRule, class Numeric extends AbstractRule { - public function getErrorMsg(): string - { + public function getErrorMsg() + { return "Значение поля должно быть числом"; } - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { return (is_numeric($container->get($this->field))); } diff --git a/src/Validator/Rule/PregMatch.php b/src/Validator/Rule/PregMatch.php index 71e4252..3d400bb 100644 --- a/src/Validator/Rule/PregMatch.php +++ b/src/Validator/Rule/PregMatch.php @@ -1,20 +1,21 @@ pattern, $container->get($this->field)) !== false; - } + public function isValid(Collection $container, $status = null) + { + return preg_match($this->pattern,$container->get($this->field)); + } } diff --git a/src/Validator/Rule/RuleContext.php b/src/Validator/Rule/RuleContext.php deleted file mode 100644 index e5be2fc..0000000 --- a/src/Validator/Rule/RuleContext.php +++ /dev/null @@ -1,10 +0,0 @@ - -1 && $hour < 24 && $minute > -1 && $minute < 60) { return true; } - return false; } - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { /** @var list */ $tmp = explode($this->split, $container->get($this->field), 2); diff --git a/src/Validator/Rule/Unique.php b/src/Validator/Rule/Unique.php index 37dfccf..81489c3 100644 --- a/src/Validator/Rule/Unique.php +++ b/src/Validator/Rule/Unique.php @@ -3,20 +3,19 @@ /** */ namespace ctiso\Validator\Rule; - -use ctiso\Validator\Rule\AbstractRule; -use ctiso\Collection; +use ctiso\Validator\Rule\AbstractRule, + ctiso\Collection; class Unique extends AbstractRule { - public function getErrorMsg(): string + public function getErrorMsg() { return $this->ctx->getMessage(); } - public function isValid(Collection $container, $status = null): bool + public function isValid(Collection $container, $status = null) { - return $this->ctx->isUnique($container->getString($this->field), $status, $container); + return $this->ctx->isUnique($container->get($this->field), $status, $container); } } diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 2225479..8c08cbe 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -1,31 +1,23 @@ + /** * Проверка коллекции */ namespace ctiso\Validator; -use Exception; -use ctiso\Validator\Rule\AbstractRule; -use ctiso\Validator\Rule\RuleContext; -use ctiso\Collection; +use Exception, + ctiso\Validator\Rule\AbstractRule, + ctiso\Collection; -/** - * @phpstan-type Rule array{ - * validate?:string, // Описание правила см. формат правила ниже - * name:string, // Имя переменой для проверки - * context?:RuleContext - * } - */ class Validator { - /** @var AbstractRule[] */ - protected array $chain = []; // Массив правил - /** @var array */ - protected array $errorMsg = []; // Массив ошибок + protected $chain = []; // Массив правил + protected $errorMsg = []; // Массив ошибок /** * Поля по умолчанию - * @var array> + * @var array> */ protected $type = [ 'date' => Rule\Date::class, @@ -44,27 +36,21 @@ class Validator 'reg' => Rule\PregMatch::class, ]; - /** - * @param Rule[] $rules - */ function __construct($rules = []) { $this->addRuleList($rules); } - /** - * Добавление правила в список - * @param string $name - * @param class-string $className - */ - function addRuleType(string $name, string $className): void { + function addRuleType($name, $className) { $this->type[$name] = $className; } /** * Добавление списка правил в специальном формате - * @param Rule[] $input + * array(array('name' => fieldname, 'validate' => ruletext), ...) + * fieldname - Имя переменой для проверки + * ruletext - Описание правила см. формат правила ниже */ - public function addRuleList(array $input): void + public function addRuleList(array $input) { // Разбор правила проверки // Формат правила 'rule1|rule2,param1=value1|rule3,param1=value1,param2=value2' @@ -97,7 +83,7 @@ class Validator } } - public function addRule(array|AbstractRule $rule): void { + public function addRule($rule/*:z any*/) { if (is_array($rule)) { $this->chain = array_merge($this->chain, $rule); } else { @@ -105,10 +91,7 @@ class Validator } } - /** - * @param AbstractRule $rule - */ - public function skip($rule, Collection $container): bool + public function skip($rule/*z: AbstractRule*/, $container/*: Collection*/) // -> Rule_Abstract { if ($rule->skipEmpty()) { $data = $container->get($rule->field); @@ -120,23 +103,17 @@ class Validator return false; } - function reset(): void { + function reset() { $this->errorMsg = []; } - /** - * @param Collection $container - * @param AbstractRule[]|null $rules - * @param bool|null $status - * @return bool - */ - public function validate(Collection $container, $rules = null, $status = null): bool + public function validate(Collection $container, $rule = null, $status = null) { $fields = []; - if ($rules) { - $this->chain = $rules; + if ($rule) { + $this->chain = $rule; } - + // $this->errorMsg = []; foreach ($this->chain as $rule) { //echo $key; if (!in_array($rule->field, $fields) && !$this->skip($rule, $container) && !$rule->isValid($container, $status)) { @@ -148,25 +125,22 @@ class Validator return $this->isValid(); } - public function addError(string $name, string $message): void + public function addError($name, $message) { $this->errorMsg[$name] = $message; } - public function isError(): bool + public function isError() { return !empty($this->errorMsg); } - public function isValid(): bool + public function isValid() { return empty($this->errorMsg); } - /** - * @return array - */ - public function getErrorMsg(): array + public function getErrorMsg() { return $this->errorMsg; } diff --git a/src/View/Composite.php b/src/View/Composite.php index edfaafb..046e18e 100644 --- a/src/View/Composite.php +++ b/src/View/Composite.php @@ -1,46 +1,45 @@ tal = new PHPTAL($file); $this->tal->setPhpCodeDestination(PHPTAL_PHP_CODE_DESTINATION); - $this->tal->setEncoding(PHPTAL_DEFAULT_ENCODING); + $this->tal->setEncoding(PHPTAL_DEFAULT_ENCODING); $this->tal->setTemplateRepository(PHPTAL_TEMPLATE_REPOSITORY); $this->tal->setOutputMode(PHPTAL::HTML5); $this->tal->stripComments(true); // $this->tal->addPreFilter(new PHPTAL_PreFilter_Normalize()); } - function set(string $key, mixed $val): void { + function set($key, $val) { if ($key == 'title') { $this->setTitle($val); } $this->tal->set($key, $val); } - function __set(string $key, mixed $val): void { + function __set($key, $val) { $this->tal->set($key, $val); } - function execute(): string + function execute() { $this->processChild(); return $this->tal->execute(); } - function setTranslator(PHPTAL_TranslationService $t): void { + function setTranslator($t) { $this->tal->setTranslator($t); } } diff --git a/src/View/JsonView.php b/src/View/JsonView.php deleted file mode 100644 index 3ba8fd4..0000000 --- a/src/View/JsonView.php +++ /dev/null @@ -1,40 +0,0 @@ -_name = $name; - } - - /** - * @param string $key - * @param mixed $value - */ - function set($key, $value): void { - $this->_data[$key] = $value; - } - - /** - * @param string $key - * @param mixed $value - */ - function __set($key, $value): void { - $this->_data[$key] = $value; - } - - /** - * @return string - */ - function execute() { - return json_encode($this->_data) ?: ''; - } -} diff --git a/src/View/Pages.php b/src/View/Pages.php index a64873d..48b2750 100644 --- a/src/View/Pages.php +++ b/src/View/Pages.php @@ -8,14 +8,6 @@ namespace ctiso\View; class Pages { static int $range = 5; - - /** - * @param int $page номер страницы - * @param int $onpage количество страниц на странице - * @param int $count количество всех страниц - * @param string $prefix префикс - * @return array{'all': bool, 'list': array, 'first': string, 'last': string, 'next': string|false, 'prev': string|false} - */ static function getPages($page, $onpage, $count, $prefix = '?') { $n = ceil($count / $onpage); @@ -28,30 +20,30 @@ class Pages } return [ 'all' => ($n > 1), - 'list' => $result, - 'first' => self::href($prefix, $url . 1), - 'last' => self::href($prefix, $url . $n), - 'next' => ($page == $n)? false : self::href($prefix, $url . ($page + 1)) , + 'list' => $result, + 'first' => self::href($prefix, $url . 1), + 'last' => self::href($prefix, $url . $n), + 'next' => ($page == $n)? false : self::href($prefix, $url . ($page + 1)) , 'prev' => ($page == 1)? false : self::href($prefix, $url . ($page - 1))]; } /** * @deprecated - * @param int $page номер страницы - * @param int $onpage количество элем на странице + * @param $page int номер страницы + * @param $onpage int количество элем на странице * @return string */ - static function getLimit(int $page, int $onpage) { + static function getLimit($page/*: number*/, $onpage/*: number*/) { if ($page <= 0) { $page = 1; } return "LIMIT $onpage OFFSET " . ($page - 1) * $onpage; } /** - * @param int $page номер страницы - * @param int $onpage количество элем на странице + * @param $page int номер страницы + * @param $onpage int количество элем на странице * @return array */ - static function _getLimit(int $page, int $onpage) { + static function _getLimit($page, $onpage) { if ($page <= 0) { $page = 1; } return [ 'count' => $onpage, @@ -59,13 +51,8 @@ class Pages ]; } - /** - * @param string $prefix префикс - * @param string $x строка - * @return string - */ - static function href($prefix, $x) { - return $prefix . $x; + static function href($prefix, $x) { + return $prefix . $x; } } diff --git a/src/View/Plain.php b/src/View/Plain.php index f070d3d..8ffc877 100644 --- a/src/View/Plain.php +++ b/src/View/Plain.php @@ -7,70 +7,41 @@ namespace ctiso\View; */ class Plain extends \stdClass { - /** @var string */ protected $document; - /** @var array */ - protected $values = []; + protected $values = array(); - /** - * Конструктор - * @param string $document шаблон - */ public function __construct ($document) { $this->document = $document; } - /** - * Установка значения - * @param string $key ключ - * @param mixed $value значение - */ - public function set($key, $value): void + public function set($key, $value) { $this->values[$key] = $value; } - /** - * Импорт значений - * @param array $list список значений - */ - public function import($list): void + public function import($list) { $this->values = array_merge($this->values, $list); } - /** - * @param string $key ключ - * @param mixed $value значение - */ - public function __set($key, $value): void + public function __set($key, $value) { $this->set($key, $value); } - /** - * Выполнение шаблона - * @return string - */ public function execute() { $result = $this->values; return self::getTemplateContent ($this->document, $result); } - /** - * Получение содержимого шаблона - * @param string $document шаблон - * @param array $result результат - * @return string содержимое шаблона - */ - static function getTemplateContent(string $document, $result): string + static function getTemplateContent($document, $result) { ob_start (); - include ($document); + include ($document); $content = ob_get_contents (); ob_clean (); - return $content === false ? '' : $content; + return $content; } } diff --git a/src/View/Top.php b/src/View/Top.php index 2a7d7fe..37b3339 100644 --- a/src/View/Top.php +++ b/src/View/Top.php @@ -8,32 +8,16 @@ class Top extends Composite { /** * Общая строка заголовка - * @var int */ public $mid = 0; - /** @var array */ - public $require = []; - /** @var array */ - public $deps = []; - /** @var \ctiso\Registry */ - public $config; + public $require = array(); + public $deps = array(); - /** - * Заголовок страницы - * - * @return string - */ public function getTitle() { return implode(" - ", array_filter($this->doTree('_title', false), [$this, 'isNotNull'])); } - /** - * Идентификатор - * - * @param string $pref - * @return string - */ function getId($pref) { $this->mid++; @@ -45,8 +29,7 @@ class Top extends Composite * * @return string */ - #[\Override] - public function execute(): string + public function render() { $this->doTree('alias'); @@ -85,12 +68,11 @@ class Top extends Composite } $init = []; - /** @var View $item */ - foreach ($s->_section as $key => $item) { - if ($item->codeGenerator !== null) { + $ss /*: View*/= $item; + if ($ss->codeGenerator !== null) { // функцию которая вычисляет а не результат - $part = call_user_func($item->codeGenerator, $this, $key, $value); + $part = call_user_func($ss->codeGenerator, $this, $key, $value); $init[] = $part; } } @@ -107,14 +89,14 @@ class Top extends Composite $this->set('title', $this->getTitle()); $this->set('jspath', $this->config->get('system', 'web')); - // - return parent::execute(); // execute+phptal ?? + // + return $this->execute(); // execute+phptal ?? } /** * Массив имен файлов скриптов * - * @return array + * return array */ public function getScripts() { @@ -131,11 +113,6 @@ class Top extends Composite return implode("\n", $this->doTree('_scriptstring')); } - /** - * Строка со скриптом - * - * @return string - */ public function getScriptStartup() { return implode("\n", $this->doTree('_startup')); @@ -144,10 +121,11 @@ class Top extends Composite /** * Массив имен файлов стилей * - * @return array + * return array */ public function getStyleSheet() { return $this->doTree('_stylesheet'); } + } \ No newline at end of file diff --git a/src/View/View.php b/src/View/View.php index 7d7776e..036cc72 100644 --- a/src/View/View.php +++ b/src/View/View.php @@ -5,35 +5,24 @@ use Exception; class View extends \stdClass { - /** @var array Вложенные шаблоны */ - protected array $_section = []; + protected $_section = array(); // Вложенные шаблоны + // Блоки + protected $_stylesheet = array(); // Массив стилей текущего шаблона + protected $_script = array(); // Массив скриптов текущего шаблона + public $_scriptstring = array(); + protected $_startup = array(); + protected $_values = array(); - /** @var string[] $_stylesheet Массив стилей текущего шаблона */ - protected array $_stylesheet = []; - /** @var string[] $_script Массив скриптов текущего шаблона */ - protected array $_script = []; - /** @var string[] $_scriptstring */ - public array $_scriptstring = []; - /** @var string[] $_startup */ - protected array $_startup = []; + protected $_title = null; // Заголовок текущего шаблона - protected array $_values = []; + public $active_module; + public $module_action; + public $prefix; - protected ?string $_title = null; // Заголовок текущего шаблона + public $suggestions; //подсказки - public ?string $active_module = null; - public string $module_action; - - /** @var string[] */ - public array $prefix; - - /** @var string[] */ - public array $suggestions = []; //подсказки - - /** @var array> */ - public array $alias = []; - // public $codeGenerator = null; - /** @var View|null */ + public $alias = []; + public $codeGenerator = null; public $parent_view = null; function __construct() { @@ -45,17 +34,14 @@ class View extends \stdClass * @param string $section переменная шаблона * @param View|string $view вложенный шаблон */ - public function setView($section, $view): void + public function setView($section, $view) { - $this->_section[$section] = $view; + $this->_section [$section] = $view; if (is_object($view)) { $view->parent_view = $this; } } - /** - * @param array $values - */ public function assignValues($values): void { $this->_values = $values; @@ -67,7 +53,7 @@ class View extends \stdClass * * @param string $name путь к скрипту */ - public function addScript(string $name): void + public function addScript($name): void { $output = $this->resolveName($this->alias, $name . '?' . http_build_query($this->prefix)); $this->_script [] = $output; @@ -76,18 +62,18 @@ class View extends \stdClass /** * Добавляет код скипта к текущему шаблону * - * @param string $code строка javascript кода + * @param string $name строка javascript кода */ - public function addScriptRaw(string $code, bool $startup = false): void + public function addScriptRaw($name, $startup = false): void { if ($startup) { - $this->_startup [] = $code; + $this->_startup [] = $name; } else { - $this->_scriptstring [] = $code; + $this->_scriptstring [] = $name; } } - public function setPrefix(string $name, string $val): void { + public function setPrefix($name, $val) { $this->prefix[$name] = $val; } @@ -96,7 +82,7 @@ class View extends \stdClass * * @param string $name путь к стилю */ - public function addStyleSheet(string $name): void + public function addStyleSheet($name) { $output = $this->resolveName($this->alias, $name . '?' . http_build_query($this->prefix)); $this->_stylesheet [] = $output; @@ -106,9 +92,9 @@ class View extends \stdClass * Рекурсивно извлекает из значение свойства обьекта * * @param string $list Имя свойства - * @param bool $flatten + * @param boolean $flatten */ - protected function doTree($list, bool $flatten = true): array + protected function doTree($list, $flatten = true) { $result = ($flatten == true) ? $this->$list : [$this->$list]; foreach ($this->_section as $value) { @@ -123,15 +109,7 @@ 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 + /*abstract*/ public function set($key, $value) { } @@ -147,35 +125,31 @@ class View extends \stdClass /** * Установка заголовка шаблона + * + * @param string $title */ - public function setTitle(string $title): void + public function setTitle($title): void { $this->_title = $title; } - protected function isNotNull(?string $title): bool + protected function isNotNull($title): bool { return $title !== null; } - /** - * @param array> $alias - */ function setAlias($alias): void { $this->alias = $alias; } - function addAlias(string $name, string $path): void + function addAlias($name, $path): void { $this->alias[$name] = $path; $this->set($name, $path); } - /** - * @param string[] $pathlist - */ - function findFile(array $pathlist, string $file): string { + function findFile($pathlist, string $file): string { foreach($pathlist as $key => $www) { if (file_exists($key . '/' . $file)) { @@ -185,12 +159,8 @@ class View extends \stdClass throw new Exception("file not found: $file"); } - - /** - * FIXME: Префикс, конфликтует с протоколом - * @param string[]|string[][] $alias - */ - function resolveName($alias, string $file): string { + // FIXME: Префикс, конфликтует с протоколом + function resolveName($alias, $file) { list($type, $filename) = explode(":", $file, 2); // Сделать поиск а не просто замену папки при совпадении имени @@ -205,23 +175,11 @@ class View extends \stdClass return $file; } - /** - * @param string[][] $alias - * @param string[] $list - * @return string[] - */ - public function resolveAllNames($alias, array $list): array { + public function resolveAllNames($alias, $list) { $result = []; foreach($list as $item) { $result [] = $this->resolveName($alias, $item); } return $result; } - - /** - * Шаблон всегда возвращает строку - */ - function execute(): string { - return ''; - } } diff --git a/src/ZipFile.php b/src/ZipFile.php index b6ecdf6..99ae70b 100644 --- a/src/ZipFile.php +++ b/src/ZipFile.php @@ -26,15 +26,12 @@ 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)) ? $this->addDir(...) : $this->addFile(...); - call_user_func($call, $location . $file, $name . $file); + $call = (is_dir($location . $file)) ? 'addDir' : 'addFile'; + call_user_func([$this, $call], $location . $file, $name . $file); } }