Skip to content

Instantly share code, notes, and snippets.

@real34
Created January 25, 2016 16:24
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save real34/46ea01dce10065c847b3 to your computer and use it in GitHub Desktop.
Allow to implement sorting in a Magento frontend Block easily.
<?php
/**
* Code extracted/inspired from the \Mage_Catalog_Block_Product_List_Toolbar class
* for being more easily reused
*/
trait My_Namespace_Block_List_SortableTrait
{
protected $_orderVarName = 'order';
protected $_directionVarName = 'dir';
protected $_availableOrder = array();
protected $_orderField = null;
protected $_direction = 'asc';
protected $_paramsMemorizeAllowed = true;
abstract protected function getSessionModel();
abstract protected function getDefaultOrderField();
abstract protected function getAttributeUsedForSortByArray();
abstract public function getUrl($route = '', $params = array()); // signature of \Mage_Core_Block_Abstract::getUrl()
protected function _construct()
{
$this->_orderField = $this->getDefaultOrderField();
$this->_availableOrder = $this->getAttributeUsedForSortByArray();
parent::_construct();
}
public function disableParamsMemorizing()
{
$this->_paramsMemorizeAllowed = false;
return $this;
}
protected function _memorizeParam($param, $value)
{
$session = $this->getSessionModel();
if ($this->_paramsMemorizeAllowed && !$session->getParamsMemorizeDisabled()) {
$session->setData($param, $value);
}
return $this;
}
public function setCollection($collection)
{
if ($this->getCurrentOrder()) {
$collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
}
parent::setCollection($collection);
return $this;
}
public function getOrderVarName()
{
return $this->_orderVarName;
}
public function getDirectionVarName()
{
return $this->_directionVarName;
}
public function getCurrentOrder()
{
$order = $this->_getData('_current_grid_order');
if ($order) {
return $order;
}
$orders = $this->getAvailableOrders();
$defaultOrder = $this->_orderField;
if (!isset($orders[$defaultOrder])) {
$keys = array_keys($orders);
$defaultOrder = $keys[0];
}
$order = $this->getRequest()->getParam($this->getOrderVarName());
if ($order && isset($orders[$order])) {
if ($order == $defaultOrder) {
$this->getSessionModel()->unsSortOrder();
} else {
$this->_memorizeParam('sort_order', $order);
}
} else {
$order = $this->getSessionModel()->getSortOrder();
}
// validate session value
if (!$order || !isset($orders[$order])) {
$order = $defaultOrder;
}
$this->setData('_current_grid_order', $order);
return $order;
}
public function getCurrentDirection()
{
$dir = $this->_getData('_current_grid_direction');
if ($dir) {
return $dir;
}
$directions = array('asc', 'desc');
$dir = strtolower($this->getRequest()->getParam($this->getDirectionVarName()));
if ($dir && in_array($dir, $directions)) {
if ($dir == $this->_direction) {
$this->getSessionModel()->unsSortDirection();
} else {
$this->_memorizeParam('sort_direction', $dir);
}
} else {
$dir = $this->getSessionModel()->getSortDirection();
}
// validate direction
if (!$dir || !in_array($dir, $directions)) {
$dir = $this->_direction;
}
$this->setData('_current_grid_direction', $dir);
return $dir;
}
public function setDefaultOrder($field)
{
if (isset($this->_availableOrder[$field])) {
$this->_orderField = $field;
}
return $this;
}
public function setDefaultDirection($dir)
{
if (in_array(strtolower($dir), array('asc', 'desc'))) {
$this->_direction = strtolower($dir);
}
return $this;
}
public function getAvailableOrders()
{
return $this->_availableOrder;
}
public function setAvailableOrders($orders)
{
$this->_availableOrder = $orders;
return $this;
}
public function addOrderToAvailableOrders($order, $value)
{
$this->_availableOrder[$order] = $value;
return $this;
}
public function removeOrderFromAvailableOrders($order)
{
if (isset($this->_availableOrder[$order])) {
unset($this->_availableOrder[$order]);
}
return $this;
}
public function isOrderCurrent($order)
{
return ($order === $this->getCurrentOrder());
}
public function getSortUrl($order)
{
$sortDirection = $this->_direction;
if ($this->isOrderCurrent($order)) {
$sortDirection = $this->oppositeDirectionOf($this->getCurrentDirection());
}
return $this->getOrderUrl($order, $sortDirection);
}
private function oppositeDirectionOf($order)
{
return ($order === 'asc') ? 'desc' : 'asc';
}
public function getOrderUrl($order, $direction)
{
if (is_null($order)) {
$order = $this->getCurrentOrder() ? $this->getCurrentOrder() : $this->_availableOrder[0];
}
return $this->getPagerUrl(array(
$this->getOrderVarName()=>$order,
$this->getDirectionVarName()=>$direction,
));
}
public function getPagerUrl($params=array())
{
$urlParams = array();
$urlParams['_current'] = true;
$urlParams['_escape'] = true;
$urlParams['_use_rewrite'] = true;
$urlParams['_query'] = $params;
return $this->getUrl('*/*/*', $urlParams);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment