-
Notifications
You must be signed in to change notification settings - Fork 3
Main birthplace #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Main birthplace #39
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ on: | |
| push: | ||
| branches: | ||
| - main | ||
| - main-* | ||
| tags: | ||
| - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| <?php | ||
|
|
||
| namespace App\Doctrine\Functions; | ||
|
|
||
| use Doctrine\ORM\Query\AST\Functions\FunctionNode; | ||
| use Doctrine\ORM\Query\Parser; | ||
| use Doctrine\ORM\Query\SqlWalker; | ||
| use Doctrine\ORM\Query\TokenType; | ||
|
|
||
| /** | ||
| * ReplaceFunction ::= "REPLACE" "(" StringPrimary "," StringPrimary "," StringPrimary ")". | ||
| */ | ||
| class ReplaceFunction extends FunctionNode | ||
| { | ||
| public mixed $subject; | ||
| public mixed $search; | ||
| public mixed $replace; | ||
|
|
||
| public function parse(Parser $parser): void | ||
| { | ||
| $parser->match(TokenType::T_IDENTIFIER); | ||
| $parser->match(TokenType::T_OPEN_PARENTHESIS); | ||
| $this->subject = $parser->StringPrimary(); | ||
| $parser->match(TokenType::T_COMMA); | ||
| $this->search = $parser->StringPrimary(); | ||
| $parser->match(TokenType::T_COMMA); | ||
| $this->replace = $parser->StringPrimary(); | ||
| $parser->match(TokenType::T_CLOSE_PARENTHESIS); | ||
| } | ||
|
|
||
| public function getSql(SqlWalker $sqlWalker): string | ||
| { | ||
| return 'REPLACE(' . | ||
| $this->subject->dispatch($sqlWalker) . ', ' . | ||
| $this->search->dispatch($sqlWalker) . ', ' . | ||
| $this->replace->dispatch($sqlWalker) . | ||
| ')'; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -23,7 +23,7 @@ | |||||
| use Symfony\Component\Serializer\Annotation\Groups; | ||||||
|
|
||||||
| #[ORM\Entity(repositoryClass: Cim11Repository::class)] | ||||||
| #[ApiFilter(Cim11Filter::class, properties: ['search', 'ids', 'cim10_code'])] | ||||||
| #[ApiFilter(Cim11Filter::class, properties: ['search', 'ids', 'cim10Code'])] | ||||||
|
||||||
| #[ApiFilter(Cim11Filter::class, properties: ['search', 'ids', 'cim10Code'])] | |
| #[ApiFilter(Cim11Filter::class, properties: ['search', 'ids', 'cim10Code', 'cim10_code' => 'cim10Code'])] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,8 @@ | |
| */ | ||
| class InseePays1943Repository extends ServiceEntityRepository | ||
| { | ||
| use SearchNormalizationTrait; | ||
|
|
||
| public function __construct(ManagerRegistry $registry) | ||
| { | ||
| parent::__construct($registry, InseePays1943::class); | ||
|
|
@@ -25,15 +27,29 @@ public function __construct(ManagerRegistry $registry) | |
| /** | ||
| * Note : might consider searching also the libelleOfficiel field. | ||
| * | ||
| * Search for countries matching a name that existed at a given date. | ||
| * Search for countries matching a name. | ||
| * Date constraints removed to allow searching for historical countries (e.g., Algeria before 1962). | ||
| */ | ||
| public function searchByNameAndDate(string $search, DateTime $date): array | ||
| { | ||
| // Normalize hyphens to spaces at the SQL level for flexible matching | ||
| // MySQL collations are typically accent-insensitive by default (utf8mb4_unicode_ci) | ||
| return $this->createQueryBuilder('p') | ||
| ->where('p.libelleCog LIKE :search') | ||
| ->where('REPLACE(p.libelleCog, \'-\', \' \') LIKE :search') | ||
| // Date constraints removed to allow historical country searches (e.g., Algeria before 1962) | ||
| ->setParameter('search', '%' . str_replace('-', ' ', $search) . '%') | ||
| ->getQuery() | ||
| ->getResult(); | ||
|
Comment on lines
33
to
+42
|
||
| } | ||
|
|
||
| public function findByCodeAndDate(string $code, DateTime $date): array | ||
| { | ||
| return $this->createQueryBuilder('p') | ||
| ->where('p.codePays = :code') | ||
| // Keep date constraints for find by code | ||
| ->andWhere('(p.dateDebut IS NULL OR p.dateDebut <= :date)') | ||
| ->andWhere('(p.dateFin IS NULL OR p.dateFin >= :date)') | ||
| ->setParameter('search', "%$search%") | ||
| ->setParameter('code', $code) | ||
| ->setParameter('date', $date) | ||
| ->getQuery() | ||
| ->getResult(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,16 +16,29 @@ | |||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
| class InseePaysRepository extends ServiceEntityRepository | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| use SearchNormalizationTrait; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| public function __construct(ManagerRegistry $registry) | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| parent::__construct($registry, InseePays::class); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| public function searchByName(string $search): array | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| // Normalize hyphens to spaces at the SQL level for flexible matching | ||||||||||||||||||||||||||||||||
| // MySQL collations are typically accent-insensitive by default (utf8mb4_unicode_ci) | ||||||||||||||||||||||||||||||||
| return $this->createQueryBuilder('p') | ||||||||||||||||||||||||||||||||
| ->where('REPLACE(p.libelleCog, \'-\', \' \') LIKE :search') | ||||||||||||||||||||||||||||||||
| ->setParameter('search', '%' . str_replace('-', ' ', $search) . '%') | ||||||||||||||||||||||||||||||||
|
Comment on lines
+28
to
+32
|
||||||||||||||||||||||||||||||||
| // Normalize hyphens to spaces at the SQL level for flexible matching | |
| // MySQL collations are typically accent-insensitive by default (utf8mb4_unicode_ci) | |
| return $this->createQueryBuilder('p') | |
| ->where('REPLACE(p.libelleCog, \'-\', \' \') LIKE :search') | |
| ->setParameter('search', '%' . str_replace('-', ' ', $search) . '%') | |
| // Normalize hyphens to spaces at the PHP level for flexible matching | |
| // MySQL collations are typically accent-insensitive by default (utf8mb4_unicode_ci) | |
| $normalized = str_replace('-', ' ', $search); | |
| $patternWithSpaces = '%' . $normalized . '%'; | |
| $patternWithHyphens = '%' . str_replace(' ', '-', $normalized) . '%'; | |
| return $this->createQueryBuilder('p') | |
| ->where('p.libelleCog LIKE :patternWithSpaces OR p.libelleCog LIKE :patternWithHyphens') | |
| ->setParameter('patternWithSpaces', $patternWithSpaces) | |
| ->setParameter('patternWithHyphens', $patternWithHyphens) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,18 @@ | ||||||||||||||||||||||||
| <?php | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| namespace App\Repository; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| trait SearchNormalizationTrait | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * Normalize search term by replacing hyphens with spaces. | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * Note: Accent normalization is handled by MySQL's collation (utf8mb4_unicode_ci) | ||||||||||||||||||||||||
| * which is accent-insensitive by default, so we don't need to remove accents here. | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| private function normalizeSearchTerm(string $search): string | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| // Replace hyphens with spaces for flexible matching | ||||||||||||||||||||||||
| return str_replace('-', ' ', $search); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+7
to
+17
|
||||||||||||||||||||||||
| /** | |
| * Normalize search term by replacing hyphens with spaces. | |
| * | |
| * Note: Accent normalization is handled by MySQL's collation (utf8mb4_unicode_ci) | |
| * which is accent-insensitive by default, so we don't need to remove accents here. | |
| */ | |
| private function normalizeSearchTerm(string $search): string | |
| { | |
| // Replace hyphens with spaces for flexible matching | |
| return str_replace('-', ' ', $search); | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -81,6 +81,15 @@ private function provideItem(Operation $operation, array $uriVariables = [], arr | |||||||||||||||||||
| throw new RuntimeException('Missing "code" in URI variables'); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| return $this->birthPlaceService->getBirthPlaceByCode($uriVariables['code'], $context['filters']['filters'] ?? null); | ||||||||||||||||||||
| $request = $this->requestStack->getCurrentRequest(); | ||||||||||||||||||||
| if (!$request) { | ||||||||||||||||||||
| throw new LogicException('No current request available'); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| $dateOfBirth = $request->query->get('dateOfBirth'); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| $code = explode('.', $uriVariables['code'])[0]; | ||||||||||||||||||||
|
||||||||||||||||||||
| $code = explode('.', $uriVariables['code'])[0]; | |
| $code = (string) $uriVariables['code']; | |
| $dotPosition = strpos($code, '.'); | |
| if ($dotPosition !== false) { | |
| $code = substr($code, 0, $dotPosition); | |
| if ($code === '') { | |
| throw new RuntimeException('Invalid "code" format in URI variables'); | |
| } | |
| } |
Copilot
AI
Feb 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After extracting the code using explode, there's no validation that the resulting code is valid (e.g., exactly 5 digits for communes/countries). An input like '123.json' would result in code='123', which is invalid but would still be passed to the service. Consider adding validation after the explode operation to ensure the code matches expected patterns before querying the database.
| $code = explode('.', $uriVariables['code'])[0]; | |
| $code = explode('.', (string) $uriVariables['code'])[0]; | |
| if (!preg_match('/^\d{5}$/', $code)) { | |
| throw new RuntimeException('Invalid "code" format'); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding 'main-' to the production release workflow triggers means that any branch starting with 'main-' will trigger production deployments. This could be risky if developers create branches like 'main-feature' or 'main-hotfix' for development purposes. Consider whether this pattern is intentional and documented. If the intent is to support multiple main branches for different environments, consider using more specific patterns like 'main-v' or documenting the naming convention clearly.