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
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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.
+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
+30 −1
Original line number Diff line number Diff line
@@ -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,
+22 −12
Original line number Diff line number Diff line
@@ -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 −1
Original line number Diff line number Diff line
@@ -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;
    }