Loading CHANGELOG.md +1 −0 Original line number Diff line number Diff line Loading @@ -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. Loading src/UnicaenDbAnonym/Provider/fr_FR/PersonExtension.php 0 → 100644 +28 −0 Original line number Diff line number Diff line <?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 src/UnicaenDbAnonym/Service/DbService.php +30 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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, Loading src/UnicaenDbAnonym/Service/GeneratorService.php +22 −12 Original line number Diff line number Diff line Loading @@ -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)) { Loading @@ -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 { Loading src/UnicaenDbAnonym/Service/GeneratorServiceFactory.php +5 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading
CHANGELOG.md +1 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
src/UnicaenDbAnonym/Provider/fr_FR/PersonExtension.php 0 → 100644 +28 −0 Original line number Diff line number Diff line <?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
src/UnicaenDbAnonym/Service/DbService.php +30 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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, Loading
src/UnicaenDbAnonym/Service/GeneratorService.php +22 −12 Original line number Diff line number Diff line Loading @@ -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)) { Loading @@ -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 { Loading
src/UnicaenDbAnonym/Service/GeneratorServiceFactory.php +5 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading