Développer avec RBS Change : Ajouter des colonnes dans les listes des documents

  • 46811.1

    18/11/2011 15:31


    guiom
    Rang : Expert
    Bonjour,

    Est-il possible d'ajouter des colonnes supplémentaires dans l'affichage des listes des documents ?
    Je souhaiterez essentiellement pouvoir afficher la marque des produits dans les rayons.

    Merci
  • 46811.2

    18/11/2011 17:04


    Gaël Port
    Titre : Développeur RBS Change
    Rang : Expert
    Ajouter une colonne se fait en deux étapes :

    1) Ajouter la colonne dans la perspective : sur chaque document pouvant contenir un produit, il faut ajouter dans la section columns la colonne à ajouter (cf par exemple les dates de publication des produits déclarées sur les shelf et topshelf ou les nombreuses colonnes ajoutées pour les commandes). Il faudra aussi déclarer la locale pour cette colonne (mais ça vous vous en rendrez vite compte en affichant la liste).

    2) S'il s'agit d'une propriété du document à afficher telle quelle (genre le code référence), la valeur sera automatiquement remontée. Si par contre il s'agit d'une propriété à formater ou à calculer (comme la marque que vous voulez ajouter), là il faudra coder sa récupération dans la méthode addTreeAttributes du service du document et l'ajouter au tableau $nodeAttributes (par exemple sur les commandes on ajoute un certain nombre de propriétés). À noter que le paramètre $treeType de cette méthode contient le type de liste qu'on est en train d'afficher et vaut 'wlist' pour la liste principale, donc là on peut ne calculer la valeur que dans ce cas là (puisque les colonnes ne sont pas présentes dans les autres types de listes comme l'arbre de gauche ou le sélecteur de ressources).



    Sur un module existant, le point 1 peut se faire en surchargeant le fichier perspective.xml du module dans override. À noter cependant que cela fige le dit fichier et que lors des mises à jour il faudra penser à vérifier qu'il n'y a pas de corrections à reporter dedans.

    Le point 2 peut se traiter en injectant le service du document concerné et en redéfinissant la méthode (sans oublier d'appeler celle du parent pour ne pas perdre les valeurs déjà calculées en standard).
  • 46811.3 en réponse à 46811.2 écrit par Gaël Port

    21/11/2011 11:22


    guiom
    Rang : Expert
    Bonjour,

    Merci, cela fonctionne bien.
    Cependant, je ne suis pas parvenue à faire l'injection sur le service. Pour tester, j'ai ajouter la fonction directement dans le service du module (VirtualproductService.class.php).

    Je dispose d'un module dans lequel j'ai fait une injection sur catalogue/produit pour ajouter un champ. Est-ce que je peu l'utiliser pour surcharger la fonction pour tout les produits ?

    Merci
  • 46811.4 en réponse à 46811.3 écrit par guiom

    21/11/2011 12:16


    Gaël Port
    Titre : Développeur RBS Change
    Rang : Expert
    Oui tout à fait. Par contre, pensez à bien appeler la méthode parente lorsque vous l'écrirez parce que la méthode addTreeAttributes est déjà définie sur ce service (pour la gestion du mode vignette).
  • 46811.5 en réponse à 46811.4 écrit par Gaël Port

    21/11/2011 13:17


    guiom
    Rang : Expert
    Je ne parviens pas à faire utiliser ma fonction, il doit me manquer quelque chose. Voici ce que j'ai
    <?xml version="1.0" encoding="utf-8"?>
    <document xmlns="http://www.rbs.fr/schema/change-document/1.0"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.rbs.fr/schema/change-document/1.0 http://www.rbschange.fr/static/schema/change-document/3.5.xsd"
    	model-version="3.5" extend="modules_catalog/product" inject="true">
    	<properties>
    		<add name="isComing" type="Boolean" default-value="false" />
    		<add name="presentation" type="LongString" localized="true" />
    	</properties>
    </document>

    class monmodule_ProductService extends catalog_ProductService
    { ...
    	public function addTreeAttributes($document, $moduleName, $treeType, &$nodeAttributes)
    	{
    		parent::addTreeAttributes($document, $moduleName, $treeType, &$nodeAttributes);
    		if ($treeType == 'wlist')
    		{
    			$brand = $document->getBrand();
    			if ($brand)
    			{
    				$nodeAttributes['brand'] = $brand->getLabel();		
    			}
    			else {
    				$nodeAttributes['brand'] = '';
    			}
    		}
    	}
    ...
    }


    Je vois pas comment le service d'un produit virtuel peut utiliser ma fonction puisqu'il dérive de catalog_ProductService (comme mon service).

    Merci pour votre aide.

    Édité par guiom 21/11/2011 14:19

  • 46811.6 en réponse à 46811.5 écrit par guiom

    21/11/2011 14:09


    Gaël Port
    Titre : Développeur RBS Change
    Rang : Expert
    En fait quand on déclare une injection sur un document, la classe finale, le modèle et le service du document sont remplacés par ceux du document qui l'injectent. Pour cela on passe par la même mécanique que pour l'AOP qui va renommer les classes d'origine et générer de nouvelles classes étendant ces classes renommées.

    Tout cela est rendu possible par la mécanique d'autoload. Lorsqu'une classe est chargée, on cherche dans cache/autoload le fichier contenant cette classe (l'arborescence étant faite selon le nom de la classe avec comme séparateur de dossier l'underscore). Par défaut ce dossier contient donc simplement des liens symboliques vers l'ensemble des classes du projet.

    Lors d'une injection (ou d'une modification de classe par AOP), le lien symbolique vers le fichier est simplement remplacé par un nouveau fichier contenant la classe d'origine renommée et la nouvelle classe. Vous pouvez jeter un œil dans le dossier cache/autoload pour vous faire une meilleure idée.

    Du coup ça veut aussi dire qu'à chaque fois qu'une classe impliquée dans une injection de document ou dans un remplacement par AOP est modifiée il faut relancer la commande compile-aop (qui va régénérer les fichiers dans cache/autoload). Donc c'est peut-être juste ça qui vous manque (en principe quand c'est le cas, un message remonte disant qu'il faudrait relancer la commande mais je ne suis pas sûr que ce soit fait dans 100% des cas).



    Sinon, en passant : en PHP 5, l'utilisation du & lors du passage d'argument est déprécié (autorisé uniquement dans le profil de la fonction), il vaudrait donc il faudrait l'enlever lors de l'appel à la méthode parente.
  • 46811.7 en réponse à 46811.6 écrit par Gaël Port

    21/11/2011 14:21


    guiom
    Rang : Expert
    Merci pour ces explications, le système est vraiment très puissant.

    C'était bien cette compilation qui manquait.
 
Merci de prendre connaissance et de respecter les règles des forums.
 
1437 membres
Aucun membre connecté