Commit 4e934240 authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Correction de bugs et réorganisation du système de génération

parent c24432f0
Loading
Loading
Loading
Loading
Loading
+26 −25
Changes for code/generator/controller.php: 26 added lines, 25 removed lines.
Original line number Diff line number Diff line
@@ -5,6 +5,29 @@ use UnicaenCode\Util;

return [
    'title' => 'Création d\'un nouveau contrôleur',

    'class' => [
        'label' => 'Nom de classe du contrôleur',
        'value' => 'Application\Controller\ExempleController',
    ],

    'route' => [
        'label' => 'Route par laquelle y accéder depuis une URL (en minus-cules ou snake_case)',
        'value' => 'exemple-de-controlleur',
    ],

    'factory' => [
        'type'  => 'checkbox',
        'label' => 'Générer une factory',
        'value' => true,
    ],

    'subDir' => [
        'type'  => 'checkbox',
        'label' => 'Les traits, interfaces et Factory seront placés dans des sous-dossiers dédiés',
        'value' => false,
    ],

    'generator' => function (array $params): array {
        $class    = $params['class'] ?? null;
        $type     = $params['type'] ?? Util::classType($class) ?? 'Controller';
@@ -16,17 +39,17 @@ return [
        $classname = Util::classClassname($class);
        $filename  = Util::classFilename($class);

        $params['class']     = $class;
        $params['namespace'] = $namespace;
        $params['classname'] = $classname;
        $params['author']    = $author;
        $params['template']  = $template;
        $params['type']      = $type;
        $params['filename']  = $filename;

        $params['controllerConfig']              = Util::codeGenerator()->transferParams($params, ['route', 'class', 'type', 'author', 'subDir']);
        $params['controllerConfig']['generator'] = ControllerConfig::class;
        $params['controllerConfig'] = true;

        Util::codeGenerator()->generateFrom($params, 'factory');
        Util::codeGenerator()->generateFrom($params, 'controllerConfig');

        if (isset($params['factory']['class'])) {
            $params['controllerConfig']['factoryClass'] = Util::classTruncated($params['factory']['class'], Util::classModule($class));
@@ -36,26 +59,4 @@ return [

        return $params;
    },

    'class' => [
        'label' => 'Nom de classe du contrôleur',
        'value' => 'Application\Controller\ExempleController',
    ],

    'route' => [
        'label' => 'Route par laquelle y accéder depuis une URL (en minus-cules ou snake_case)',
        'value' => 'exemple-de-controlleur',
    ],

    'factory' => [
        'type'  => 'checkbox',
        'label' => 'Générer une factory',
        'value' => true,
    ],

    'subDir' => [
        'type'  => 'checkbox',
        'label' => 'Les traits, interfaces et Factory seront placés dans des sous-dossiers dédiés',
        'value' => false,
    ],
];
 No newline at end of file
+14 −1
Changes for code/generator/controllerConfig.php: 14 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -3,13 +3,26 @@
use UnicaenCode\Util;

return [
    'title' => 'Génération de configuration de contrôleur',
    'class'          => [
        'label' => 'Classe du Controller',
        'value' => 'Application\Controller\ExempleController',
    ],
    'factory' => [
        'label' => 'Classe de la factory correspondante',
        'value' => 'Application\Service\ExempleControllerFactory',
    ],
    'name'         => [
        'label' => 'Nom ou alias pour y accéder',
        'value' => null,
    ],

    'generator' => function (array $params): array {
        $class    = $params['class'] ?? null;
        $template = $params['template'] ?? 'ControllerConfig';
        $author   = $params['author'] ?? Util::getAuthor();
        $route    = $params['route'] ?? null;


        $namespace = Util::classModule($class, Util::CLASS_MODULE_NAMESPACE);
        $classname = Util::classClassname($class);

+0 −1
Changes for code/generator/factory.php: 0 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@ return [
    'type'      => [
        'type'  => 'text',
        'label' => 'Type de classe',
        'value' => true,
    ],
    'subDir'         => [
        'type'  => 'checkbox',
+104 −78
Changes for src/Service/CodeGeneratorService.php: 104 added lines, 78 removed lines.
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@ use Laminas\Stdlib\Parameters;
 */
class CodeGeneratorService
{
    const STATE_CONSOLE     = 'console';
    const STATE_WEB_DISPLAY = 'web-display';
    const STATE_WEB_GEN     = 'web-gen';
    const STATE_CODE        = 'code';

    use ConfigServiceAwareTrait;


@@ -32,40 +37,34 @@ class CodeGeneratorService
     */
    public function generer($params, $input = true): array
    {
        if (is_string($params)) {
            $params = $this->getGenerator($params);
        }

        $hasInputData = is_array($input);

        if ($hasInputData){
            if (isset($input['expanded'])){
                $params['expanded'] = $input['expanded'];
        /* Récupération de l'input */
        if (true === $input) {
            if (Console::isConsole()) {
                $input = $this->paramsFromConsole();
                $state = self::STATE_CONSOLE;
            } elseif (Util::$controller->getRequest()->isPost()) {
                $input = Util::$controller->getRequest()->getPost()->toArray();
                $state = self::STATE_WEB_GEN;
            } else {
                $input = [];
                $state = self::STATE_WEB_DISPLAY;
            }
        } elseif (is_array($input)) {
            $state = self::STATE_CODE;
        } else {
            $input = [];
        }



        $oriParams = $params;

        if ($title = $params['title'] ?? null) {
            if (Console::isConsole()) {
                Util::getAuthor(); // sert à éviter un bug en console qui charge la session trop tard
                echo $title . "\n";
            } elseif($input === true) {
                echo '<h1>' . $title . '</h1>';
            }
        /* Récupération du générator */
        if (is_string($params)) {
            $params = $this->getGenerator($params);
        }

        if (!is_array($input) && $input !== true) {
            $input = []; // sécurité, on envoie un array ou TRUE, sinon rien ne sera pris en compte
        }

        $doGen = true;
        if (Console::isConsole()) {
            if (true === $input) {
                $input = $this->paramsFromConsole();
            }
        /* Fusion de l'input dans les params */
        $oriParams = $params;
        $params    = [];
        foreach ($oriParams as $name => $value) {
            if (is_array($value)) {
                if (array_key_exists($name, $input)) {
@@ -73,48 +72,72 @@ class CodeGeneratorService
                } else {
                    $params[$name] = $value['value'] ?? null;
                }
            } else {
                $params[$name] = $value;
            }
        }
        } else {
            $formParams = [];
            if (true === $input) {
                if (Util::$controller->getRequest()->isPost()) {
                    $input = Util::$controller->getRequest()->getPost()->toArray();
                } else {
                    $input = [];
                    $doGen = false;


        /* Création de la ligne de commande */
        $params['commandLine'] = $this->genCmd($oriParams, $params);


        /* Génération de paramètres supplémentaires */
        if ($state === self::STATE_CODE) {
            $params['expanded'] ??= true;
        }


        /* On affiche le titre */
        $title = $params['title'] ?? null;
        if ($title) switch ($state) {
            case self::STATE_CONSOLE:
//                    Util::getAuthor(); // sert à éviter un bug en console qui charge la session trop tard
                echo $title . "\n";
            break;
            case self::STATE_WEB_DISPLAY:
            case self::STATE_WEB_GEN:
                echo '<h1>' . $title . '</h1>';
            break;
        }


        /* On s'occupe du formulaire */
        if (in_array($state, [self::STATE_WEB_GEN, self::STATE_WEB_DISPLAY])) {
            $formParams = [];
            foreach ($oriParams as $name => $value) {
                if (is_array($value)) {
                    $formParams[$name]          = $value;
                    if (array_key_exists($name, $input)) {
                        $formParams[$name]['value'] = $input[$name];
                    $formParams[$name]['value'] = $params[$name];
                }
            }
            }

            $form = FormMaker::createFromArray($formParams);
            if (!$hasInputData && $form->hasSaisieElements()) {
            if ($form->hasSaisieElements()) {
                $form->afficher();
            } else {
                $doGen = true;
            }

            foreach ($oriParams as $name => $value) {
                if (is_array($value)) {
                    $params[$name] = $form->getParamValue($name);
                }
            }
        }

        if ($cmd = $this->genCmd($oriParams, $params)) {
            $params['commandLine'] = $cmd;
            $params['echoCommandLine'] = !Console::isConsole() && !$hasInputData;
        }

        if ($doGen) {
        /* Génération des paramètres finaux et rendu */
        if (!($state === self::STATE_WEB_DISPLAY && $form->hasSaisieElements())) {
            $params = $this->generate($params);
            $this->render($params);
        }


        /* Affichage éventuel de la ligne de commande */
        if ($state === self::STATE_WEB_GEN) {
            ?>
            <h1>Création des fichiers depuis la ligne de commandes</h1>
            <div class="alert alert-warning">
                <p>Pour ajouter les fichiers listés ci-dessus à votre projet (hors exemples de configuration), lancez depuis le répertoire de votre projet la
                    commande suivante :
                    <br/>
                    <code><?= $params['commandLine'] ?></code>

                </p>
            </div>
            <?php
        }

        return $params;
@@ -162,15 +185,28 @@ class CodeGeneratorService

        /* On crée les sous-configs */
        foreach ($params as $key => $val) {
            if (true === $val && $this->isGenerator($key)) {
            if ((true === $val || '1' === $val) && $this->isGenerator($key)) {
                $this->generateFrom($params, $key);
            }elseif (is_array($val)) {
            } elseif (is_array($val) && isset($val['generator'])) {
                $params[$key] = $this->generate($val);
            }
        }

        $params = $this->runTriggers($params);

        return $params;
    }



    protected function render(array $params)
    {
        foreach( $params as $p => $v ){
            if (is_array($v)){
                $this->render($v);
            }
        }

        /* Génération du fichier final & rendu */
        $params = $this->makeCode($params);

@@ -179,27 +215,11 @@ class CodeGeneratorService
        } else {
            $this->echo($params);
        }

        if ($params['echoCommandLine'] ?? false) {
            ?>
            <h1>Création des fichiers depuis la ligne de commandes</h1>
            <div class="alert alert-warning">
                <p>Pour ajouter les fichiers listés ci-dessus à votre projet (hors exemples de configuration), lancez depuis le répertoire de votre projet la
                    commande suivante :
                    <br/>
                    <code><?= $params['commandLine'] ?></code>

                </p>
            </div>
            <?php
        }

        return $params;
    }



    protected function genCmd(array $oriParams, array $params): ?string
    protected function genCmd(array $oriParams, array $params): string
    {
        $diff = [];
        foreach ($oriParams as $key => $oriVal) {
@@ -231,22 +251,28 @@ class CodeGeneratorService
    {
        $subGenerator = $this->getGenerator($key);

        foreach ($subGenerator as $useParam => $useVal) {
            if (isset($params[$useParam]) && is_array($useVal)) $subGenerator[$useParam] = $params[$useParam];
        foreach ($subGenerator as $p => $v) {
            if (is_array($v)) {
                if (array_key_exists($p, $params)) {
                    $subGenerator[$p] = $params[$p];
                } else {
                    $subGenerator[$p] = $v['value'] ?? null;
                }
            }
        }
        $params[$key] = $this->generate($subGenerator);
    }



    public static function transferParams(array $params, array &$subGenerator): array
    public static function transferParams(array $params, array $subGenerator): array
    {

        foreach ($subGenerator as $useParam => $useVal) {
            if (isset($params[$useParam]) && is_array($useVal)) $subGenerator[$useParam] = $params[$useParam];
        foreach ($subGenerator as $param) {
            if (isset($params[$param]) && is_array($useVal)) $subGenerator[$param] = $params[$param];
        }


        return $subGenerator;
    }


+16 −5
Changes for src/Util.php: 16 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -560,8 +560,17 @@ class Util
            'Provider'     => 'Provider',
            'Processus'    => 'Processus',
            'Proxy'        => 'Proxy',
            'Fieldset'     => 'Fieldset',
            'Form'         => 'Form',
            'ViewHelper'   => 'ViewHelper',
            'View\\Helper' => 'ViewHelper',
            'Controller'   => 'Controller',
            'Validator'    => 'Validator',
            'Hydrator'     => 'Hydrator',
            'Assertion'    => 'Assertion',
        ];

        if (class_exists($class)) {
            $rc = new \ReflectionClass($class);
            foreach ($subClassTypes as $parent => $type) {
                if ($rc->isSubclassOf($parent)) {
@@ -569,17 +578,19 @@ class Util
                }
            }

            $entities = self::introspection()->getDbEntities();
            if (isset($entities[$class])) {
                return 'Entity';
            }
        }

        /* Au cas où ça n'existe pas encore, parsing à partir du nom et du namespace complet */
        foreach ($types as $key => $type) {
            if (false !== strpos($class, '\\' . $key . '\\')) {
                return $type;
            }
        }

        $entities = self::introspection()->getDbEntities();
        if (isset($entities[$class])) {
            return 'Entity';
        }

        return null;
    }