Pour commencer nous allons nous rendre dans le back office de prestashop afin de créer des pages CMS.
L’astuce ici consiste à utiliser les sous catégories de pages CMS comme des références à des marques de votre catalogue. (ATTENTION, cela détourne la fonctionnalité première des catégories de CMS de prestashop).
Etant donné que la catégorie 1 existe déjà et ne peut pas être supprimée (c’est la catégorie d’accueil), il faudra bien faire attention de ne pas créer de marque avec l’identifiant 1 (ou du moins penser à désactiver cette marque).
Je vais donc créer en premier lieu une sous catégorie 2, portant le nom « Ma marque » puis je vais lui rattacher 3 pages CMS que je vais également créer. Une fois cela fait, je vais pouvoir commencer mes overrides.
Nous allons tout d’abord surcharger la classe CMSCore afin de lui ajouter une méthode (getFirstCMSPage()), qui nous permettra de savoir quelle est la première page CMS rattachée à notre marque. Nous nous en servirons dans le CMSController afin de rediriger vers la page CMS récupérée. Voici le code :
<?php
class CMS extends CMSCore
{
public static function getFirstCMSPage($id_lang = NULL, $id_cms_category = NULL, $active = true)
{
return Db::getInstance()->ExecuteS('
SELECT *
FROM `'._DB_PREFIX_.'cms` c
JOIN `'._DB_PREFIX_.'cms_lang` l ON (c.id_cms = l.id_cms)'.
(isset($id_cms_category) ? 'WHERE `id_cms_category` = '.(int)($id_cms_category) : '').
($active ? ' AND c.`active` = 1 ' : '').'
AND l.id_lang = '.(int)($id_lang).'
ORDER BY `position`
LIMIT 0, 1');
}
} |
Comme indiqué dans mon premier tuto sur l’override de classes prestashop, pour surcharger cette classe CMS, vous devrez enregistrer ce fichier sous le nom « CMS.php » dans le répertoire « override/classes« .
Maintenant, allons surcharger le CMSController afin de pouvoir afficher des infos sur la marque en entête de page et afficher également le listing des pages CMS rattachées à ce Manufacturer.
<?php
class CmsController extends CmsControllerCore
{
public $php_self = 'cms.php';
public $assignCase;
public $manufacturer;
public $cms;
public $cms_category;
public function preProcess()
{
if ($id_cms = (int)Tools::getValue('id_cms')) {
$this->cms = new CMS($id_cms, self::$cookie->id_lang);
$this->manufacturer = new Manufacturer($this->cms->id_cms_category, self::$cookie->id_lang);
}
$this->canonicalRedirection();
parent::preProcess();
/* assignCase (1 = CMS page, 2 = CMS category) */
if (Validate::isLoadedObject($this->cms) AND ($this->cms->active OR (Tools::getValue('adtoken') == Tools::encrypt('PreviewCMS'.$this->cms->id) AND file_exists(dirname(__FILE__).'/../'.Tools::getValue('ad').'/ajax.php'))))
$this->assignCase = 1;
else
Tools::display404Error('404.php');
}
public function process()
{
global $link;
$pipe = Configuration::get('PS_NAVIGATION_PIPE');
if (empty($pipe))
$pipe = '>';
FrontControllerCore::process();
$parent_cat = new CMSCategory(1, (int)(self::$cookie->id_lang));
self::$smarty->assign('id_current_lang', self::$cookie->id_lang);
self::$smarty->assign('home_title', $parent_cat->name);
if ($this->assignCase == 1)
{
$path = '<a title="'.htmlentities($this->manufacturer->name, ENT_NOQUOTES, 'UTF-8').
'" href="%27%20.%20%20%09%09%09%09Tools::safeOutput%28$link-%3EgetManufacturerLink%28%28int%29$this-%3Emanufacturer-%3Eid_manufacturer%29%29.%0A%09%09%09%09%27">' . $this->manufacturer->name . '</a>'. $pipe. '';
self::$smarty->assign(array(
'cms' => $this->cms,
'content_only' => (int)(Tools::getValue('content_only')),
'path' => $path . Tools::getFullPath(1, $this->cms->meta_title, 'CMS'),
'cms_pages' => CMS::getCMSPages((int)(self::$cookie->id_lang), (int)($this->cms->id_cms_category) )
));
}
if (Validate::isLoadedObject($this->manufacturer) AND $this->manufacturer->active)
{
self::$smarty->assign(array(
'manufacturer' => $this->manufacturer));
}
}
public function displayContent()
{
FrontControllerCore::displayContent();
self::$smarty->display(_PS_THEME_DIR_.'manufacturer-cms.tpl');
}
} |
Maintenant, décrivons ce que nous venons de faire : comme expliqué en introduction, nous avons besoin d’un Manufacturer pour pouvoir afficher les infos en entete de page et mettre un lien vers ses produits. C’est ce que nous faisons à la ligne 10 en initialisant un objet Manufacturer avec l’identifiant de category de notre page CMS en cours :
$this->manufacturer = new Manufacturer($this->cms->id_cms_category, self::$cookie->id_lang); |
Puis, nous avons besoin des autres pages CMS rattachées à notre marque pour pouvoir les afficher dans notre menu, c’est ce que fait cette ligne :
'cms_pages' => CMS::getCMSPages((int)(self::$cookie->id_lang), (int)($this->cms->id_cms_category) ) |
Vous remarquerez au passage que nous avons complètement enlevé les lignes de code faisant référence aux sous catégories de CMS (assignCase == 2).
Je passe rapidement sur l’initialisation du fil d’ariane (ou chemin de fer) que l’on aurait certainement pu gérer autrement. Nous afficherons juste le nom de la marque entre la page Accueil et le nom de la page CMS en cours.
$pipe = Configuration::get('PS_NAVIGATION_PIPE');
if (empty($pipe))
$pipe = '>'; |
$path = '<a title="'.htmlentities($this->manufacturer->name, ENT_NOQUOTES, 'UTF-8').
'" href="%27%20.%20%20%09%09%09%09Tools::safeOutput%28$link-%3EgetManufacturerLink%28%28int%29$this-%3Emanufacturer-%3Eid_manufacturer%29%29.%0A%09%09%09%09%27">' . $this->manufacturer->name . '</a>'. $pipe. ''; |
'path' => $path . Tools::getFullPath(1, $this->cms->meta_title, 'CMS'), |
Attention également à bien appeler la méthode « process()« , non pas du parent mais du FrontController (pour éviter d’appeler 2 fois les mêmes choses vu que votre Controller hérite de CMSControllerCore):
FrontControllerCore::process(); |
Idem dans la méthode « displayContent()« , pensez bien à appeler la méthode de FrontControllerCore.
Voici le code du fichier manufacturer-cms.tpl pour ceux que cela intéresse :
{include file="$tpl_dir./breadcrumb.tpl"}
{include file="$tpl_dir./manufacturer-header.tpl"}
{if isset($cms) && !isset($category)}
<div class="rte{if $content_only} content_only{/if}">
<div id="left">{$cms->content}</div>
<div id="right">{if isset($cms_pages) & !empty($cms_pages)}
<ul class="bullet">
<ul class="bullet">{foreach from=$cms_pages item=cmspages} id} class='actif'{/if}></ul>
</ul>
<a href="{$link->getCMSLink($cmspages.id_cms, $cmspages.link_rewrite)|escape:'htmlall':'UTF-8'}#anchor">{if $cmspages.meta_keywords}{$cmspages.meta_keywords|escape:'htmlall':'UTF-8'}{else}{$cmspages.meta_title|escape:'htmlall':'UTF-8'}{/if}</a>{/foreach}
{/if}
</div>
</div>
{else} {l s='This page does not exist.'} {/if} |
Et également le code de manufacturer-header.tpl utilisé dans manufacturer-cms.tpl et manufacturer.tpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| <div id="imgprod"><img src="{$img_manu_dir}{$manufacturer->id}.jpg"></div>
<div id="infoprod">
<h1>{$manufacturer->name}</h1>
<h2>{$manufacturer->title}</h2>
<div id="adresse">
<p>{l s='Address :'}</p>
<address>
{$manufacturer->address1}
{$manufacturer->address2}
{$manufacturer->postcode}
{$manufacturer->city}
</address>
</div>
<div id="infocontact">
<ul>
<li>
<p>{l s='Phone :'}</p>
{$manufacturer->phone}
</li>
</ul>
</div>
</div>
<hr class="clearhr" />
<a name="anchor"></a>
<ul id="sousnav">
{if isset($first_cms_page)}
{foreach from=$first_cms_page item=cmspage}
<li><a href="{$link->getCMSLink($cmspage.id_cms, $cmspage.link_rewrite)|escape:'htmlall':'UTF-8'}#anchor"{if $smarty.server.SCRIPT_NAME == "/cms.php"} class="actif"{/if}>{l s='Presentation'}</a></li>
{/foreach}
{else}
<li><a{if $smarty.server.SCRIPT_NAME == "/cms.php"} class="actif"{/if}>{l s='Presentation'}</a></li>
{/if}
<li><a href="{$link->getManufacturerProductsLink($manufacturer)}#anchor"{if ($smarty.server.SCRIPT_NAME == "/manufacturer.php" && $smarty.get.param == "products") || $smarty.server.SCRIPT_NAME == "/product.php"} class="actif"{/if}>{l s='Our products'}</a></li>
</ul> |
Et voilà pour notre surcharge de CMSController, nos pages CMS sont prêtes à être affichées, nous pouvons maintenant travailler sur les pages Manufacturer et le controller Manufacturer :
Tutoriel override prestashop partie 2 : surcharge du controller ManufacturerController