THELIA Forum

Welcome to the THELIA support and discusssion forum

Announcement

Rejoignez la communauté sur le Discord Thelia : https://discord.gg/YgwpYEE3y3

Offline


Bonjour !

J'ai un léger soucis sur une page de configuration d'un module perso. La page (module-configuration.html] se trouve dans le dossier AdminIncludes du module et propose de mettre des données à jour, mais le traitement PHP dans le contrôleur vérifie qu'il n'y a pas de bêtise. C'est un peu compliqué donc je n'ai pas pu opérer cette vérification avec du Javascript, j'ai préféré la faire côté serveur.

Mon problème c'est qu'en cas d'erreur, je veux rediriger vers cette même page de configuration mais en y incluant des paramètres, qui me permettront d'afficher ce div :

{if $error_min}
    <div class="alert alert-danger" role="alert">
        <h4>Erreur constatée parmi vos dimensions :</h4>
        <p>Entre {$error_min} et {$error_max}m<sup>3</sup> de l'application {$error_application}</p>
    </div>
{/if}

Mon contrôleur ressemble donc à ça pour l'instant :

public function update() {
        //Récupérer les informations du formulaire
        $request = $this->container->get("request");
        //Faire le traitement en procédant par application (pour vérifier que les volumes minimaux et maximaux correspondent)
        $applications = ["appli1", "appli2", "appli3"];
        foreach ($applications as $application) {
            $groupes = GroupeDimensionQuery::create()->filterByApplication($application)->find();

            //Je crée une variable qui permet de vérifier que le minimum est tout de
            // même plus grand que le maximum du groupe précédent
            $precedent = 0;
            //Pour chaque groupe de dimension que j'ai en BDD, je récupère sa valeur dans le formulaire
            foreach ($groupes as $groupe) {
                $min = $request->request->get("min".$groupe->getId());
                $max = $request->request->get("max".$groupe->getId());

                //Si c'est OK je sauvegarde la modification en base
                if($min < $max && $min > $precedent) {
                    $groupe->setVolumeMin($min)->setVolumeMax($max)->save();
                    $precedent = $max;
                //Sinon j'arrête le traitement et je renvoie vers le formulaire en montrant l'erreur
                } else {
                    return $this->render(                                // => ne fonctionne pas
                        "module_configuration",
                        [
                            "error_min" => $min,
                            "error_max" => $max,
                            "error_application" => $application
                        ]
                    );
                }
            }
        }
        //Si tout s'est bien passé, on est redirigé vers la même page de configuration
        return $this->generateRedirect("/admin/module/Dimension");
    }

Voilà, rien de bien compliqué, mais je bloque au niveau du else : j'aimerai que, dans ce cas, on arrête le traitement en l'état, on renvoie la page de configuration mais cette fois avec des variables qui me permettront de montrer mon div d'erreur.
Le problème c'est que la méthode generateRedirect() ne prends pas de paramètre autre que le status (optionnel), et que la méthode render() fouille directement dans le dossier templates du module, et pas dans AdminIncludes.

Comment faire pour avoir un redirect vers "/admin/module/Dimension" avec des variables en paramètres ?

Last edited by HeishPi (12-07-2019 10:54:21)


Développeur web Junior

Offline


Tu devrais utiliser une Form, qui permet de valider les champs, de passer un message d'erreur général et un message d'erreur sur le ou les champs en erreur.

La doc des forms : http://doc.thelia.net/en/documentation/form/index.html

Par ailleurs, utiliser AdminIncludes est déprécié, il vaudrait mieux utiliser le hook module.configuration

Regarde comment tout ceci est fait dans un module existant.


OpenStudio Toulouse

Offline


J'essaye actuellement de faire ça mais je bloque dans la création de la fonction qui va vérifier la contrainte.
Je ne sais tout simplement pas comment je peux demander à la fonction de regarder les autres entrées de la table pour vérifier que la valeur actuelle est bien plus grande ou plus petite. Pour bien faire, il faudrait que je puisse passer des paramètres à l'appel de la fonction dans la contrainte mais ça n'a pas l'air d'être possible.

protected function buildForm() {
    $applications = ["appli1", "appli2", "appli3"];
    foreach ($applications as $application) {
        $groupes = DimensionGroupQuery::create()->filterByApplication($application)->find();
        foreach ($groupes as $groupe) {
                $id = $groupe->getId();
                $this->formBuilder
                    ->add('min' . $id,
                        'integer', array(
                        'constraints' => array(
                            [$this, "checkGreaterVolume"],
                        )
                    ))
                    ->add('max' . $id,
                        'integer', array(
                        'constraints' => array(
                            new GreaterThan()
                        )
                    ))
                ;
        }
    }
}

public function checkGreaterVolume($value, ExecutionContextInterface $context) {
    //Ici il faudrait que je puisse récupérer au moins l'application dans laquelle on se situe pour vérifier que les données concordent
}

J'ai vu que Symfony disposait d'une contrainte "GreaterThan()", ce qui aurait pu très bien fonctionner mais c'est pareil, comment lui spécifier que le paramètre de greaterThan doit être le volume qu'on a accepté juste avant...? (et encore, si tant est qu'il y en ait un, puisque au départ de chaque application, la première valeur n'aura pas de valeur précédente).

Last edited by HeishPi (12-07-2019 09:37:11)


Développeur web Junior

Offline


Utilise la contrainte Callback, qui te permet d'écrire toi même le test de validité, et d'ajouter une violation de contrainte si nécessaire. Exemple ici : https://github.com/thelia/thelia/blob/m … rm.php#L36

Et le callback est là : https://github.com/thelia/thelia/blob/m … rm.php#L70

Si tu as besoin de la valeur d'autres champs de la form en plus de la valeur du champ courant, tu peux utiliser $context->getRoot()->getData(), comme ici https://github.com/thelia/thelia/blob/m … m.php#L115


OpenStudio Toulouse

Offline


En essayant d'appliquer ta solution, je suis passé par l'un de mes anciens contrôleur qui utilisait la méthode suivante :

return $this->render(
    "module-configure",
    [   "module_code" => "ModuleName"];

Du coup j'ai fait ça dans mon contrôleur :

//Si c'est OK je sauvegarde la modification en base
                if($min < $max && $min == ($precedent+1)){
                    $groupe->setVolumeMin($min)->setVolumeMax($max)->save();
                    $precedent = $max;
//Sinon j'arrête le traitement et je renvoie vers le formulaire en montrant l'erreur
                } else {
                    return $this->render(
                        "module-configure",
                        [   "module_code" => "Dimension",
                            "error_min" => $min,
                            "error_max" => $max,
                            "error_application" => $application
                        ]);
                }

Et ça marche ! Y a encore un petit défaut dans l'URL générée avec cette méthode mais c'est pas bien grave, je vais m'en dépatouiller.
Merci de ton aide !


Développeur web Junior