<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Artisan Numérique</title>
  <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1510"/>
  <link rel="self" type="application/atom+xml" href="http://artisan.karma-lab.net/node/1510/atom/feed"/>
  <id>http://artisan.karma-lab.net/node/1510/atom/feed</id>
  <updated>2008-03-14T11:00:28+01:00</updated>
  <entry>
    <title>Changer le thème de drupal, avec le cache</title>
    <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1510" />
    <id>http://artisan.karma-lab.net/node/1510</id>
    <published>2008-03-14T10:58:37+01:00</published>
    <updated>2008-03-14T11:00:28+01:00</updated>
    <author>
      <name>Ulhume</name>
    </author>
    <category term="Drupal" />
    <category term="drupalfr.org" />
    <category term="Planet Libre" />
    <category term="Tutoriel" />
    <summary type="html"><![CDATA[<p>
   Dans le volet précédent de la saga "<a class='external' target='_blank' href='/node/1509' >Comment changer dynamiquement de thème Drupal</a>, notre module souffrait d'un défaut de taille : Il fallait désactiver le cache pour qu'il fonctionne. Nous allons voir maintenant comment le modifier pour que la même chose soit possible sans perte de performances.  
</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>
   Dans le volet précédent de la saga "<a class='external' target='_blank' href='/node/1509' >Comment changer dynamiquement de thème Drupal</a>, notre module souffrait d'un défaut de taille : Il fallait désactiver le cache pour qu'il fonctionne. Nous allons voir maintenant comment le modifier pour que la même chose soit possible sans perte de performances.  
</p>
<!--break-->

	<a name='chapter_1'></a>
	<h2>Gestion du cache</h2>
	
<p>
  Le cache de page sous Drupal est un mécanisme bête et efficace. S'il est actif, on commence avant d'afficher quoi que ce soit, par vérifier qu'il n'existe pas un enregistrement correspondant à l'URL demandée dans la table <kbd>cache_page</kbd>. Si c'est le cas, les données de cet enregistrement sont directement expédiées sur le navigateur client et le traitement s'arrête là. Le cache de page contient donc toute la page, thème compris. Et c'est bien là notre problème. 
</p>
<p>
  Ce cache peut être soit désactivé, soit en mode "normal", soit en mode "agressif". En mode agressif, aucun module ne peut intervenir et le site est quasiment "statique". C'est pour cela qu'il est assez rarement utilisé. En mode normal, certains modules dits "bootstrap" (voir l'article précédent) peuvent avoir une action sur le contenu, c'est ce que nous allons exploiter. 
  </p>
  <p>Bien évidement, une page mise en cache n'est pas valide à vie. Il y a un paramètre que vous pouvez modifier dans les performances indiquant de durée de validité des enregistrements. Passé ce temps, la page est refabriquée et vient écraser l'ancienne version en base.  
</p>
<p>
  Un autre aspect important à connaître sur ce cache de page, c'est qu'il est désactivé pour tout utilisateur connecté. Ce qui peut poser un problème de performance dans le cas où votre site n’a que des utilisateurs authentifiés. En gros, le cache n'agit que sur la version anonyme du site et c'est un aspect à ne pas négliger car lorsque l'on développe, nous sommes souvent connectés, et le comportement n'est plus du tout le même...
</p>
<p>
  Donc pour créer un thème dynamique en fonction du navigateur cible, avec un cache en mode "normal", on va tomber sur le problème du "premier qui gagne". Si un navigateur IE6 passe avant les autres, c'est le thème IE6 qui va finir dans le cache et tout le monde sera logé à la même enseigne. Pire, vu qu'il y a un enregistrement par page, et donc à la rubrique/billet affiché, on aurait rapidement un site "arlequin" avec un thème qui change de manière aléatoire d'une page à l'autre.  
</p>
<p>
  La seule solution pour régler ce problème est donc de modifier la stratégie de gestion du cache.    
</p>



	<a name='chapter_2'></a>
	<h2>Stratégie de cache</h2>
	
<p>
  Malheureusement il n'y a pas de hooks que l'on puisse implémenter pour changer la manière dont fonctionne le cache. Il va donc nous falloir modifier les sources du coeur de Drupal. Prenez donc soin d'en faire une copie préalable. 
</p>
<p>
  Le principe général est assez simple. Drupal retrouve le bon enregistrement d'une page dans le cache en fonction d'une clef. Cette clef est simplement l'URL de la page à afficher. Il va donc nous falloir changer un peu cela pour que la nouvelle clef soit cette fois l'URL <b>additionnée du thème $custom_theme</b>. 
</p>
<p>
  La stratégie du cache de page est pris en charge dans le module <kbd>includes/bootstrap.inc</kbd>, dans la fonction <kbd>_drupal_cache_init</kbd>. C'est là que sont appelés nos kooks _init et _exit. Et c'est aussi là qu'est fait la distinction entre les trois modes du cache. 
  </p>
  <p>Le problème est que le hook _init est appelé après récupération de la page en cache. Et du coup notre clef va être fausse. Il faut donc modifier la fonction pour faire appel à notre module avant que le cache ne soit lu. Malheureusement il n'existe pas de fonction dans l'API de cache pour vérifier qu'un enregistrement existe avant de le charger effectivement. Et si l'on continue d'utiliser le hook _init, on prend le risque qu'il soit appelé deux fois de suite : une fois avant la lecture en cache, et une fois de plus s'il n'y avait pas d'enregistrement en cache pour cette page. Ce n'est pas un problème pour notre module mais cela risque d'en devenir un pour les autres modules "bootstrap" utilisant init/exit. Nous allons donc éviter le problème en créant notre propre hook, _preinit, et en l'invoquant avant la récupération des données en cache. Cela nous donne la fonction de remplacement suivante :
  <div class='code-container-area'><div class='code-container-caption'>includes/bootstrap.inc</div><div class='code-container'><div class="code"><ol><li class="li1"><div class="de1"><span class="kw2">function</span> _drupal_cache_init<span class="br0">&#40;</span><span class="re0">$phase</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">require_once</span> variable_get<span class="br0">&#40;</span><span class="st0">'cache_inc'</span><span class="sy0">,</span> <span class="st0">'./includes/cache.inc'</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$phase</span> <span class="sy0">==</span> DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE <span class="sy0">&amp;&amp;</span> variable_get<span class="br0">&#40;</span><span class="st0">'page_cache_fastpath'</span><span class="sy0">,</span> <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>page_cache_fastpath<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <a target="blank" &nbsp;href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">elseif</span> <span class="br0">&#40;</span><span class="re0">$phase</span> <span class="sy0">==</span> DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>variable_get<span class="br0">&#40;</span><span class="st0">'cache'</span><span class="sy0">,</span> CACHE_DISABLED<span class="br0">&#41;</span> <span class="sy0">==</span> CACHE_AGGRESSIVE<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$cache</span> <span class="sy0">=</span> page_get_cache<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; drupal_page_cache_header<span class="br0">&#40;</span><span class="re0">$cache</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a target="blank" &nbsp;href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">elseif</span> <span class="br0">&#40;</span>variable_get<span class="br0">&#40;</span><span class="st0">'cache'</span><span class="sy0">,</span> CACHE_DISABLED<span class="br0">&#41;</span> <span class="sy0">==</span> CACHE_NORMAL<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">require_once</span> <span class="st0">'./includes/module.inc'</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; bootstrap_invoke_all<span class="br0">&#40;</span><span class="st0">'preinit'</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$cache</span> <span class="sy0">=</span> page_get_cache<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bootstrap_invoke_all<span class="br0">&#40;</span><span class="st0">'init'</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; drupal_page_cache_header<span class="br0">&#40;</span>page_get_cache<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bootstrap_invoke_all<span class="br0">&#40;</span><span class="st0">'exit'</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a target="blank" &nbsp;href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">require_once</span> <span class="st0">'./includes/module.inc'</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div></div></div>  
</p>
<p>
  Ensuite, nous allons modifier le module de l'article précédent pour renommer _init en _preinit, et créer une nouvelle fonction _init qui sera cette fois vide. 
</p>


	<a name='chapter_3'></a>
	<h2>Lecture et écriture du cache</h2>
	
<p>
  Maintenant nous allons modifier les fonctions qui lisent et qui écrivent dans le cache pour ajouter le thème dans la clef. La lecture tout d'abord, se trouve dans <kbd>includes/bootstrap.inc, fonction page_get_cache</kbd>. La modification est enfantine, elle consiste juste à déclarer en global notre variable <kbd>$custom_theme</kbd> et ajouter cette référence dans la clef de lecture du cache :
    <div class='code-container-area'><div class='code-container-caption'>includes/bootstrap.inc, fonction page_get_cache</div><div class='code-container'><div class="code"><ol><li class="li1"><div class="de1"><span class="kw2">function</span> page_get_cache<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// { Premiere modification</span></div></li>
<li class="li1"><div class="de1">&nbsp; <a target="blank" &nbsp;href="http://www.php.net/global"><span class="kw3">global</span></a> <span class="re0">$user</span><span class="sy0">,</span> <span class="re0">$base_root</span><span class="sy0">,</span> <span class="re0">$custom_theme</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// }</span></div></li>
<li class="li2"><div class="de2">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="re0">$cache</span> <span class="sy0">=</span> <span class="kw2">NULL</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">uid</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st0">'REQUEST_METHOD'</span><span class="br0">&#93;</span> <span class="sy0">==</span> <span class="st0">'GET'</span> <span class="sy0">&amp;&amp;</span> <a target="blank" &nbsp;href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span>drupal_set_message<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// { Deuxième modification</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; <span class="re0">$cache</span> <span class="sy0">=</span> cache_get<span class="br0">&#40;</span><span class="re0">$base_root</span> <span class="sy0">.</span> request_uri<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st0">&quot;___&quot;</span><span class="sy0">.</span><span class="re0">$custom_theme</span><span class="sy0">,</span> <span class="st0">'cache_page'</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// }</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a target="blank" &nbsp;href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$cache</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <a target="blank" &nbsp;href="http://www.php.net/ob_start"><span class="kw3">ob_start</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">return</span> <span class="re0">$cache</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span> </div></li></ol></div></div></div>  
</p>
<p>
  Enfin, il ne nous reste plus qu'à modifier la fonction de sauvegarde de la page, qui elle se trouve dans <kbd>includes/common.inc, fonction page_set_cache</kbd>. Et c'est le même type d'altération :
    <div class='code-container-area'><div class='code-container-caption'>includes/bootstrap.inc, fonction page_get_cache</div><div class='code-container'><div class="code"><ol><li class="li1"><div class="de1"><span class="kw2">function</span> page_set_cache<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// { première modification</span></div></li>
<li class="li1"><div class="de1">&nbsp; <a target="blank" &nbsp;href="http://www.php.net/global"><span class="kw3">global</span></a> <span class="re0">$user</span><span class="sy0">,</span> <span class="re0">$base_root</span><span class="sy0">,</span> <span class="re0">$custom_theme</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// }</span></div></li>
<li class="li2"><div class="de2">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">uid</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st0">'REQUEST_METHOD'</span><span class="br0">&#93;</span> <span class="sy0">==</span> <span class="st0">'GET'</span> <span class="sy0">&amp;&amp;</span> <a target="blank" &nbsp;href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span>drupal_get_messages<span class="br0">&#40;</span><span class="kw2">NULL</span><span class="sy0">,</span> <span class="kw2">FALSE</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// This will fail in some cases, see page_get_cache() for the explanation.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$data</span> <span class="sy0">=</span> <a target="blank" &nbsp;href="http://www.php.net/ob_get_contents"><span class="kw3">ob_get_contents</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="re0">$cache</span> <span class="sy0">=</span> <span class="kw2">TRUE</span><span class="sy0">;</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a target="blank" &nbsp;href="http://www.php.net/function_exists"><span class="kw3">function_exists</span></a><span class="br0">&#40;</span><span class="st0">'gzencode'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// We do not store the data in case the zlib mode is deflate.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// This should be rarely happening.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a target="blank" &nbsp;href="http://www.php.net/zlib_get_coding_type"><span class="kw3">zlib_get_coding_type</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">==</span> <span class="st0">'deflate'</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cache</span> <span class="sy0">=</span> <span class="kw2">FALSE</span><span class="sy0">;</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span><a target="blank" &nbsp;href="http://www.php.net/zlib_get_coding_type"><span class="kw3">zlib_get_coding_type</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">==</span> <span class="kw2">FALSE</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> <span class="sy0">=</span> <a target="blank" &nbsp;href="http://www.php.net/gzencode"><span class="kw3">gzencode</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="sy0">,</span> <span class="nu0">9</span><span class="sy0">,</span> FORCE_GZIP<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// The remaining case is 'gzip' which means the data is</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// already compressed and nothing left to do but to store it.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <a target="blank" &nbsp;href="http://www.php.net/ob_end_flush"><span class="kw3">ob_end_flush</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$cache</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$data</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// { seconde modification</span></div></li>
<li class="li2"><div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; cache_set<span class="br0">&#40;</span><span class="re0">$base_root</span> <span class="sy0">.</span> request_uri<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st0">&quot;___&quot;</span><span class="sy0">.</span><span class="re0">$custom_theme</span><span class="sy0">,</span> <span class="st0">'cache_page'</span><span class="sy0">,</span> <span class="re0">$data</span><span class="sy0">,</span> CACHE_TEMPORARY<span class="sy0">,</span> drupal_get_headers<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// }</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li2"><div class="de2"><span class="br0">&#125;</span></div></li></ol></div></div></div>  
</p>
<p>
  Et voilà, c'est terminé. Il ne reste plus qu'à vider le "vieux" cache en passant par votre base de donnée et en exécutant un <kbd>delete from cache_page</kbd>. Maintenant, vous pouvez ré-activer le cache (en mode normal, pas agressif !!) et tester. En base de donnée, un <kbd>select cid from page_cache</kbd> vous confirme que les nouvelles clefs sont prise en compte. 
</p>

	<a name='chapter_4'></a>
	<h2>Conclusion</h2>
	
<p>
  Outre une meilleure compréhension du système de cache de Drupal, nous avons maintenant un module de changement dynamique de thème qui fonctionne parfaitement avec le cache, sans perte de performances. Le seul impacte est donc un doublement du volume du cache en base, ce qui n'est pas un problème en soit. Alors certes cela s'est fait au prix d'une modification mineure du Coeur mais le résultat est là. Maintenant il est toujours possible de rendre cette modification plus générique en introduisant un hook _get_cache_page_key qui prendrait en paramètre la clef d'origine et qui renverrait la clef modifiée. Cela réduirait considérablement l'impacte sur le coeur de Drupal. Pour une prochaine fois peut-être <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/wink2.gif" title="Wink" alt="Wink" class="smiley-content"/>
  </p>
</p>
    ]]></content>
  </entry>
</feed>
