Est-il bon d'instancier une classe getModel sur des modèles phtml?

14

C'est une question concernant les bonnes pratiques de programmation dans Magento.

Je dois montrer (dans la liste des produits de la catégorie) le produit avec ses produits associés dans les vignettes. J'ai donc édité mypackage/mytheme/template/catalog/product/list.phtmlavec quelque chose comme ça

<?php 
    $related=$_product->getRelatedProductIds();
    if(count($related)>0){
        echo '<div class="a'.$ap.'"></div>';
        echo '<div class="li_p"><ul>';
        foreach($related as $rela){
            $rela_nom=Mage::getModel('catalog/product')->load($rela);
            echo '<li><a href="'.$rela_nom->getProductUrl().'"> <img src="'.$this->helper('catalog/image')->init($rela_nom, 'small_image')->resize(20).'" width="20" height="20"> </a><li>';
        }
        echo '</ul></div>';
    }
?>

Et ça marche très bien.

Mais ma question est: est-ce correct d'instancier une classe de modèle sur les fichiers phtml?

Si ce n'est pas le cas, quelle serait la meilleure façon d'obtenir cette fonctionnalité? Je veux dire, quel fichier est préférable d'éditer ou quelle classe est préférable d'ajouter, où? Un assistant?

Pouvez-vous donner un petit exemple ou me donner un aperçu des fichiers qu'il est préférable d'éditer.

user604
la source

Réponses:

10

Je ne suis pas d'accord avec la réponse de Sonassi :)

Le lancement d'un modèle dans le modèle est une mauvaise pratique. Parfois, c'est nécessaire et parfois je le fais aussi. Mais si cela est possible, vous devez empêcher d'ajouter du code à vos fichiers pHTML et seulement des echochoses données.

C'est la séparation des préoccupations . Ne mélangez pas le HTML et le codage. Cela devrait être dans la classe Block.

Fabian Blechschmidt
la source
3
Je suis également d'accord avec votre désaccord :) Mais charger un seul modèle en dehors d'une boucle n'est pas la fin du monde. Sinon, cela devient un cas d' abstraction à l'infini - en ajoutant des classes supplémentaires existant simplement pour la séparation d'une seule ligne de code de la vue. Cela ne fait qu'ajouter à la réécriture des frais généraux, sans parler de la maintenance.
Ben Lessani - Sonassi
Vous avez trop de temps si vous voulez corriger toutes mes fautes d'orthographe, merci pour cela :-)
Fabian Blechschmidt
Btw, vous avez raison sonassi :-) C'est juste quelque chose que nous devons faire attention. J'ai vu des requêtes SQL dans des fichiers phtml ... NON NON :-)
Fabian Blechschmidt
4

Il n'y a rien de mal à charger un modèle dans un phtmlfichier. Mais cela dépend de la raison pour laquelle vous le faites.

Si vous avez besoin de l'intégralité du modèle et de toutes les données qui lui sont associées, vous pouvez également charger l'intégralité du modèle.

Mais si vous avez juste besoin de l'URL du produit (de votre exemple), vous pouvez simplement charger la bonne collection

$_product->getRelatedProductCollection();

Ensuite, répétez cela si nécessaire

<?php $_relatedCollection = $_product->getRelatedProductCollection(); ?>
<?php foreach ($_relatedCollection as $_item): ?>
<li>
  <a href="<?php echo $_item->getProductUrl(); ?>">
    <img src="<?php echo $this->helper('catalog/image')->init($_item, 'small_image')->resize(20); ?>" width="20" height="20">
  </a>
<li>
<?php endforeach; ?>
Ben Lessani - Sonassi
la source
3

Je veux mettre mes 5 cents ici. Nous devons respecter les principes d'architecture utilisés dans Magento. Le modèle architectural principal utilisé dans Magento est MVC. Dans le cas de Magento, la partie "Affichage" contient plusieurs éléments (bloc, modèle, mise en page). Des blocs ont été créés pour déplacer la logique de préparation des données du modèle vers une autre classe afin de rendre les modèles plus propres et lisibles pour les développeurs frontaux. Ici, je veux être d'accord avec Fabian.

En ce qui concerne les préoccupations de Sonassi concernant trop de classes inutiles, je suggère de se réjouir de pousser MVC basé. Dans ce cas, nous considérons le contrôleur comme un commandant qui définit quel bloc et quelles données doivent avoir. L'action dans le contrôleur peut contenir le code requis pour charger les données et les mettre en bloc (via des setters magiques) avant le rendu.

Dmitriy Vasilenko
la source
3

Je suis d'accord avec Fabian Blechschmidt que c'est une mauvaise pratique et vous devez respecter la séparation des préoccupations.

Pour ajouter une suggestion constructive:

C'est quelque chose, les classes Block sont destinées. Dans votre cas, vous devrez réécrire Mage_Catalog_Block_Product_List pour ajouter la fonctionnalité souhaitée:

public function hasRelatedProducts()
{
    return count($this->getRelatedProductIds()) > 0;
}
public function getRelatedProducts()
{
    $products = array();
    foreach ($this->getRelatedProductIds() as $id) {
        $products[] = Mage::getModel('catalog/product')->load($id);
    }
    return $products;
}

Il devrait être évident comment utiliser ces méthodes dans le modèle.

Remarque: Réécrire ne signifie pas éditer le fichier core. Suivez le tutoriel de personnalisation si vous ne savez pas comment réécrire un bloc.

Fabian Schmengler
la source