From e03c9bccfcf5b2a1e7a30ff803b1a703df6b4ae4 Mon Sep 17 00:00:00 2001 From: User Date: Thu, 2 May 2024 11:29:58 +0300 Subject: [PATCH] 20240502#1 --- .env.dist | 4 +- README.md | 2 +- application/config/container/services.php | 2 +- .../config/factories/templateFactory.php | 4 +- .../main/{09-main.yaml => 90-main.yaml} | 4 +- .../{Services => Application}/AbstractDTO.php | 2 +- .../ApplicationException.php} | 4 +- .../DTOException.php | 2 +- application/src/Domain/AbstractObject.php | 79 +--------------- application/src/Domain/EntityInterface.php | 18 ++++ .../{ => Infrastructure}/Components/.gitkeep | 0 .../Repository/AbstractMysqlRepository.php | 39 ++++++++ .../Repository/AbstractRepository.md | 12 +++ .../Repository/AbstractRepository.php | 93 +++++++++++++++++++ .../Repository/RepositoryException.php | 2 +- .../Controllers/AbstractController.php | 2 +- .../Controllers/AbstractPageController.php | 8 +- .../Controllers/NotFoundException.php | 2 +- .../src/Presentation/templates}/base.tpl | 0 .../src/Presentation/templates}/error/404.tpl | 0 .../src/Presentation/templates}/error/501.tpl | 0 .../Presentation/templates}/error/errpage.tpl | 0 .../src/Presentation/templates/inc/footer.tpl | 0 .../src/Presentation/templates/inc/header.tpl | 12 +++ .../Repository/AbstractMysqlRepository.php | 35 ------- application/src/Services/AbstractService.php | 10 -- composer.json | 13 +-- src/Main/{Services => Application}/.gitkeep | 0 src/Main/Infrastructure/Repository/.gitkeep | 0 .../Controllers/IndexController.php | 6 +- .../Main/Presentation/templates}/index.tpl | 0 31 files changed, 208 insertions(+), 147 deletions(-) rename application/config/routes/main/{09-main.yaml => 90-main.yaml} (52%) rename application/src/{Services => Application}/AbstractDTO.php (96%) rename application/src/{Services/ServiceException.php => Application/ApplicationException.php} (74%) rename application/src/{Services => Application}/DTOException.php (90%) create mode 100644 application/src/Domain/EntityInterface.php rename application/src/{ => Infrastructure}/Components/.gitkeep (100%) create mode 100644 application/src/Infrastructure/Repository/AbstractMysqlRepository.php create mode 100644 application/src/Infrastructure/Repository/AbstractRepository.md create mode 100644 application/src/Infrastructure/Repository/AbstractRepository.php rename application/src/{ => Infrastructure}/Repository/RepositoryException.php (86%) rename application/src/{ => Presentation}/Controllers/AbstractController.php (99%) rename application/src/{ => Presentation}/Controllers/AbstractPageController.php (84%) rename application/src/{ => Presentation}/Controllers/NotFoundException.php (57%) rename {templates => application/src/Presentation/templates}/base.tpl (100%) rename {templates => application/src/Presentation/templates}/error/404.tpl (100%) rename {templates => application/src/Presentation/templates}/error/501.tpl (100%) rename {templates => application/src/Presentation/templates}/error/errpage.tpl (100%) rename src/Main/Repository/.gitkeep => application/src/Presentation/templates/inc/footer.tpl (100%) create mode 100644 application/src/Presentation/templates/inc/header.tpl delete mode 100644 application/src/Repository/AbstractMysqlRepository.php delete mode 100644 application/src/Services/AbstractService.php rename src/Main/{Services => Application}/.gitkeep (100%) create mode 100644 src/Main/Infrastructure/Repository/.gitkeep rename src/Main/{ => Presentation}/Controllers/IndexController.php (73%) rename {templates/main => src/Main/Presentation/templates}/index.tpl (100%) diff --git a/.env.dist b/.env.dist index ae74f5a..5695ddf 100644 --- a/.env.dist +++ b/.env.dist @@ -17,8 +17,8 @@ CONTAINER_DIR=application/config/container CONTAINER_CACHE=var/cache/container # Default page -PAGE404=templates/error/404.tpl -PAGE501=templates/error/501.tpl +PAGE404="/application/src/Presentation/templates/error/404.tpl" +PAGE501="/application/src/Presentation/templates/error/501.tpl" # Users environment MYSQL_PARAM='{"host":"host.docker.internal", "user":"***user***", "pass":"***password***","base":"***basename***", "logsEnable":true}' \ No newline at end of file diff --git a/README.md b/README.md index 322cc22..b6c12a8 100644 --- a/README.md +++ b/README.md @@ -9,5 +9,5 @@ composer create-project rmphp/skeleton project-name ``` ```bash -composer create-project rmphp/skeleton:"^4.0" project-name +composer create-project rmphp/skeleton:"^4.1" project-name ``` \ No newline at end of file diff --git a/application/config/container/services.php b/application/config/container/services.php index 1dc2fdb..43e29ef 100644 --- a/application/config/container/services.php +++ b/application/config/container/services.php @@ -11,5 +11,5 @@ return [ MysqlStorageInterface::class => DI\create(MysqlStorage::class)->constructor(json_decode(getenv("MYSQL_PARAM"), true)), SessionInterface::class => DI\create(Session::class)->constructor(), CacheInterface::class => DI\create(Cache::class)->constructor("../var/cache"), - 'App\*\Domain\Repository\*Repository\*RepositoryInterface' => DI\autowire('App\*\Repository\Mysql\*Repository'), + 'App\*\Domain\Repository\*RepositoryInterface' => DI\autowire('App\*\Infrastructure\Repository\*Repository'), ]; \ No newline at end of file diff --git a/application/config/factories/templateFactory.php b/application/config/factories/templateFactory.php index d025a55..4d076c7 100644 --- a/application/config/factories/templateFactory.php +++ b/application/config/factories/templateFactory.php @@ -1,2 +1,4 @@ setSubtemplatePath('/templates'); \ No newline at end of file +return (new \Rmphp\Content\Content('/application/src/Presentation/templates/base.tpl'))->setSubtemplatePath('/application/src/Presentation/templates/')->setSubtemplatePathAlias([ + "main" => "/src/Main/Presentation/templates", +]); \ No newline at end of file diff --git a/application/config/routes/main/09-main.yaml b/application/config/routes/main/90-main.yaml similarity index 52% rename from application/config/routes/main/09-main.yaml rename to application/config/routes/main/90-main.yaml index 52bd3ee..5c6c9e8 100644 --- a/application/config/routes/main/09-main.yaml +++ b/application/config/routes/main/90-main.yaml @@ -1,13 +1,13 @@ # Index - key: "/" routes: - - action: "App\\Main\\Controllers\\IndexController" + - action: "App\\Main\\Presentation\\Controllers\\IndexController" method: "index" params: "" # Empty - key: "<@any>" routes: - - action: "App\\Main\\Controllers\\IndexController" + - action: "App\\Main\\Presentation\\Controllers\\IndexController" method: "emptyAction" params: "" diff --git a/application/src/Services/AbstractDTO.php b/application/src/Application/AbstractDTO.php similarity index 96% rename from application/src/Services/AbstractDTO.php rename to application/src/Application/AbstractDTO.php index 0aa5192..c285ba6 100644 --- a/application/src/Services/AbstractDTO.php +++ b/application/src/Application/AbstractDTO.php @@ -1,6 +1,6 @@ setProperties($data); - return $self; - } - - /** - * @param array $data - * @return void - * @throws DomainException - */ - public function setProperties(array $data) : void { - $class = new ReflectionClass(static::class); - foreach ($class->getProperties() as $property) { - $propertyNameSnakeCase = strtolower(preg_replace("'([A-Z])'", "_$1", $property->getName())); - // data[propertyName] ?? data[property_name] ?? null - $value = $data[$property->getName()] ?? $data[$propertyNameSnakeCase] ?? null; - - // если есть внутренний метод (приоритетная обработка) - if($class->hasMethod('set'.ucfirst($property->getName()))) $this->{'set'.ucfirst($property->getName())}($value); - // Если тип свойства класс (valueObject) - elseif($property->hasType() && class_exists($property->getType()->getName())) $this->{$property->getName()} = new ($property->getType()->getName())($value); - // если значения не пустое - elseif(isset($value)) $this->{$property->getName()} = $value; - } - } - - /** - * @param callable|null $method - * @return array - */ - public function getProperties(callable $method = null) : array { - $objectData = get_object_vars($this); - foreach ($objectData as $fieldName => $value) - { - // to option_id - $fieldNameSnakeCase = strtolower(preg_replace("'([A-Z])'", "_$1", $fieldName)); - - // если есть внутренний метод (приоритетная обработка) - if(method_exists($this, 'get'.ucfirst($fieldName))) { - $out[$fieldNameSnakeCase] = $this->{'get'.ucfirst($fieldName)}($value); - } - // если тип свойства класс (valueObject) - elseif($value instanceof ValueObjectInterface && null !== $value->get()) { - $out[$fieldNameSnakeCase] = $value->get(); - } - // если передана callable функция через которую нужно пропустить все элементы - elseif(isset($method) && !is_array($value) && !is_object($value)) { - $out[$fieldNameSnakeCase] = $method($value); - } - // если это логическое значение - elseif(is_bool($value)){ - $out[$fieldNameSnakeCase] = (int) $value; - } - // если это дробное число - elseif(is_float($value)) { - $out[$fieldNameSnakeCase] = $value; - } - // если это целое число - elseif(is_int($value)) { - $out[$fieldNameSnakeCase] = $value; - } - // если это строка - elseif(is_string($value)) { - $out[$fieldNameSnakeCase] = $value; - } - - } - return $out ?? []; + public function getId(): mixed { + return (isset($this->id)) ? (($this->id instanceof ValueObjectInterface) ? $this->id->get() : $this->id) : null; } } \ No newline at end of file diff --git a/application/src/Domain/EntityInterface.php b/application/src/Domain/EntityInterface.php new file mode 100644 index 0000000..a444486 --- /dev/null +++ b/application/src/Domain/EntityInterface.php @@ -0,0 +1,18 @@ +getProperties($object, function ($value){ + return (is_string($value)) ? $this->mysql->escapeStr($value) : $value; + }); + //dd($object, $in); + try { + if (!empty($object->getId()) && !empty($this->mysql->findById($table, $object->getId()))) { + $this->mysql->updateById($table, $in, $object->getId()); + return $object->getId(); + } else { + $this->mysql->insert($table, $in); + return (is_string($object->getId())) ? $object->getId() : $this->mysql->mysql()->insert_id; + } + } catch (\Throwable $throwable) {throw new RepositoryException($throwable->getMessage());} + } + + + + +} \ No newline at end of file diff --git a/application/src/Infrastructure/Repository/AbstractRepository.md b/application/src/Infrastructure/Repository/AbstractRepository.md new file mode 100644 index 0000000..183e9ef --- /dev/null +++ b/application/src/Infrastructure/Repository/AbstractRepository.md @@ -0,0 +1,12 @@ +### Создание объекта из массива + +```php +setProperties(array $data) : void +``` + + +### Получение массива из объекта + +```php +getProperties(callable $method = null) : array +``` \ No newline at end of file diff --git a/application/src/Infrastructure/Repository/AbstractRepository.php b/application/src/Infrastructure/Repository/AbstractRepository.php new file mode 100644 index 0000000..4533ce5 --- /dev/null +++ b/application/src/Infrastructure/Repository/AbstractRepository.php @@ -0,0 +1,93 @@ +getProperties() as $property) { + $propertyNameSnakeCase = strtolower(preg_replace("'([A-Z])'", "_$1", $property->getName())); + // data[propertyName] ?? data[property_name] ?? null + $value = $data[$property->getName()] ?? $data[$propertyNameSnakeCase] ?? null; + + // если есть внутренний метод (приоритетная обработка) + if(static::$classes[$class]->hasMethod('set'.ucfirst($property->getName()))) $object->{'set'.ucfirst($property->getName())}($value); + // Если тип свойства класс (valueObject) + elseif($property->hasType() && class_exists($property->getType()->getName())) $object->{$property->getName()} = new ($property->getType()->getName())($value); + // если значения не пустое + elseif(isset($value)) $object->{$property->getName()} = $value; + } + return $object; + } + catch (ReflectionException $exception) { + throw new RepositoryException($exception->getMessage()); + } + } + + /** + * @param object $class + * @param callable|null $method + * @return array + */ + public function getProperties(object $class, callable $method = null) : array { + + $objectData = get_object_vars($class); + foreach ($objectData as $fieldName => $value) + { + // to option_id + $fieldNameSnakeCase = strtolower(preg_replace("'([A-Z])'", "_$1", $fieldName)); + + // если есть внутренний метод (приоритетная обработка) + if(method_exists($this, 'get'.ucfirst($fieldName))) { + $out[$fieldNameSnakeCase] = $this->{'get'.ucfirst($fieldName)}($value); + } + // если тип свойства класс (valueObject) + elseif($value instanceof ValueObjectInterface && null !== $value->get()) { + $out[$fieldNameSnakeCase] = $value->get(); + } + // если передана callable функция через которую нужно пропустить все элементы + elseif(isset($method) && !is_array($value) && !is_object($value)) { + $out[$fieldNameSnakeCase] = $method($value); + } + // если это логическое значение + elseif(is_bool($value)){ + $out[$fieldNameSnakeCase] = (int) $value; + } + // если это дробное число + elseif(is_float($value)) { + $out[$fieldNameSnakeCase] = $value; + } + // если это целое число + elseif(is_int($value)) { + $out[$fieldNameSnakeCase] = $value; + } + // если это строка + elseif(is_string($value)) { + $out[$fieldNameSnakeCase] = $value; + } + + } + return $out ?? []; + } +} \ No newline at end of file diff --git a/application/src/Repository/RepositoryException.php b/application/src/Infrastructure/Repository/RepositoryException.php similarity index 86% rename from application/src/Repository/RepositoryException.php rename to application/src/Infrastructure/Repository/RepositoryException.php index 5745154..3e4534f 100644 --- a/application/src/Repository/RepositoryException.php +++ b/application/src/Infrastructure/Repository/RepositoryException.php @@ -1,6 +1,6 @@ logException($e) : $this->logError($e); - if($e instanceof DTOException || $e instanceof DomainException || $e instanceof ServiceException) return $e->getMessage(); + if($e instanceof DTOException || $e instanceof DomainException || $e instanceof ApplicationException) return $e->getMessage(); return "Ошибка. Дата и время: ".date("d-m-Y H:i:s"); } } \ No newline at end of file diff --git a/application/src/Controllers/NotFoundException.php b/application/src/Presentation/Controllers/NotFoundException.php similarity index 57% rename from application/src/Controllers/NotFoundException.php rename to application/src/Presentation/Controllers/NotFoundException.php index 00e47e4..42b657e 100644 --- a/application/src/Controllers/NotFoundException.php +++ b/application/src/Presentation/Controllers/NotFoundException.php @@ -1,6 +1,6 @@ + +
+
user->fio ?? "Гость"?>
+
+ + + +
+ \ No newline at end of file diff --git a/application/src/Repository/AbstractMysqlRepository.php b/application/src/Repository/AbstractMysqlRepository.php deleted file mode 100644 index cb267db..0000000 --- a/application/src/Repository/AbstractMysqlRepository.php +++ /dev/null @@ -1,35 +0,0 @@ -getProperties(function ($value){ - return (is_string($value)) ? $this->mysql->escapeStr($value) : $value; - }); - try { - if (!empty($object->id) && !empty($this->mysql->findById($table, $object->id))) { - $this->mysql->updateById($table, $in, $object->id); - } else { - $this->mysql->insert($table, $in); - $object->id = $this->mysql->mysql()->insert_id; - } - } catch (\Throwable $throwable) {throw new RepositoryException($throwable->getMessage());} - return $object; - } - - - - -} \ No newline at end of file diff --git a/application/src/Services/AbstractService.php b/application/src/Services/AbstractService.php deleted file mode 100644 index 9309e46..0000000 --- a/application/src/Services/AbstractService.php +++ /dev/null @@ -1,10 +0,0 @@ -addHeader("App-Mode", "Dev"); $this->template()->setValue("title", "Главная"); - $this->template()->setSubtemplate("main", "/main/index.tpl", [ + $this->template()->setSubtemplate("main", "@main/index.tpl", [ "date" => (new \DateTime())->format('Y-m-d H:i:s') ]); } diff --git a/templates/main/index.tpl b/src/Main/Presentation/templates/index.tpl similarity index 100% rename from templates/main/index.tpl rename to src/Main/Presentation/templates/index.tpl