Jump to content

Utilisé les données des autres fichiers dans un module


Recommended Posts

Bonjour,

Je débute sous prestashop dans le cadre de mon stage, actuellement j'essaye de réaliser un module qui s'affiche en ayant pour condition une donnée d'un autre fichier.

Mon problème est que je ne sais pas comment faire le lien du dis fichier à mon module pour pouvoir mettre en place ma condition et je ne suis pas totalement certain de l'endroit de cette donnée. Dans mon cas ce serait le nom du produit dans le détail d'une commande.

Link to comment
Share on other sites

Hello thomasjrsn !

Pourrais-tu détailler un peu plus l'objectif de ton module stp.

Il doit faire quoi exactement et ou ? Tu veux récupérer quel produit exactement dans la commande ?

peux-tu eventuellement joindre un screen de l'arbo de ton module.

Tu es sous quelle version de presta stp.

 

 

Edited by jef933 (see edit history)
Link to comment
Share on other sites

Bonjour jef933, 

Mon module doit afficher pour un certain produit, qui serait un pack d'une durée limité, le nombre de jours restant avant l'expiration du pack. J'essaye donc d'identifier le nom du produit dans le détail de la commande qui se trouve dans l'historique des commandes car mon module sera affiché dans ce détail de la commande via le hookDisplayOrderDetail. Il faut donc que je fasse une condition sur l'affichage de mon module en fonction du produit.

Voici l'arbo de mon module :

arbo_module.PNG.268089453f3350f5113083ae6eae6ad5.PNG

J'utilise la dernière version de prestashop, soit la 1.7.6.5.

Link to comment
Share on other sites

Dacc merci ,

je bosse pricipalement sur des versions antérieures de presta mais tu peux pas utiliser id_product  ou id_attribute ?

Dans ta commande tu as les produits , donc si tu conditionnes sur l'id de ton produit pour l'affichage.

Par exemple:

$id_produitConcerné = 1001

if(id_product === $id_produitConcerné){

tu affiche ton le nombre de jours restant avant l'expiration du pack

}

Après je ne sais pas si ton produit a des déclinaisons ou pas.

Tu peux le faire dans ton template ou dans le hook.

Jef

Link to comment
Share on other sites

C'est là mon problème, je ne sais pas comment utiliser id_product ou product_name. Quand je les appelle dans mymodule.php, elles ne renvoient pas de valeur et il me faudrait la valeur qui est renvoyé dans le code qui affiche le détails de la commande.

Mon module affiche simplement une donnée récupéré par un webservice.

Link to comment
Share on other sites

Hello,

la donnée récupérée du web service tu l'as dans le hook DisplayOrderDetail ?

essaye un truc dans le genre :

hookDisplayOrders($params){

     $products = $order->getProducts();

      foreach($products as $product){

               et là tu fais ton test 

      }

}

 

Link to comment
Share on other sites

Je récupère la donnée du webservice dans mymodule.php, dans la fonction : public function hookDisplayOrderDetail($params).

Ce code ne marche pas, je pense qu'il ne reconnait pas la fonction getProducts() mais je n'en suis pas sûre, lorsque je lance ce code la page de détails de la commande ne se charge plus.

Link to comment
Share on other sites

Essaye en overridant le OrderDetailsController ...

Je pense que je serais parti plutot comme ça.

Tu as ta commande dedans. $order = new Order($id_order);

tu peux ainsi parser ton $order et checker les produits.

Tu peux faire un appel à la méthode de ton module dans laquelle tu récupère la donnée du webservice dans cet override.

Il est lourd ton module ? Tu peux me l'envoyer ?

Merci

Link to comment
Share on other sites

Voici mon module, c'est le module qu'on apprend à faire avec la documentation fournis par prestashop. J'avance petit à petit.

L'override est encore un très flou pour moi, il faut que je crée un fichier dans le dossier override? Je ne sais pas du tout quel démarche je dois suivre.

Merci à toi et du temps que tu m'accordes.

mymodule.rar

Link to comment
Share on other sites

Merci , j 'y jetterais un oeil ce soir mais je pense que dans ton cas l'override est la meilleur solution.

Oui renseinge toi là dessus c'est souvent très utile l'override.

En gros c'est ça tu vas créer une surcharge pour le controller orderdetails

La structure dans ton module c'est :

override > controllers > front > OrderDetailsController.php

ton fichier d'overrider doit commencer ainsi: 

<?php

class OrderDetailsController extends OrderDetailsControllerCore {

et à l'intérieur je pense que tu vas overrider la méthode public function initContent()

Tu vas tout copier/coller de celle d'origine , et tu rajoute ce dont tu as besoin

}

De rien :) j'espère que ça te fera avancer.

Link to comment
Share on other sites

essaye de créer ton override avec et surcharge la methode init content.

Tu lui met un bon vieux echo 'toto' avec un die() juste derrière pour verifier que ton override prend bien.

Si c'est pas le cas , suprime le fichier class_index.php dans le dossier cache et réessaye.

Link to comment
Share on other sites

Dans la version 1.7 il faut encore supprimer class_index?

Je demande car il n'est pas dans le dossier cache et il y en a un dans var > cache > prod.

Du coup j'ajoute un echo 'toto' dans la fonction initContent mais je ne le vois pas sur la page.

Link to comment
Share on other sites

met ça dans ton override et réessaye:

 

  

<?php

class OrderDetailsController extends OrderDetailsControllerCore {
public function initContent()
    {
        if (Configuration::isCatalogMode()) {
            Tools::redirect('index.php');
        }

        $id_order = (int) Tools::getValue('id_order');
        $id_order = $id_order && Validate::isUnsignedId($id_order) ? $id_order : false;

        if (!$id_order) {
            $reference = Tools::getValue('reference');
            $reference = $reference && Validate::isReference($reference) ? $reference : false;
            $order = $reference ? Order::getByReference($reference)->getFirst() : false;
            $id_order = $order ? $order->id : false;
        }

        if (!$id_order) {
            $this->redirect_after = '404';
            $this->redirect();
        } else {
            if (Tools::getIsset('errorQuantity')) {
                $this->errors[] = $this->trans('You do not have enough products to request an additional merchandise return.', array(), 'Shop.Notifications.Error');
            } elseif (Tools::getIsset('errorMsg')) {
                $this->errors[] = $this->trans('Please provide an explanation for your RMA.', array(), 'Shop.Notifications.Error');
            } elseif (Tools::getIsset('errorDetail1')) {
                $this->errors[] = $this->trans('Please check at least one product you would like to return.', array(), 'Shop.Notifications.Error');
            } elseif (Tools::getIsset('errorDetail2')) {
                $this->errors[] = $this->trans('For each product you wish to add, please specify the desired quantity.', array(), 'Shop.Notifications.Error');
            } elseif (Tools::getIsset('errorNotReturnable')) {
                $this->errors[] = $this->trans('This order cannot be returned', array(), 'Shop.Notifications.Error');
            } elseif (Tools::getIsset('messagesent')) {
                $this->success[] = $this->trans('Message successfully sent', array(), 'Shop.Notifications.Success');
            }

            $order = new Order($id_order);
            if (Validate::isLoadedObject($order) && $order->id_customer == $this->context->customer->id) {
                $this->order_to_display = (new OrderPresenter())->present($order);

                $this->context->smarty->assign([
                    'order' => $this->order_to_display,
                    'HOOK_DISPLAYORDERDETAIL' => Hook::exec('displayOrderDetail', ['order' => $order]),
                ]);
            } else {
                $this->redirect_after = '404';
                $this->redirect();
            }
            unset($order);
        }
echo 'toto';
        parent::initContent();
        $this->setTemplate('customer/order-detail');
    }
}

 

Link to comment
Share on other sites

Hello !

ça fonctionne chez moi.

met ça dans ton override

<?php

class OrderDetailController extends OrderDetailControllerCore
{
    public function initContent()
    {
        echo 'toto';
    }

}

désinstalle ton module et réinstalle le.

Link to comment
Share on other sites

Tu vas devoir copier/coller tout ce qu'il y a dans la méthode initContent() d'origine dans celle de ton override, ensuite tu rcupères tes produits, là pour le coup tu dois pouvoir utilisé le

$order->getProducts(), tu dois déjà l'avoir quelque part. et là tu fais ton test.

Ou alors tu fais ton test directement en overridant le template , du coup plus besoin de l'override de orderdetails mais tu auras vu comment ça fonctionne . ;)

Link to comment
Share on other sites

Ok, et est-ce qu'il faut réinstaller le module à chaque modification de l'override?

Pour le test je vois comment faire mais du coup ce que je met dedans ça va être l'appel de mon module ou plutôt de ma fonction hookDisplayOrderDetail? Est ce que j'y ai accès depuis l'override?

Link to comment
Share on other sites

 $order = new Order($id_order);
            if (Validate::isLoadedObject($order) && $order->id_customer == $this->context->customer->id) {
                $this->order_to_display = (new OrderPresenter())->present($order);

                $this->context->smarty->assign([
                    'order' => $this->order_to_display,
                    'HOOK_DISPLAYORDERDETAIL' => Hook::exec('displayOrderDetail', ['order' => $order]),
                ]);

regarde dans ta classe OrderPresenter qui est instanciée dans le initContent()

Celle-ci utilise elle même une instance de return new OrderLazyArray:

return new OrderLazyArray($order);

   return new OrderLazyArray($order);

regarde les différentes méthodes de cette classe

 

 et ton $order c'est une instance de order donc le plus simple est peut être d'utiliser ses méthodes:

j'ai pas regarder en détails mais je vois 

public function getProducts($products = false, $selected_products = false, $selected_qty = false)

public function getProductsDetail()

 

Edited by jef933 (see edit history)
Link to comment
Share on other sites

Je n'arrive pas à utiliser le getProducts(), dans le OrderLazyArray.php la fonction n'a pas de paramètre d'entrée et retourne $orderProducts si je ne me trompe pas.

Donc pour moi il faudrait simplement un $product = getProducts(); mais quand je le fais la page du détail de la commande ne se charge plus. 

Link to comment
Share on other sites

$order = new Order($id_order);
          if (Validate::isLoadedObject($order) && $order->id_customer == $this->context->customer->id) {
              $this->order_to_display = (new OrderPresenter())->present($order);

              $product = $order->getProducts();
              echo $product;

              $this->context->smarty->assign([
                  'order' => $this->order_to_display,
                  'HOOK_DISPLAYORDERDETAIL' => Hook::exec('displayOrderDetail', ['order' => $order]),
              ]);

Ah ok je comprends mieux.

Link to comment
Share on other sites

Alors tu as quelque chose ?

sort peut être de la condition pour le moment

$order = new Order($id_order);
$products = $order->getProducts();
            print_r($products);
            die();

          if (Validate::isLoadedObject($order) && $order->id_customer == $this->context->customer->id) {
              $this->order_to_display = (new OrderPresenter())->present($order);

              $this->context->smarty->assign([
                  'order' => $this->order_to_display,
                  'HOOK_DISPLAYORDERDETAIL' => Hook::exec('displayOrderDetail', ['order' => $order]),
              ]);

Tu devrais obtenir un array avec tes produits

Link to comment
Share on other sites

J'obtient bien un array maintenant avec beaucoup d'information dedans, j'ai réussi à afficher l'information dont j'avais besoin en m'inspirant d'autres codes.

$products = $order->getProducts();
          foreach ($products as $product) {
            print_r($product['product_id']);
          }

Maintenant, mon problème est l'affichage de mon module selon la condition. Je ne sais pas ce que je dois mettre dans mon if().

 

Link to comment
Share on other sites

Oui voilà 💪

afficher le module ?  tu veux afficher quoi exactement ?

regarde aussi le template qui est retourné par initContent() pour voir comment sont utilisées tes variables :

 $this->context->smarty->assign([
                    'order' => $this->order_to_display,
                    'HOOK_DISPLAYORDERDETAIL' => Hook::exec('displayOrderDetail', ['order' => $order]),
                ]);

 

Link to comment
Share on other sites

Mon module est greffer au hookDisplayOrderDetail, et il affiche mymodule.tpl. Du coup j'aimerai que contrôler le display de mon module sur le hook j'imagine.

J'ai essayer de commenter la ligne 'HOOK_DISPLAYORDERDETAIL' => Hook::exec('displayOrderDetail', ['order' => $order]), mais cela n'a rien changé à l'affiche de la page et mon module est toujours affiché. J'ai essayé d'enlever le 'displayOrderDetail' dans le Hook::exec mais cela crée une erreur (500 Server Error) et la page ne se charge plus. J'ai aussi essayer de retirer le ['order' => $order]) mais je n'ai pas vu de différence.

Link to comment
Share on other sites

Hello ,  c'est sûrement car tu travailles dans tonModule/override/OrderdetailsController que ça ne prends pas.

Bosse plutôt dans /override/OrderdetailsController c'est le fichier généré par l'override de ton module.

Une fois que tout te convient tu mets tout dans ton module

Edited by jef933 (see edit history)
Link to comment
Share on other sites

refait un test simple , un echo de quelque chose. Si tu le vois c'est que ton override est pris donc toutes tes modifs dedans sont prises en compte. Si ça ne fonctionne pas c'est peut être autre chose . 

Fais bien ton test dans Override/Controllers/front/Orderbidulle et pas dans le dossier override de ton module.

Link to comment
Share on other sites

Si ton echo fonctionne , ton override prend le dessus sur le fichier d'origine.

Tu peux tout à fait modifier le code de initContent, essaie de renvoyer un autre template par exemple ...

 

 parent::initContent();
        $this->setTemplate('customer/order-detail');

 

Link to comment
Share on other sites

Quand je renvoie un autre template ça marche effectivement, je ne comprends pas pourquoi mon code ne marche pas lui.

Je vous montre ce que j'ai fais :

$order = new Order($id_order);
        $products = $order->getProducts();
        foreach ($products as $product) {
          $product_id = $product['product_id'];
        }
        echo("testecho");
        if (Validate::isLoadedObject($order) && $order->id_customer == $this->context->customer->id) {
              $this->order_to_display = (new OrderPresenter())->present($order);
              $this->context->smarty->assign(['order' => $this->order_to_display]);
              if ($product_id == 11) {
                  $this->context->smarty->assign(['HOOK_DISPLAYORDERDETAIL' => Hook::exec('displayOrderDetail', ['order' => $order])]);
              }

 

Link to comment
Share on other sites

J'ai pas le code sous les yeux mais tu peux me dire ce qu'il y a comme clé au tableau product quand tu fais print_r($product) dans ta boucle.

Tu dois avoir

$product['name']

ou un truc du genre.

C'est peux être pas terrible , j'en sais trop rien mais tu peux faire un truc du genre:

if($product['product_id'] == ton id){

$product['product_name'] .= '(pack valable encore tant de temps) enfin la donnée de ton webservice'
}

 

Link to comment
Share on other sites

Oui, il y a bien une clé product_name. C'est vrai que je pourrais passer directement l'affichage dans le code de l'override, ça éviterai l'utilisation d'un module. Mais du coup il faudrait que je crée un nouvel affichage pour cette partie dans le order-detail?

Link to comment
Share on other sites

Si tu as besoin de ton module, c'est lui qui récupère ta donnée du webservice et c'est lui qui va installer ton override.

Là on bosse directe dans le dossier override pour le coté pratique mais après tu vas tout mettre dans le dossier override de ton module et il va tout copié ou il faut à l'installation.

Link to comment
Share on other sites

1 hour ago, jef933 said:

J'ai pas le code sous les yeux mais tu peux me dire ce qu'il y a comme clé au tableau product quand tu fais print_r($product) dans ta boucle.

Tu dois avoir


$product['name']

ou un truc du genre.

C'est peux être pas terrible , j'en sais trop rien mais tu peux faire un truc du genre:


if($product['product_id'] == ton id){

$product['product_name'] .= '(pack valable encore tant de temps) enfin la donnée de ton webservice'
}

 

Du coup je comprends pas vers où tu veux m'emmener avec ce truc du genre 😉

Link to comment
Share on other sites

Ce code c'est ce que tu va mettre dans tonModule/override/OrderdetailsController, donc tu as bien besoin de ton module du coup.

Cet override te permet de rajouter l'infos dans le tableau sur la clé product name donc dans ton template tu la verra.

Link to comment
Share on other sites

non il est pas remplacé, tu le concatène avec ta donnée.

$product['product_name'] .= ta donnée


comme si tu fesait ça :

$product['product_name'] = $product['product_name'] . 'ta donnée'

Du coup dans ton affichage tu auras automatiquement le nom de ton produit + la donnée que tu lui passe

Link to comment
Share on other sites

Du coup c'est moi qui comprend plus là 😂

C'est pas ce que tu voulais afficher ta donnée récupérée de l'api en fonction de ton produit ?

On 6/13/2020 at 11:23 AM, thomasjrsn said:

Bonjour jef933, 

Mon module doit afficher pour un certain produit, qui serait un pack d'une durée limité, le nombre de jours restant avant l'expiration du pack. J'essaye donc d'identifier le nom du produit dans le détail de la commande qui se trouve dans l'historique des commandes car mon module sera affiché dans ce détail de la commande via le hookDisplayOrderDetail. Il faut donc que je fasse une condition sur l'affichage de mon module en fonction du produit.

 

 

Link to comment
Share on other sites

Ce que je veux marche mais je suis obligé de passer par le code du OrderDetailController original pour que l'affichage de mon module se fasse correctement et non pas par le override.

C'est d'utiliser la concaténation dont je ne comprends pas l'intérêt, j'ai bien ma donnée avec le nom du produit mais du coup je ne sais pas gérer son affichage comme pour le module.

Link to comment
Share on other sites

2 minutes ago, thomasjrsn said:

Ce que je veux marche mais je suis obligé de passer par le code du OrderDetailController original pour que l'affichage de mon module se fasse correctement et non pas par le override.

non, tu dois passer par l'override comme je t'ai dit plus haut. copie tout ce que tu as mis dans l'override Orderdetails dans l'override de ton module.

 

2 minutes ago, thomasjrsn said:

C'est d'utiliser la concaténation dont je ne comprends pas l'intérêt, j'ai bien ma donnée avec le nom du produit mais du coup je ne sais pas gérer son affichage comme pour le module.

Comment ça gérer son affichage ?

désolé je comprend pas bien 

Link to comment
Share on other sites

1 minute ago, thomasjrsn said:

J'ai mis dans les deux overrides le code mais cela ne fonctionne pas.

Renvoit moi ton module que je regarde stp

 

1 minute ago, thomasjrsn said:

Et bien l'afficher sur la page du détail de la commande, il faudrait créer un bloc spécialement pour cette donnée.

là on envoie juste une string pour tester mais tu peux utiliser un template smarty pour mettre en forme ta donnée.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...