Magento utilise ses propres méthodes pour utiliser les sessions. Nous n’allons pas passer par les sessions PHP classiques.
Emplacement des sessions
Magento stocke les sessions de deux façons différentes :
– En mode fichier, dans les sessions de PHP. Sur ma machine, le dossier est le suivant : /var/lib/php5/sessions
– En mode BDD, dans la table « session »
Ce choix est fait à l’installation de Magento et peut-être modifié dans :
app/etc/env.php
Pour le mode fichier :
'save' => 'files',
Pour le mode BDD :
'save' => 'db',
À vous de choisir en fonction du nombre de serveurs frontaux que vous avez, la puissance de votre serveur de BDD etc…
Différents types de session
Selon les zones du site, Magento permet d’utiliser des sessions de différents types :
\Magento\Backend\Model\Session : Admin
\Magento\Catalog\Model\Session : Catalogue (Fiches et listes produit)
\Magento\Checkout\Model\Session : Tunnel de commande
\Magento\Customer\Model\Session : Compte client
\Magento\Newsletter\Model\Session : Gestion Newsletter
\Magento\Framework\Session\Generic : Comme son nom l’indique cette session est générique et correspond à tout ce qui n’est pas concerné par les sessions ci-dessus
Cela permet d’enregistrer une session selon la zone que vous souhaitez utiliser.
Cela peut-être pratique pour les messages de succès par exemple lors de l’ajout au panier, pour que ce message s’affiche uniquement sur l’espace catalogue du site et non ailleurs.
Utiliser une session avec Magento 2
Pour cela il faut injecter la session de votre choix dans la méthode __construct de votre classe.
Dans notre cas, nous allons reprendre la classe
app/code/Maxime/Jobs/Block/Job/ListJob.php
Et remplacez le code par celui-ci :
<?php namespace Maxime\Jobs\Block\Job; class ListJob extends \Magento\Framework\View\Element\Template { protected $_job; protected $_department; protected $_resource; protected $_jobCollection = null; protected $_jobSession = null; /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Maxime\Jobs\Model\Job $job * @param \Maxime\Jobs\Model\Department $department * @param \Magento\Framework\App\ResourceConnection $resource * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Maxime\Jobs\Model\Job $job, \Maxime\Jobs\Model\Department $department, \Magento\Framework\App\ResourceConnection $resource, \Magento\Framework\Session\Generic $jobSession, array $data = [] ) { $this->_job = $job; $this->_department = $department; $this->_resource = $resource; $this->_jobSession = $jobSession; parent::__construct( $context, $data ); } /** * @return $this */ protected function _prepareLayout() { parent::_prepareLayout(); // You can put these informations editable on BO $title = __('We are hiring'); $description = __('Look at the jobs we have got for you'); $keywords = __('job,hiring'); $this->getLayout()->createBlock('Magento\Catalog\Block\Breadcrumbs'); if ($breadcrumbsBlock = $this->getLayout()->getBlock('breadcrumbs')) { $breadcrumbsBlock->addCrumb( 'jobs', [ 'label' => $title, 'title' => $title, 'link' => false // No link for the last element ] ); } $this->pageConfig->getTitle()->set($title); $this->pageConfig->setDescription($description); $this->pageConfig->setKeywords($keywords); $pageMainTitle = $this->getLayout()->getBlock('page.main.title'); if ($pageMainTitle) { $pageMainTitle->setPageTitle($title); } return $this; } protected function _getJobCollection() { if ($this->_jobCollection === null) { $jobCollection = $this->_job->getCollection()->addStatusFilter($this->_job, $this->_department); $numberByPage = $this->_jobSession->getNumberByPage(); // If no session value or value not available, we take and set the first value if(empty($numberByPage) || !in_array($numberByPage, $this->getAvailablePager())){ $numberByPage = $this->getAvailablePager()[0]; $this->_jobSession->setNumberByPage($numberByPage); } $jobCollection->setPageSize($numberByPage)->setCurPage(1); $this->_jobCollection = $jobCollection; } return $this->_jobCollection; } public function getLoadedJobCollection() { return $this->_getJobCollection(); } public function getListUrl(){ return $this->getUrl('jobs/job'); } public function getPagerUrl($numberByPage){ return $this->getUrl('jobs/job', array('n' => $numberByPage)); } public function getAvailablePager(){ return array( 1, 3, 10 ); } public function getJobUrl($job){ if(!$job->getId()){ return '#'; } return $this->getUrl('jobs/job/view', ['id' => $job->getId()]); } public function getDepartmentUrl($job){ if(!$job->getDepartmentId()){ return '#'; } return $this->getUrl('jobs/department/view', ['id' => $job->getDepartmentId()]); } public function getJobSession() { return $this->_jobSession; } }
– Nous avons ajouté l’attribut de classe $_jobSession, puis via le construct, nous l’avons injecté à notre objet.
– La méthode getJobSession a également été ajoutée afin de pouvoir récupérer notre session n’importe où vu que la méthode est publique.
– La méthode getPagerUrl a été ajoutée, elle va nous permettre de retourner une URL avec un paramètre, qui sera le nombre de jobs que l’on veut afficher sur la page
– La méthode getAvailablePager a été ajoutée pour définir un tableau de nombre d’éléments par page disponible à proposer. Cela permettra d’éviter que l’utilisateur mette le nombre de son choix dans l’URL.
– Nous avons modifié la méthode _getJobCollection pour récupérer la valeur de session « getNumberByPage », vérifier qu’elle est bien dans notre tableau retourné par getAvailablePager, et limiter notre collection au nombre d’éléments à afficher.
Notez que pour le moment notre collection n’affiche que la première page :
$jobCollection->setPageSize($numberByPage)->setCurPage(1);
Il est tout à fait possible d’ajouter un deuxième paramètre à l’URL pour modifier ce numéro de page 🙂
Setter une variable de session
Pour le moment on peut utiliser notre session, mais nous à aucun moment nous n’enregistrons sa valeur.
Le principe sera le suivant, dans notre page d’affichage par liste des offres d’emploi, nous allons mettre des liens permettant d’envoyer via l’URL le nombre de jobs que l’on souhaite afficher.
Modifiez en premier lieu le fichier :
app/code/Maxime/Jobs/view/frontend/templates/jobs/list.phtml
Avec ce contenu :
<?php $jobCollection = $this->getLoadedJobCollection(); $iterator = 1; $total = $jobCollection->count(); $firstPager = true; ?> <div class="job-wrapper"> <div class="job-pager"> <?php echo __('View per page : '); ?> <?php foreach($this->getAvailablePager() AS $numberByPage): ?> <?php if(!$firstPager) echo ' - '; ?> <a href="<?php echo $this->getPagerUrl($numberByPage); ?>"><?php echo $numberByPage; ?></a> <?php $firstPager = false; ?> <?php endforeach; ?> </div> <ol class="jobs list"> <?php foreach($jobCollection AS $job): ?> <li class="item<?php echo ($iterator == 1) ? ' first' : ''; ?><?php echo ($total == $iterator) ? ' last' : ''; ?>"> <div class="title"> <a href="<?php echo $this->getJobUrl($job); ?>" title="<?php echo $job->getTitle(); ?>"> <?php echo $job->getTitle(); ?> </a> </div> <div class="department_name"> <?php echo __('Department : '); ?> <a href="<?php echo $this->getDepartmentUrl($job); ?>" title="<?php echo $job->getDepartmentName(); ?>"> <?php echo $job->getDepartmentName(); ?> </a> </div> <div class="type"><?php echo $job->getType(); ?></div> <div class="location"><?php echo $job->getLocation(); ?></div> <div class="date"><?php echo $this->formatDate($job->getDate()); ?></div> <div class="description"><?php echo $job->getDescription(); ?></div> </li> <?php $iterator++; ?> <?php endforeach; ?> </ol> </div>
– Nous avons ajouté un block permettant de choisir le nombre d’éléments à afficher dans la page, nous utilisons la méthode implémentée précédemment dans notre block qui est getPagerUrl. Si vous regardez le lien affiche en front est du type jobs/job/index/n/3/
, où n est le nom de notre paramètre, et 3 sa valeur.
Comme notre valeur est dans un paramètre dans l’URL, nous allons devoir la récupérer dans notre contrôleur !
Nous allons donc la récupérer en modifiant la classe :
app/code/Maxime/Jobs/Controller/Job/Index.php
Et mettez-y le code suivant :
<?php namespace Maxime\Jobs\Controller\Job; class Index extends \Magento\Framework\App\Action\Action { protected $_jobSession; /** * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Framework\Session\Generic $jobSession */ public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Framework\Session\Generic $jobSession ) { parent::__construct($context); $this->_jobSession = $jobSession; } public function execute() { // If n not exists, will return the second parameter : false $numberByPage = (int) $this->getRequest()->getParam('n', false); if($numberByPage){ $this->_jobSession->setNumberByPage($numberByPage); } $this->_view->loadLayout(); $this->_view->getLayout()->initMessages(); $this->_view->renderLayout(); } }
– On injecte notre session dans le construct
– Dans la méthode exécute on récupère le paramètre renseigné dans l’URL
– On l’enregistre dans notre session
Récupérer / modifier une session depuis un template
Étant donné que notre block possède une méthode publique pour récupérer notre session, nous pourrions très bien faire depuis le template :
<?php $this->getJobSession()->setNumberByPage(10); $this->getJobSession()->getNumberByPage();
Il est également possible de passer par la méthode setData(‘number_by_page’, 10) à la place de setNumberByPage(10)
Supprimer une variable de session
Pour supprimer une variable de session, vous pouvez utiliser la méthode :
<?php $this->_jobSession->unsNumberByPage() // ou $this->_jobSession->unsetData('number_by_page');
Vous savez désormais gérer les sessions avec Magento 🙂 Si vous désirez un peu de pratique, vous pouvez adapter le module pour gérer le deuxième paramètre qui est la page courante :
– Ajouter dans le bloc une méthode pour récupérer le nombre de page total en fonction du nombre de jobs et le nombre d’éléments par page
– Gérer dans le bloc le paramètre de pagination et l’ajouter dans le « setCurPage »
– Dans le template, créer le block de pagination en modifiant / ajoutant les différentes méthodes dont vous pouvez avoir besoin dans votre block