Version Notes
ajax, seo urls, price slider, multiple selection for the same attribute.
Download this release
Release Info
Developer | Catalin |
Extension | Catalin_Seo |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- app/code/community/Catalin/SEO/Block/Catalog/Layer/Filter/Attribute.php +37 -0
- app/code/community/Catalin/SEO/Block/Catalog/Layer/Filter/Price.php +60 -0
- app/code/community/Catalin/SEO/Block/Catalog/Layer/State.php +46 -0
- app/code/community/Catalin/SEO/Block/Catalog/Product/List/Pager.php +40 -0
- app/code/community/Catalin/SEO/Block/Catalog/Product/List/Toolbar.php +40 -0
- app/code/community/Catalin/SEO/Block/CatalogSearch/Layer/Filter/Attribute.php +30 -0
- app/code/community/Catalin/SEO/Controller/Router.php +135 -0
- app/code/community/Catalin/SEO/Helper/Data.php +201 -0
- app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Attribute.php +120 -0
- app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Category.php +97 -0
- app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Item.php +116 -0
- app/code/community/Catalin/SEO/Model/Catalog/Resource/Layer/Filter/Attribute.php +122 -0
- app/code/community/Catalin/SEO/Model/CatalogSearch/Layer/Filter/Attribute.php +30 -0
- app/code/community/Catalin/SEO/Model/System/Config/Backend/Seo/Catalog.php +35 -0
- app/code/community/Catalin/SEO/controllers/CategoryController.php +94 -0
- app/code/community/Catalin/SEO/controllers/ResultController.php +88 -0
- app/code/community/Catalin/SEO/etc/adminhtml.xml +22 -0
- app/code/community/Catalin/SEO/etc/config.xml +100 -0
- app/code/community/Catalin/SEO/etc/system.xml +75 -0
- app/design/frontend/default/default/layout/catalin_seo.xml +53 -0
- app/design/frontend/default/default/template/catalin_seo/catalog/layer/filter.phtml +26 -0
- app/design/frontend/default/default/template/catalin_seo/catalog/layer/price.phtml +48 -0
- app/design/frontend/default/default/template/catalin_seo/catalog/layer/view.phtml +35 -0
- app/design/frontend/default/default/template/catalin_seo/catalog/product/list.phtml +181 -0
- app/etc/modules/Catalin_SEO.xml +12 -0
- package.xml +31 -0
- skin/frontend/default/default/css/price_slider/style.css +18 -0
- skin/frontend/default/default/images/price_slider/bkg_slider.png +0 -0
- skin/frontend/default/default/images/price_slider/slider.png +0 -0
app/code/community/Catalin/SEO/Block/Catalog/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Block_Catalog_Layer_Filter_Attribute extends Mage_Catalog_Block_Layer_Filter_Attribute
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Class constructor
|
22 |
+
*/
|
23 |
+
public function __construct()
|
24 |
+
{
|
25 |
+
parent::__construct();
|
26 |
+
|
27 |
+
if ($this->helper('catalin_seo')->isEnabled()
|
28 |
+
&& $this->helper('catalin_seo')->isMultipleChoiceFiltersEnabled()) {
|
29 |
+
/**
|
30 |
+
* Modify template for multiple filters rendering
|
31 |
+
* It has checkboxes instead of classic links
|
32 |
+
*/
|
33 |
+
$this->setTemplate('catalin_seo/catalog/layer/filter.phtml');
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
}
|
app/code/community/Catalin/SEO/Block/Catalog/Layer/Filter/Price.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Block_Catalog_Layer_Filter_Price extends Mage_Catalog_Block_Layer_Filter_Price
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Class constructor
|
22 |
+
*
|
23 |
+
* Set correct template depending on module state
|
24 |
+
*/
|
25 |
+
public function __construct()
|
26 |
+
{
|
27 |
+
parent::__construct();
|
28 |
+
if ($this->helper('catalin_seo')->isEnabled()
|
29 |
+
&& $this->helper('catalin_seo')->isPriceSliderEnabled()) {
|
30 |
+
// Modify template to render price filter as slider
|
31 |
+
$this->setTemplate('catalin_seo/catalog/layer/price.phtml');
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Get max price for the collection
|
37 |
+
*
|
38 |
+
* @return int
|
39 |
+
*/
|
40 |
+
public function getMaxPriceInt()
|
41 |
+
{
|
42 |
+
return $this->_filter->getMaxPriceInt() + 1;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* URL Pattern used in javascript for price filtering
|
47 |
+
*
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function getUrlPattern()
|
51 |
+
{
|
52 |
+
$item = Mage::getModel('catalog/layer_filter_item')
|
53 |
+
->setFilter($this->_filter)
|
54 |
+
->setValue('__PRICE_VALUE__')
|
55 |
+
->setCount(0);
|
56 |
+
|
57 |
+
return $item->getUrl();
|
58 |
+
}
|
59 |
+
|
60 |
+
}
|
app/code/community/Catalin/SEO/Block/Catalog/Layer/State.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Block_Catalog_Layer_State extends Mage_Catalog_Block_Layer_State
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Retrieve Clear Filters URL
|
22 |
+
*
|
23 |
+
* @return string
|
24 |
+
*/
|
25 |
+
public function getClearUrl()
|
26 |
+
{
|
27 |
+
if (!$this->helper('catalin_seo')->isEnabled()) {
|
28 |
+
return parent::getClearUrl();
|
29 |
+
}
|
30 |
+
|
31 |
+
if ($this->helper('catalin_seo')->isCatalogSearch()) {
|
32 |
+
$filterState = array('isLayerAjax' => null);
|
33 |
+
foreach ($this->getActiveFilters() as $item) {
|
34 |
+
$filterState[$item->getFilter()->getRequestVar()] = $item->getFilter()->getCleanValue();
|
35 |
+
}
|
36 |
+
$params['_current'] = true;
|
37 |
+
$params['_use_rewrite'] = true;
|
38 |
+
$params['_query'] = $filterState;
|
39 |
+
$params['_escape'] = true;
|
40 |
+
return Mage::getUrl('*/*/*', $params);
|
41 |
+
}
|
42 |
+
|
43 |
+
return $this->helper('catalin_seo')->getClearFiltersUrl();
|
44 |
+
}
|
45 |
+
|
46 |
+
}
|
app/code/community/Catalin/SEO/Block/Catalog/Product/List/Pager.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Block_Catalog_Product_List_Pager extends Mage_Page_Block_Html_Pager
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Return current URL with rewrites and additional parameters
|
22 |
+
*
|
23 |
+
* @param array $params Query parameters
|
24 |
+
* @return string
|
25 |
+
*/
|
26 |
+
public function getPagerUrl($params = array())
|
27 |
+
{
|
28 |
+
if (!Mage::helper('catalin_seo')->isEnabled()) {
|
29 |
+
return parent::getPagerUrl($params);
|
30 |
+
}
|
31 |
+
|
32 |
+
if ($this->helper('catalin_seo')->isCatalogSearch()) {
|
33 |
+
$params['isLayerAjax'] = null;
|
34 |
+
return parent::getPagerUrl($params);
|
35 |
+
}
|
36 |
+
|
37 |
+
return $this->helper('catalin_seo')->getPagerUrl($params);
|
38 |
+
}
|
39 |
+
|
40 |
+
}
|
app/code/community/Catalin/SEO/Block/Catalog/Product/List/Toolbar.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Block_Catalog_Product_List_Toolbar extends Mage_Catalog_Block_Product_List_Toolbar
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Return current URL with rewrites and additional parameters
|
22 |
+
*
|
23 |
+
* @param array $params Query parameters
|
24 |
+
* @return string
|
25 |
+
*/
|
26 |
+
public function getPagerUrl($params = array())
|
27 |
+
{
|
28 |
+
if (!$this->helper('catalin_seo')->isEnabled()) {
|
29 |
+
return parent::getPagerUrl($params);
|
30 |
+
}
|
31 |
+
|
32 |
+
if ($this->helper('catalin_seo')->isCatalogSearch()) {
|
33 |
+
$params['isLayerAjax'] = null;
|
34 |
+
return parent::getPagerUrl($params);
|
35 |
+
}
|
36 |
+
|
37 |
+
return $this->helper('catalin_seo')->getPagerUrl($params);
|
38 |
+
}
|
39 |
+
|
40 |
+
}
|
app/code/community/Catalin/SEO/Block/CatalogSearch/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Block_CatalogSearch_Layer_Filter_Attribute extends Catalin_SEO_Block_Catalog_Layer_Filter_Attribute
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Set filter model name
|
22 |
+
*
|
23 |
+
*/
|
24 |
+
public function __construct()
|
25 |
+
{
|
26 |
+
parent::__construct();
|
27 |
+
$this->_filterModelName = 'catalogsearch/layer_filter_attribute';
|
28 |
+
}
|
29 |
+
|
30 |
+
}
|
app/code/community/Catalin/SEO/Controller/Router.php
ADDED
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Controller_Router extends Mage_Core_Controller_Varien_Router_Standard
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Add catalog router to front controller
|
22 |
+
*
|
23 |
+
* @param Varien_Event_Observer $observer
|
24 |
+
*/
|
25 |
+
public function initControllerRouters(Varien_Event_Observer $observer)
|
26 |
+
{
|
27 |
+
$front = $observer->getEvent()->getFront();
|
28 |
+
// Collect routes - needed for match()
|
29 |
+
$this->collectRoutes('frontend', 'standard');
|
30 |
+
$front->addRouter('catalin_catalog', $this);
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Match the request
|
35 |
+
*
|
36 |
+
* @param Zend_Controller_Request_Http $request
|
37 |
+
* @return boolean
|
38 |
+
*/
|
39 |
+
public function match(Zend_Controller_Request_Http $request)
|
40 |
+
{
|
41 |
+
if (!Mage::helper('catalin_seo')->isEnabled()) {
|
42 |
+
return false;
|
43 |
+
}
|
44 |
+
|
45 |
+
$suffix = Mage::getStoreConfig('catalog/seo/category_url_suffix');
|
46 |
+
$identifier = trim(str_replace($suffix, '', $request->getPathInfo()), '/');
|
47 |
+
$urlSplit = explode(Catalin_SEO_Helper_Data::ROUTING_CATEGORY_SUFFIX, $identifier, 2);
|
48 |
+
|
49 |
+
//Check if it is a link generated by the SEO module
|
50 |
+
if (!isset($urlSplit[1])) {
|
51 |
+
return false;
|
52 |
+
}
|
53 |
+
|
54 |
+
$urlRewrite = Mage::getModel('core/url_rewrite');
|
55 |
+
$urlRewrite->setStoreId(Mage::app()->getStore()->getId());
|
56 |
+
$cat = $urlSplit[0];
|
57 |
+
|
58 |
+
$catPath = $cat . $suffix;
|
59 |
+
$urlRewrite->loadByRequestPath($catPath);
|
60 |
+
|
61 |
+
// Check if a valid category is found
|
62 |
+
if ($urlRewrite->getId()) {
|
63 |
+
$modules = $this->getModuleByFrontName('catalog');
|
64 |
+
|
65 |
+
$found = false;
|
66 |
+
|
67 |
+
// Find the controller to be executed
|
68 |
+
// It takes in account rewrites
|
69 |
+
foreach ($modules as $realModule) {
|
70 |
+
$request->setRouteName($this->getRouteByFrontName('catalog'));
|
71 |
+
|
72 |
+
// Check if this place should be secure
|
73 |
+
$this->_checkShouldBeSecure($request, '/catalog/category/view');
|
74 |
+
|
75 |
+
// Find controller class name
|
76 |
+
$controllerClassName = $this->_validateControllerClassName($realModule, 'category');
|
77 |
+
if (!$controllerClassName) {
|
78 |
+
continue;
|
79 |
+
}
|
80 |
+
|
81 |
+
// Instantiate controller class
|
82 |
+
$controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $this->getFront()->getResponse());
|
83 |
+
|
84 |
+
// Check if controller has viewAction() method
|
85 |
+
if (!$controllerInstance->hasAction('view')) {
|
86 |
+
continue;
|
87 |
+
}
|
88 |
+
$found = true;
|
89 |
+
break;
|
90 |
+
}
|
91 |
+
|
92 |
+
// Check if we found a controller
|
93 |
+
if (!$found) {
|
94 |
+
return false;
|
95 |
+
}
|
96 |
+
|
97 |
+
// Set the required data on $request object
|
98 |
+
$request->setPathInfo($catPath . Catalin_SEO_Helper_Data::ROUTING_CATEGORY_SUFFIX);
|
99 |
+
$request->setModuleName('catalog')
|
100 |
+
->setControllerName('category')
|
101 |
+
->setActionName('view')
|
102 |
+
->setParam('id', $urlRewrite->getCategoryId())
|
103 |
+
->setAlias(
|
104 |
+
Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, $catPath . Catalin_SEO_Helper_Data::ROUTING_CATEGORY_SUFFIX
|
105 |
+
);
|
106 |
+
|
107 |
+
// Parse url params
|
108 |
+
$params = explode('/', trim($urlSplit[1], '/'));
|
109 |
+
$layerParams = array();
|
110 |
+
$total = count($params);
|
111 |
+
for ($i = 0; $i < $total - 1; $i++) {
|
112 |
+
if (isset($params[$i + 1])) {
|
113 |
+
$layerParams[$params[$i]] = urldecode($params[$i + 1]);
|
114 |
+
++$i;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
// Add post params to parsed ones from url
|
118 |
+
// Usefull to easily override params
|
119 |
+
$layerParams += $request->getPost();
|
120 |
+
// Add params to request
|
121 |
+
$request->setParams($layerParams);
|
122 |
+
|
123 |
+
// Save params in registry - used later to generate links
|
124 |
+
Mage::register('layer_params', $layerParams);
|
125 |
+
|
126 |
+
// dispatch action
|
127 |
+
$request->setDispatched(true);
|
128 |
+
$controllerInstance->dispatch('view');
|
129 |
+
|
130 |
+
return true;
|
131 |
+
}
|
132 |
+
return false;
|
133 |
+
}
|
134 |
+
|
135 |
+
}
|
app/code/community/Catalin/SEO/Helper/Data.php
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Helper_Data extends Mage_Core_Helper_Abstract
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Routing suffix
|
22 |
+
*/
|
23 |
+
const ROUTING_CATEGORY_SUFFIX = '/f';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Delimiter for multiple filters
|
27 |
+
*/
|
28 |
+
const MULTIPLE_FILTERS_DELIMITER = ',';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Check if module is enabled or not
|
32 |
+
*
|
33 |
+
* @return boolean
|
34 |
+
*/
|
35 |
+
public function isEnabled()
|
36 |
+
{
|
37 |
+
return Mage::getStoreConfigFlag('catalin_seo/catalog/enabled');
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Check if ajax is enabled
|
42 |
+
*
|
43 |
+
* @return boolean
|
44 |
+
*/
|
45 |
+
public function isAjaxEnabled()
|
46 |
+
{
|
47 |
+
if (!$this->isEnabled()) {
|
48 |
+
return false;
|
49 |
+
}
|
50 |
+
return Mage::getStoreConfigFlag('catalin_seo/catalog/ajax_enabled');
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Check if multipe choice filters is enabled
|
55 |
+
*
|
56 |
+
* @return boolean
|
57 |
+
*/
|
58 |
+
public function isMultipleChoiceFiltersEnabled()
|
59 |
+
{
|
60 |
+
if (!$this->isEnabled()) {
|
61 |
+
return false;
|
62 |
+
}
|
63 |
+
return Mage::getStoreConfigFlag('catalin_seo/catalog/multiple_choise_filters');
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Check if price slider is enabled
|
68 |
+
*
|
69 |
+
* @return boolean
|
70 |
+
*/
|
71 |
+
public function isPriceSliderEnabled()
|
72 |
+
{
|
73 |
+
if (!$this->isEnabled()) {
|
74 |
+
return false;
|
75 |
+
}
|
76 |
+
return Mage::getStoreConfigFlag('catalin_seo/catalog/price_slider');
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Getter for layered navigation params
|
81 |
+
* If $params are provided then it overrides the ones from registry
|
82 |
+
*
|
83 |
+
* @param array $params
|
84 |
+
* @return array|null
|
85 |
+
*/
|
86 |
+
public function getCurrentLayerParams(array $params = null)
|
87 |
+
{
|
88 |
+
$layerParams = Mage::registry('layer_params');
|
89 |
+
|
90 |
+
if (!is_array($layerParams)) {
|
91 |
+
$layerParams = array();
|
92 |
+
}
|
93 |
+
|
94 |
+
if (!empty($params)) {
|
95 |
+
foreach ($params as $key => $value) {
|
96 |
+
if ($value === null) {
|
97 |
+
unset($layerParams[$key]);
|
98 |
+
} else {
|
99 |
+
$layerParams[$key] = $value;
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
// Sort by key - small SEO improvement
|
105 |
+
ksort($layerParams);
|
106 |
+
return $layerParams;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Method to get url for layered navigation
|
111 |
+
*
|
112 |
+
* @param array $filters array with new filter values
|
113 |
+
* @param integer $escape to autoescape or not
|
114 |
+
* @param boolean $noFilters to add filters to the url or not
|
115 |
+
* @param array $q array with values to add to query string
|
116 |
+
* @return string
|
117 |
+
*/
|
118 |
+
public function getFilterUrl(array $filters, $escape = true, $noFilters = false, array $q = array())
|
119 |
+
{
|
120 |
+
$query = array(
|
121 |
+
'isLayerAjax' => null, // this needs to be removed because of ajax request
|
122 |
+
Mage::getBlockSingleton('page/html_pager')->getPageVarName() => null // exclude current page from urls
|
123 |
+
);
|
124 |
+
$query = array_merge($query, $q);
|
125 |
+
|
126 |
+
$suffix = Mage::getStoreConfig('catalog/seo/category_url_suffix');
|
127 |
+
$params = array(
|
128 |
+
'_current' => true,
|
129 |
+
'_use_rewrite' => true,
|
130 |
+
'_query' => $query,
|
131 |
+
'_nosid' => true,
|
132 |
+
);
|
133 |
+
// If we should escape or not
|
134 |
+
if ($escape) {
|
135 |
+
$params['_escape'] = true;
|
136 |
+
}
|
137 |
+
$url = Mage::getUrl('*/*/*', $params);
|
138 |
+
$url = str_replace($suffix, '', $url);
|
139 |
+
$urlPath = '';
|
140 |
+
|
141 |
+
if (!$noFilters) {
|
142 |
+
// Add filters
|
143 |
+
$layerParams = $this->getCurrentLayerParams($filters);
|
144 |
+
foreach ($layerParams as $key => $value) {
|
145 |
+
// Encode and replace escaped delimiter with the delimiter itself
|
146 |
+
$value = str_replace(urlencode(self::MULTIPLE_FILTERS_DELIMITER), self::MULTIPLE_FILTERS_DELIMITER, urlencode($value));
|
147 |
+
$urlPath .= "/{$key}/{$value}";
|
148 |
+
}
|
149 |
+
}
|
150 |
+
|
151 |
+
$urlParts = explode('?', $url);
|
152 |
+
|
153 |
+
// Add the suffix to the url - fixes when comming from non suffixed pages
|
154 |
+
if (stripos($urlParts[0], self::ROUTING_CATEGORY_SUFFIX) === false) {
|
155 |
+
$urlParts[0] .= self::ROUTING_CATEGORY_SUFFIX;
|
156 |
+
}
|
157 |
+
|
158 |
+
$url = $urlParts[0] . $urlPath . $suffix;
|
159 |
+
if (!empty($urlParts[1])) {
|
160 |
+
$url .= '?' . $urlParts[1];
|
161 |
+
}
|
162 |
+
|
163 |
+
return $url;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Get the url to clear all layered navigation filters
|
168 |
+
*
|
169 |
+
* @return string
|
170 |
+
*/
|
171 |
+
public function getClearFiltersUrl()
|
172 |
+
{
|
173 |
+
return $this->getFilterUrl(array(), true, true);
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Get url for layered navigation pagination
|
178 |
+
*
|
179 |
+
* @param array $query
|
180 |
+
* @return string
|
181 |
+
*/
|
182 |
+
public function getPagerUrl(array $query)
|
183 |
+
{
|
184 |
+
return $this->getFilterUrl(array(), true, false, $query);
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Check if we are in the catalog search
|
189 |
+
*
|
190 |
+
* @return boolean
|
191 |
+
*/
|
192 |
+
public function isCatalogSearch()
|
193 |
+
{
|
194 |
+
$pathInfo = $this->_getRequest()->getPathInfo();
|
195 |
+
if (stripos($pathInfo, '/catalogsearch/result') !== false) {
|
196 |
+
return true;
|
197 |
+
}
|
198 |
+
return false;
|
199 |
+
}
|
200 |
+
|
201 |
+
}
|
app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_Catalog_Layer_Filter_Attribute extends Mage_Catalog_Model_Layer_Filter_Attribute
|
18 |
+
{
|
19 |
+
|
20 |
+
protected $_values = array();
|
21 |
+
|
22 |
+
public function getValues()
|
23 |
+
{
|
24 |
+
return $this->_values;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Apply attribute filter to layer
|
29 |
+
*
|
30 |
+
* @param Zend_Controller_Request_Abstract $request
|
31 |
+
* @param object $filterBlock
|
32 |
+
* @return Enterprise_Search_Model_Catalog_Layer_Filter_Attribute
|
33 |
+
*/
|
34 |
+
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
|
35 |
+
{
|
36 |
+
if (!Mage::helper('catalin_seo')->isEnabled()) {
|
37 |
+
return parent::apply($request, $filterBlock);
|
38 |
+
}
|
39 |
+
|
40 |
+
$filter = $request->getParam($this->_requestVar);
|
41 |
+
if (is_array($filter)) {
|
42 |
+
return $this;
|
43 |
+
}
|
44 |
+
|
45 |
+
if (empty($filter)) {
|
46 |
+
return $this;
|
47 |
+
}
|
48 |
+
|
49 |
+
$this->_values = explode(Catalin_SEO_Helper_Data::MULTIPLE_FILTERS_DELIMITER, $filter);
|
50 |
+
|
51 |
+
if (!empty($this->_values)) {
|
52 |
+
$this->_getResource()->applyFilterToCollection($this, $this->_values);
|
53 |
+
foreach ($this->_values as $filter) {
|
54 |
+
$this->getLayer()->getState()->addFilter($this->_createItem($filter, $filter));
|
55 |
+
// process all items if multiple choice is enabled
|
56 |
+
if (!Mage::helper('catalin_seo')->isMultipleChoiceFiltersEnabled()) {
|
57 |
+
$this->_items = array();
|
58 |
+
}
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
return $this;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Get data array for building attribute filter items
|
67 |
+
*
|
68 |
+
* @return array
|
69 |
+
*/
|
70 |
+
protected function _getItemsData()
|
71 |
+
{
|
72 |
+
if (!Mage::helper('catalin_seo')->isEnabled()) {
|
73 |
+
return parent::_getItemsData();
|
74 |
+
}
|
75 |
+
|
76 |
+
$attribute = $this->getAttributeModel();
|
77 |
+
$this->_requestVar = $attribute->getAttributeCode();
|
78 |
+
|
79 |
+
$key = $this->getLayer()->getStateKey() . '_' . $this->_requestVar;
|
80 |
+
$data = $this->getLayer()->getAggregator()->getCacheData($key);
|
81 |
+
|
82 |
+
if ($data === null) {
|
83 |
+
$options = $attribute->getFrontend()->getSelectOptions();
|
84 |
+
$optionsCount = $this->_getResource()->getCount($this);
|
85 |
+
$data = array();
|
86 |
+
foreach ($options as $option) {
|
87 |
+
if (is_array($option['value'])) {
|
88 |
+
continue;
|
89 |
+
}
|
90 |
+
if (Mage::helper('core/string')->strlen($option['value'])) {
|
91 |
+
// Check filter type
|
92 |
+
if ($this->_getIsFilterableAttribute($attribute) == self::OPTIONS_ONLY_WITH_RESULTS) {
|
93 |
+
if (!empty($optionsCount[$option['value']])) {
|
94 |
+
$data[] = array(
|
95 |
+
'label' => $option['label'],
|
96 |
+
'value' => $option['label'],
|
97 |
+
'count' => $optionsCount[$option['value']],
|
98 |
+
);
|
99 |
+
}
|
100 |
+
} else {
|
101 |
+
$data[] = array(
|
102 |
+
'label' => $option['label'],
|
103 |
+
'value' => $option['label'],
|
104 |
+
'count' => isset($optionsCount[$option['value']]) ? $optionsCount[$option['value']] : 0,
|
105 |
+
);
|
106 |
+
}
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
$tags = array(
|
111 |
+
Mage_Eav_Model_Entity_Attribute::CACHE_TAG . ':' . $attribute->getId()
|
112 |
+
);
|
113 |
+
|
114 |
+
$tags = $this->getLayer()->getStateTags($tags);
|
115 |
+
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
|
116 |
+
}
|
117 |
+
return $data;
|
118 |
+
}
|
119 |
+
|
120 |
+
}
|
app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Category.php
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_Catalog_Layer_Filter_Category extends Mage_Catalog_Model_Layer_Filter_Category
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get data array for building category filter items
|
22 |
+
*
|
23 |
+
* @return array
|
24 |
+
*/
|
25 |
+
protected function _getItemsData()
|
26 |
+
{
|
27 |
+
if (!Mage::helper('catalin_seo')->isEnabled()) {
|
28 |
+
return parent::_getItemsData();
|
29 |
+
}
|
30 |
+
|
31 |
+
$key = $this->getLayer()->getStateKey().'_SUBCATEGORIES';
|
32 |
+
$data = $this->getLayer()->getAggregator()->getCacheData($key);
|
33 |
+
|
34 |
+
if ($data === null) {
|
35 |
+
$categoty = $this->getCategory();
|
36 |
+
/** @var $categoty Mage_Catalog_Model_Categeory */
|
37 |
+
$categories = $categoty->getChildrenCategories();
|
38 |
+
|
39 |
+
$this->getLayer()->getProductCollection()
|
40 |
+
->addCountToCategories($categories);
|
41 |
+
|
42 |
+
$data = array();
|
43 |
+
foreach ($categories as $category) {
|
44 |
+
if ($category->getIsActive() && $category->getProductCount()) {
|
45 |
+
$data[] = array(
|
46 |
+
'label' => Mage::helper('core')->htmlEscape($category->getName()),
|
47 |
+
'value' => $category->getUrlKey(),
|
48 |
+
'count' => $category->getProductCount(),
|
49 |
+
);
|
50 |
+
}
|
51 |
+
}
|
52 |
+
$tags = $this->getLayer()->getStateTags();
|
53 |
+
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
|
54 |
+
}
|
55 |
+
return $data;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Apply category filter to layer
|
60 |
+
*
|
61 |
+
* @param Zend_Controller_Request_Abstract $request
|
62 |
+
* @param Mage_Core_Block_Abstract $filterBlock
|
63 |
+
* @return Mage_Catalog_Model_Layer_Filter_Category
|
64 |
+
*/
|
65 |
+
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
|
66 |
+
{
|
67 |
+
if (!Mage::helper('catalin_seo')->isEnabled()) {
|
68 |
+
return parent::apply($request, $filterBlock);
|
69 |
+
}
|
70 |
+
|
71 |
+
$filter = $request->getParam($this->getRequestVar());
|
72 |
+
if (!$filter) {
|
73 |
+
return $this;
|
74 |
+
}
|
75 |
+
|
76 |
+
// Load the category filter by url_key
|
77 |
+
$this->_appliedCategory = Mage::getModel('catalog/category')
|
78 |
+
->setStoreId(Mage::app()->getStore()->getId())
|
79 |
+
->loadByAttribute('url_key', $filter);
|
80 |
+
|
81 |
+
$this->_categoryId = $this->_appliedCategory->getId();
|
82 |
+
|
83 |
+
Mage::register('current_category_filter', $this->getCategory(), true);
|
84 |
+
|
85 |
+
if ($this->_isValidCategory($this->_appliedCategory)) {
|
86 |
+
$this->getLayer()->getProductCollection()
|
87 |
+
->addCategoryFilter($this->_appliedCategory);
|
88 |
+
|
89 |
+
$this->getLayer()->getState()->addFilter(
|
90 |
+
$this->_createItem($this->_appliedCategory->getName(), $filter)
|
91 |
+
);
|
92 |
+
}
|
93 |
+
|
94 |
+
return $this;
|
95 |
+
}
|
96 |
+
|
97 |
+
}
|
app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Item.php
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_Catalog_Layer_Filter_Item extends Mage_Catalog_Model_Layer_Filter_Item
|
18 |
+
{
|
19 |
+
|
20 |
+
protected $_helper;
|
21 |
+
|
22 |
+
protected function _helper()
|
23 |
+
{
|
24 |
+
if ($this->_helper === null) {
|
25 |
+
$this->_helper = Mage::helper('catalin_seo');
|
26 |
+
}
|
27 |
+
return $this->_helper;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Get filter item url
|
32 |
+
*
|
33 |
+
* @return string
|
34 |
+
*/
|
35 |
+
public function getUrl()
|
36 |
+
{
|
37 |
+
if (!$this->_helper()->isEnabled()) {
|
38 |
+
return parent::getUrl();
|
39 |
+
}
|
40 |
+
|
41 |
+
$values = $this->getFilter()->getValues();
|
42 |
+
if (!empty($values)) {
|
43 |
+
$tmp = array_merge($values, array($this->getValue()));
|
44 |
+
$values = implode(Catalin_SEO_Helper_Data::MULTIPLE_FILTERS_DELIMITER, $tmp);
|
45 |
+
} else {
|
46 |
+
$values = $this->getValue();
|
47 |
+
}
|
48 |
+
|
49 |
+
if ($this->_helper()->isCatalogSearch()) {
|
50 |
+
$query = array(
|
51 |
+
'isLayerAjax' => null,
|
52 |
+
$this->getFilter()->getRequestVar() => $values,
|
53 |
+
Mage::getBlockSingleton('page/html_pager')->getPageVarName() => null // exclude current page from urls
|
54 |
+
);
|
55 |
+
return Mage::getUrl('*/*/*', array('_current' => true, '_use_rewrite' => true, '_query' => $query));
|
56 |
+
}
|
57 |
+
|
58 |
+
return $this->_helper()->getFilterUrl(array(
|
59 |
+
$this->getFilter()->getRequestVar() => $values
|
60 |
+
), false);
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Get url for remove item from filter
|
65 |
+
*
|
66 |
+
* @return string
|
67 |
+
*/
|
68 |
+
public function getRemoveUrl()
|
69 |
+
{
|
70 |
+
if (!$this->_helper()->isEnabled()) {
|
71 |
+
return parent::getRemoveUrl();
|
72 |
+
}
|
73 |
+
|
74 |
+
$values = $this->getFilter()->getValues();
|
75 |
+
if (!empty($values)) {
|
76 |
+
$tmp = array_diff($values, array($this->getValue()));
|
77 |
+
if (!empty($tmp)) {
|
78 |
+
$values = implode(Catalin_SEO_Helper_Data::MULTIPLE_FILTERS_DELIMITER, $tmp);
|
79 |
+
} else {
|
80 |
+
$values = null;
|
81 |
+
}
|
82 |
+
} else {
|
83 |
+
$values = null;
|
84 |
+
}
|
85 |
+
if ($this->_helper()->isCatalogSearch()) {
|
86 |
+
$query = array(
|
87 |
+
'isLayerAjax' => null,
|
88 |
+
$this->getFilter()->getRequestVar() => $values
|
89 |
+
);
|
90 |
+
$params['_current'] = true;
|
91 |
+
$params['_use_rewrite'] = true;
|
92 |
+
$params['_query'] = $query;
|
93 |
+
$params['_escape'] = true;
|
94 |
+
return Mage::getUrl('*/*/*', $params);
|
95 |
+
}
|
96 |
+
|
97 |
+
return $this->_helper()->getFilterUrl(array(
|
98 |
+
$this->getFilter()->getRequestVar() => $values
|
99 |
+
));
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Check if current filter is selected
|
104 |
+
*
|
105 |
+
* @return boolean
|
106 |
+
*/
|
107 |
+
public function isSelected()
|
108 |
+
{
|
109 |
+
$values = $this->getFilter()->getValues();
|
110 |
+
if (in_array($this->getValue(), $values)) {
|
111 |
+
return true;
|
112 |
+
}
|
113 |
+
return false;
|
114 |
+
}
|
115 |
+
|
116 |
+
}
|
app/code/community/Catalin/SEO/Model/Catalog/Resource/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_Catalog_Resource_Layer_Filter_Attribute extends Mage_Catalog_Model_Resource_Layer_Filter_Attribute
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Apply attribute filter to product collection
|
22 |
+
*
|
23 |
+
* @param Mage_Catalog_Model_Layer_Filter_Attribute $filter
|
24 |
+
* @param int $value
|
25 |
+
* @return Mage_Catalog_Model_Resource_Layer_Filter_Attribute
|
26 |
+
*/
|
27 |
+
public function applyFilterToCollection($filter, $value)
|
28 |
+
{
|
29 |
+
if (!Mage::helper('catalin_seo')->isEnabled()) {
|
30 |
+
return parent::applyFilterToCollection($filter, $value);
|
31 |
+
}
|
32 |
+
|
33 |
+
$collection = $filter->getLayer()->getProductCollection();
|
34 |
+
$attribute = $filter->getAttributeModel();
|
35 |
+
$connection = $this->_getReadAdapter();
|
36 |
+
$tableAlias = $attribute->getAttributeCode() . '_idx' . uniqid();
|
37 |
+
$conditions = array(
|
38 |
+
"{$tableAlias}.entity_id = e.entity_id",
|
39 |
+
$connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()),
|
40 |
+
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId()),
|
41 |
+
);
|
42 |
+
|
43 |
+
$options = $attribute->getSource()->getAllOptions(false);
|
44 |
+
if (!is_array($value)) {
|
45 |
+
foreach ($options as $option) {
|
46 |
+
if ($option['label'] == $value) {
|
47 |
+
$value = $option['value'];
|
48 |
+
}
|
49 |
+
}
|
50 |
+
$conditions[] = $connection->quoteInto("{$tableAlias}.value = ?", $value);
|
51 |
+
} else {
|
52 |
+
$conditions[] = "{$tableAlias}.value in ( ";
|
53 |
+
foreach ($value as $v) {
|
54 |
+
foreach ($options as $option) {
|
55 |
+
if ($option['label'] == $v) {
|
56 |
+
$v = $option['value'];
|
57 |
+
}
|
58 |
+
}
|
59 |
+
$conditions[count($conditions) - 1] .= $connection->quoteInto("?", $v) . ' ,';
|
60 |
+
}
|
61 |
+
$conditions[count($conditions) - 1] = rtrim($conditions[count($conditions) - 1], ',');
|
62 |
+
$conditions[count($conditions) - 1] .= ')';
|
63 |
+
}
|
64 |
+
|
65 |
+
$collection->getSelect()->join(
|
66 |
+
array($tableAlias => $this->getMainTable()), implode(' AND ', $conditions), array()
|
67 |
+
);
|
68 |
+
$collection->getSelect()->distinct();
|
69 |
+
|
70 |
+
return $this;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Retrieve array with products counts per attribute option
|
75 |
+
*
|
76 |
+
* @param Mage_Catalog_Model_Layer_Filter_Attribute $filter
|
77 |
+
* @return array
|
78 |
+
*/
|
79 |
+
public function getCount($filter)
|
80 |
+
{
|
81 |
+
if (!Mage::helper('catalin_seo')->isEnabled()) {
|
82 |
+
return parent::getCount($filter);
|
83 |
+
}
|
84 |
+
|
85 |
+
// clone select from collection with filters
|
86 |
+
$select = clone $filter->getLayer()->getProductCollection()->getSelect();
|
87 |
+
// reset columns, order and limitation conditions
|
88 |
+
$select->reset(Zend_Db_Select::COLUMNS);
|
89 |
+
$select->reset(Zend_Db_Select::ORDER);
|
90 |
+
$select->reset(Zend_Db_Select::LIMIT_COUNT);
|
91 |
+
$select->reset(Zend_Db_Select::LIMIT_OFFSET);
|
92 |
+
|
93 |
+
|
94 |
+
$connection = $this->_getReadAdapter();
|
95 |
+
$attribute = $filter->getAttributeModel();
|
96 |
+
$tableAlias = sprintf('%s_idx', $attribute->getAttributeCode());
|
97 |
+
$conditions = array(
|
98 |
+
"{$tableAlias}.entity_id = e.entity_id",
|
99 |
+
$connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()),
|
100 |
+
$connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId()),
|
101 |
+
);
|
102 |
+
|
103 |
+
// start removing all filters for current attribute - we need correct count
|
104 |
+
$parts = $select->getPart(Zend_Db_Select::FROM);
|
105 |
+
$from = array();
|
106 |
+
foreach ($parts as $key => $part) {
|
107 |
+
if (stripos($key, $tableAlias) === false) {
|
108 |
+
$from[$key] = $part;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
$select->setPart(Zend_Db_Select::FROM, $from);
|
112 |
+
// end of removing
|
113 |
+
|
114 |
+
$select
|
115 |
+
->join(
|
116 |
+
array($tableAlias => $this->getMainTable()), join(' AND ', $conditions), array('value', 'count' => new Zend_Db_Expr("COUNT({$tableAlias}.entity_id)")))
|
117 |
+
->group("{$tableAlias}.value");
|
118 |
+
|
119 |
+
return $connection->fetchPairs($select);
|
120 |
+
}
|
121 |
+
|
122 |
+
}
|
app/code/community/Catalin/SEO/Model/CatalogSearch/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_CatalogSearch_Layer_Filter_Attribute extends Catalin_SEO_Model_Catalog_Layer_Filter_Attribute
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Set filter model name
|
22 |
+
*
|
23 |
+
*/
|
24 |
+
public function __construct()
|
25 |
+
{
|
26 |
+
parent::__construct();
|
27 |
+
$this->_filterModelName = 'catalogsearch/layer_filter_attribute';
|
28 |
+
}
|
29 |
+
|
30 |
+
}
|
app/code/community/Catalin/SEO/Model/System/Config/Backend/Seo/Catalog.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_System_Config_Backend_Seo_Catalog extends Mage_Core_Model_Config_Data
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* After enabling layered navigation seo cache refresh is required
|
22 |
+
*
|
23 |
+
* @return Catalin_SEO_Model_System_Config_Backend_Seo_Catalog
|
24 |
+
*/
|
25 |
+
protected function _afterSave()
|
26 |
+
{
|
27 |
+
if ($this->isValueChanged()) {
|
28 |
+
$instance = Mage::app()->getCacheInstance();
|
29 |
+
$instance->invalidateType('block_html');
|
30 |
+
}
|
31 |
+
|
32 |
+
return $this;
|
33 |
+
}
|
34 |
+
|
35 |
+
}
|
app/code/community/Catalin/SEO/controllers/CategoryController.php
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
require_once 'Mage/Catalog/controllers/CategoryController.php';
|
18 |
+
|
19 |
+
class Catalin_Seo_CategoryController extends Mage_Catalog_CategoryController
|
20 |
+
{
|
21 |
+
|
22 |
+
public function viewAction()
|
23 |
+
{
|
24 |
+
if (($category = $this->_initCatagory())) {
|
25 |
+
$design = Mage::getSingleton('catalog/design');
|
26 |
+
$settings = $design->getDesignSettings($category);
|
27 |
+
|
28 |
+
// apply custom design
|
29 |
+
if ($settings->getCustomDesign()) {
|
30 |
+
$design->applyCustomDesign($settings->getCustomDesign());
|
31 |
+
}
|
32 |
+
|
33 |
+
Mage::getSingleton('catalog/session')->setLastViewedCategoryId($category->getId());
|
34 |
+
|
35 |
+
$update = $this->getLayout()->getUpdate();
|
36 |
+
$update->addHandle('default');
|
37 |
+
|
38 |
+
if (!$category->hasChildren()) {
|
39 |
+
$update->addHandle('catalog_category_layered_nochildren');
|
40 |
+
}
|
41 |
+
|
42 |
+
$this->addActionLayoutHandles();
|
43 |
+
$update->addHandle($category->getLayoutUpdateHandle());
|
44 |
+
$update->addHandle('CATEGORY_' . $category->getId());
|
45 |
+
// apply custom ajax layout
|
46 |
+
if ($this->getRequest()->isAjax()) {
|
47 |
+
$update->addHandle('catalog_category_layered_ajax_layer');
|
48 |
+
}
|
49 |
+
$this->loadLayoutUpdates();
|
50 |
+
|
51 |
+
// apply custom layout update once layout is loaded
|
52 |
+
if (($layoutUpdates = $settings->getLayoutUpdates())) {
|
53 |
+
if (is_array($layoutUpdates)) {
|
54 |
+
foreach ($layoutUpdates as $layoutUpdate) {
|
55 |
+
$update->addUpdate($layoutUpdate);
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
$this->generateLayoutXml()->generateLayoutBlocks();
|
61 |
+
// apply custom layout (page) template once the blocks are generated
|
62 |
+
if ($settings->getPageLayout()) {
|
63 |
+
$this->getLayout()->helper('page/layout')->applyTemplate($settings->getPageLayout());
|
64 |
+
}
|
65 |
+
|
66 |
+
if (($root = $this->getLayout()->getBlock('root'))) {
|
67 |
+
$root->addBodyClass('categorypath-' . $category->getUrlPath())
|
68 |
+
->addBodyClass('category-' . $category->getUrlKey());
|
69 |
+
}
|
70 |
+
|
71 |
+
$this->_initLayoutMessages('catalog/session');
|
72 |
+
$this->_initLayoutMessages('checkout/session');
|
73 |
+
|
74 |
+
// return json formatted response for ajax
|
75 |
+
if ($this->getRequest()->isAjax()) {
|
76 |
+
$listing = $this->getLayout()->getBlock('product_list')->toHtml();
|
77 |
+
$layer = $this->getLayout()->getBlock('catalog.leftnav')->toHtml();
|
78 |
+
|
79 |
+
$response = array(
|
80 |
+
'listing' => $listing,
|
81 |
+
'layer' => $layer
|
82 |
+
);
|
83 |
+
|
84 |
+
$this->getResponse()->setHeader('Content-Type', 'application/json', true);
|
85 |
+
$this->getResponse()->setBody(json_encode($response));
|
86 |
+
} else {
|
87 |
+
$this->renderLayout();
|
88 |
+
}
|
89 |
+
} elseif (!$this->getResponse()->isRedirect()) {
|
90 |
+
$this->_forward('noRoute');
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
}
|
app/code/community/Catalin/SEO/controllers/ResultController.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Catalin Ciobanu
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/osl-3.0.php
|
12 |
+
*
|
13 |
+
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2012 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
require_once 'Mage/CatalogSearch/controllers/ResultController.php';
|
18 |
+
|
19 |
+
class Catalin_Seo_ResultController extends Mage_CatalogSearch_ResultController
|
20 |
+
{
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Display search result
|
24 |
+
*/
|
25 |
+
public function indexAction()
|
26 |
+
{
|
27 |
+
$query = Mage::helper('catalogsearch')->getQuery();
|
28 |
+
/* @var $query Mage_CatalogSearch_Model_Query */
|
29 |
+
|
30 |
+
$query->setStoreId(Mage::app()->getStore()->getId());
|
31 |
+
|
32 |
+
if ($query->getQueryText() != '') {
|
33 |
+
if (Mage::helper('catalogsearch')->isMinQueryLength()) {
|
34 |
+
$query->setId(0)
|
35 |
+
->setIsActive(1)
|
36 |
+
->setIsProcessed(1);
|
37 |
+
} else {
|
38 |
+
if ($query->getId()) {
|
39 |
+
$query->setPopularity($query->getPopularity() + 1);
|
40 |
+
} else {
|
41 |
+
$query->setPopularity(1);
|
42 |
+
}
|
43 |
+
|
44 |
+
if ($query->getRedirect()) {
|
45 |
+
$query->save();
|
46 |
+
$this->getResponse()->setRedirect($query->getRedirect());
|
47 |
+
return;
|
48 |
+
} else {
|
49 |
+
$query->prepare();
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
Mage::helper('catalogsearch')->checkNotes();
|
54 |
+
|
55 |
+
$this->loadLayout();
|
56 |
+
// apply custom ajax layout
|
57 |
+
if ($this->getRequest()->isAjax()) {
|
58 |
+
$update = $this->getLayout()->getUpdate();
|
59 |
+
$update->addHandle('catalog_category_layered_ajax_layer');
|
60 |
+
}
|
61 |
+
$this->_initLayoutMessages('catalog/session');
|
62 |
+
$this->_initLayoutMessages('checkout/session');
|
63 |
+
|
64 |
+
// return json formatted response for ajax
|
65 |
+
if ($this->getRequest()->isAjax()) {
|
66 |
+
$listing = $this->getLayout()->getBlock('search_result_list')->toHtml();
|
67 |
+
$layer = $this->getLayout()->getBlock('catalogsearch.leftnav')->toHtml();
|
68 |
+
|
69 |
+
$response = array(
|
70 |
+
'listing' => $listing,
|
71 |
+
'layer' => $layer
|
72 |
+
);
|
73 |
+
|
74 |
+
$this->getResponse()->setHeader('Content-Type', 'application/json', true);
|
75 |
+
$this->getResponse()->setBody(json_encode($response));
|
76 |
+
} else {
|
77 |
+
$this->renderLayout();
|
78 |
+
}
|
79 |
+
|
80 |
+
if (!Mage::helper('catalogsearch')->isMinQueryLength()) {
|
81 |
+
$query->save();
|
82 |
+
}
|
83 |
+
} else {
|
84 |
+
$this->_redirectReferer();
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
}
|
app/code/community/Catalin/SEO/etc/adminhtml.xml
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<acl>
|
4 |
+
<resources>
|
5 |
+
<admin>
|
6 |
+
<children>
|
7 |
+
<system>
|
8 |
+
<children>
|
9 |
+
<config>
|
10 |
+
<children>
|
11 |
+
<catalin_seo translate="title" module="catalin_seo">
|
12 |
+
<title>Catalin SEO</title>
|
13 |
+
</catalin_seo>
|
14 |
+
</children>
|
15 |
+
</config>
|
16 |
+
</children>
|
17 |
+
</system>
|
18 |
+
</children>
|
19 |
+
</admin>
|
20 |
+
</resources>
|
21 |
+
</acl>
|
22 |
+
</config>
|
app/code/community/Catalin/SEO/etc/config.xml
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<global>
|
4 |
+
<modules>
|
5 |
+
<Catalin_SEO>
|
6 |
+
<version>1.0.0</version>
|
7 |
+
</Catalin_SEO>
|
8 |
+
</modules>
|
9 |
+
<models>
|
10 |
+
<catalog>
|
11 |
+
<rewrite>
|
12 |
+
<layer_filter_item>Catalin_SEO_Model_Catalog_Layer_Filter_Item</layer_filter_item>
|
13 |
+
<layer_filter_category>Catalin_SEO_Model_Catalog_Layer_Filter_Category</layer_filter_category>
|
14 |
+
<layer_filter_attribute>Catalin_SEO_Model_Catalog_Layer_Filter_Attribute</layer_filter_attribute>
|
15 |
+
</rewrite>
|
16 |
+
</catalog>
|
17 |
+
<catalogsearch>
|
18 |
+
<rewrite>
|
19 |
+
<layer_filter_attribute>Catalin_SEO_Model_CatalogSearch_Layer_Filter_Attribute</layer_filter_attribute>
|
20 |
+
</rewrite>
|
21 |
+
</catalogsearch>
|
22 |
+
<catalog_resource>
|
23 |
+
<rewrite>
|
24 |
+
<layer_filter_attribute>Catalin_SEO_Model_Catalog_Resource_Layer_Filter_Attribute</layer_filter_attribute>
|
25 |
+
</rewrite>
|
26 |
+
</catalog_resource>
|
27 |
+
<catalin_seo>
|
28 |
+
<class>Catalin_SEO_Model</class>
|
29 |
+
</catalin_seo>
|
30 |
+
</models>
|
31 |
+
<blocks>
|
32 |
+
<catalog>
|
33 |
+
<rewrite>
|
34 |
+
<layer_state>Catalin_SEO_Block_Catalog_Layer_State</layer_state>
|
35 |
+
<product_list_toolbar>Catalin_SEO_Block_Catalog_Product_List_Toolbar</product_list_toolbar>
|
36 |
+
<layer_filter_attribute>Catalin_SEO_Block_Catalog_Layer_Filter_Attribute</layer_filter_attribute>
|
37 |
+
<layer_filter_price>Catalin_SEO_Block_Catalog_Layer_Filter_Price</layer_filter_price>
|
38 |
+
</rewrite>
|
39 |
+
</catalog>
|
40 |
+
<catalogsearch>
|
41 |
+
<rewrite>
|
42 |
+
<layer_filter_attribute>Catalin_SEO_Block_CatalogSearch_Layer_Filter_Attribute</layer_filter_attribute>
|
43 |
+
</rewrite>
|
44 |
+
</catalogsearch>
|
45 |
+
<catalin_seo>
|
46 |
+
<class>Catalin_SEO_Block</class>
|
47 |
+
</catalin_seo>
|
48 |
+
</blocks>
|
49 |
+
<helpers>
|
50 |
+
<catalin_seo>
|
51 |
+
<class>Catalin_SEO_Helper</class>
|
52 |
+
</catalin_seo>
|
53 |
+
</helpers>
|
54 |
+
<events>
|
55 |
+
<controller_front_init_routers>
|
56 |
+
<observers>
|
57 |
+
<catalin_seo>
|
58 |
+
<class>Catalin_SEO_Controller_Router</class>
|
59 |
+
<method>initControllerRouters</method>
|
60 |
+
</catalin_seo>
|
61 |
+
</observers>
|
62 |
+
</controller_front_init_routers>
|
63 |
+
</events>
|
64 |
+
</global>
|
65 |
+
<frontend>
|
66 |
+
<routers>
|
67 |
+
<catalog>
|
68 |
+
<args>
|
69 |
+
<modules>
|
70 |
+
<Catalin_SEO before="Mage_Catalog">Catalin_SEO</Catalin_SEO>
|
71 |
+
</modules>
|
72 |
+
</args>
|
73 |
+
</catalog>
|
74 |
+
<catalogsearch>
|
75 |
+
<args>
|
76 |
+
<modules>
|
77 |
+
<Catalin_SEO before="Mage_CatalogSearch">Catalin_SEO</Catalin_SEO>
|
78 |
+
</modules>
|
79 |
+
</args>
|
80 |
+
</catalogsearch>
|
81 |
+
</routers>
|
82 |
+
<layout>
|
83 |
+
<updates>
|
84 |
+
<catalin_seo module="Catalin_SEO">
|
85 |
+
<file>catalin_seo.xml</file>
|
86 |
+
</catalin_seo>
|
87 |
+
</updates>
|
88 |
+
</layout>
|
89 |
+
</frontend>
|
90 |
+
<default>
|
91 |
+
<catalin_seo>
|
92 |
+
<catalog>
|
93 |
+
<enabled>1</enabled>
|
94 |
+
<ajax_enabled>1</ajax_enabled>
|
95 |
+
<price_slider>1</price_slider>
|
96 |
+
<multiple_choise_filters>1</multiple_choise_filters>
|
97 |
+
</catalog>
|
98 |
+
</catalin_seo>
|
99 |
+
</default>
|
100 |
+
</config>
|
app/code/community/Catalin/SEO/etc/system.xml
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<tabs>
|
4 |
+
<catalin translate="label" module="catalin_seo">
|
5 |
+
<label>Catalin</label>
|
6 |
+
<sort_order>300</sort_order>
|
7 |
+
</catalin>
|
8 |
+
</tabs>
|
9 |
+
<sections>
|
10 |
+
<catalin_seo translate="label" module="catalin_seo">
|
11 |
+
<label>Catalin SEO</label>
|
12 |
+
<tab>catalin</tab>
|
13 |
+
<frontend_type>text</frontend_type>
|
14 |
+
<sort_order>1</sort_order>
|
15 |
+
<show_in_default>1</show_in_default>
|
16 |
+
<show_in_website>1</show_in_website>
|
17 |
+
<show_in_store>1</show_in_store>
|
18 |
+
<groups>
|
19 |
+
<catalog translate="label">
|
20 |
+
<label>Catalog Layered Navigation</label>
|
21 |
+
<frontend_type>text</frontend_type>
|
22 |
+
<sort_order>2</sort_order>
|
23 |
+
<show_in_default>1</show_in_default>
|
24 |
+
<show_in_website>1</show_in_website>
|
25 |
+
<show_in_store>1</show_in_store>
|
26 |
+
<fields>
|
27 |
+
<enabled translate="label">
|
28 |
+
<label>Enable</label>
|
29 |
+
<frontend_type>select</frontend_type>
|
30 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
31 |
+
<backend_model>catalin_seo/system_config_backend_seo_catalog</backend_model>
|
32 |
+
<sort_order>1</sort_order>
|
33 |
+
<show_in_default>1</show_in_default>
|
34 |
+
<show_in_website>1</show_in_website>
|
35 |
+
<show_in_store>1</show_in_store>
|
36 |
+
</enabled>
|
37 |
+
<ajax_enabled translate="label">
|
38 |
+
<label>Enable AJAX</label>
|
39 |
+
<frontend_type>select</frontend_type>
|
40 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
41 |
+
<backend_model>catalin_seo/system_config_backend_seo_catalog</backend_model>
|
42 |
+
<sort_order>2</sort_order>
|
43 |
+
<show_in_default>1</show_in_default>
|
44 |
+
<show_in_website>1</show_in_website>
|
45 |
+
<show_in_store>1</show_in_store>
|
46 |
+
<depends><enabled>1</enabled></depends>
|
47 |
+
</ajax_enabled>
|
48 |
+
<price_slider translate="label">
|
49 |
+
<label>Enable Price Slider</label>
|
50 |
+
<frontend_type>select</frontend_type>
|
51 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
52 |
+
<backend_model>catalin_seo/system_config_backend_seo_catalog</backend_model>
|
53 |
+
<sort_order>3</sort_order>
|
54 |
+
<show_in_default>1</show_in_default>
|
55 |
+
<show_in_website>1</show_in_website>
|
56 |
+
<show_in_store>1</show_in_store>
|
57 |
+
<depends><enabled>1</enabled></depends>
|
58 |
+
</price_slider>
|
59 |
+
<multiple_choise_filters translate="label">
|
60 |
+
<label>Enable Multipe Choise Filter</label>
|
61 |
+
<frontend_type>select</frontend_type>
|
62 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
63 |
+
<backend_model>catalin_seo/system_config_backend_seo_catalog</backend_model>
|
64 |
+
<sort_order>4</sort_order>
|
65 |
+
<show_in_default>1</show_in_default>
|
66 |
+
<show_in_website>1</show_in_website>
|
67 |
+
<show_in_store>1</show_in_store>
|
68 |
+
<depends><enabled>1</enabled></depends>
|
69 |
+
</multiple_choise_filters>
|
70 |
+
</fields>
|
71 |
+
</catalog>
|
72 |
+
</groups>
|
73 |
+
</catalin_seo>
|
74 |
+
</sections>
|
75 |
+
</config>
|
app/design/frontend/default/default/layout/catalin_seo.xml
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<layout version="0.1.0">
|
3 |
+
<catalog_category_layered>
|
4 |
+
<reference name="head">
|
5 |
+
<action method="addItem">
|
6 |
+
<type>skin_css</type>
|
7 |
+
<name>css/price_slider/style.css</name>
|
8 |
+
</action>
|
9 |
+
</reference>
|
10 |
+
<reference name="product_list_toolbar">
|
11 |
+
<block type="catalin_seo/catalog_product_list_pager" name="product_list_toolbar_pager"/>
|
12 |
+
</reference>
|
13 |
+
<reference name="product_list">
|
14 |
+
<action method="setTemplate">
|
15 |
+
<template>catalin_seo/catalog/product/list.phtml</template>
|
16 |
+
</action>
|
17 |
+
</reference>
|
18 |
+
<reference name="catalog.leftnav">
|
19 |
+
<action method="setTemplate">
|
20 |
+
<template>catalin_seo/catalog/layer/view.phtml</template>
|
21 |
+
</action>
|
22 |
+
</reference>
|
23 |
+
</catalog_category_layered>
|
24 |
+
|
25 |
+
<catalog_category_layered_ajax_layer>
|
26 |
+
<remove name="right"/>
|
27 |
+
<remove name="header"/>
|
28 |
+
<remove name="head"/>
|
29 |
+
<remove name="footer"/>
|
30 |
+
</catalog_category_layered_ajax_layer>
|
31 |
+
|
32 |
+
<catalogsearch_result_index>
|
33 |
+
<reference name="head">
|
34 |
+
<action method="addItem">
|
35 |
+
<type>skin_css</type>
|
36 |
+
<name>css/price_slider/style.css</name>
|
37 |
+
</action>
|
38 |
+
</reference>
|
39 |
+
<reference name="search_result_list">
|
40 |
+
<action method="setTemplate">
|
41 |
+
<template>catalin_seo/catalog/product/list.phtml</template>
|
42 |
+
</action>
|
43 |
+
</reference>
|
44 |
+
<reference name="catalogsearch.leftnav">
|
45 |
+
<action method="setTemplate">
|
46 |
+
<template>catalin_seo/catalog/layer/view.phtml</template>
|
47 |
+
</action>
|
48 |
+
</reference>
|
49 |
+
<reference name="product_list_toolbar">
|
50 |
+
<block type="catalin_seo/catalog_product_list_pager" name="product_list_toolbar_pager"/>
|
51 |
+
</reference>
|
52 |
+
</catalogsearch_result_index>
|
53 |
+
</layout>
|
app/design/frontend/default/default/template/catalin_seo/catalog/layer/filter.phtml
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<ol>
|
2 |
+
<?php foreach ($this->getItems() as $_item): ?>
|
3 |
+
<li>
|
4 |
+
<?php if ($_item->getCount() > 0): ?>
|
5 |
+
<input type="checkbox"<?php if ($_item->isSelected()): ?> checked="checked" <?php endif; ?>
|
6 |
+
<?php if ($this->helper('catalin_seo')->isAjaxEnabled()): ?>
|
7 |
+
onclick="$(this).next().click()"
|
8 |
+
<?php else: ?>
|
9 |
+
onclick="setLocation('<?php echo ($_item->isSelected()) ? $this->urlEscape($_item->getRemoveUrl()) : $this->urlEscape($_item->getUrl()) ?>')"
|
10 |
+
<?php endif; ?>
|
11 |
+
/>
|
12 |
+
<a
|
13 |
+
<?php if ($_item->isSelected()): ?>
|
14 |
+
onclick="$(this).previous().checked = false;"
|
15 |
+
<?php else: ?>
|
16 |
+
onclick="$(this).previous().checked = true;"
|
17 |
+
<?php endif; ?>
|
18 |
+
href="<?php echo ($_item->isSelected()) ? $_item->getRemoveUrl() : $_item->getUrl() ?>"
|
19 |
+
><?php echo $_item->getLabel() ?></a>
|
20 |
+
<?php else: ?>
|
21 |
+
<?php echo $_item->getLabel() ?>
|
22 |
+
<?php endif; ?>
|
23 |
+
(<?php echo $_item->getCount() ?>)
|
24 |
+
</li>
|
25 |
+
<?php endforeach ?>
|
26 |
+
</ol>
|
app/design/frontend/default/default/template/catalin_seo/catalog/layer/price.phtml
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div id="price-range" class="filter-track price-slider">
|
2 |
+
<span id="price-min" class="filter-handle price-slider-from" title="Scroll to set your minimum value"></span>
|
3 |
+
<span id="price-max" class="filter-handle price-slider-to" title="Scroll to set your maximum value"></span>
|
4 |
+
</div>
|
5 |
+
<ul>
|
6 |
+
<li>
|
7 |
+
<span id="price-min-display">0</span>
|
8 |
+
<span style="float: right;" id="price-max-display"><?php echo $this->getMaxPriceInt(); ?></span>
|
9 |
+
</li>
|
10 |
+
</ul>
|
11 |
+
|
12 |
+
<script type="text/javascript">
|
13 |
+
var maxPriceInt = <?php echo $this->getMaxPriceInt(); ?>;
|
14 |
+
|
15 |
+
function handlePriceEvent(val) {
|
16 |
+
var link = '<?php echo $this->getUrlPattern(); ?>';
|
17 |
+
if (val[0] != 0 || val[1] != maxPriceInt) {
|
18 |
+
var price = val.join('-');
|
19 |
+
link = link.replace('__PRICE_VALUE__', price);
|
20 |
+
<?php if ($this->helper('catalin_seo')->isAjaxEnabled()): ?>
|
21 |
+
handleEvent(link);
|
22 |
+
<?php else: ?>
|
23 |
+
window.location.href = link;
|
24 |
+
<?php endif; ?>
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
var handles = [$('price-min'), $('price-max')];
|
29 |
+
// horizontal slider control with preset values
|
30 |
+
new Control.Slider(handles, 'price-range', {
|
31 |
+
range: $R(0, maxPriceInt, false),
|
32 |
+
sliderValue: [0, maxPriceInt],
|
33 |
+
values: [
|
34 |
+
<?php for ($i = 0; $i <= $this->getMaxPriceInt(); $i++): ?>
|
35 |
+
<?php echo $i ?><?php echo ($i == $this->getMaxPriceInt()) ? '' : ',' ?>
|
36 |
+
<?php endfor; ?>
|
37 |
+
],
|
38 |
+
|
39 |
+
restricted: true,
|
40 |
+
onChange: function(val){
|
41 |
+
handlePriceEvent(val);
|
42 |
+
},
|
43 |
+
onSlide: function(val){
|
44 |
+
$('price-max-display').innerHTML = val[1];
|
45 |
+
$('price-min-display').innerHTML = val[0];
|
46 |
+
}
|
47 |
+
});
|
48 |
+
</script>
|
app/design/frontend/default/default/template/catalin_seo/catalog/layer/view.phtml
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ($this->canShowBlock()): ?>
|
2 |
+
<?php if (!$this->getRequest()->isAjax()): ?>
|
3 |
+
<div id="layered-navigation">
|
4 |
+
<?php endif; ?>
|
5 |
+
<div class="block block-layered-nav">
|
6 |
+
<div class="block-title">
|
7 |
+
<strong><span><?php echo $this->__('Shop By') ?></span></strong>
|
8 |
+
</div>
|
9 |
+
<?php echo $this->getStateHtml() ?>
|
10 |
+
<div class="block-content">
|
11 |
+
<?php if ($this->getLayer()->getState()->getFilters()): ?>
|
12 |
+
<div class="actions"><a href="<?php echo $this->getClearUrl() ?>"><?php echo $this->__('Clear All') ?></a></div>
|
13 |
+
<?php endif; ?>
|
14 |
+
<?php if ($this->canShowOptions()): ?>
|
15 |
+
<p class="block-subtitle"><?php echo $this->__('Shopping Options') ?></p>
|
16 |
+
<dl id="narrow-by-list">
|
17 |
+
<?php $_filters = $this->getFilters() ?>
|
18 |
+
<?php foreach ($_filters as $_filter): ?>
|
19 |
+
<?php if ($_filter->getItemsCount()): ?>
|
20 |
+
<dt><?php echo $this->__($_filter->getName()) ?></dt>
|
21 |
+
<dd><?php echo $_filter->getHtml() ?></dd>
|
22 |
+
<?php endif; ?>
|
23 |
+
<?php endforeach; ?>
|
24 |
+
</dl>
|
25 |
+
<script type="text/javascript">decorateDataList('narrow-by-list')</script>
|
26 |
+
<?php endif; ?>
|
27 |
+
<?php if ($this->getLayer()->getState()->getFilters()): ?>
|
28 |
+
<div class="actions"><a href="<?php echo $this->getClearUrl() ?>"><?php echo $this->__('Clear All') ?></a></div>
|
29 |
+
<?php endif; ?>
|
30 |
+
</div>
|
31 |
+
</div>
|
32 |
+
<?php if (!$this->getRequest()->isAjax()): ?>
|
33 |
+
</div>
|
34 |
+
<?php endif; ?>
|
35 |
+
<?php endif; ?>
|
app/design/frontend/default/default/template/catalin_seo/catalog/product/list.phtml
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$_productCollection=$this->getLoadedProductCollection();
|
3 |
+
$_helper = $this->helper('catalog/output');
|
4 |
+
?>
|
5 |
+
<?php if(!$_productCollection->count()): ?>
|
6 |
+
<p class="note-msg"><?php echo $this->__('There are no products matching the selection.') ?></p>
|
7 |
+
<?php else: ?>
|
8 |
+
<?php if (!$this->getRequest()->isAjax()): ?>
|
9 |
+
<div id="ajax-errors" style="display: none;">
|
10 |
+
<ul class="messages">
|
11 |
+
<li class="error-msg">
|
12 |
+
<ul>
|
13 |
+
<li><span><?php echo $this->__('An error occurred, please try again later.'); ?></span></li>
|
14 |
+
</ul>
|
15 |
+
</li>
|
16 |
+
</ul>
|
17 |
+
</div>
|
18 |
+
<div id="loading" style="display: none; margin-bottom: 10px; text-align: center;">
|
19 |
+
<img class="v-middle" alt="" src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif'); ?>"> <?php echo $this->__('Loading, please wait...'); ?>
|
20 |
+
</div>
|
21 |
+
<div id="catalog-listing">
|
22 |
+
<?php endif; ?>
|
23 |
+
<div class="category-products">
|
24 |
+
<?php echo $this->getToolbarHtml() ?>
|
25 |
+
<?php // List mode ?>
|
26 |
+
<?php if($this->getMode()!='grid'): ?>
|
27 |
+
<?php $_iterator = 0; ?>
|
28 |
+
<ol class="products-list" id="products-list">
|
29 |
+
<?php foreach ($_productCollection as $_product): ?>
|
30 |
+
<li class="item<?php if( ++$_iterator == sizeof($_productCollection) ): ?> last<?php endif; ?>">
|
31 |
+
<?php // Product Image ?>
|
32 |
+
<a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" /></a>
|
33 |
+
<?php // Product description ?>
|
34 |
+
<div class="product-shop">
|
35 |
+
<div class="f-fix">
|
36 |
+
<?php $_productNameStripped = $this->stripTags($_product->getName(), null, true); ?>
|
37 |
+
<h2 class="product-name"><a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $_productNameStripped; ?>"><?php echo $_helper->productAttribute($_product, $_product->getName() , 'name'); ?></a></h2>
|
38 |
+
<?php if($_product->getRatingSummary()): ?>
|
39 |
+
<?php echo $this->getReviewsSummaryHtml($_product) ?>
|
40 |
+
<?php endif; ?>
|
41 |
+
<?php echo $this->getPriceHtml($_product, true) ?>
|
42 |
+
<?php if($_product->isSaleable()): ?>
|
43 |
+
<p><button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button></p>
|
44 |
+
<?php else: ?>
|
45 |
+
<p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
|
46 |
+
<?php endif; ?>
|
47 |
+
<div class="desc std">
|
48 |
+
<?php echo $_helper->productAttribute($_product, $_product->getShortDescription(), 'short_description') ?>
|
49 |
+
<a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $_productNameStripped ?>" class="link-learn"><?php echo $this->__('Learn More') ?></a>
|
50 |
+
</div>
|
51 |
+
<ul class="add-to-links">
|
52 |
+
<?php if ($this->helper('wishlist')->isAllow()) : ?>
|
53 |
+
<li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
|
54 |
+
<?php endif; ?>
|
55 |
+
<?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
|
56 |
+
<li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
|
57 |
+
<?php endif; ?>
|
58 |
+
</ul>
|
59 |
+
</div>
|
60 |
+
</div>
|
61 |
+
</li>
|
62 |
+
<?php endforeach; ?>
|
63 |
+
</ol>
|
64 |
+
<script type="text/javascript">decorateList('products-list', 'none-recursive')</script>
|
65 |
+
|
66 |
+
<?php else: ?>
|
67 |
+
|
68 |
+
<?php // Grid Mode ?>
|
69 |
+
|
70 |
+
<?php $_collectionSize = $_productCollection->count() ?>
|
71 |
+
<?php $_columnCount = $this->getColumnCount(); ?>
|
72 |
+
<?php $i=0; foreach ($_productCollection as $_product): ?>
|
73 |
+
<?php if ($i++%$_columnCount==0): ?>
|
74 |
+
<ul class="products-grid">
|
75 |
+
<?php endif ?>
|
76 |
+
<li class="item<?php if(($i-1)%$_columnCount==0): ?> first<?php elseif($i%$_columnCount==0): ?> last<?php endif; ?>">
|
77 |
+
<a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" /></a>
|
78 |
+
<h2 class="product-name"><a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($_product->getName(), null, true) ?>"><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></a></h2>
|
79 |
+
<?php if($_product->getRatingSummary()): ?>
|
80 |
+
<?php echo $this->getReviewsSummaryHtml($_product, 'short') ?>
|
81 |
+
<?php endif; ?>
|
82 |
+
<?php echo $this->getPriceHtml($_product, true) ?>
|
83 |
+
<div class="actions">
|
84 |
+
<?php if($_product->isSaleable()): ?>
|
85 |
+
<button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
|
86 |
+
<?php else: ?>
|
87 |
+
<p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
|
88 |
+
<?php endif; ?>
|
89 |
+
<ul class="add-to-links">
|
90 |
+
<?php if ($this->helper('wishlist')->isAllow()) : ?>
|
91 |
+
<li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
|
92 |
+
<?php endif; ?>
|
93 |
+
<?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
|
94 |
+
<li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
|
95 |
+
<?php endif; ?>
|
96 |
+
</ul>
|
97 |
+
</div>
|
98 |
+
</li>
|
99 |
+
<?php if ($i%$_columnCount==0 || $i==$_collectionSize): ?>
|
100 |
+
</ul>
|
101 |
+
<?php endif ?>
|
102 |
+
<?php endforeach ?>
|
103 |
+
<script type="text/javascript">decorateGeneric($$('ul.products-grid'), ['odd','even','first','last'])</script>
|
104 |
+
<?php endif; ?>
|
105 |
+
|
106 |
+
<div class="toolbar-bottom">
|
107 |
+
<?php echo $this->getToolbarHtml() ?>
|
108 |
+
</div>
|
109 |
+
</div>
|
110 |
+
<?php if (!$this->getRequest()->isAjax()): ?>
|
111 |
+
</div>
|
112 |
+
<?php endif; ?>
|
113 |
+
<?php endif; ?>
|
114 |
+
|
115 |
+
<?php if ($this->helper('catalin_seo')->isAjaxEnabled() && !$this->getRequest()->isAjax()): ?>
|
116 |
+
<script type="text/javascript">
|
117 |
+
//<![CDATA[
|
118 |
+
function handleEvent(el, event) {
|
119 |
+
var link;
|
120 |
+
if (typeof el === 'string') {
|
121 |
+
link = el;
|
122 |
+
} else if (el.tagName.toLowerCase() === 'a') {
|
123 |
+
link = $(el).readAttribute('href');
|
124 |
+
} else if (el.tagName.toLowerCase() === 'select') {
|
125 |
+
link = $(el).getValue();
|
126 |
+
}
|
127 |
+
|
128 |
+
<?php // Add this parameter for full page caching systems ?>
|
129 |
+
if (link.indexOf('?') != -1) {
|
130 |
+
link = link + '&isLayerAjax=1';
|
131 |
+
} else {
|
132 |
+
link = link + '?isLayerAjax=1';
|
133 |
+
}
|
134 |
+
|
135 |
+
$('loading').show();
|
136 |
+
$('ajax-errors').hide();
|
137 |
+
|
138 |
+
new Ajax.Request(link, {
|
139 |
+
method: 'get',
|
140 |
+
onSuccess: function(transport) {
|
141 |
+
if (transport.responseJSON) {
|
142 |
+
$('catalog-listing').update(transport.responseJSON.listing);
|
143 |
+
$('layered-navigation').update(transport.responseJSON.layer);
|
144 |
+
ajaxListener();
|
145 |
+
} else {
|
146 |
+
$('ajax-errors').show();
|
147 |
+
}
|
148 |
+
$('loading').hide();
|
149 |
+
}
|
150 |
+
});
|
151 |
+
if (event) {
|
152 |
+
event.preventDefault();
|
153 |
+
}
|
154 |
+
}
|
155 |
+
function ajaxListener() {
|
156 |
+
var els;
|
157 |
+
els = $$('div.pager a').concat(
|
158 |
+
$$('div.sorter a'),
|
159 |
+
$$('div.pager select'),
|
160 |
+
$$('div.sorter select'),
|
161 |
+
$$('div.block-layered-nav a')
|
162 |
+
);
|
163 |
+
els.each(function(el) {
|
164 |
+
if (el.tagName.toLowerCase() === 'a') {
|
165 |
+
$(el).observe('click', function(event) {
|
166 |
+
handleEvent(this, event);
|
167 |
+
});
|
168 |
+
} else if (el.tagName.toLowerCase() === 'select') {
|
169 |
+
$(el).setAttribute('onchange', '');
|
170 |
+
$(el).observe('change', function(event) {
|
171 |
+
handleEvent(this, event);
|
172 |
+
});
|
173 |
+
}
|
174 |
+
});
|
175 |
+
}
|
176 |
+
document.observe("dom:loaded", function() {
|
177 |
+
ajaxListener();
|
178 |
+
});
|
179 |
+
//]]>
|
180 |
+
</script>
|
181 |
+
<?php endif; ?>
|
app/etc/modules/Catalin_SEO.xml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Catalin_SEO>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
<depends>
|
8 |
+
<Mage_Catalog/>
|
9 |
+
</depends>
|
10 |
+
</Catalin_SEO>
|
11 |
+
</modules>
|
12 |
+
</config>
|
package.xml
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>Catalin_Seo</name>
|
4 |
+
<version>1.0.0</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://opensource.org/licenses/osl-3.0.php">OSL</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>ajax, seo urls, price slider, multiple selection for the same attribute.</summary>
|
10 |
+
<description><h2>Layered Navigation SEO</h2>
|
11 |
+
<p>ajax, seo urls, price slider, multiple selection for the same attribute.</p>
|
12 |
+
<h2>Features</h2>
|
13 |
+
<ul>
|
14 |
+
<li>ajax navigation</li>
|
15 |
+
<li>simple price slider</li>
|
16 |
+
<li>SEO URLs (http://www.example.com/apparel/shoes/list/color/Brown,Blue/shoe_type/Sandal.html)</li>
|
17 |
+
<li>multiple filters for the same attribute</li>
|
18 |
+
</ul>
|
19 |
+
<p>All the above features can be enabled/disabled from backend from "System -> Configuration -> Catalin SEO -> Catalog Layered Navigation"</p>
|
20 |
+
<h2>Known Issues</h2>
|
21 |
+
<ul>
|
22 |
+
<li>In the attribute values "," (comma) and "/" (slash) cannot be used.</li>
|
23 |
+
</ul></description>
|
24 |
+
<notes>ajax, seo urls, price slider, multiple selection for the same attribute.</notes>
|
25 |
+
<authors><author><name>Catalin</name><user>Ciobanu</user><email>ciobanu.catalin@yahoo.com</email></author></authors>
|
26 |
+
<date>2012-11-17</date>
|
27 |
+
<time>13:16:33</time>
|
28 |
+
<contents><target name="magecommunity"><dir name="Catalin"><dir name="SEO"><dir name="Block"><dir name="Catalog"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="b0fb7deaeec0d46bc170e510c3d6f73a"/><file name="Price.php" hash="73fe2b9d21dab816474ee8d662a530bd"/></dir><file name="State.php" hash="fece6cd5534ae48f0f9f9233a7f714af"/></dir><dir name="Product"><dir name="List"><file name="Pager.php" hash="5f41fc06bddb70fc2f7de3792c933879"/><file name="Toolbar.php" hash="6db34892e1937dd1e527c8ac2fda4746"/></dir></dir></dir><dir name="CatalogSearch"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="120da8cc984bf1d55428ee4cfeaedca5"/></dir></dir></dir></dir><dir name="Controller"><file name="Router.php" hash="71c67346a0c3e89775e5d7762c8a3588"/></dir><dir name="Helper"><file name="Data.php" hash="47a5e37ea96a12615ad1818f919d634f"/></dir><dir name="Model"><dir name="Catalog"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="cd5ef92601544ed236617881b0dd6352"/><file name="Category.php" hash="bc5df542ef28c4e7a9583ae441c550c8"/><file name="Item.php" hash="9d89a99bebad467ca14e50333c556649"/></dir></dir><dir name="Resource"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="ab59cb798f1069786a98408f6ebaf948"/></dir></dir></dir></dir><dir name="CatalogSearch"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="137c0b3795d3eea4da8442db3e05e7a0"/></dir></dir></dir><dir name="System"><dir name="Config"><dir name="Backend"><dir name="Seo"><file name="Catalog.php" hash="ea4cd41cf4e919935919585a22dfea29"/></dir></dir></dir></dir></dir><dir name="controllers"><file name="CategoryController.php" hash="3f3404592e64ffc3d3e302a92e76dc06"/><file name="ResultController.php" hash="660c07990539e5605112cb42e24c02d6"/></dir><dir name="etc"><file name="adminhtml.xml" hash="240f607b0156d1de84667b382ba3f73c"/><file name="config.xml" hash="9e2487e6c0eb5b09c43f65c01db3d882"/><file name="system.xml" hash="9fd01148901e15950868e312b96dbfde"/></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="css"><dir name="price_slider"><file name="style.css" hash="61d0b59ed239bc64deaf4aed969652cd"/></dir></dir><dir name="images"><dir name="price_slider"><file name="bkg_slider.png" hash="1b7a1eb7add1d2b2002501f4602c3d3e"/><file name="slider.png" hash="d77b417b68ba91402c3b7180b165110c"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Catalin_SEO.xml" hash="e0ad01abfe976aefb6587fcfb3bf0d2b"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><dir name="template"><dir name="catalin_seo"><dir><dir name="catalog"><dir name="layer"><file name="filter.phtml" hash="dd1d3278e691814f0cd242179e5bf53f"/><file name="price.phtml" hash="19f1583df9e7f14d81318c633b334a88"/><file name="view.phtml" hash="bc5f21109be4dab996b152e7a756fe03"/></dir><dir name="product"><file name="list.phtml" hash="bd332a192ed36c56c00968e13b599cd3"/></dir></dir></dir></dir></dir><dir name="layout"><file name="catalin_seo.xml" hash="61db4d9d696f2d12c562ae70a5164e4c"/></dir></dir></dir></dir></target></contents>
|
29 |
+
<compatible/>
|
30 |
+
<dependencies><required><php><min>5.2.0</min><max>5.4.0</max></php></required></dependencies>
|
31 |
+
</package>
|
skin/frontend/default/default/css/price_slider/style.css
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
div.price-slider {
|
2 |
+
background: url("../../images/price_slider/bkg_slider.png") repeat-x scroll 0 0 transparent;
|
3 |
+
height: 17px;
|
4 |
+
}
|
5 |
+
div.price-slider .filter-handle {
|
6 |
+
height: 17px;
|
7 |
+
width: 17px;
|
8 |
+
cursor: e-resize;
|
9 |
+
display: block;
|
10 |
+
}
|
11 |
+
div.price-slider .price-slider-from {
|
12 |
+
background: url("../../images/price_slider/slider.png") no-repeat scroll 0 0 transparent;
|
13 |
+
}
|
14 |
+
div.price-slider .price-slider-to {
|
15 |
+
background: url("../../images/price_slider/slider.png") no-repeat scroll -19px 0 transparent;
|
16 |
+
cursor: w-resize;
|
17 |
+
margin-top: -17px;
|
18 |
+
}
|
skin/frontend/default/default/images/price_slider/bkg_slider.png
ADDED
Binary file
|
skin/frontend/default/default/images/price_slider/slider.png
ADDED
Binary file
|