Développer avec RBS Change : [Résolu] Envoi d'un document spécifique par request à un block
-
18/04/2013 11:30
Bonjour,
Je suis entrain de développer un module spec dans lequel j'ai créé un document xxx, je voulais récupérer au niveau du template du block associé à ce module l'ensemble des infos relatives à ce module.
Au niveau de l'action du block j'ai ajouté un$xxx = $this->getDocumentParameter(); if ($xxx=== null || !($xxx instanceof nom_module_persistentdocument_xxx) || !$xxx->isPublished()) { // We choose not to throw anything if document parameter is missing $request->setAttribute('xxx', "NON OK"); } else { // We transmit the document to the view $request->setAttribute('xxx', $xxx); }
Mais il me retourne toujour un 'NON OK' lorsque je tente de récupèrer l'attribut au niveau de template...
Cordialement.
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
Bonjour,
Avez-vous identifié laquelle de vos 3 conditions est satisfaite pour arriver à "NON OK"?
Passez-vous bien un document en paramètre à votre bloc? Comment est le bloc est-il invoqué? N'y a-t-il pas d'erreur à l'invocation du bloc, cf page wiki sur la macro link PHPTal?
Avez vous cherché à regarder que valait "$xxx" en ajoutant par exemple une ligne de ce type pour la voir dans le fichier de log :Framework::fatal("##################### MA VARIABLE XXX :\n".var_export($xxx, true)."\n#######################");
Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié. -
77581.3 en réponse à 77581.2 écrit par Jean-Michel
18/04/2013 12:31
Bonjour,
Merci pour votre réponse,
J'ai essayé les trois conditions chacune à part:
- Le '===null' m'a retourné au niveau des logs un2013-04-18 10:47:39 [FATAL] ##################### MA VARIABLE XXX : NULL #######################
- Le instantof m'a retourné la même erreur
- Le isPublished() m'a retourné une erreur PHP m'indiquant Call to a member function isPublished() on a non-object.
Au niveau du FO j'ai toujours un "NON OK" sauf pour le dernier cas.
Et ce que j'ai voulu avoir c'est de faire un<tal;blocks> <tal:block tal:condition="xxx/getBoolean">${xxx/getLabel}</tal:block> <tal:block tal:condition="not: xxx/getBoolean">autre traitement ...</tal:block> <tal:blocks>
et pas plus pour l'instant donc mon besoin se résume a envoyé un document de type xxx au block, tester sur un boolean qu'on a ajouter au niveau du bo et afficher le label sinon faire un autre traitement...
Cordialement
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
Avec ces informations, je suppose donc que le document n'est pas passé au bloc, d'où le retour NULL pour "$this->getDocumentParameter()". Les comportements observés sont effectivement prévisible vu que "$xxx" vaut NULL.
Vu que je n'ai toujours pas d'information sur le contexte d'appel du bloc, je vais donc supposer les choses suivantes :
- un bloc A chargé d'afficher un lien vers le bloc X
- le bloc A se trouve dans une page AA (par exemple un bloc de liste de documents sur une page contenant un lien vers le bloc de détail du document -> le bloc X sur la page XX)
- j'admet que le bloc X est repéré par le tag T
Ce qui laisse place à un code du type :
- Dans le template de notre bloc A (bloc de liste) :<!-- La variable docsArray est un tableau de documents --> <ul tal:condition="docsArray"> <li tal:repeat="doc docsArray"> <!-- Voir wiki pour change:link (http://wiki.rbschange.fr/ref:phptal:liens) --> <a change:link="tag T;document doc">${doc/getLabelAsHtml}</a> </li> </ul>
- Dans le code de l'action du bloc X :$xxx = $this->getDocumentParameter(); if ($xxx != null && $xxx instanceof nom_module_persistentdocument_xxx && $xxx->isPublished()) { // We transmit the document to the view $request->setAttribute('xxx', $xxx); }
- Dans le code du template du bloc X (bloc de détail du document) :<!-- On vérifie que l'on a bien un document xxx transmis au template --> <tal:block tal:condition="xxx">${xxx/getLabelAsHtml}</tal:block> <tal:block tal:condition="not: xxx">autre traitement ...</tal:block>
Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié. -
77581.5 en réponse à 77581.4 écrit par Jean-Michel
18/04/2013 15:29
Bonjour,
Je vais vous expliquer le comportement désiré car j'ai pas besoin d'avoir un lien vers un document dans mon cas, je veux faire de manière a avoir un interface BO d'un module spec dans lequel l'utilisateur BO ajoute un nouveau document xxx et lui donne une valeur (true ou false) à un boolean et ajoute un label et un filtre d'application et enregistre ce dernier, et moi j'ai créé un template d'un block dans lequel je veux afficher un checkbox et une zone de texte et l'inclure dans la page panier, du coup je veux tester sur ce dernier si le boolean est a true c'est à dire que je dois afficher le bloc sinon je ne l'affiche pas...
J'ai essayé au premier instant de faire directement un<tal:block tal:condition="xxx/getBoolean"></tal:block>
mais le retour était toujours la non condition, donc j'ai cru que avant que j'invoque le getBoolean sur le xxx je dois faire un setAttribute dans l'action du block pour que ce dernier saura de quel document il s'agit.
Je sais pas si je suis sur le bon chemin ou je dois agir autrement pour avoir le comportement souhaité??
Cordialement.
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
Donc si je comprends bien, le document que doit rendre le bloc est un paramètre de configuration du bloc donc définit dans le fichier blocks.xml? C'est la seule solution que je vois pour avoir un bloc qui fait le rendu d'un document sans que l'on ait besoin de faire de lien vers le bloc.
Si nous sommes donc bien dans ce cas, alors effectivement le document ne se récupère pas de cette manière. En admettant que le nom du paramètre de bloc désignant le document se nomme "myParam" alors dans ce cas, la récupération du document se fait de la manière suivante :$xxx = $this->getConfiguration()->getMyParam();
Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié. -
77581.7 en réponse à 77581.6 écrit par Jean-Michel
18/04/2013 18:16
Bonjour,
Je vois bien que vous qu'on se rapproche de la solution
Je viens d'ajouter au niveau du block.xml le paramètre désiré<?xml version="1.0" encoding="utf-8"?> <blocks> <block type="modules_nommodule_Xxx" icon=""> <parameter name="xxx" type="modules_nommodule/xxx"/> </block> </blocks>
Après dans l'action du block<?php /** * nommodule_BlockXxxAction * @package modules.nommodule.lib.blocks */ class nommodule_BlockXxxAction extends website_BlockAction { /** * @param f_mvc_Request $request * @param f_mvc_Response $response * @return String */ public function execute($request, $response) { if ($this->isInBackofficeEdition()) { return website_BlockView::NONE; } $xxx=$this->getConfiguration()->getXxx(); Framework::fatal("##################### MA VARIABLE XXX :\n".var_export($xxx,true)."\n#######################"); $request->setAttribute("xxx", $xxx); return website_BlockView::SUCCESS; } }
Au niveau des logs j'ai rien reçu et j'ai un message d'erreur sur le FrontFatal error: Call to undefined method nommodule_BlockXxxConfiguration::getXxx()
J'ai lancé un clear-all suivi d'un compile-all et un compile-blocks
Cordialement.Édité par mamous 18/04/2013 18:20
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
Modifiez encore votre configuration de bloc comme suit :
<?xml version="1.0" encoding="utf-8"?> <blocks> <block type="modules_nommodule_Xxx" icon=""> <parameters> <parameter name="xxx" type="modules_nommodule/xxx"/> </parameters> </block> </blocks>
puis exécutez un compile-all, là le paramètre sera correctement déclaré puisque dans le bon noeud XML
Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié. -
77581.9 en réponse à 77581.8 écrit par Jean-Michel
18/04/2013 18:57
Merci ou sa passe mais j'ai pas pu rien visualiser le<tal:block tal:condition="xxx/getActive">${xxx/getLabel}</tal:block><tal:block tal:condition="not: xxx/getActive">${xxx/getLabel}</tal:block>
J'ai rien comme retour dans le template du block et de plus au niveau des logs j'ai pas reçu de msg m'indiquant le contenu de la variable...
j'ai fait un var_dump dans l'action de $xxx il me retourne un null aussi :/
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
Y'a autre chose à laquelle j'ai pas pensé, dans mon cas, mon besoin est d'afficher le block xxx dans le cas ou le document créé à partir du BO satisfait la condition d'un filtre sur le module order. donc ici au niveau du template j'ai pas une seule variable de type ce document, donc logiquement je dois faire un tal:repeat sur tout les doc et comme sa s'il y aura un doc qui satisfait la condition du filtre et avec un Active à true on aura le block affiché sinon rien.
Est ce que vous confirmer ce que je viens de dire et si c'est le cas comment dois je procédé et merci bien
Cordialement
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
Si le log n'apparaît pas dans le fichier de log, cela ne veut dire qu'une seule chose : le code n'est pas appelé et n'est pas exécuté. A ce moment là je ne peux rien faire pour vous ne connaissant pas la masse de code autour de ce log.
En principe si vous avez un tableau d'éléments dans le template PHPTal il faut effectivement faire un tal:repeat. Ce n'est pas parce que vous avez un tableau d'éléments qu'il y en a forcément un qui va vérifier votre condition, car on parle ici de condition. Un filtre pour moi renvoi à un filtre utilisé pour le requêtage de la base, cf tuto de création de filtre sur le wiki.
Je crois que ce que vous cherchez à faire se rapproche du fonctionnement du bloc de mise en avant du module "event" (bloc "modules_event_Highlight"), je vous invite donc à vous baser sur le code de ce bloc pour arriver à vos fins.
Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié. -
77581.12 en réponse à 77581.11 écrit par Jean-Michel
19/04/2013 11:06
Bonjour,
Le log n'est pas apparut je crois parce que j'ai dans une condition if($xxx ===null) return null; et le log je l'ai mis après la condition donc je le voyais pas.
et ici le tableau d'élément dont vous parlez, j'ai cru que c'est logique vu que dans le module je peux créer bcp de document donc j'avais cru qu'un tal:repeat est indispensable...
Le module 'event' dont vous parlez n'existe pas pour la 3.5.2 a ce qu'il parait, je suis entrain de télécharger la v 3.6.4 en espérant que sa va m'aider.
Merci bien pour vos réponses et je vous tiendrez au courant
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
ok, juste pour info le module event existe en 3.5.2.
Si vous n'arrivez pas à l'avoir, voici l'adresse de la branche 3.5.2 du module : https://github.com/RBSChange/modules.event/tree/3.5.2
En principe en faisantphp framework/bin/change.php install-module event-3.5.2
Le module devrait s'installer tout seulÉdité par Jean-Michel 19/04/2013 11:27
Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié. -
77581.14 en réponse à 77581.13 écrit par Jean-Michel
19/04/2013 16:19
Bonjour,
J'ai essayer d'autres trucs sur le document mais en vain...
J'ai essayer de mettre au niveau de block.xml<?xml version="1.0" encoding="utf-8"?> <blocks> <block type="modules_papergift_Papergift" icon=""> <parameters> <parameter name="label" type="String"/> <parameter name="description" type="String"/> <parameter name="active" type="Boolean"/> <parameter name="nbr_char" type="Integer" /> <parameter name="query" type="Lob"/> </parameters> </block> </blocks>
!!j'ai essayé de faire un$xxx=$this->getDocumentParameter('874115');
avec 874115 un id d'un document de type nommodule/xxx et aussi il ma retourné un null au niveau des logs.
Je sais pas j'avais cru que mon besoin est assez simple, créer des documents du backoffice et récupérer quelques info dans le front!!!
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
Le besoin indiqué ; créer des documents en back office et les afficher est quelque chose de simple, pour vous en convaincre je vous laisse regarder le tuto de création d'un module dans le wiki.
Pour rappel, il est plus simple de définir un filtre dans un document que comme paramètre de configuration du bloc, comme c'est le cas dans le module "event" pour le block de rendu des document "highlight".
D'autre part, comme je vous ai indiqué les deux pistes sur lesquelles il était possible de partir, à partir des explications fournies, je vous propose de décrire à nouveau votre scénario, mais cette fois de manière simple. Pour cela utiliser des phrases courtes et des listes à puces.
Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié. -
77581.16 en réponse à 77581.15 écrit par Jean-Michel
19/04/2013 18:22
Bonjour,
Déjà c'est ce que je me disais, je crois qu'on a un peu compliqué les choses c'est pour cela que je me suis posé la question ...
Voila je t'explique tout simplement le besoin.
- Au niveau BO:
> Ajouter une interface BO, dans laquelle on ajoute des documents qui contiennent un label, une description, un boolean et un filtre (condition d'application sur un panier)
- Au niveau FO:
>Ajouter un block dans la page panier.
>Si la condition du filtre est satisfaite, on teste sur le boolean s'il est a true on affiche le block.
>Si c'est pas le cas, on affiche pas le block.
Voila en gros ce que je veux faire, pour l'instant je me suis pas trop foncé dans le filtre, je voulais faire de sorte à juste récupérer le boolean et tester dessus.
Merci bien Jean MichelÉdité par mamous 19/04/2013 18:24
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
Bonjour Mamous,
Pour ton besoin BO, toutes les informations nécessaires sont disponibles dans le wiki, dans la rubrique "Guide du développeur", il est expliqué pas à pas comment ajouter un nouveau document, puis comment le rendre éditable en BO et en bonus, comment personnaliser les éditeurs BO.
Une fois que ces étapes sont remplies, tu es capable de créer en BO autant de documents que tu le souhaites, maintenant il reste a les afficher en FO. Tant que tu ne peux pas faire ça, il n'est pas la peine de lire la suite
Avant de passer à ton besoin FO, attention à la terminologie des éléments, c'est ce qui à mon avis rend ton sujet difficile à résoudre :
- un module est un ensemble fonctionnel composé de documents, blocks (etc...) et tout un tas de fonctionnalités spécifiques au module.
- la structure d'un document est représentée par un fichier xml (situés dans le dossier persistendocument) et les instances de documents sont enregistrés en bdd (ex : une commande, un client, une page etc...)
- un block permet d'afficher des éléments en FO, est composé d'une action (php) et d'une vue (gabarit html phptal), et est définit/paramètrable par un fichier de configuration situé dans monmodule/config/blocks.xml.
Il permet la plupart du temps d'afficher des documents, mais il peut faire aussi d'autres choses (ex: évaluer les frais de livraison sur le panier).
- un filtre, est un composant Change qui permet de renseigner des conditions d'applications sur un document ou un dossier (pour faire des dossiers intelligents par exemple).
Revenons à ton besoin FO, qui pour le coup, n'est pas du tout simple à comprendre sans le contexte métier. Il y a plusieurs incompréhension dans ce que tu dis, et dans l'ordre que tu le dis.
Il n'est pas possible de tester le filtre renseigné sur une instance de document que tu as créé, sans avoir choisi au préalable cette instance de document.
Comment comptes-tu le faire ? Boucler sur toutes les instances ? En choisir une par son ID ? Que l'utilisateur en sélectionne une lui-même sur l page du panier ? En fonction des produits qui sont ajoutés au panier ? etc....
Une fois que tu auras l'instance du document, tu pourras faire tout ce que tu veux via le code, mais maintenant, tant que je ne sais pas ce que tu veux faire concrètement, avec des exemples concrets, je ne peux pas aller plus loin sans faire de trop nombreuses hypothèses...
Tu peux par exemple nous donner un cas complet, comprenant les propriétés valorisées de ton document, quel est le filtre que tu souhaites appliquer, et quel est le message a afficher dans la block si les conditions sont remplies.Édité par Mathias 20/04/2013 16:32
Développe sous linux Ubuntu 12.04 LTS Desktop
Projet ecommerce core 3.6.7 -
Bonjour et merci bien pour votre réponse,
Normalement, et dans mon cas, je vais utiliser les mêmes filtres sur le panier qui sont employé dans le module animation commerciale dans l'action de réduction..
Pour que ce que je vais afficher sur le front c'est un simple check box et un peu de texte que je vais intégrer dans la page panier.
Maintenant pour les doc, j'ai pensé en premier instant à boucler sur tout les documents et afficher dans le cas ou j'aurais un des documents qui aura la condition du filtre correcte mais sinon si sa serait pénible a faire on pourrais faire de sorte a choisir un document, par exp le dernier, et l'appliqué au panier.
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core -
bon ben a priori dans ce cas ce n'est pas très compliqué...
Toute la logique va se retrouver dans l'action (php) de ton block, qui va ensuite en fonction du résultat afficher la vue (html) souhaitée.
A savoir que ce qui te manque, au vu des échanges précédents, c'est comment récupérer des instances de documents en base.
Imaginons que tu as les éléments suivants :
- module = monModule
- document = monDoc
- block = monBlock
Le code de l'action de ton block va ressembler à ça :/** * monModule_BlockMonBlockAction * @package modules.monmodule.lib.blocks */ class monModule_BlockMonBlockAction extends website_BlockAction { /** * @param f_mvc_Request $request * @param f_mvc_Response $response * @return String */ public function execute($request, $response) { //on récupère tous les documents $monDocs = $this->getMySpecificDocuments(); //on boucle sur les documents //il est préférable de tester avant que tu as bien des docs (pas fait ici) foreach($monDocs as $monDoc) { //on valide le filtre et le boolean if($this->checkMyFilterAndMyBoolean($mondoc)) { //dès qu'une instance valide le filtre on renvoi la vue success return website_BlockView::SUCCESS; } } //sinon on n'affiche pas la vue du block return website_BlockView::NONE; } /** * Ceci va récupérer toutes les instances publiées de monDoc de monModule * @return <monModule_persistendocument_mondoc> array */ public function getMySpecificDocuments() { $query = monModule_MonDocService::getinstance()->createQuery(); $query->add(Restrictions::published()); return $query->find(); } /** * ici ton code qui valide tes filtres et ton boolean (à toi de voir quels sont les contrôles à faire sur ce document) * @return boolean */ public function checkMyFilterAndMyBoolean($monDoc) { } }
Édité par Mathias 22/04/2013 10:50
Développe sous linux Ubuntu 12.04 LTS Desktop
Projet ecommerce core 3.6.7 -
Bonjour,
je tiens à vous remercier pour votre réponse bien détaillée.
Je viens d'ajouter le bout de code dont vous m'avez envoyer, en faisant dans la méthodepublic function checkMyFilterAndMyBoolean($monDoc) { return true; }
ainsi si j'aurais un document dans le BO le block s'affichera en Front.
c'est deja pas mal.
Maintenant, et dans mon cas, l'attribut query que j'ai utiliser pour le filtre, fait appel aux filtres définit dans le module order<field name="query" type="objectfilter" allow="order/cart,order/cartdiscount::checkValue" hidehelp="true" />
du coup, je voulais dans la méthode checkMyFilterAndMyBoolean tester sur le retour de ce dernier.
En suivant quelques exemples de modules, j'ai ajouter la méthode/** * @param xxx_persistentdocument_xxx $xxx * @param order_CartInfo $cart * @return boolean */ public function validateForCart($xxx, $cart) { $df = f_persistentdocument_DocumentFilterService::getInstance(); $errors = array(); if ($df->checkValueFromJson($xxx->getQuery(), $cart) { return true; } return false; }
mais je me trouve avec un message d'erreur m'indiquant que je peux pas invoquer la méthode getQuery sur un non objet ($xxx) sachant que j'ai modifier dans l'entête du service pour qu'il étend order_CartmodifierService.
Une deuxième question, si je procéde de cette manière là, au niveau de l'action du block dois je faire une chose de ce typepublic function checkMyFilter($monDoc) { return xxx_xxxService::getinstance()->validateForCart($monDoc, $cart); }
et dans mon cas le $cart n'est pas définit donc comment dois je le récupérer...
Développeur & Intégrateur Web
RBS Change
V 3.5.2
Ecommerce Core