diff --git a/README.md b/README.md index 4e4f9d2..4339d56 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,3 @@ # tutorial-101 -Book tutorial starting from Dotkernel Light: Level 101 beginner - -### BRANCH : - main unde e documentatia , se compileaza documentatia. aplicatie din light, deploy functional !!!! --> 101.dotkernel.net - 1. instalezi light la tine pe WSL2 - 2. iei chapter 1, citesti documentation, implementezi una cite una - - CHAPTER-1-doctrine # protected - including Light, and add visible DIFF between branches - - CHAPTER-2- forms # protected - - CHAPTER-3- inputfilter # protected - - CHAPTER-4 -list books # protected - - main: incepi de la light , clone - - adaigi folderul docs/book cu structura asta https://github.com/dotkernel/dot-session/tree/5.0/docs/book - - cu fisier symlink si etc. - +Book tutorial starting from Dotkernel Light: Level 101 beginner diff --git a/bin/doctrine-migrations b/bin/doctrine-migrations new file mode 100755 index 0000000..d40cc55 --- /dev/null +++ b/bin/doctrine-migrations @@ -0,0 +1,8 @@ +#!/usr/bin/env php + [ - 'host' => 'localhost', - 'dbname' => 'light', - 'user' => 'root', - 'password' => '123', - 'port' => 3306, - 'driver' => 'pdo_mysql', - 'charset' => 'utf8mb4', - 'collate' => 'utf8mb4_general_ci', - ], - // you can add more database connections into this array -]; - -return [ - 'databases' => $databases, - 'doctrine' => [ - 'connection' => [ - 'orm_default' => [ - 'params' => $databases['default'], - ], - ], - ], - 'application' => [ - 'url' => $baseUrl, - ], - 'routes' => [ - 'page' => [ - 'about' => 'about', - 'who-we-are' => 'who-we-are', - ], - ], -]; diff --git a/config/cli-config.php b/config/cli-config.php new file mode 100644 index 0000000..0b723df --- /dev/null +++ b/config/cli-config.php @@ -0,0 +1,18 @@ +get(EntityManager::class); +$entityManager->getEventManager(); + +return DependencyFactory::fromEntityManager( + new ConfigurationArray($container->get('config')['doctrine']['migrations']), + new ExistingEntityManager($entityManager) +); diff --git a/config/config.php b/config/config.php index 1c58178..d45c47a 100644 --- a/config/config.php +++ b/config/config.php @@ -31,6 +31,7 @@ // Default App module config \Light\App\ConfigProvider::class, \Light\Page\ConfigProvider::class, + \Light\Book\ConfigProvider::class, // Load application config in a pre-defined order in such a way that local settings // overwrite global settings. (Loaded as first to last): diff --git a/data/cache/.gitignore b/data/cache/.gitignore old mode 100755 new mode 100644 diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index aa23067..0000000 --- a/mkdocs.yml +++ /dev/null @@ -1,16 +0,0 @@ -docs_dir: docs/book -site_dir: docs/html -extra: - project: Tutorial-101 - current_version: v1 - versions: - - v1 -nav: - - Home: index.md - - book: - - Chapter 1: book/chapter-1.md -site_name: 101.dotkernel -site_description: "Beginner tutorial for using Dotkernel" -repo_url: "https://github.com/dotkernel/tutorial-101#" -plugins: - - search \ No newline at end of file diff --git a/src/App/src/ConfigProvider.php b/src/App/src/ConfigProvider.php index f41f864..fd5a51b 100644 --- a/src/App/src/ConfigProvider.php +++ b/src/App/src/ConfigProvider.php @@ -6,24 +6,72 @@ use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Doctrine\Persistence\Mapping\Driver\MappingDriverChain; use Dot\Cache\Adapter\ArrayAdapter; use Dot\Cache\Adapter\FilesystemAdapter; +use Light\App\DBAL\Types\UuidType; use Light\App\Factory\GetIndexViewHandlerFactory; use Light\App\Handler\GetIndexViewHandler; use Mezzio\Application; -use Ramsey\Uuid\Doctrine\UuidType; use Roave\PsrContainerDoctrine\EntityManagerFactory; +use Symfony\Component\Cache\Adapter\AdapterInterface; use function getcwd; +/** + * @phpstan-type ConfigType array{ + * dependencies: DependenciesType, + * doctrine: DoctrineConfigType, + * } + * @phpstan-type DoctrineConfigType array{ + * cache: array{ + * array: array{ + * class: class-string, + * }, + * filesystem: array{ + * class: class-string, + * directory: non-empty-string, + * namespace: non-empty-string, + * }, + * }, + * configuration: array{ + * orm_default: array{ + * result_cache: non-empty-string, + * metadata_cache: non-empty-string, + * query_cache: non-empty-string, + * hydration_cache: non-empty-string, + * typed_field_mapper: non-empty-string|null, + * second_level_cache: array{ + * enabled: bool, + * default_lifetime: int, + * default_lock_lifetime: int, + * file_lock_region_directory: string, + * regions: string[], + * }, + * }, + * }, + * driver: array{ + * orm_default: array{ + * class: class-string, + * }, + * }, + * migrations: array{ + * migrations_paths: array, + * all_or_nothing: bool, + * check_database_platform: bool, + * }, + * types: array, + * } + * @phpstan-type DependenciesType array{ + * factories: array, + * aliases: array, + * } + **/ class ConfigProvider { /** - @return array{ - * dependencies: array, - * templates: array, - * } + * @return ConfigType */ public function __invoke(): array { @@ -35,10 +83,7 @@ public function __invoke(): array } /** - * @return array{ - * delegators: array>, - * factories: array, - * } + * @return DependenciesType */ public function getDependencies(): array { @@ -81,6 +126,9 @@ public function getTemplates(): array ]; } + /** + * @return DoctrineConfigType + */ private function getDoctrineConfig(): array { return [ @@ -117,6 +165,21 @@ private function getDoctrineConfig(): array 'class' => MappingDriverChain::class, ], ], + 'migrations' => [ + 'table_storage' => [ + 'table_name' => 'doctrine_migration_versions', + 'version_column_name' => 'version', + 'version_column_length' => 191, + 'executed_at_column_name' => 'executed_at', + 'execution_time_column_name' => 'execution_time', + ], + // Modify this line based on where you would like to have your migrations + 'migrations_paths' => [ + 'Migrations' => 'src/App/src/Migration', + ], + 'all_or_nothing' => true, + 'check_database_platform' => true, + ], 'types' => [ UuidType::NAME => UuidType::class, ], diff --git a/src/App/src/DBAL/Types/UuidType.php b/src/App/src/DBAL/Types/UuidType.php new file mode 100644 index 0000000..aafa1ac --- /dev/null +++ b/src/App/src/DBAL/Types/UuidType.php @@ -0,0 +1,17 @@ +id = Uuid::uuid7(); + } + + public function getId(): UuidInterface + { + return $this->id; + } + + public function setId(UuidInterface $id): static + { + $this->id = $id; + + return $this; + } + + public function getCreated(): ?DateTimeImmutable + { + return $this->created; + } + + public function getCreatedFormatted(string $dateFormat = 'Y-m-d H:i:s'): string + { + return $this->created->format($dateFormat); + } + + public function getUpdated(): ?DateTimeImmutable + { + return $this->updated; + } + + public function getUpdatedFormatted(string $dateFormat = 'Y-m-d H:i:s'): ?string + { + if ($this->updated instanceof DateTimeImmutable) { + return $this->updated->format($dateFormat); + } + + return null; + } + + #[ORM\PrePersist] + public function created(): void + { + $this->created = new DateTimeImmutable(); + } + + #[ORM\PreUpdate] + public function touch(): void + { + $this->updated = new DateTimeImmutable(); + } + + /** + * @param array $array + */ + public function exchangeArray(array $array): void + { + foreach ($array as $property => $values) { + if (is_array($values)) { + $method = 'add' . ucfirst($property); + if (! method_exists($this, $method)) { + continue; + } + foreach ($values as $value) { + $this->$method($value); + } + } else { + $method = 'set' . ucfirst($property); + if (! method_exists($this, $method)) { + continue; + } + $this->$method($values); + } + } + } +} diff --git a/src/App/src/Entity/EntityInterface.php b/src/App/src/Entity/EntityInterface.php new file mode 100644 index 0000000..f84aa49 --- /dev/null +++ b/src/App/src/Entity/EntityInterface.php @@ -0,0 +1,21 @@ + + */ +class AbstractRepository extends EntityRepository +{ + public function deleteResource(EntityInterface $resource): void + { + $this->getEntityManager()->remove($resource); + $this->getEntityManager()->flush(); + } + + public function getQueryBuilder(): QueryBuilder + { + return $this->getEntityManager()->createQueryBuilder(); + } + + public function saveResource(EntityInterface $resource): void + { + $this->getEntityManager()->persist($resource); + $this->getEntityManager()->flush(); + } +} diff --git a/src/Book/src/ConfigProvider.php b/src/Book/src/ConfigProvider.php new file mode 100644 index 0000000..063acbc --- /dev/null +++ b/src/Book/src/ConfigProvider.php @@ -0,0 +1,59 @@ +, + * }, + * BookEntities: array{ + * class: class-string, + * cache: non-empty-string, + * paths: non-empty-string[], + * }, + * }, + * } + */ +class ConfigProvider +{ + /** + * @return ConfigType + */ + public function __invoke(): array + { + return [ + 'doctrine' => $this->getDoctrineConfig(), + ]; + } + + /** + * @return DoctrineConfigType + */ + private function getDoctrineConfig(): array + { + return [ + 'driver' => [ + 'orm_default' => [ + 'drivers' => [ + 'Light\Book\Entity' => 'BookEntities', + ], + ], + 'BookEntities' => [ + 'class' => AttributeDriver::class, + 'cache' => 'array', + 'paths' => [__DIR__ . '/Entity'], + ], + ], + ]; + } +} diff --git a/src/Book/src/Entity/Book.php b/src/Book/src/Entity/Book.php new file mode 100644 index 0000000..bb24e86 --- /dev/null +++ b/src/Book/src/Entity/Book.php @@ -0,0 +1,57 @@ +title; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } + + public function getAuthor(): ?string + { + return $this->author; + } + + public function setAuthor(string $author): void + { + $this->author = $author; + } + + /** + * @return array{ + * id: non-empty-string, + * title: string, + * author: string + * } + */ + public function getArrayCopy(): array + { + return [ + 'id' => $this->id->toString(), + 'title' => $this->title, + 'author' => $this->author, + ]; + } +} diff --git a/src/Book/src/Repository/BookRepository.php b/src/Book/src/Repository/BookRepository.php new file mode 100644 index 0000000..44352b0 --- /dev/null +++ b/src/Book/src/Repository/BookRepository.php @@ -0,0 +1,14 @@ +