From fb7221e95fb31eb685ba8e3a4598270e9a578025 Mon Sep 17 00:00:00 2001 From: Howriq Date: Mon, 17 Nov 2025 18:25:45 +0200 Subject: [PATCH 1/4] Installing doctrine guide Signed-off-by: Howriq --- .../v1/tutorials/doctrine-installation.md | 312 ++++++++++++++++++ mkdocs.yml | 2 + 2 files changed, 314 insertions(+) create mode 100644 docs/book/v1/tutorials/doctrine-installation.md diff --git a/docs/book/v1/tutorials/doctrine-installation.md b/docs/book/v1/tutorials/doctrine-installation.md new file mode 100644 index 0000000..2334993 --- /dev/null +++ b/docs/book/v1/tutorials/doctrine-installation.md @@ -0,0 +1,312 @@ +# Installing Doctrine + +## Composer Requirements + +The first step is to add alongside your current packages the required entries for our Doctrine installation. We would add the following to our `composer.json` file located in our root folder: + +```json +{ + "require": { + "dotkernel/dot-cache": "^4.0", + "ramsey/uuid": "^4.5.0", + "ramsey/uuid-doctrine": "^2.1.0", + "roave/psr-container-doctrine": "^5.2.2" + }, + "require-dev": { + "phpstan/phpstan-doctrine": "^2.0.3" + } +} +``` + +`dotkernel/dot-cache` + +Provides caching support for DotKernel applications. +It offers a PSR-6 and PSR-16 compatible caching system that integrates smoothly with DotKernel's service container. + +`ramsey/uuid` + +A widely used PHP library for generating and working with UUIDs (Universally Unique Identifiers). +It supports multiple UUID versions. + +`ramsey/uuid-doctrine` + +Adds UUID support to Doctrine ORM using ramsey/uuid. +It allows Doctrine to store and retrieve UUIDs as proper value objects instead of plain strings, improving type safety. + +`roave/psr-container-doctrine` + +Provides a set of factory classes that integrate Doctrine ORM with any PSR-11 container. +It simplifies wiring Doctrine EntityManager, DBAL, configuration, and related services in frameworks like DotKernel. + +`phpstan/phpstan-doctrine (dev requirement)` + +An extension for PHPStan that improves static analysis for Doctrine. +It understands entity metadata, repositories, and common Doctrine patterns, helping catch errors during development. + +# Setting Up Doctrine + +After successfully installing our dependencies we now need to configure our Doctrine instance. + +### Declare your database + +In the file `config/autoload/local.php`: + +```php +$databases = [ + 'default' => [ + '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, + //the rest of your configuration variables +]; +``` + +### Declare the Doctrine Drivers and Migrations Location + +With the very nice utility of the package `laminas/laminas-config-aggregator` we can declare our doctrine settings in the `src/App/src/ConfigProvider.php` file. +This package takes all the provided configs from the `config/config.php` file and merges them into one. + +Our new `src/App/src/ConfigProvider.php` class would look like this now: + +```php +, + * templates: array, + * } + */ + public function __invoke(): array + { + return [ + 'dependencies' => $this->getDependencies(), + 'doctrine' => $this->getDoctrineConfig(), + 'templates' => $this->getTemplates(), + ]; + } + + /** + * @return array{ + * delegators: array>, + * factories: array, + * } + */ + public function getDependencies(): array + { + return [ + 'delegators' => [ + Application::class => [ + RoutesDelegator::class, + ], + ], + 'factories' => [ + 'doctrine.entity_manager.orm_default' => EntityManagerFactory::class, + GetIndexViewHandler::class => GetIndexViewHandlerFactory::class, + ], + 'aliases' => [ + EntityManager::class => 'doctrine.entity_manager.orm_default', + EntityManagerInterface::class => 'doctrine.entity_manager.orm_default', + ], + ]; + } + + /** + * @return array{ + * paths: array{ + * app: array{literal-string&non-falsy-string}, + * error: array{literal-string&non-falsy-string}, + * layout: array{literal-string&non-falsy-string}, + * partial: array{literal-string&non-falsy-string}, + * } + * } + */ + public function getTemplates(): array + { + return [ + 'paths' => [ + 'app' => [__DIR__ . '/../templates/app'], + 'error' => [__DIR__ . '/../templates/error'], + 'layout' => [__DIR__ . '/../templates/layout'], + 'partial' => [__DIR__ . '/../templates/partial'], + ], + ]; + } + + private function getDoctrineConfig(): array + { + return [ + 'cache' => [ + 'array' => [ + 'class' => ArrayAdapter::class, + ], + 'filesystem' => [ + 'class' => FilesystemAdapter::class, + 'directory' => getcwd() . '/data/cache', + 'namespace' => 'doctrine', + ], + ], + 'configuration' => [ + 'orm_default' => [ + 'result_cache' => 'filesystem', + 'metadata_cache' => 'filesystem', + 'query_cache' => 'filesystem', + 'hydration_cache' => 'array', + 'typed_field_mapper' => null, + 'second_level_cache' => [ + 'enabled' => true, + 'default_lifetime' => 3600, + 'default_lock_lifetime' => 60, + 'file_lock_region_directory' => '', + 'regions' => [], + ], + ], + ], + 'connection' => [ + 'orm_default' => [ + 'doctrine_mapping_types' => [ + UuidBinaryType::NAME => 'binary', + UuidBinaryOrderedTimeType::NAME => 'binary', + ], + ], + ], + 'driver' => [ + // The default metadata driver aggregates all other drivers into a single one. + // Override `orm_default` only if you know what you're doing. + 'orm_default' => [ + 'class' => MappingDriverChain::class, + ], + ], + 'migrations' => [ + // Modify this line based on where you would like to have you migrations + 'migrations_paths' => [ + 'Migrations' => 'src/Migrations', + ], + 'all_or_nothing' => true, + 'check_database_platform' => true, + ], + 'types' => [ + UuidType::NAME => UuidType::class, + UuidBinaryType::NAME => UuidBinaryType::class, + UuidBinaryOrderedTimeType::NAME => UuidBinaryOrderedTimeType::class, + ], + ]; + } +} + +``` + +We also require a new file `config/cli-config.php`. +It initializes and returns a `DependencyFactory` that Doctrine Migrations uses to run migrations. + +```php +get(EntityManager::class); +$entityManager->getEventManager(); + +return DependencyFactory::fromEntityManager( + new ConfigurationArray($container->get('config')['doctrine']['migrations']), + new ExistingEntityManager($entityManager) +); +``` + +# Running doctrine + +Now that everything has been configured we only need to do one last thing, to create an executable for the Doctrine CLI. +In our case we will create it as `/bin/doctrine` + +```php +#!/usr/bin/env php +get(EntityManager::class); +$entityManager->getEventManager(); + +ConsoleRunner::run(new SingleManagerProvider($entityManager)); +``` + +(Optional) To keep things tidy I recommend to make an executable for the migrations of Doctrine as well for example `/bin/doctrine-migrations`: + +```php +#!/usr/bin/env php + Date: Mon, 17 Nov 2025 18:28:24 +0200 Subject: [PATCH 2/4] Installing doctrine guide Signed-off-by: Howriq --- docs/book/v1/tutorials/doctrine-installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/book/v1/tutorials/doctrine-installation.md b/docs/book/v1/tutorials/doctrine-installation.md index 2334993..7b2a01a 100644 --- a/docs/book/v1/tutorials/doctrine-installation.md +++ b/docs/book/v1/tutorials/doctrine-installation.md @@ -43,7 +43,7 @@ It simplifies wiring Doctrine EntityManager, DBAL, configuration, and related se An extension for PHPStan that improves static analysis for Doctrine. It understands entity metadata, repositories, and common Doctrine patterns, helping catch errors during development. -# Setting Up Doctrine +## Setting Up Doctrine After successfully installing our dependencies we now need to configure our Doctrine instance. @@ -252,7 +252,7 @@ return DependencyFactory::fromEntityManager( ); ``` -# Running doctrine +## Running doctrine Now that everything has been configured we only need to do one last thing, to create an executable for the Doctrine CLI. In our case we will create it as `/bin/doctrine` From 50c3a8d1a4b2dbf1f5110955f3a5c2ea1f8a347f Mon Sep 17 00:00:00 2001 From: Howriq Date: Mon, 17 Nov 2025 18:30:00 +0200 Subject: [PATCH 3/4] Installing doctrine guide Signed-off-by: Howriq --- docs/book/v1/tutorials/doctrine-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/v1/tutorials/doctrine-installation.md b/docs/book/v1/tutorials/doctrine-installation.md index 7b2a01a..50d6a57 100644 --- a/docs/book/v1/tutorials/doctrine-installation.md +++ b/docs/book/v1/tutorials/doctrine-installation.md @@ -298,7 +298,7 @@ php bin/doctrine Example (truncated) output: -``` +```terminaloutput Doctrine Command Line Interface 3.5.7.0 Options: From d0c1430f316f640fa442d91453dc67fb5c48f09f Mon Sep 17 00:00:00 2001 From: Howriq Date: Mon, 17 Nov 2025 18:30:37 +0200 Subject: [PATCH 4/4] Installing doctrine guide Signed-off-by: Howriq --- docs/book/v1/tutorials/doctrine-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/v1/tutorials/doctrine-installation.md b/docs/book/v1/tutorials/doctrine-installation.md index 50d6a57..c6cb65f 100644 --- a/docs/book/v1/tutorials/doctrine-installation.md +++ b/docs/book/v1/tutorials/doctrine-installation.md @@ -277,7 +277,7 @@ $entityManager->getEventManager(); ConsoleRunner::run(new SingleManagerProvider($entityManager)); ``` -(Optional) To keep things tidy I recommend to make an executable for the migrations of Doctrine as well for example `/bin/doctrine-migrations`: +(Optional) To keep things tidy we recommend to make an executable for the migrations of Doctrine as well for example `/bin/doctrine-migrations`: ```php #!/usr/bin/env php