Skip to content

Commit ac95ffa

Browse files
committed
Added docs starting
Signed-off-by: Howriq <[email protected]>
1 parent 8b5860a commit ac95ffa

File tree

3 files changed

+329
-0
lines changed

3 files changed

+329
-0
lines changed

docs/book/chapter-1.md

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
# Installing Doctrine
2+
3+
## Composer Requirements
4+
5+
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:
6+
7+
```json
8+
{
9+
"require": {
10+
"dotkernel/dot-cache": "^4.0",
11+
"ramsey/uuid": "^4.5.0",
12+
"ramsey/uuid-doctrine": "^2.1.0",
13+
"roave/psr-container-doctrine": "^5.2.2"
14+
},
15+
"require-dev": {
16+
"phpstan/phpstan-doctrine": "^2.0.3"
17+
}
18+
}
19+
```
20+
21+
`dotkernel/dot-cache`
22+
23+
Provides caching support for DotKernel applications.
24+
It offers a PSR-6 and PSR-16 compatible caching system that integrates smoothly with DotKernel's service container.
25+
26+
`ramsey/uuid`
27+
28+
A widely used PHP library for generating and working with UUIDs (Universally Unique Identifiers).
29+
It supports multiple UUID versions.
30+
31+
`ramsey/uuid-doctrine`
32+
33+
Adds UUID support to Doctrine ORM using ramsey/uuid.
34+
It allows Doctrine to store and retrieve UUIDs as proper value objects instead of plain strings, improving type safety.
35+
36+
`roave/psr-container-doctrine`
37+
38+
Provides a set of factory classes that integrate Doctrine ORM with any PSR-11 container.
39+
It simplifies wiring Doctrine EntityManager, DBAL, configuration, and related services in frameworks like DotKernel.
40+
41+
`phpstan/phpstan-doctrine (dev requirement)`
42+
43+
An extension for PHPStan that improves static analysis for Doctrine.
44+
It understands entity metadata, repositories, and common Doctrine patterns, helping catch errors during development.
45+
46+
## Setting Up Doctrine
47+
48+
After successfully installing our dependencies we now need to configure our Doctrine instance.
49+
50+
### Declare your database
51+
52+
In the file `config/autoload/local.php`:
53+
54+
```php
55+
$databases = [
56+
'default' => [
57+
'host' => 'localhost',
58+
'dbname' => 'light',
59+
'user' => 'root',
60+
'password' => '123',
61+
'port' => 3306,
62+
'driver' => 'pdo_mysql',
63+
'charset' => 'utf8mb4',
64+
'collate' => 'utf8mb4_general_ci',
65+
],
66+
// you can add more database connections into this array
67+
];
68+
69+
return [
70+
'databases' => $databases,
71+
//the rest of your configuration variables
72+
];
73+
```
74+
75+
### Declare the Doctrine Drivers and Migrations Location
76+
77+
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.
78+
This package takes all the provided configs from the `config/config.php` file and merges them into one.
79+
80+
Our new `src/App/src/ConfigProvider.php` class would look like this now:
81+
82+
```php
83+
<?php
84+
85+
declare(strict_types=1);
86+
87+
namespace Light\App;
88+
89+
use Doctrine\ORM\EntityManager;
90+
use Doctrine\ORM\EntityManagerInterface;
91+
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
92+
use Dot\Cache\Adapter\ArrayAdapter;
93+
use Dot\Cache\Adapter\FilesystemAdapter;
94+
use Light\App\Factory\GetIndexViewHandlerFactory;
95+
use Light\App\Handler\GetIndexViewHandler;
96+
use Mezzio\Application;
97+
use Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType;
98+
use Ramsey\Uuid\Doctrine\UuidBinaryType;
99+
use Ramsey\Uuid\Doctrine\UuidType;
100+
use Roave\PsrContainerDoctrine\EntityManagerFactory;
101+
102+
use function getcwd;
103+
104+
class ConfigProvider
105+
{
106+
/**
107+
@return array{
108+
* dependencies: array<mixed>,
109+
* templates: array<mixed>,
110+
* }
111+
*/
112+
public function __invoke(): array
113+
{
114+
return [
115+
'dependencies' => $this->getDependencies(),
116+
'doctrine' => $this->getDoctrineConfig(),
117+
'templates' => $this->getTemplates(),
118+
];
119+
}
120+
121+
/**
122+
* @return array{
123+
* delegators: array<class-string, array<class-string>>,
124+
* factories: array<class-string, class-string>,
125+
* }
126+
*/
127+
public function getDependencies(): array
128+
{
129+
return [
130+
'delegators' => [
131+
Application::class => [
132+
RoutesDelegator::class,
133+
],
134+
],
135+
'factories' => [
136+
'doctrine.entity_manager.orm_default' => EntityManagerFactory::class,
137+
GetIndexViewHandler::class => GetIndexViewHandlerFactory::class,
138+
],
139+
'aliases' => [
140+
EntityManager::class => 'doctrine.entity_manager.orm_default',
141+
EntityManagerInterface::class => 'doctrine.entity_manager.orm_default',
142+
],
143+
];
144+
}
145+
146+
/**
147+
* @return array{
148+
* paths: array{
149+
* app: array{literal-string&non-falsy-string},
150+
* error: array{literal-string&non-falsy-string},
151+
* layout: array{literal-string&non-falsy-string},
152+
* partial: array{literal-string&non-falsy-string},
153+
* }
154+
* }
155+
*/
156+
public function getTemplates(): array
157+
{
158+
return [
159+
'paths' => [
160+
'app' => [__DIR__ . '/../templates/app'],
161+
'error' => [__DIR__ . '/../templates/error'],
162+
'layout' => [__DIR__ . '/../templates/layout'],
163+
'partial' => [__DIR__ . '/../templates/partial'],
164+
],
165+
];
166+
}
167+
168+
private function getDoctrineConfig(): array
169+
{
170+
return [
171+
'cache' => [
172+
'array' => [
173+
'class' => ArrayAdapter::class,
174+
],
175+
'filesystem' => [
176+
'class' => FilesystemAdapter::class,
177+
'directory' => getcwd() . '/data/cache',
178+
'namespace' => 'doctrine',
179+
],
180+
],
181+
'configuration' => [
182+
'orm_default' => [
183+
'result_cache' => 'filesystem',
184+
'metadata_cache' => 'filesystem',
185+
'query_cache' => 'filesystem',
186+
'hydration_cache' => 'array',
187+
'typed_field_mapper' => null,
188+
'second_level_cache' => [
189+
'enabled' => true,
190+
'default_lifetime' => 3600,
191+
'default_lock_lifetime' => 60,
192+
'file_lock_region_directory' => '',
193+
'regions' => [],
194+
],
195+
],
196+
],
197+
'connection' => [
198+
'orm_default' => [
199+
'doctrine_mapping_types' => [
200+
UuidBinaryType::NAME => 'binary',
201+
UuidBinaryOrderedTimeType::NAME => 'binary',
202+
],
203+
],
204+
],
205+
'driver' => [
206+
// The default metadata driver aggregates all other drivers into a single one.
207+
// Override `orm_default` only if you know what you're doing.
208+
'orm_default' => [
209+
'class' => MappingDriverChain::class,
210+
],
211+
],
212+
'migrations' => [
213+
// Modify this line based on where you would like to have you migrations
214+
'migrations_paths' => [
215+
'Migrations' => 'src/Migrations',
216+
],
217+
'all_or_nothing' => true,
218+
'check_database_platform' => true,
219+
],
220+
'types' => [
221+
UuidType::NAME => UuidType::class,
222+
UuidBinaryType::NAME => UuidBinaryType::class,
223+
UuidBinaryOrderedTimeType::NAME => UuidBinaryOrderedTimeType::class,
224+
],
225+
];
226+
}
227+
}
228+
229+
```
230+
231+
We also require a new file `config/cli-config.php`.
232+
It initializes and returns a `DependencyFactory` that Doctrine Migrations uses to run migrations.
233+
234+
```php
235+
<?php
236+
237+
declare(strict_types=1);
238+
239+
use Doctrine\Migrations\Configuration\EntityManager\ExistingEntityManager;
240+
use Doctrine\Migrations\Configuration\Migration\ConfigurationArray;
241+
use Doctrine\Migrations\DependencyFactory;
242+
use Doctrine\ORM\EntityManager;
243+
244+
$container = require 'config/container.php';
245+
246+
$entityManager = $container->get(EntityManager::class);
247+
$entityManager->getEventManager();
248+
249+
return DependencyFactory::fromEntityManager(
250+
new ConfigurationArray($container->get('config')['doctrine']['migrations']),
251+
new ExistingEntityManager($entityManager)
252+
);
253+
```
254+
255+
## Running doctrine
256+
257+
Now that everything has been configured we only need to do one last thing, to create an executable for the Doctrine CLI.
258+
In our case we will create it as `/bin/doctrine`
259+
260+
```php
261+
#!/usr/bin/env php
262+
<?php
263+
264+
declare(strict_types=1);
265+
266+
use Doctrine\ORM\EntityManager;
267+
use Doctrine\ORM\Tools\Console\ConsoleRunner;
268+
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
269+
270+
require_once 'vendor/autoload.php';
271+
272+
$container = require 'config/container.php';
273+
274+
$entityManager = $container->get(EntityManager::class);
275+
$entityManager->getEventManager();
276+
277+
ConsoleRunner::run(new SingleManagerProvider($entityManager));
278+
```
279+
280+
(Optional) To keep things tidy we recommend to make an executable for the migrations of Doctrine as well for example `/bin/doctrine-migrations`:
281+
282+
```php
283+
#!/usr/bin/env php
284+
<?php
285+
286+
declare(strict_types=1);
287+
288+
namespace Doctrine\Migrations;
289+
290+
require __DIR__ . '/../vendor/doctrine/migrations/bin/doctrine-migrations.php';
291+
```
292+
293+
Now by running the command bellow we should see the Doctrine CLI version alongside its available commands:
294+
295+
```shell
296+
php bin/doctrine
297+
```
298+
299+
Example (truncated) output:
300+
301+
```terminaloutput
302+
Doctrine Command Line Interface 3.5.7.0
303+
304+
Options:
305+
-h, --help Display help for the given command. When no command is given display help for the list command
306+
--silent Do not output any message
307+
-q, --quiet Only errors are displayed. All other output is suppressed
308+
-V, --version Display this application version
309+
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
310+
-n, --no-interaction Do not ask any interactive question
311+
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
312+
```

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# ../../README.md

mkdocs.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
docs_dir: docs/book
2+
site_dir: docs/html
3+
extra:
4+
project: Tutorial-101
5+
current_version: v1
6+
versions:
7+
- v1
8+
nav:
9+
- Home: index.md
10+
- book:
11+
- Chapter 1: book/chapter-1.md
12+
site_name: 101.dotkernel
13+
site_description: "Beginner tutorial for using Dotkernel"
14+
repo_url: "https://github.com/dotkernel/tutorial-101#"
15+
plugins:
16+
- search

0 commit comments

Comments
 (0)