THELIA Forum

Welcome to the THELIA support and discusssion forum

Announcement

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

Offline

#1 Aide pour loop perso

(29-03-2021 13:51:35)


Bonjour tout le monde,

je suis en train de dev une loop perso, jusque là rien de compliqué.

Le code de la boucle:

namespace CrossSelling\Loop;

use Propel\Runtime\Connection\SqlConnectionInterface;
use Propel\Runtime\Propel;
use Thelia\Core\Template\Element\ArraySearchLoopInterface;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;

class OrderedProductLoop extends BaseLoop implements ArraySearchLoopInterface
{
    protected function getArgDefinitions()
    {
        return new ArgumentCollection(
            Argument::createIntListTypeArgument('product_id')
        );
    }

    public function buildArray()
    {
        $productId = $this->getProductId();
        
        /** @var SqlConnectionInterface $con */
        $con = Propel::getConnection();

        $query = "SELECT product.id as product_id FROM product
                 WHERE product.ref IN(
                     SELECT DISTINCT order_product.product_ref FROM order_product
                    RIGHT JOIN product_sale_elements ON order_product.product_ref = product_sale_elements.ref
                    JOIN product ON product_sale_elements.id = product.id
                    WHERE  product.visible = 1 AND order_product.order_id IN(
                        SELECT `order`.id FROM `order`
                        WHERE `order`.id IN(
                             SELECT order_product.order_id FROM order_product 
                             WHERE order_product.product_ref IN (SELECT product.ref from product where product.id='$productId')
                        )
                    )
                 )";

        


        $stmt = $con->prepare($query);
        $stmt->execute();

        $results = [];

        while ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
            $results[] = $result['product_id'];
        }

        return $results;
    }

    public function parseResults(LoopResult $loopResult)
    {
        foreach ($loopResult->getResultDataCollection() as $result) {
            $loopResultRow = new LoopResultRow();

            $loopResultRow->set("PRODUCT_ID", $result);

            $loopResult->addRow($loopResultRow);
        }

        return $loopResult;
    }
}

L'appel de la boucle dans le template:

 {loop type="crossselling" product_id=$product_id name="crossselling"}
             {include file="includes/single-product.html" product_id=$PRODUCT_ID}
             {/loop}

Pas d'erreur en étant avec index_dev.php, j'ai vidé les caches à plusieurs reprises (notamment avant chaque test)
Mais rien n'est retournée par la boucle... je cherche... je passe un ID produit en "dur"... meme chose.

Et il me vient l'idée de regardé dans les log de thelia...

Voilà le résultat:

88: INFO [ConnectionWrapper.php:log()] {653} 2021-03-29 14:15:28:SELECT product.id as product_id FROM product
                 WHERE product.ref IN(
                     SELECT DISTINCT order_product.product_ref FROM order_product
                    RIGHT JOIN product_sale_elements ON order_product.product_ref = product_sale_elements.ref
                    JOIN product ON product_sale_elements.id = product.id
                    WHERE  product.visible = 1 AND order_product.order_id IN(
                        SELECT `order`.id FROM `order`
                        WHERE `order`.id IN(
                             SELECT order_product.order_id FROM order_product 
                             WHERE order_product.product_ref IN (SELECT product.ref from product where product.id='Array')
                        )
                    )
                 )

Et là je bloque sur le pourquoi il me sort 'array'

Si quelqu'un a une piste, je suis preneur smile

Offline

#2 Re: Aide pour loop perso

(29-03-2021 14:35:56)


Salut!

Je ne suis pas (encore?) un expert thelia 2 mais je suis justement en train de faire ma première loop...

Je pense que cette ligne :

Argument::createIntListTypeArgument('product_id')

Renvoie un array

Si tu mets :

Argument::createIntTypeArgument('product_id')

Peut-être que tu n'auras plus ce souci.

Ou si tu veux laisser la possibilité de mettre une liste d'id produit en paramètres, tu laisse comme c'est et tu modifies ça

 WHERE order_product.product_ref IN (SELECT product.ref from product where product.id='$productId')

en ça

 WHERE order_product.product_ref IN (SELECT product.ref from product where product.id in('".implode(',',$productId)."'))

Last edited by Elyos (29-03-2021 14:40:53)


Aide les autres, ils t'aideront en retour.

Offline

#3 Re: Aide pour loop perso

(30-03-2021 05:43:44)


En effet cela fonctionne beaucoup mieux (un peu trop de fatigue je crois )

Je finis ce module et je le mettrais sur GitHub smile

Offline

#4 Re: Aide pour loop perso

(30-03-2021 06:59:53)


Ta requête va prendre beaucoup de temps sur une boutique qui a beaucoup de commandes.

Une strategie serait de pre-calculer les ventes liées avec une commande Thelia placée dans un cron, qui régulièrement met à jour une table de crosselling.
Tu n'as plus alors qu'a piocher dans cette table avec la boucle, accès instantané !


OpenStudio Toulouse

Offline

#5 Re: Aide pour loop perso

(30-03-2021 07:28:59)


C'est vrai que c'est pas bête

J'avais juste tester sur une petite base (5300 commande en gros / 1300 produits).

Je vais me pencher dessus smile

Merci pour la piste