mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-22 15:43:51 +00:00
[WIP] Add PostalCodeForAddressReferenceRepository and associated tests
Introduced `PostalCodeForAddressReferenceRepository` and its interface to support optimized postal code search using materialized views. Updated `AddressReferenceRepository` to improve query handling. Added test coverage for the new repository functionality.
This commit is contained in:
@@ -85,7 +85,7 @@ final readonly class AddressReferenceRepository implements AddressReferenceRepos
|
||||
|
||||
$paramId = 0;
|
||||
|
||||
foreach ($terms as $k => $term) {
|
||||
foreach ($terms as $term) {
|
||||
$qb->andWhere('var.address like ?');
|
||||
$qb->setParameter(++$paramId, "%{$term}%");
|
||||
}
|
||||
|
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Repository;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
final readonly class PostalCodeForAddressReferenceRepository implements PostalCodeForAddressReferenceRepositoryInterface
|
||||
{
|
||||
public function __construct(private Connection $connection) {}
|
||||
|
||||
public function findPostalCode(string $search, int $firstResult = 0, int $maxResults = 50): iterable
|
||||
{
|
||||
$terms = $this->buildTermsFromSearchString($search);
|
||||
if ([] === $terms) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
|
||||
$qb->from('chill_main_postal_code', 'cmpc')
|
||||
->join('cmpc', 'view_chill_main_address_reference', 'vcmar', 'vcmar.postcode_id = cmpc.id')
|
||||
->join('vcmar', 'country', 'country', condition: 'cmpc.country_id = country.id')
|
||||
->setFirstResult($firstResult)
|
||||
->setMaxResults($maxResults)
|
||||
;
|
||||
|
||||
$qb->select(
|
||||
'DISTINCT ON (cmpc.code, cmpc.label) cmpc.id AS postcode_id',
|
||||
'cmpc.code AS code',
|
||||
'cmpc.label AS label',
|
||||
'country.id AS country_id',
|
||||
'country.countrycode AS country_code',
|
||||
'country.name AS country_name'
|
||||
);
|
||||
|
||||
$paramId = 0;
|
||||
|
||||
foreach ($terms as $term) {
|
||||
$qb->andWhere('vcmar.address like ?');
|
||||
$qb->setParameter(++$paramId, "%{$term}%");
|
||||
}
|
||||
|
||||
$result = $qb->executeQuery();
|
||||
|
||||
return $result->iterateAssociative();
|
||||
}
|
||||
|
||||
private function buildTermsFromSearchString(string $search): array
|
||||
{
|
||||
return array_filter(
|
||||
array_map(
|
||||
static fn (string $term) => trim($term),
|
||||
explode(' ', $search)
|
||||
),
|
||||
static fn (string $term) => '' !== $term
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Repository;
|
||||
|
||||
/**
|
||||
* Search for postal code using optimized materialized view.
|
||||
*/
|
||||
interface PostalCodeForAddressReferenceRepositoryInterface
|
||||
{
|
||||
public function findPostalCode(string $search, int $firstResult = 0, int $maxResults = 50): iterable;
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Tests\Repository;
|
||||
|
||||
use Chill\MainBundle\Repository\PostalCodeForAddressReferenceRepository;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
final class PostalCodeForAddressReferenceRepositoryTest extends KernelTestCase
|
||||
{
|
||||
private Connection $connection;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
$this->connection = self::getContainer()->get(Connection::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<string[]>
|
||||
*/
|
||||
public static function provideSearches(): iterable
|
||||
{
|
||||
yield [''];
|
||||
yield [' '];
|
||||
yield ['hugo'];
|
||||
yield [' hugo'];
|
||||
yield ['hugo '];
|
||||
yield ['rue victor hugo'];
|
||||
yield ['rue victor hugo'];
|
||||
}
|
||||
|
||||
#[DataProvider('provideSearches')]
|
||||
public function testFindPostalCodeDoesNotErrorAndIsIterable(string $search): void
|
||||
{
|
||||
$repository = new PostalCodeForAddressReferenceRepository($this->connection);
|
||||
|
||||
$result = $repository->findPostalCode($search);
|
||||
|
||||
self::assertIsIterable($result);
|
||||
|
||||
// Ensure it can be converted to an array (and iterate without error)
|
||||
$rows = \is_array($result) ? $result : iterator_to_array($result, false);
|
||||
self::assertIsArray($rows);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user