From cbd03528864d6c4d8011433f187d31e1160eab50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Debussch=C3=A8re?= Date: Fri, 18 Jul 2025 11:42:40 +0200 Subject: [PATCH 1/3] feat(bdd): now uses laminas-db - updated repositories - updated services - added mappers --- composer.json | 3 +- config/containers/database.container.php | 11 +-- src/Model/Album.php | 5 +- src/Model/Artist.php | 5 +- src/Model/Model.php | 13 +++ src/Repository/AbstractRepository.php | 64 ++++++++++++++ src/Repository/AlbumRepository.php | 87 +------------------ src/Repository/ArtistRepository.php | 72 +-------------- src/Repository/ArtistRepositoryInterface.php | 22 ----- src/Repository/Mapper/AlbumMapper.php | 20 +++++ src/Repository/Mapper/ArtistMapper.php | 20 +++++ ...yInterface.php => RepositoryInterface.php} | 8 +- src/Service/AbstractService.php | 58 +++++++++++++ src/Service/AlbumService.php | 37 +++++--- src/Service/ArtistService.php | 23 +++-- 15 files changed, 235 insertions(+), 213 deletions(-) create mode 100644 src/Model/Model.php create mode 100644 src/Repository/AbstractRepository.php delete mode 100644 src/Repository/ArtistRepositoryInterface.php create mode 100644 src/Repository/Mapper/AlbumMapper.php create mode 100644 src/Repository/Mapper/ArtistMapper.php rename src/Repository/{AlbumRepositoryInterface.php => RepositoryInterface.php} (72%) create mode 100644 src/Service/AbstractService.php diff --git a/composer.json b/composer.json index 2cec473..3902234 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,8 @@ "monolog/monolog": "^2 || ^3", "vlucas/phpdotenv": "^v5.1", "league/container": "^4", - "zircote/swagger-php": "^5.0" + "zircote/swagger-php": "^5.0", + "laminas/laminas-db": "^2.20" }, "require-dev": { "pestphp/pest": "^3.0", diff --git a/config/containers/database.container.php b/config/containers/database.container.php index e5ab000..0d47b31 100644 --- a/config/containers/database.container.php +++ b/config/containers/database.container.php @@ -1,12 +1,13 @@ add(PDO::class) - ->addArgument('sqlite:'.storage_path('database.sqlite')) - ->addMethodCall('setAttribute', [PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION]) - ->addMethodCall('setAttribute', [PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC]) - ->addMethodCall('setAttribute', [PDO::ATTR_EMULATE_PREPARES, false]); + ->add(AdapterInterface::class, Adapter::class) + ->addArgument([ + 'driver' => 'Pdo_Sqlite', + 'dsn' => 'sqlite:'.storage_path('database.sqlite') + ]); }; diff --git a/src/Model/Album.php b/src/Model/Album.php index 2a1aef4..daa5fe8 100644 --- a/src/Model/Album.php +++ b/src/Model/Album.php @@ -5,12 +5,9 @@ use OpenApi\Attributes as OA; #[OA\Schema] -class Album +class Album extends Model { - #[OA\Property(example: 42, nullable: false)] - public int $id; - #[OA\Property(example: 'Minha História', nullable: false)] public string $title; diff --git a/src/Model/Artist.php b/src/Model/Artist.php index b6c2b6a..7840117 100644 --- a/src/Model/Artist.php +++ b/src/Model/Artist.php @@ -5,12 +5,9 @@ use OpenApi\Attributes as OA; #[OA\Schema] -class Artist +class Artist extends Model { - #[OA\Property(example: 1, nullable: false)] - public int $id; - #[OA\Property(example: 'AC/DC', nullable: false)] public string $name; } \ No newline at end of file diff --git a/src/Model/Model.php b/src/Model/Model.php new file mode 100644 index 0000000..e43f596 --- /dev/null +++ b/src/Model/Model.php @@ -0,0 +1,13 @@ +table_gateway = new TableGateway($this->getTable(), $adapter); + $this->logger = $logger->withName(__CLASS__); + } + + abstract protected function getTable(): string; + + /** + * @return T[] + */ + public function all(): array + { + return iterator_to_array($this->table_gateway->select()); + } + + /** + * @return T|null + */ + public function find(int $id): ?array + { + $rowset = $this->table_gateway->select([static::ROW_IDENTIFIER => $id]); + $row = (array)$rowset->current(); + + return $row ?: null; + } + + public function create(array $data): int + { + $this->table_gateway->insert($data); + + return $this->table_gateway->getLastInsertValue(); + } + + public function update(int $id, array $data): bool + { + return $this->table_gateway->update($data, [static::ROW_IDENTIFIER => $id]) > 0; + } + + public function delete(int $id): bool + { + return $this->table_gateway->delete([static::ROW_IDENTIFIER => $id]) > 0; + } +} diff --git a/src/Repository/AlbumRepository.php b/src/Repository/AlbumRepository.php index 97d87db..d4aac8d 100644 --- a/src/Repository/AlbumRepository.php +++ b/src/Repository/AlbumRepository.php @@ -2,92 +2,13 @@ namespace App\Repository; -use App\Model\Artist; -use InvalidArgumentException; -use Monolog\Logger; -use PDO; -use RuntimeException; - -readonly class AlbumRepository implements AlbumRepositoryInterface +readonly class AlbumRepository extends AbstractRepository { - private Logger $logger; - - public function __construct( - private PDO $pdo, - Logger $logger - ) { - $this->logger = $logger->withName(__CLASS__); - } - - /** @return Artist[] */ - public function all(): array - { - return $this - ->pdo - ->query('SELECT AlbumId AS id, Title AS title, ArtistId as artist_id FROM albums') - ->fetchAll(PDO::FETCH_CLASS, Artist::class); - } - - public function find(int $id): ?Artist - { - $stmt = $this - ->pdo - ->prepare('SELECT AlbumId AS id, Title AS title, ArtistId as artist_id FROM albums WHERE AlbumId = ?'); - - $stmt->execute([$id]); - - return $stmt->fetchObject(Artist::class) ?: null; - } - - public function create(array $data): int - { - $stmt = $this - ->pdo - ->prepare('INSERT INTO albums (Title, ArtistId) VALUES (?, ?)'); - - if (!$stmt->execute([$data['title'], $data['artist_id']])) { - $this->logger->error('An error occurred while trying to create an album with data: {data}', ['{data}' => implode(', ', array_keys($data))]); - throw new RuntimeException('Error creating album', 500); - } - - return (int)$this->pdo->lastInsertId(); - } + public const ROW_IDENTIFIER = 'AlbumId'; - public function update(int $id, array $data): bool + protected function getTable(): string { - $fields = []; - $values = []; - - if (isset($data['title'])) { - $fields[] = 'Title = ?'; - $values[] = $data['title']; - } - - if (isset($data['artist_id'])) { - $fields[] = 'ArtistId = ?'; - $values[] = $data['artist_id']; - } - - if (empty($fields)) { - $this->logger->error('No data provided to update Album #{id}', ['{id}' => $id]); - throw new InvalidArgumentException('No data to update'); - } - - $values[] = $id; - $sql = 'UPDATE albums SET '.implode(', ', $fields).' WHERE AlbumId = ?'; - - $stmt = $this->pdo->prepare($sql); - - return $stmt->execute($values); - } - - public function delete(int $id): bool - { - $stmt = $this - ->pdo - ->prepare('DELETE FROM albums WHERE AlbumId = ?'); - - return $stmt->execute([$id]); + return 'albums'; } } diff --git a/src/Repository/ArtistRepository.php b/src/Repository/ArtistRepository.php index c3d3c56..813a41e 100644 --- a/src/Repository/ArtistRepository.php +++ b/src/Repository/ArtistRepository.php @@ -2,77 +2,13 @@ namespace App\Repository; -use App\Model\Artist; -use Monolog\Logger; -use PDO; -use RuntimeException; - -readonly class ArtistRepository implements ArtistRepositoryInterface +readonly class ArtistRepository extends AbstractRepository { - private Logger $logger; - - public function __construct( - private PDO $pdo, - Logger $logger - ) { - $this->logger = $logger->withName(__CLASS__); - } - - /** @return Artist[] */ - public function all(): array - { - return $this - ->pdo - ->query('SELECT ArtistId AS id, Name AS name FROM artists') - ->fetchAll(PDO::FETCH_CLASS, Artist::class); - } - - public function find(int $id): ?Artist - { - $stmt = $this - ->pdo - ->prepare('SELECT ArtistId AS id, Name AS name FROM artists WHERE ArtistId = ?'); - - $stmt->execute([$id]); - - return $stmt->fetchObject(Artist::class) ?: null; - } - - public function create(array $data): int - { - $stmt = $this - ->pdo - ->prepare('INSERT INTO artists (Name) VALUES (?)'); - - if (!$stmt->execute([$data['name']])) { - $this->logger->error('An error occurred while trying to create an artist with data: {data}', ['{data}' => implode(', ', array_keys($data))]); - throw new RuntimeException('Error creating artist', 500); - } + public const ROW_IDENTIFIER = 'ArtistId'; - return (int)$this->pdo->lastInsertId(); - } - - public function update(int $id, array $data): bool + protected function getTable(): string { - if (!isset($data['name'])) { - $this->logger->error('No data provided to update Artist #{id}', ['{id}' => $id]); - throw new RuntimeException('No fields to update', 400); - } - - $stmt = $this - ->pdo - ->prepare('UPDATE artists SET Name = ? WHERE ArtistId = ?'); - - return $stmt->execute([$data['name'], $id]); - } - - public function delete(int $id): bool - { - $stmt = $this - ->pdo - ->prepare('DELETE FROM artists WHERE ArtistId = ?'); - - return $stmt->execute([$id]); + return 'artists'; } } diff --git a/src/Repository/ArtistRepositoryInterface.php b/src/Repository/ArtistRepositoryInterface.php deleted file mode 100644 index 1dea9c1..0000000 --- a/src/Repository/ArtistRepositoryInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -id = $object[AlbumRepository::ROW_IDENTIFIER] ?? null; + $album->title = $object['Title'] ?? null; + $album->artist_id = $object['ArtistId'] ?? null; + + return $album; + } +} diff --git a/src/Repository/Mapper/ArtistMapper.php b/src/Repository/Mapper/ArtistMapper.php new file mode 100644 index 0000000..95460cf --- /dev/null +++ b/src/Repository/Mapper/ArtistMapper.php @@ -0,0 +1,20 @@ +id = $object[ArtistRepository::ROW_IDENTIFIER] ?? null; + $artist->name = $object['Name'] ?? null; + + return $artist; + } + +} diff --git a/src/Repository/AlbumRepositoryInterface.php b/src/Repository/RepositoryInterface.php similarity index 72% rename from src/Repository/AlbumRepositoryInterface.php rename to src/Repository/RepositoryInterface.php index 2e4f4c7..1265abd 100644 --- a/src/Repository/AlbumRepositoryInterface.php +++ b/src/Repository/RepositoryInterface.php @@ -2,15 +2,15 @@ namespace App\Repository; -use App\Model\Artist; +use App\Model\Model; -interface AlbumRepositoryInterface +interface RepositoryInterface { - /** @return Artist[] */ + /** @return Model[] */ public function all(): array; - public function find(int $id): ?Artist; + public function find(int $id): ?array; /** @param array{title: string, artist_id: int} $data */ public function create(array $data): int; diff --git a/src/Service/AbstractService.php b/src/Service/AbstractService.php new file mode 100644 index 0000000..dbbd3ea --- /dev/null +++ b/src/Service/AbstractService.php @@ -0,0 +1,58 @@ +table_gateway = new TableGateway($this->getTable(), $this->adapter); + $this->logger = $logger->withName(__CLASS__); + } + + public function getRowIdentifier(): string + { + return 'id'; + } + + abstract protected function getTable(): string; + + public function findAll(): array + { + return iterator_to_array($this->table_gateway->select()); + } + + public function findById(int $id): ?array + { + $rowset = $this->table_gateway->select([$this->getRowIdentifier() => $id]); + $row = (array)$rowset->current(); + return $row ?: null; + } + + public function insert(array $data): int + { + $this->table_gateway->insert($data); + + return $this->table_gateway->getLastInsertValue(); + } + + public function update(array $data, array $where): int + { + return $this->table_gateway->update($data, $where); + } + + public function delete(array $where): int + { + return $this->table_gateway->delete($where); + } +} diff --git a/src/Service/AlbumService.php b/src/Service/AlbumService.php index f1bbb39..2a72c5f 100644 --- a/src/Service/AlbumService.php +++ b/src/Service/AlbumService.php @@ -2,8 +2,11 @@ namespace App\Service; +use App\Model\Album; use App\Model\Artist; use App\Repository\AlbumRepository; +use App\Repository\Mapper\AlbumMapper; +use ArrayObject; use InvalidArgumentException; use Monolog\Logger; use RuntimeException; @@ -20,13 +23,16 @@ public function __construct( $this->logger = $logger->withName(__CLASS__); } - /** @return Artist[] */ + /** @return Album[] */ public function all(): array { - return $this->repository->all(); + return array_map( + fn(ArrayObject $album): Album => AlbumMapper::toAlbum($album), + $this->repository->all() + ); } - public function find(int $id): ?Artist + public function find(int $id): ?Album { $album = $this->repository->find($id); if ($album === null) { @@ -34,52 +40,57 @@ public function find(int $id): ?Artist throw new RuntimeException('Album does not exist', 404); } - return $this->repository->find($id); + return AlbumMapper::toAlbum($album); } /** @param array{title: string, artist_id: int} $data */ - public function create(array $data): Artist + public function create(array $data): Album { if (!isset($data['title'], $data['artist_id'])) { $this->logger->error('Missing required data, unable to save Album, provided data: {data}', ['{data}' => implode(', ', array_keys($data))]); throw new InvalidArgumentException('Missing data, "title" and "artist_id" fields are required'); } - $id = $this->repository->create($data); + $id = $this->repository->create(['Title' => $data['title'], 'ArtistId' => $data['artist_id']]); if ($id === 0) { $this->logger->error('Unable to create album, provided data: {data}', ['{data}' => implode(', ', array_keys($data))]); throw new RuntimeException('Album could not be created', 500); } - return $this->repository->find($id); + return $this->find($id); } /** @param array{title?: string, artist_id?: int} $data */ - public function update(int $id, array $data): Artist + public function update(int $id, array $data): Album { if (!isset($data['title']) && !isset($data['artist_id'])) { $this->logger->error('Missing required data, unable to update Album, provided data: {data}', ['{data}' => implode(', ', array_keys($data))]); throw new InvalidArgumentException('Missing data, "title" and/or "artist_id" fields are required'); } - $album = $this->repository->find($id); - if ($album === null) { + $album = $this->find($id); + if (!$album instanceof Album) { $this->logger->error('Album with ID #{id} not found', ['{id}' => $id]); throw new RuntimeException('Album does not exist', 404); } + $data = array_filter([ + 'Title' => $data['title'] ?? null, + 'ArtistId' => $data['artist_id'] ?? null, + ]); + if (!$this->repository->update($id, $data)) { $this->logger->error('Album could not be updated with provided data: {data}', ['{data}' => implode(', ', array_keys($data))]); throw new RuntimeException('Album could not be updated', 500); } - return $this->repository->find($id); + return $this->find($id); } public function delete(int $id): bool { - $album = $this->repository->find($id); - if ($album === null) { + $album = $this->find($id); + if (!$album instanceof Album) { $this->logger->error('Album with ID #{id} not found', ['{id}' => $id]); throw new RuntimeException('Album does not exist', 404); } diff --git a/src/Service/ArtistService.php b/src/Service/ArtistService.php index 3740751..a6c4269 100644 --- a/src/Service/ArtistService.php +++ b/src/Service/ArtistService.php @@ -4,6 +4,8 @@ use App\Model\Artist; use App\Repository\ArtistRepository; +use App\Repository\Mapper\ArtistMapper; +use ArrayObject; use InvalidArgumentException; use Monolog\Logger; use RuntimeException; @@ -23,7 +25,10 @@ public function __construct( /** @return Artist[] */ public function all(): array { - return $this->repository->all(); + return array_map( + fn(ArrayObject $artist): Artist => ArtistMapper::toArtist($artist), + $this->repository->all() + ); } public function find(int $id): ?Artist @@ -34,7 +39,7 @@ public function find(int $id): ?Artist throw new RuntimeException('Artist does not exist', 404); } - return $artist; + return ArtistMapper::toArtist($artist); } /** @param array{name: string} $data */ @@ -45,13 +50,13 @@ public function create(array $data): Artist throw new InvalidArgumentException('Missing data, "name" field is required'); } - $id = $this->repository->create($data); + $id = $this->repository->create(['Name' => $data['name']]); if ($id === 0) { $this->logger->error('Unable to create artist, provided data: {data}', ['data' => implode(', ', array_keys($data))]); throw new RuntimeException('Artist could not be created', 500); } - return $this->repository->find($id); + return $this->find($id); } /** @param array{name: string} $data */ @@ -62,8 +67,8 @@ public function update(int $id, array $data): Artist throw new InvalidArgumentException('Missing data, "name" field is required'); } - $artist = $this->repository->find($id); - if ($artist === null) { + $artist = $this->find($id); + if (!$artist instanceof Artist) { $this->logger->error('Artist with ID #{id} not found', ['{id}' => $id]); throw new RuntimeException('Artist does not exist', 404); } @@ -73,13 +78,13 @@ public function update(int $id, array $data): Artist throw new RuntimeException('Artist could not be updated', 500); } - return $this->repository->find($id); + return $this->find($id); } public function delete(int $id): bool { - $artist = $this->repository->find($id); - if ($artist === null) { + $artist = $this->find($id); + if (!$artist instanceof Artist) { $this->logger->error('Artist with ID #{id} not found', ['{id}' => $id]); throw new RuntimeException('Artist does not exist', 404); } From e04460fa4c73b4c1e5636ff80792b2ce5929983d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Debussch=C3=A8re?= Date: Fri, 18 Jul 2025 18:44:33 +0200 Subject: [PATCH 2/3] fix(php): php 8.4 for tests and laminas-db --- .github/workflows/php.yml | 4 +- src/Repository/AbstractRepository.php | 14 +++---- src/Repository/Mapper/AlbumMapper.php | 3 +- src/Repository/Mapper/ArtistMapper.php | 3 +- src/Repository/RepositoryInterface.php | 7 ++-- src/Service/AbstractService.php | 58 -------------------------- src/Service/AlbumService.php | 4 +- src/Service/ArtistService.php | 3 +- 8 files changed, 18 insertions(+), 78 deletions(-) delete mode 100644 src/Service/AbstractService.php diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index ac8402a..84735b7 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -37,7 +37,7 @@ jobs: run: composer config --no-plugins allow-plugins.pestphp/pest-plugin true - name: Install dependencies - run: composer install --prefer-dist --no-interaction --no-progress + run: composer install --prefer-dist --no-interaction --no-progress --ignore-platform-reqs - name: Copy environment file run: cp .env.example .env @@ -46,4 +46,4 @@ jobs: run: composer test - name: PHPStan - run: composer phpstan \ No newline at end of file + run: composer phpstan diff --git a/src/Repository/AbstractRepository.php b/src/Repository/AbstractRepository.php index eadf1a2..f7821a4 100644 --- a/src/Repository/AbstractRepository.php +++ b/src/Repository/AbstractRepository.php @@ -3,12 +3,10 @@ namespace App\Repository; use Laminas\Db\Adapter\AdapterInterface; +use Laminas\Db\ResultSet\ResultSet; use Laminas\Db\TableGateway\TableGateway; use Monolog\Logger; -/** - * @template T - */ abstract readonly class AbstractRepository implements RepositoryInterface { @@ -27,7 +25,7 @@ public function __construct(AdapterInterface $adapter, Logger $logger) abstract protected function getTable(): string; /** - * @return T[] + * @return array> */ public function all(): array { @@ -35,14 +33,14 @@ public function all(): array } /** - * @return T|null + * @return array|null */ public function find(int $id): ?array { - $rowset = $this->table_gateway->select([static::ROW_IDENTIFIER => $id]); - $row = (array)$rowset->current(); + /** @var ResultSet $result */ + $results = $this->table_gateway->select([static::ROW_IDENTIFIER => $id]); - return $row ?: null; + return $results->current(); } public function create(array $data): int diff --git a/src/Repository/Mapper/AlbumMapper.php b/src/Repository/Mapper/AlbumMapper.php index 8b15625..7aadc38 100644 --- a/src/Repository/Mapper/AlbumMapper.php +++ b/src/Repository/Mapper/AlbumMapper.php @@ -8,7 +8,8 @@ readonly class AlbumMapper { - public static function toAlbum($object): Album + /** @param iterable $object */ + public static function toAlbum(iterable $object): Album { $album = new Album(); $album->id = $object[AlbumRepository::ROW_IDENTIFIER] ?? null; diff --git a/src/Repository/Mapper/ArtistMapper.php b/src/Repository/Mapper/ArtistMapper.php index 95460cf..13627f8 100644 --- a/src/Repository/Mapper/ArtistMapper.php +++ b/src/Repository/Mapper/ArtistMapper.php @@ -8,7 +8,8 @@ class ArtistMapper { - public static function toArtist($object): Artist + /** @param iterable $object */ + public static function toArtist(iterable $object): Artist { $artist = new Artist(); $artist->id = $object[ArtistRepository::ROW_IDENTIFIER] ?? null; diff --git a/src/Repository/RepositoryInterface.php b/src/Repository/RepositoryInterface.php index 1265abd..38a59c1 100644 --- a/src/Repository/RepositoryInterface.php +++ b/src/Repository/RepositoryInterface.php @@ -7,15 +7,16 @@ interface RepositoryInterface { - /** @return Model[] */ + /** @return array> */ public function all(): array; + /** @return array|null */ public function find(int $id): ?array; - /** @param array{title: string, artist_id: int} $data */ + /** @param array{Title?: string, ArtistId?: int, Name?: string} $data */ public function create(array $data): int; - /** @param array{title?: string, artist_id?: int} $data */ + /** @param array{Title?: string, ArtistId?: int} $data */ public function update(int $id, array $data): bool; public function delete(int $id): bool; diff --git a/src/Service/AbstractService.php b/src/Service/AbstractService.php deleted file mode 100644 index dbbd3ea..0000000 --- a/src/Service/AbstractService.php +++ /dev/null @@ -1,58 +0,0 @@ -table_gateway = new TableGateway($this->getTable(), $this->adapter); - $this->logger = $logger->withName(__CLASS__); - } - - public function getRowIdentifier(): string - { - return 'id'; - } - - abstract protected function getTable(): string; - - public function findAll(): array - { - return iterator_to_array($this->table_gateway->select()); - } - - public function findById(int $id): ?array - { - $rowset = $this->table_gateway->select([$this->getRowIdentifier() => $id]); - $row = (array)$rowset->current(); - return $row ?: null; - } - - public function insert(array $data): int - { - $this->table_gateway->insert($data); - - return $this->table_gateway->getLastInsertValue(); - } - - public function update(array $data, array $where): int - { - return $this->table_gateway->update($data, $where); - } - - public function delete(array $where): int - { - return $this->table_gateway->delete($where); - } -} diff --git a/src/Service/AlbumService.php b/src/Service/AlbumService.php index 2a72c5f..05446f5 100644 --- a/src/Service/AlbumService.php +++ b/src/Service/AlbumService.php @@ -3,10 +3,8 @@ namespace App\Service; use App\Model\Album; -use App\Model\Artist; use App\Repository\AlbumRepository; use App\Repository\Mapper\AlbumMapper; -use ArrayObject; use InvalidArgumentException; use Monolog\Logger; use RuntimeException; @@ -27,7 +25,7 @@ public function __construct( public function all(): array { return array_map( - fn(ArrayObject $album): Album => AlbumMapper::toAlbum($album), + fn(iterable $album): Album => AlbumMapper::toAlbum($album), $this->repository->all() ); } diff --git a/src/Service/ArtistService.php b/src/Service/ArtistService.php index a6c4269..252b99b 100644 --- a/src/Service/ArtistService.php +++ b/src/Service/ArtistService.php @@ -5,7 +5,6 @@ use App\Model\Artist; use App\Repository\ArtistRepository; use App\Repository\Mapper\ArtistMapper; -use ArrayObject; use InvalidArgumentException; use Monolog\Logger; use RuntimeException; @@ -26,7 +25,7 @@ public function __construct( public function all(): array { return array_map( - fn(ArrayObject $artist): Artist => ArtistMapper::toArtist($artist), + fn(iterable $artist): Artist => ArtistMapper::toArtist($artist), $this->repository->all() ); } From 022ab9b30a6986bfc130b795fb2ab1d47055755a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Debussch=C3=A8re?= Date: Fri, 18 Jul 2025 18:45:46 +0200 Subject: [PATCH 3/3] fix(php): php 8.4 for tests and laminas-db --- src/Repository/AbstractRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Repository/AbstractRepository.php b/src/Repository/AbstractRepository.php index f7821a4..6c172c4 100644 --- a/src/Repository/AbstractRepository.php +++ b/src/Repository/AbstractRepository.php @@ -37,7 +37,7 @@ public function all(): array */ public function find(int $id): ?array { - /** @var ResultSet $result */ + /** @var ResultSet $results */ $results = $this->table_gateway->select([static::ROW_IDENTIFIER => $id]); return $results->current();