THELIA Forum

Welcome to the THELIA support and discusssion forum

Announcement

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

Offline


Bonjour la communauté,

Voilà j'ai un soucis de validation de datas avec mon module.
Il s'agit de faire juste un update pour un changement de status_id et de date dans la table order.
J'ai un formulaire dans un hook ou je récupère les données et elles sont présentes.
Je ne sais pas si elles sont bien récupérées par le contrôleur -> comment le voir.
Pour le moment je n'arrive pas non plus à les valider.

{form name="hookretraction.live.form"}

{form_hidden_fields form=$form}
<div>
    <form method="POST" id="hookretraction-form" action="#" {form_enctype form=$form} class="clearfix">
    {loop type="order" name="hookretractionorder.status" customer="current" exclude_status={config key="retraction_status"} retraction="true" order=$ID}
    {if $retraction}
    {loop type="order-status" name="order.status" code="retraction"}
        <input id="status_id" type="hidden" name="status_id" value="{$ID}">
    {/loop}   
        <input id="order_id" type="hidden" name="order_id" value="{$ID}">
        <button name="{$name}" class="btn btn-default">{intl l="retraction" d='hookretraction.fo.default'}</button>
        <p></p>
    {/if}
    {/loop}
    </form>
</div>
{/form}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Le contrôleur
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

<?php

namespace HookRetraction\Controller\Front;

use HookRetraction\HookRetraction;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Thelia\Controller\BaseController;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Core\HttpKernel\Exception\RedirectException;
use Thelia\Core\Template\ParserInterface;
use Thelia\Core\Template\TemplateDefinition;
use Thelia\Core\Security\AccessManager;
use Thelia\Core\Security\Resource\AdminResources;
use Thelia\Form\Definition\FrontForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Log\Tlog;
use Thelia\Model\ConfigQuery;
use Thelia\Model\OrderQuery;
use Thelia\Model\OrderStatusQuery;
use Thelia\Tools\URL;

/**
* Class HookRetractionFrontController
* @package HookRetraction\Form
* @author Frederic Faou <fredodefrance@gmail.com>
*/

class HookRetractionFrontController extends BaseFrontController
{
    const FORM_NAME = 'hookretraction_live_form';
   
    /**
     * @param Form $form
     * @param string $fieldName
     * @param int $id
     * @return string
     */
    public function updateStatus($order_id = null)
    {
        $request = $this->getRequest();
        // Create the form from the request
        $form = $this->createForm('hookretraction_live_form');
       
        // Initialize the potential exception
        $ex = null;   
   
        try {
       
            // Obtains current date
            $today = new \DateTime('now');
           
            // Check the form against constraints violations
            $validateForm = $this->validateForm($form, "post");

            //Get the id in the form value and search it in the order table
            $data = $validateForm->getData();
           
            $order = OrderQuery::create()->findPk($data['order_id']);

            if (null === $order) {
                throw new \InvalidArgumentException("The order you want to update status does not exist");
            }
            if (null === $status) {
                throw new \InvalidArgumentException("The status you want to set to the order does not exist");
            }
           
            $event = new OrderEvent($order);
           
            $event
                ->setStatusId($data['status_id']))
                ->setUpdatedAt($today->format('%a'))
                ->save();
           
            $event->setOrder($order);
           
            $this->dispatch(TheliaEvents::ORDER_UPDATE_STATUS, $event);
           
        } catch (FormValidationException $ex) {
            // Form cannot be validated. Create the error message using
            // the BaseAdminController helper method.
            $error_message = $this->createStandardFormValidationErrorMessage($ex);
        }
        catch (\Exception $ex) {
            // Any other error
            $error_message = $ex->getMessage();
        }
       
        if (null !== $ex) {
            $this->setupFormErrorContext(
                'HookRetraction retraction',
                $error_message,
                $form
            );

            $response = $this->render("account");
        }

        return $response;           
   
    }   
   
    public function getName()
    {
        return self::FORM_NAME;
    }   
}

Last edited by fredodefrance (21-04-2017 16:57:46)


C'est en faisant qu'on apprends.

Offline

Offline


Alors en 1 je dirais de savoir si les datas sont bien récupérées dans les différents champs.
En 2 il faut que le statut de la commande passe à Rétractation via un update fait côté client.
Avec la sécurité je ne sais pas si ça passe.
Je suis en train de regarder OrderController dans le core lib.


C'est en faisant qu'on apprends.

Offline


Alors en 1 je dirais de savoir si les datas sont bien récupérées dans les différents champs.

C'est à ça que sert la validation de la form (le $this->validateForm($form);). D’où l'importance de mettre en place des contraintes pertinentes dans la déclaration de ta form.

il faut que le statut de la commande passe à Rétractation via un update fait côté client

Il faut que cet ID de status existe dans les tables OrderStatus et OrderStatusI18n, car dans la table order, order_status_id est une clef étrangère vers la table order_status.


OpenStudio Toulouse

Offline


Problème toujours pas résolu.
Pas d'update du statut de commande en Rétractation.
Le contrôle du form est bien pris en charge par le controller.

////////////////////////le form//////////////////////////////

{form name="hookretraction.live.form"}

{form_hidden_fields form=$form}
<div>
    <form method="POST" id="hookretraction-form" action="#update" {form_enctype form=$form} class="clearfix">
    {loop type="order" name="hookretractionorder.status" customer="current" exclude_status={config key="retraction_status"} retraction="true" order=$ID}
    {if $retraction}
    {form_field form=$form field='status_id'}   
        {loop type="order-status" name="order.status" code="retraction"}
        <input id="status_id" type="hidden" name="status_id" value="{$ID}">
        {/loop}   
    {/form_field}
    {form_field form=$form field='order_id'}
        <input id="order_id" type="hidden" name="order_id" value="{$ID}">
    {/form_field}
        <button name="{$name}" class="btn btn-default">{intl l="retraction" d='hookretraction.fo.default'}</button>
        <p></p>
    {/if}
    {/loop}
    </form>
</div>
{/form}

/////////////////////////////////////////////////////////////////////////

///////////////////////le controller//////////////////////////////
<?php

namespace HookRetraction\Controller\Front;

use HookRetraction\HookRetraction;
use Symfony\Component\Routing\Router;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\HttpKernel\Exception\RedirectException;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Security\User\UserInterface;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Exception\TheliaProcessException;
use Thelia\Log\Tlog;
use Thelia\Model\Order;
use Thelia\Model\OrderQuery;
use Thelia\Model\OrderQueryStatus;
use Thelia\Tools\URL;

/**
* Class HookRetractionFrontController
* @package HookRetraction\Form
* @author Frederic Faou <fredodefrance@gmail.com>
*/

class HookRetractionFrontController extends BaseFrontController
{
    const FORM_NAME = 'hookretraction_live_form';
   
    protected $request;

    /**
     * @param Form $form
     * @param string $fieldName
     * @param int $id
     * @return string
     */
    public function updateStatus(OrderEvent $event)
    {
    $request = $this->getRequest();
        // Create the form from the request
        $form = $this->createForm('hookretraction_live_form');
       
        // Initialize the potential exception
        $ex = null;   
   
        try {
       
         // Obtains current date
         $today = new \DateTime('now');
           
            // Check the form against constraints violations
            $validateForm = $this->validateForm($form);

            //Get the id in the form value and search it in the order table
            $data = $validateForm->getData();
                   
        $order = $this->getOrderId($data['order_id']);

            if (null === $order) {
                throw new \InvalidArgumentException("The order you want to update status does not exist");
            }
            if (null === $status) {
                throw new \InvalidArgumentException("The status you want to set to the order does not exist");
            }
           
            $event = new OrderEvent($order);
           
            $event
                ->setStatusId($data['status_id']))
                ->setUpdatedAt($today->format('%a'))
        ->save();
       
        $event->setOrder($order);
           
        $this->dispatch(TheliaEvents::ORDER_UPDATE_STATUS, $event);
           
        } catch (FormValidationException $ex) {
            // Form cannot be validated. Create the error message using
            // the BaseAdminController helper method.
            $error_message = $this->createStandardFormValidationErrorMessage($ex);
        }
        catch (\Exception $ex) {
            // Any other error
            $error_message = $ex->getMessage();
        }
       
        if (null !== $ex) {
            $this->setupFormErrorContext(
                'HookRetraction retraction',
                $error_message,
                $form
            );

            //$response = $this->render("account");
        }

        return $response;           
   
    }   
   
    public function getName()
    {
        return self::FORM_NAME;
    }   
}

Last edited by fredodefrance (21-04-2017 00:54:06)


C'est en faisant qu'on apprends.

Offline


Mon EventListeners

<?php
/*************************************************************************************/
/*                                                                                   */
/*      Thelia                                                                         */
/*                                                                                   */
/*      Copyright (c) OpenStudio                                                     */
/*      email : info@thelia.net                                                      */
/*      web : http://www.thelia.net                                                  */
/*                                                                                   */
/*      This program is free software; you can redistribute it and/or modify         */
/*      it under the terms of the GNU General Public License as published by         */
/*      the Free Software Foundation; either version 3 of the License                */
/*                                                                                   */
/*      This program is distributed in the hope that it will be useful,              */
/*      but WITHOUT ANY WARRANTY; without even the implied warranty of               */
/*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                */
/*      GNU General Public License for more details.                                 */
/*                                                                                   */
/*      You should have received a copy of the GNU General Public License            */
/*        along with this program. If not, see <http://www.gnu.org/licenses/>.         */
/*                                                                                   */
/*************************************************************************************/

namespace HookRetraction\EventListeners;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Mailer\MailerFactory;

/**
* Class OrderListener
* @package HookRetraction\EventListeners
*/
class OrderListener implements EventSubscriberInterface
{
    /** @var MailerFactory */
    protected $mailer;
   
    /** @var Request */
    protected $request;

    /**
     * @param MailerFactory $mailer
     * @param EventDispatcherInterface $dispatcher
     * @param EventRequest $request    
     */
   
    public function __construct(MailerFactory $mailer, Request $request)
    {

        $this->mailer = $mailer;   
        $this->request = $request;
    }

    public static function getSubscribedEvents()
    {
        return [
            TheliaEvents::ORDER_UPDATE_STATUS => array("updateStatus", 128)
        ];
    }
    
    public function updateStatus(OrderEvent $event)
    {
        $order = $event->getOrder();

        $this->mailer->sendEmailToCustomer(
            Order::CONFIRMATION_MESSAGE_NAME,
            $order->getCustomer(),
            [
                'order_id'  => $order->getId(),
                'order_ref' => $order->getRef(),
                'status_id' => $order->getStatusId()
            ]
        );
    }
}


C'est en faisant qu'on apprends.

Offline


Avec un IDE qui te permet d'utiliser XDebug, ce serait plus simple de trouver ton problème.


OpenStudio Toulouse

Offline


Oui je debug sous Eclipse.
Je revérifie une énième fois ma syntaxe.


C'est en faisant qu'on apprends.

Offline


Erreur 404 - Problème de route non callable (sécurité?)

<form method="POST" id="hookretraction-live-form" action="/account/order/{$order_id}/update" {form_enctype form=$form} class="clearfix">

   <route id="hookretraction.live" path="/account/order/{order_id}/update" methods="post">
        <default key="_controller">HookRetraction\Controller\Front\HookRetractionFrontController::updateAction</default>
        <requirement key="order_id">\d+</requirement>
    </route>

Le message d'erreur suivant a été trouvé : Controller "HookRetraction\Controller\Front\HookRetractionFrontController::updateAction" for URI "/account/order/2146/update" is not callable.

Et


C'est en faisant qu'on apprends.

Offline


Fais voir ta méthode HookRetractionFrontController::updateAction


OpenStudio Toulouse

Offline


Bizarre ça me renvoyait en GET.

<?php

namespace HookRetraction\Controller\Front;

use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\Exception\FormValidationException;
use HookRetraction\Model\OrderQuery;
use Thelia\Core\HttpFoundation\Request;
/**
* Class HookRetractionFrontController
* @package HookRetraction\Form
* @author Frederic Faou <fredodefrance@gmail.com>
*/

class HookRetractionFrontController extends BaseFrontController
{
    const FORM_NAME = 'hookretraction_live_form';

    protected $request;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function updateAction()
    {
        $request = $this->getRequest();
        // Create the form from the request
        $form = $this->createForm('hookretraction_live_form');

        // Initialize the potential exception
        $ex = null;
        $response = null;
        try {

            // Obtains current date
            $today = new \DateTime('now');

            // Check the form against constraints violations
            $validateForm = $this->validateForm($form);

            //Get the id in the form value and search it in the order table
            $data = $validateForm->getData();

            $order = OrderQuery::create()->findPk($data['order_id']);

            if (null === $order) {
                throw new \InvalidArgumentException("The order you want to update status does not exist");
            }

            $event = new OrderEvent($order);
            $event
                ->setStatus($data['status_id']);

            $event->setOrder($order);

            $this->dispatch(TheliaEvents::ORDER_UPDATE_STATUS, $event);


        } catch (FormValidationException $ex) {
            // Form cannot be validated. Create the error message using
            $response = $ex->getMessage();
        }
        catch (\Exception $ex) {
            // Any other error
            $response = $ex->getMessage();

        }

        if (null !== $ex) {
            $this->render('hook-retraction-error' , $response);
        }

        return $response;

    }

    public function getName()
    {
        return self::FORM_NAME;
    }
}

Last edited by fredodefrance (01-05-2017 11:06:10)


C'est en faisant qu'on apprends.

Offline


Bizarre ça me renvoyait en GET.

Qu'est-ce que ça veut dire ?


OpenStudio Toulouse

Offline


J'avais un message d'erreur qui me spécifiait que les variables ne pouvaient être renvoyées avec la méthode GET. (POST Allowed)

J'ai changé ma route pour: /account/order/{$order_id} au lieu de /account/order/{$order_id}/update

Ca à résolu l'erreur.

Donc je me retrouve avec ça dans la source de la page.
Je pense que le form est correct.

<form method="POST" id="hookretraction-form" action="/index_dev.php/account/order/2146" class="clearfix">
                <input type="hidden" name="hookretraction_live_form[status_id]" value="11">
                <input type="hidden" name="hookretraction_live_form[order_id]" value="2146">
            <button class="btn btn-default" type="submit">Rétractation</button>
            <p></p>
    </form>

Je crois que j'ai compris mon erreur.
J'essaye de renvoyer les vars sur un EventListener qui me sert pour etendre le loop  order-status au chargement du formulaire.
Alors que je devrais les renvoyer sur un EventListener pour l'update de la table Order.

Last edited by fredodefrance (02-05-2017 00:06:27)


C'est en faisant qu'on apprends.

Offline


Je n'arrive pas à faire la liaison entre mon controller et mon listener

//le controller
<?php

namespace HookRetraction\Controller\Front;

use HookRetraction\Event\HookRetractionEvents;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\OrderQuery;
use Thelia\Model\OrderStatusQuery;

/**
* Class HookRetractionFrontController
* @package HookRetraction\Form
* @author Frederic Faou <fredodefrance@gmail.com>
*/
class HookRetractionFrontController extends BaseFrontController
{

    const FORM_NAME = 'hookretraction.live.form';

    protected $response;

    public function CreateAction()
    {

        if (null != $response = $this->getSecurityContext()->getCustomerUser()) {
            return $this->generateRedirectFromRoute("customer.login.view");
        }
        // Create the form from the request
        $form = $this->createForm('hookretraction.live.form');

        // Initialize the potential exception
        $message = null;
        try {

            // Obtains current date
            $today = new \DateTime('now');

            // Check the form against constraints violations
            $validateForm = $this->validateForm($form, "post");

            //Get the id in the form value and search it in the order table
            $data = $validateForm->getData();

            $order = OrderQuery::create()->findPk($data['order_id']);
            $status = OrderStatusQuery::create()->findPk($data['status_id']);

            if (null === $order) {
                throw new \InvalidArgumentException("The order you want to update status does not exist");
            }
            if (null === $status) {
                throw new \InvalidArgumentException("The status you want to set to the order does not exist");
            }

            $event = new OrderEvent($order);
            $event
                ->setOrder($data['order_id'])
                ->setStatus($data['status_id'])
            ;
           
        } catch (FormValidationException $message) {
            // Form cannot be validated. Create the error message using
            $response = $message->getMessage();
        }
        catch (\Exception $message) {
            // Any other error
            $response = $message->getMessage();

        }

        if (null !== $message) {
            \Thelia\Log\Tlog::getInstance()->error(
                sprintf("Error validation : %s.", $message)
            );
            $form->setErrorMessage($message);

            $this->getParserContext()
                ->addForm($form)
                ->setGeneralError($message)
            ;
            return $this->render("account", $response);
        }

        return $response;

    }

    private function createEventInstance($data)
    {

        $HookRetractionEvent = new HookRetractionEvents(
            $data['order_id'],
            $data['status_id']
        );

        return $HookRetractionEvent;
    }

    public function getName()
    {
        return self::FORM_NAME;
    }
}

//le listener

<?php
/*************************************************************************************/
/*      This file is part of the Thelia package.                                     */
/*                                                                                   */
/*      Copyright (c) OpenStudio                                                     */
/*      email : dev@thelia.net                                                       */
/*      web : http://www.thelia.net                                                  */
/*                                                                                   */
/*      For the full copyright and license information, please view the LICENSE.txt  */
/*      file that was distributed with this source code.                             */
/*************************************************************************************/
/*************************************************************************************/
namespace HookRetraction\EventListener;

use HookRetraction\HookRetraction;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Action\BaseAction;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Template\ParserInterface;
use Thelia\Mailer\MailerFactory;
use Thelia\Model\ConfigQuery;
use Thelia\Model\MessageQuery;

/**
* Class SendConfirmationEmail
*/
class HookRetractionUpdateFrontListener extends BaseAction implements EventSubscriberInterface
{
    /**
     * @var MailerFactory
     */
    protected $mailer;
    /**
     * @var ParserInterface
     */
    protected $parser;

    public function __construct(ParserInterface $parser, MailerFactory $mailer)
    {
        $this->parser = $parser;
        $this->mailer = $mailer;
    }

    /*
    * @params OrderEvent $order
    * Checks if order new status is sent, send an email to the customer.
    */
    public function update_status(OrderEvent $event)
    {
        if ($event->getOrder()->isSent()) {
            $contact_email = ConfigQuery::getStoreEmail();

            if ($contact_email) {
                $order = $event->getOrder();
                $customer = $order->getCustomer();
                $this->mailer->sendEmailToCustomer(
                    HookRetraction::MESSAGE_SEND_CONFIRMATION,
                    $order->getCustomer(),
                    [
                        'order_id' => $order->getId(),
                        'order_ref' => $order->getRef(),
                        'customer_id' => $customer->getId(),
                        'status_id' => $order->getStatusId(),
                        'order_date' => $order->getCreatedAt(),
                        'update_date' => $order->getUpdatedAt()
                    ]
                );
            }
        }
    }


    /**
     *
     * @inheritdoc
     */
    public static function getSubscribedEvents()
    {
        return array(
            TheliaEvents::ORDER_UPDATE_STATUS => array("update_status", 128)
        );
    }
}

Last edited by fredodefrance (02-05-2017 01:47:59)


C'est en faisant qu'on apprends.