Skip to content
Snippets Groups Projects
Commit 6d3ece31 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Possibilité de transmettre le contexte (valeurs générées jusqu'à présent) à...

Possibilité de transmettre le contexte (valeurs générées jusqu'à présent) à une méthode maison (ex : PersonExtension::firstName)
parent 853555a8
No related branches found
No related tags found
No related merge requests found
Pipeline #30240 passed
......@@ -5,6 +5,7 @@ CHANGELOG
-----
- Config : possibilité d'utiliser des noms de colonnes en plus des noms d'attributs Doctrine.
- Config : support d'un format plus explicite permettant de spécifier le modificateur Faker 'unique'.
- Possibilité de transmettre le contexte (valeurs générées jusqu'à présent) à une méthode maison (ex: PersonExtension::firstName).
- Suppression des dépendances à unicaen/app en faveur de la nouvelle bibliothèque unicaen/sql.
- Renommage de la table _METADATA en `unicaen_db_anonym`.
- [FIX] Plus d'anonymisation si la valeur est null.
......
<?php
namespace UnicaenDbAnonym\Provider\fr_FR;
use Faker\Provider\fr_FR\Person;
use Individu\Entity\Db\Individu;
class PersonExtension extends Person
{
/**
* Remplacement de 'firstName()' pour prendre en compte la 'civilite' éventuelle dans le contexte.
*/
public function firstName($gender = null, ?array $context = null): string
{
if ($gender !== null) {
return parent::firstName($gender);
}
$civilite = $context['civilite'] ?? null;
if ($civilite === null) {
return parent::firstName($gender);
}
$gender = [Individu::CIVILITE_MME => 'female', Individu::CIVILITE_M => 'male'][$civilite] ?? null;
return parent::firstName($gender);
}
}
\ No newline at end of file
......@@ -104,6 +104,33 @@ class DbService
return array_combine($fields, $mapping);
}
/**
* @param string $entityName
* @param array $records
* @param array $mapping Exemple :
* ```
* [
* 'nomUsuel' => 'lastName', // càd `$faker->lastName()`
* 'nomPatronymique' => 'null', // càd mise à NULL.
* 'leitmotiv' => ['words', 3, true], // càd `$faker->words(3, true)`
* 'leitmotivUnique' => [
* 'name' => 'words',
* 'unique' => true,
* 'params' => [3, true],
* ], // càd `$faker->unique()->words(3, true)`
* 'civilite' => [
* 'name' => 'randomElement',
* 'params' => [Individu::CIVILITE_MME, Individu::CIVILITE_M],
* ], // càd `$faker->randomElement([Individu::CIVILITE_MME, Individu::CIVILITE_M])`
* 'prenom1' => [
* 'name' => 'firstName',
* 'params' => [null],
* 'context' => true,
* ] // càd `$faker->firstName(null, $context)` // Cf. {@see \UnicaenDbAnonym\Provider\fr_FR\PersonExtension}
* ]
* ```
* @return array[]
*/
public function generateSqlLines(string $entityName, array $records, array $mapping): array
{
$metadata = $this->getEntityClassMetadata($entityName);
......@@ -136,11 +163,13 @@ class DbService
$entity = $metadata->getName();
$sets = [];
$context = [];
$this->generatorService->seed($record['id']);
foreach ($mapping as $name => $fakerConfig) {
$fakeValue = $this->generatorService->generateFakeValue((array)$fakerConfig);
$fakeValue = $this->generatorService->generateFakeValue((array)$fakerConfig, $context);
Assert::scalar($fakeValue, "Le mapping spécifiée pour l'attribut '$name' de l'entité '$entity' produit une valeur non supportée : %s");
$sets[] = $metadata->getColumnName($name) . ' = ' . $this->databasePlatform->quoteStringLiteral($fakeValue);
$context[$name] = $fakeValue; // contexte = valeurs générées jusqu'à présent
}
return sprintf($this->updateSQLTemplate,
......
......@@ -34,21 +34,18 @@ class GeneratorService
/**
* Génère une valeur fictive aléatoire selon la config spécifiée.
*
* @param array $config Config, exemple :
* @param array $config Config, exemples :
* ```
* [
* 'nomUsuel' => 'lastName', // càd `$faker->lastName()`
* 'nomPatronymique' => 'null', // càd mise à NULL.
* 'leitmotiv' => ['words', 3, true], // càd `$faker->words(3, true)`
* 'leitmotivUnique' => [
* 'name' => 'words',
* 'unique' => true,
* 'params' => [3, true],
* ], // càd `$faker->unique()->words(3, true)`
* ]
* 'lastName', // càd `$faker->lastName()`
* 'null', // càd mise à NULL.
* ['words', 3, true], // càd `$faker->words(3, true)`
* ['name' => 'words', 'unique' => true, 'params' => [3, true]], // càd `$faker->unique()->words(3, true)`
* ['name' => 'randomElement', 'params' => [Individu::CIVILITE_MME, Individu::CIVILITE_M]],
* ['name' => 'firstName', 'params' => [null], 'context' => true] // càd `$faker->firstName(null, $context)` // Cf. {@see \UnicaenDbAnonym\Provider\fr_FR\PersonExtension}
* ```
* @param array $context Contexte : autres valeurs générées jusqu'à présent
*/
public function generateFakeValue(array $config): string
public function generateFakeValue(array $config, array $context = []): string
{
// normalisation
if (!array_key_exists('name', $config)) {
......@@ -58,14 +55,27 @@ class GeneratorService
if (!array_key_exists('unique', $config)) {
$config['unique'] = false;
}
if (!array_key_exists('context', $config)) {
$config['context'] = false;
}
$method = $config['name'];
if ($method === 'null') {
return 'NULL';
}
if ($config['context'] === true && !array_key_exists('params', $config)) {
throw new \InvalidArgumentException("Si la clé 'context' est à true, la clé 'params' doit être présente (méthode '$method').");
}
$params = $config['params'] ?? [];
$unique = (bool) $config['unique'];
// si demandé, passage du contexte à la méthode (en dernier argument)
if ($config['context'] === true) {
$params[] = $context;
}
if ($unique) {
$fakeValue = $this->faker->unique()->$method(...$params);
} else {
......
......@@ -5,13 +5,17 @@ namespace UnicaenDbAnonym\Service;
use Faker\Factory;
use Locale;
use Psr\Container\ContainerInterface;
use UnicaenDbAnonym\Provider\fr_FR\PersonExtension;
class GeneratorServiceFactory
{
public function __invoke(ContainerInterface $container): GeneratorService
{
$service = new GeneratorService();
$service->setFaker(Factory::create(Locale::getDefault()));
$faker = Factory::create(Locale::getDefault());
$faker->addProvider(new PersonExtension($faker));
$service->setFaker($faker);
return $service;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment