Pour un besoin d’un site Internet développé sous Symfony, j’ai décidé d’utiliser le behavior NestedSet pour gérer des catégories d’un catalogue produit sous la forme d’un arbre.
Un des inconvénients des arbres avec Doctrine NestedSet, c’est le nombre important de requêtes exécutées pour récupérer la totalité de l’arbre. Je vais vous montrer comment j’ai mis en place le cache Doctrine (useResultCache) avec le behavior NestedSet.
Tout d’abord, dans config/ProjectConfiguration.class.php, vérifiez que vous avez bien activé le cache Doctrine:
public function configureDoctrine(Doctrine_Manager $manager)
{
/* Initialisation du cache Doctrine APC */
$cacheDriver = new Doctrine_Cache_Apc();
$manager->setAttribute(Doctrine::ATTR_QUERY_CACHE, $cacheDriver);
$manager->setAttribute(Doctrine::ATTR_QUERY_CACHE_LIFESPAN, sfConfig::get('app_cache_lifetime')); //mettre cette variable dans app.yml
$manager->setAttribute(Doctrine::ATTR_RESULT_CACHE, $cacheDriver);
$manager->setAttribute(Doctrine::ATTR_RESULT_CACHE_LIFESPAN, sfConfig::get('app_cache_lifetime'));
}
Ensuite au niveau de votre action ou component, pour récupérer la totalité de votre arbre avec le cache d’activé :
$this->categories = Doctrine::getTable('category')->getTree();
$q = Doctrine::getTable('category')->createQuery()->useResultCache();
$this->categories->setBaseQuery($q);
$this->categories = $this->categories->fetchTree();
Et enfin, au niveau du template, voici le code pour afficher correctement votre arbre sous la forme de menu par exemple :
<h2>Catégories</h2>
<ul>
<?php foreach ($categories as $node) : ?>
<?php if($node['level'] == 0) continue; ?> //ici on affiche pas la catégorie ROOT
<?php if($node['level'] == '1'): ?>
<li>
<span><a href="#"><?php echo $node['label'] ?></a></span>
<?php if($node->getNode()->hasChildren()): ?>
<ul id="child_<?php echo $node['id']; ?>">
<?php foreach($node->getNode()->getChildren() as $child): ?>
<li><a href="<?php echo url_for('category', $child); ?>"><?php echo $child->getLabel(); ?></a></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</li>
<?php endif;?>
<?php endforeach; ?>
</ul>
Voilà, votre arbre est maintenant mis en cache!
To be continued…
