THELIA Forum

Welcome to the THELIA support and discusssion forum

Announcement

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

Offline

#1 Etendre la loop produit

(24-05-2018 09:34:41)


Je souhaiterais étendre le loop produit.

Voici mon code :

ArtabanMarketplace\Config\config.xml

.....
        <service id="loopevent.loop.extends" class="ArtabanMarketplace\EventListeners\Loop" scope="request">
            <argument type="service" id="request"/>
            <tag name="kernel.event_subscriber" />
        </service>
.....

ArtabanMarketplace\EventListeners\Loop.php

<?php

/**
 * Extends Loops
 *
 * Class Loop
 * @author Gilles Lengy
 */

namespace ArtabanMarketplace\EventListeners;

use ArtabanMarketplace\Model\Map\AmpSellerProductTableMap;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\TheliaEvents;

class Loop implements EventSubscriberInterface {

    /** @var Request $request */
    protected $request = null;

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

    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents() {
        return [
            // Product
            TheliaEvents::getLoopExtendsEvent(TheliaEvents::LOOP_EXTENDS_ARG_DEFINITIONS, 'product') => ['productArgDefinitions', 128],
            TheliaEvents::getLoopExtendsEvent(TheliaEvents::LOOP_EXTENDS_INITIALIZE_ARGS, 'product') => ['productInitializeArgs', 128],
            TheliaEvents::getLoopExtendsEvent(TheliaEvents::LOOP_EXTENDS_BUILD_MODEL_CRITERIA, 'product') => ['productBuildModelCriteria', 128],
        ];
    }

    /**
     * Add a new parameter for loop lang
     * you can now call the loop with this argument
     */
    public function productArgDefinitions(LoopExtendsArgDefinitionsEvent $event) {
        $argument = $event->getArgumentCollection();
        $argument->addArgument(Argument::createIntListTypeArgument('amp_seller_id'));
    }

    /**
     * Change the query search of the loop product
     */
    public function productBuildModelCriteria(LoopExtendsBuildModelCriteriaEvent $event) {

        $id = "1";
        $ampSellerJoin = new Join(ProductTableMap::ID, AmpSellerProductTableMap::PRODUCT_ID, Criteria::LEFT_JOIN);
        $event->getModelCriteria()->addJoinObject($ampSellerJoin, "ampSellerJoin")->where(AmpSellerProductTableMap::AMP_SELLER_ID . " " . Criteria::IN . " (" . $id . ")");
    }

    /**
     * Set the amp_seller_id parameters from the query string
     */
    public function productInitializeArgs(LoopExtendsInitializeArgsEvent $event) {
        $parameters = $event->getLoopParameters();
        if ($this->request->query->has('loop-amp_seller_id')) {
            $parameters['amp_seller_id'] = 1;
            $event->setLoopParameters($parameters);
        }
    }

}

La loop

                <ul>
                    {loop type="product" name="my_product_loop" amp_seller_id=1 order="min_price"}
                    <li>{$TITLE} ({$REF})</li>
                    {/loop}
                </ul>

L'id est en "dur" plusieurs fois pour être sur que ce soit le bon :-)

Voici l'erreur que j'obtiens :

FatalThrowableError in Loop.php line 21:
Type error: Argument 1 passed to ArtabanMarketplace\EventListeners\Loop::__construct() must be an instance of ArtabanMarketplace\EventListeners\Request, instance of Thelia\Core\HttpFoundation\Request given, called in C:\wamp64\www\theliatestmp\cache\dev\CoreDevDebugProjectContainer.php on line 1619

Je ne sais pas trop quoi en penser. Dois-je m'arranger pour que l'argument 1 soit une instance de Thelia\Core\HttpFoundation\Request ou donner une instance de ArtabanMarketplace\EventListeners\Request...

Dans les deux cas, je ne sais pas comment faire...

Je ne sais pas non plus comment récupérer amp_seller_id.

Toute aide sera grandement appréciée !
Merci.

Offline

#2 Re: Etendre la loop produit

(25-05-2018 11:17:06)


Bon, j'ai trouvé la solution, il fallait utiliser les bonnes classes...
Je met en place une solution pour passer le bonne argument pour le seller_id qui est en dur pour le moment et je poste mon code.

Offline

#3 Re: Etendre la loop produit

(25-05-2018 16:33:47)


Voici le code qui marche avec quelques remarques et questions

ArtabanMarketplace\Config\config.xml

...
        <service id="loopevent.loop.extends" class="ArtabanMarketplace\EventListeners\Loop">
            <argument type="service" id="request"/>
            <tag name="kernel.event_subscriber" />
        </service>
...

ArtabanMarketplace\EventListeners\Loop.php

<?php

/**
 * Extends Loops
 *
 * Class Loop
 * @author Gilles Lengy
 */

namespace ArtabanMarketplace\EventListeners;

use ArtabanMarketplace\Model\Map\AmpSellerProductTableMap;
use Thelia\Model\Map\ProductTableMap;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Event\Loop\LoopExtendsArgDefinitionsEvent;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Core\Event\Loop\LoopExtendsInitializeArgsEvent;
//use Thelia\Core\EventListeners\LoopExtendsBuildModelCriteriaEvent as LoopExtendsBuildModelCriteriaEventListeners; // !!!!!!!!!!!!!!!!!!!! ATTENTION ARTABAN GL :::: Vraiment utile ?
use Thelia\Core\Event\Loop\LoopExtendsBuildModelCriteriaEvent;
use Propel\Runtime\ActiveQuery\Join;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Core\Event\Loop\LoopExtendsParseResultsEvent;

class Loop implements EventSubscriberInterface {

    /** @var Request $request */
    protected $request = null;

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

    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents() {
        return [
            // Product
            TheliaEvents::getLoopExtendsEvent(TheliaEvents::LOOP_EXTENDS_ARG_DEFINITIONS, 'product') => ['productArgDefinitions', 128],
            TheliaEvents::getLoopExtendsEvent(TheliaEvents::LOOP_EXTENDS_INITIALIZE_ARGS, 'product') => ['productInitializeArgs', 128],
            TheliaEvents::getLoopExtendsEvent(TheliaEvents::LOOP_EXTENDS_BUILD_MODEL_CRITERIA, 'product') => ['productBuildModelCriteria', 128],
            TheliaEvents::getLoopExtendsEvent(TheliaEvents::LOOP_EXTENDS_PARSE_RESULTS, 'product') => ['productParseResults', 128],
        ];
    }

    /**
     * Add a new parameter for loop lang
     * you can now call the loop with this argument
     */
    public function productArgDefinitions(LoopExtendsArgDefinitionsEvent $event) {
        $argument = $event->getArgumentCollection();
        $argument->addArgument(Argument::createIntListTypeArgument('amp_seller_id'));
    }

    /**
     * Change the query search of the loop product
     */
    public function productBuildModelCriteria(LoopExtendsBuildModelCriteriaEvent $event) {
        $Array_id = $event->getLoop()->getAmpSellerId();
        if (!empty($Array_id)) {
            $id = $Array_id[0];
            $ampSellerJoin = new Join(ProductTableMap::ID, AmpSellerProductTableMap::PRODUCT_ID, Criteria::LEFT_JOIN);
            $event->getModelCriteria()->addJoinObject($ampSellerJoin, "ampSellerJoin")->where(AmpSellerProductTableMap::AMP_SELLER_ID . " " . Criteria::IN . " (" . $id . ")");
        }
    }

    /**
     * Add the UUID variable to the output variables of the loop lang
     */
    public function productParseResults(LoopExtendsParseResultsEvent $event) {
        $loopResult = $event->getLoopResult();
        $arguments = $event->getLoop()->getArgumentCollection();
//        var_dump($arguments);
//        die();
        if ($arguments->get('amp_seller_id')->getValue()) {
            foreach ($loopResult as $row) {
                $amp_seller_id_array = $arguments->get('amp_seller_id')->getValue();
                $amp_seller_id = $amp_seller_id_array[0];
                $row->set('ID_AMP_SELLER', $amp_seller_id);
            }
        }
    }

    /**
     * Set the amp_seller_id parameters from the query string
     */
    public function productInitializeArgs(LoopExtendsInitializeArgsEvent $event) {
        $parameters = $event->getLoopParameters();
        if ($this->request->query->has('loop-amp_seller_id')) {
            $parameters['amp_seller_id'] = 1; ///// !!!!!!!!!!!!!!!!!!!!! ATTENTION ATTENTION ARTABAN GL !!!! Est ce que cela donne toujours la valeur 1 au critère ou est ce un 'booléen' ??????
            $event->setLoopParameters($parameters);
        }
    }

}

Est ce que quelqu'un à une réponse aux 2 commentaires avec "ATTENTION ARTABAN GL" ?

Et question subsitiaire : comment récupérer le $TITRE du seller ?
J'arrive à récupérer son id depuis la boucle. Faut-il faire une requête pour récupérer toutes les info, ou bien, il y a-t-il un autre moyen grâce à la jointure ?

Merci d'avance de votre aide !

Last edited by GillesL (25-05-2018 16:40:43)

Offline

#4 Re: Etendre la loop produit

(25-05-2018 21:33:42)


!!!!!!!!!!! ATTENTION ARTABAN GL :::: Vraiment utile ?
use Thelia\Core\Event\Loop\LoopExtendsBuildModelCriteriaEvent;

Oui, car la classe est utilisée ici :

public function productBuildModelCriteria(LoopExtendsBuildModelCriteriaEvent $event) {

$parameters['amp_seller_id'] = 1

1, c'est l'entier 1.
true, c'est le booléen vrai


OpenStudio Toulouse

Offline

#5 Re: Etendre la loop produit

(28-05-2018 08:41:53)


Merci pour tes réponses.

Je vais créer un topic pour savoir comment récupérer un champ dans le cas d'une boucle créée avec jointure.