Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions bin/doctrine-fixtures
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env php
<?php

declare(strict_types=1);

use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Loader;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\EntityManager;

require_once 'vendor/autoload.php';

$container = require 'config/container.php';

$entityManager = $container->get(EntityManager::class);
$config = $container->get('config');

// Get fixtures directory from config
$fixturesPath = $config['doctrine']['fixtures'];

if (! is_dir($fixturesPath)) {
echo "Fixtures directory not found: {$fixturesPath}\n";
exit(1);
}

// Load fixtures
$loader = new Loader();
$loader->loadFromDirectory($fixturesPath);

// Execute fixtures
$purger = new ORMPurger();
$executor = new ORMExecutor($entityManager, $purger);

echo "Loading fixtures from: {$fixturesPath}\n";

$executor->execute($loader->getFixtures());

echo "Fixtures loaded successfully!\n";
File renamed without changes.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
},
"require": {
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
"doctrine/data-fixtures": "^2.2",
"doctrine/doctrine-fixtures-bundle": "^4.3",
"dotkernel/dot-cache": "^4.0",
"ramsey/uuid": "^4.5.0",
"ramsey/uuid-doctrine": "^2.1.0",
Expand Down
46 changes: 0 additions & 46 deletions config/autoload/local.php

This file was deleted.

2 changes: 2 additions & 0 deletions src/App/src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
* class: class-string<MappingDriver>,
* },
* },
* fixtures: non-empty-string,
* migrations: array{
* migrations_paths: array<non-empty-string, non-empty-string>,
* all_or_nothing: bool,
Expand Down Expand Up @@ -165,6 +166,7 @@ private function getDoctrineConfig(): array
'class' => MappingDriverChain::class,
],
],
'fixtures' => getcwd() . '/src/App/src/Fixture',
'migrations' => [
'table_storage' => [
'table_name' => 'doctrine_migration_versions',
Expand Down
32 changes: 32 additions & 0 deletions src/App/src/Factory/BookHandlerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Light\App\Factory;

use Light\Book\Handler\GetBooksHandler;
use Light\Book\Repository\BookRepository;
use Mezzio\Template\TemplateRendererInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;

use function assert;

class BookHandlerFactory
{
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function __invoke(ContainerInterface $container, string $requestedName): GetBooksHandler
{
$repository = $container->get(BookRepository::class);
$template = $container->get(TemplateRendererInterface::class);

assert($repository instanceof BookRepository);
assert($template instanceof TemplateRendererInterface);

return new GetBooksHandler($template, $repository);
}
}
31 changes: 31 additions & 0 deletions src/App/src/Factory/BookRepositoryFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Light\App\Factory;

use Doctrine\ORM\EntityManager;
use Light\Book\Entity\Book;
use Light\Book\Repository\BookRepository;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;

use function assert;

class BookRepositoryFactory
{
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function __invoke(ContainerInterface $container): BookRepository
{
$entityManager = $container->get(EntityManager::class);

$repository = $entityManager->getRepository(Book::class);
assert($repository instanceof BookRepository);

return $repository;
}
}
32 changes: 32 additions & 0 deletions src/App/src/Fixture/BookLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Light\App\Fixture;

use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Light\Book\Entity\Book;

class BookLoader extends Fixture
{
public function load(ObjectManager $manager): void
{
$book1 = new Book();
$book1->setTitle('A Game of Thrones');
$book1->setAuthor('George Martin');
$manager->persist($book1);

$book2 = new Book();
$book2->setTitle('The Lord of the Rings');
$book2->setAuthor('J.R.R. Tolkien');
$manager->persist($book2);

$book3 = new Book();
$book3->setTitle('Dune');
$book3->setAuthor('Frank Herbert');
$manager->persist($book3);

$manager->flush();
}
}
1 change: 1 addition & 0 deletions src/App/templates/layout/default.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<div class="dropdown-menu" aria-labelledby="pageDropdown">
<a class="dropdown-item" href="{{ url('page::about') }}">About Us</a>
<a class="dropdown-item" href="{{ url('page::who-we-are') }}">Who We Are</a>
<a class="dropdown-item" href="{{ url('books::list') }}">Books</a>
</div>
</li>
<li class="nav-item">
Expand Down
45 changes: 44 additions & 1 deletion src/Book/src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Light\App\Factory\BookHandlerFactory;
use Light\App\Factory\BookRepositoryFactory;
use Light\Book\Handler\GetBooksHandler;
use Light\Book\Repository\BookRepository;
use Mezzio\Application;

/**
* @phpstan-type ConfigType array{
Expand All @@ -23,6 +28,10 @@
* },
* },
* }
* @phpstan-type DependenciesType array{
* delegators: array<class-string, array<class-string>>,
* factories: array<class-string, class-string>,
* }
*/
class ConfigProvider
{
Expand All @@ -32,7 +41,27 @@ class ConfigProvider
public function __invoke(): array
{
return [
'doctrine' => $this->getDoctrineConfig(),
'dependencies' => $this->getDependencies(),
'doctrine' => $this->getDoctrineConfig(),
'templates' => $this->getTemplates(),
];
}

/**
* @return DependenciesType
*/
private function getDependencies(): array
{
return [
'delegators' => [
Application::class => [
RoutesDelegator::class,
],
],
'factories' => [
GetBooksHandler::class => BookHandlerFactory::class,
BookRepository::class => BookRepositoryFactory::class,
],
];
}

Expand All @@ -56,4 +85,18 @@ private function getDoctrineConfig(): array
],
];
}

/**
* @return array{
* paths: array{page: array{literal-string&non-falsy-string}}
* }
*/
private function getTemplates(): array
{
return [
'paths' => [
'page' => [__DIR__ . '/../templates/page'],
],
];
}
}
34 changes: 34 additions & 0 deletions src/Book/src/Handler/GetBooksHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Light\Book\Handler;

use Laminas\Diactoros\Response\HtmlResponse;
use Light\Book\Repository\BookRepository;
use Mezzio\Template\TemplateRendererInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

class GetBooksHandler implements RequestHandlerInterface
{
public function __construct(
protected TemplateRendererInterface $template,
protected BookRepository $bookRepository,
) {
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
$titles = $this->bookRepository->getTitles();
$authors = $this->bookRepository->getAuthors();

return new HtmlResponse(
$this->template->render('page::books', [
'titles' => $titles,
'authors' => $authors,
])
);
}
}
23 changes: 22 additions & 1 deletion src/Book/src/Repository/BookRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,31 @@
namespace Light\Book\Repository;

use Light\App\Repository\AbstractRepository;
use Light\Book\Entity\Book;

class BookRepository extends AbstractRepository
{
/**
* Any other custom methods can be added here
* @return array<int, array{id: non-empty-string, title: string}>
*/
public function getTitles(): array
{
$qb = $this->getQueryBuilder()
->select('book.id, book.title')
->from(Book::class, 'book');

return $qb->getQuery()->getResult();
}

/**
* @return array<int, array{id: non-empty-string, author: string}>
*/
public function getAuthors(): array
{
$qb = $this->getQueryBuilder()
->select('book.id, book.author')
->from(Book::class, 'book');

return $qb->getQuery()->getResult();
}
}
24 changes: 24 additions & 0 deletions src/Book/src/RoutesDelegator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Light\Book;

use Light\Book\Handler\GetBooksHandler;
use Mezzio\Application;
use Psr\Container\ContainerInterface;

use function assert;

class RoutesDelegator
{
public function __invoke(ContainerInterface $container, string $serviceName, callable $callback): Application
{
$app = $callback();
assert($app instanceof Application);

$app->get('/books', [GetBooksHandler::class], 'books::list');

return $app;
}
}
Loading