Version Notes
- Fixed the issue: in attribute values "," (comma) and "/" (slash) cannot be used.
- Disabled History for browsers HTML4 browsers.
Download this release
Release Info
Developer | Catalin Ciobanu |
Extension | Catalin_Seo |
Version | 2.0.0 |
Comparing to | |
See all releases |
Code changes from version 1.2.1 to 2.0.0
- app/code/community/Catalin/SEO/Block/Catalog/Layer/Filter/Attribute.php +1 -1
- app/code/community/Catalin/SEO/Block/Catalog/Layer/Filter/Price.php +1 -1
- app/code/community/Catalin/SEO/Block/Catalog/Layer/State.php +1 -1
- app/code/community/Catalin/SEO/Block/Catalog/Product/List/Pager.php +1 -1
- app/code/community/Catalin/SEO/Block/Catalog/Product/List/Toolbar.php +1 -1
- app/code/community/Catalin/SEO/Block/CatalogSearch/Layer/Filter/Attribute.php +1 -1
- app/code/community/Catalin/SEO/Controller/Router.php +1 -1
- app/code/community/Catalin/SEO/Helper/Data.php +2 -2
- app/code/community/Catalin/SEO/Model/Catalog/Layer.php +36 -0
- app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Attribute.php +9 -4
- app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Category.php +1 -1
- app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Item.php +3 -1
- app/code/community/Catalin/SEO/Model/Catalog/Resource/Layer/Filter/Attribute.php +4 -7
- app/code/community/Catalin/SEO/Model/CatalogSearch/Layer.php +116 -0
- app/code/community/Catalin/SEO/Model/CatalogSearch/Layer/Filter/Attribute.php +1 -1
- app/code/community/Catalin/SEO/Model/Indexer/Attribute.php +75 -0
- app/code/community/Catalin/SEO/Model/Resource/Attribute/Urlkey.php +139 -0
- app/code/community/Catalin/SEO/Model/Resource/Indexer/Attribute.php +204 -0
- app/code/community/Catalin/SEO/Model/System/Config/Backend/Seo/Catalog.php +1 -1
- app/code/community/Catalin/SEO/Model/System/Config/Source/Slider/Submit/Type.php +16 -2
- app/code/community/Catalin/SEO/controllers/CategoryController.php +2 -2
- app/code/community/Catalin/SEO/controllers/ResultController.php +1 -1
- app/code/community/Catalin/SEO/etc/config.xml +30 -5
- app/code/community/Catalin/SEO/sql/catalin_seo_setup/install-2.0.0.php +42 -0
- package.xml +13 -169
- skin/frontend/default/default/js/catalin_seo/native.history.js +1 -1
app/code/community/Catalin/SEO/Block/Catalog/Layer/Filter/Attribute.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Block/Catalog/Layer/Filter/Price.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Block/Catalog/Layer/State.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Block/Catalog/Product/List/Pager.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Block/Catalog/Product/List/Toolbar.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Block/CatalogSearch/Layer/Filter/Attribute.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Controller/Router.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Helper/Data.php
CHANGED
@@ -11,10 +11,10 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
15 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
*/
|
17 |
-
class Catalin_SEO_Helper_Data extends
|
18 |
{
|
19 |
/**
|
20 |
* Delimiter for multiple filters
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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_Data
|
18 |
{
|
19 |
/**
|
20 |
* Delimiter for multiple filters
|
app/code/community/Catalin/SEO/Model/Catalog/Layer.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) 2013 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 extends Mage_Catalog_Model_Layer
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get collection of all filterable attributes for layer products set
|
22 |
+
*
|
23 |
+
* @return Mage_Catalog_Model_Resource_Eav_Mysql4_Attribute_Collection
|
24 |
+
*/
|
25 |
+
public function getFilterableAttributes()
|
26 |
+
{
|
27 |
+
$collection = parent::getFilterableAttributes();
|
28 |
+
|
29 |
+
// Load them at once - one query at once not multiple
|
30 |
+
$attrUrlKeyModel = Mage::getResourceModel('catalin_seo/attribute_urlkey');
|
31 |
+
$attrUrlKeyModel->preloadAttributesOptions($collection);
|
32 |
+
|
33 |
+
return $collection;
|
34 |
+
}
|
35 |
+
|
36 |
+
}
|
app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Attribute.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
@@ -49,9 +49,12 @@ class Catalin_SEO_Model_Catalog_Layer_Filter_Attribute extends Mage_Catalog_Mode
|
|
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->
|
|
|
|
|
55 |
// process all items if multiple choice is enabled
|
56 |
if (!Mage::helper('catalin_seo')->isMultipleChoiceFiltersEnabled()) {
|
57 |
$this->_items = array();
|
@@ -80,6 +83,7 @@ class Catalin_SEO_Model_Catalog_Layer_Filter_Attribute extends Mage_Catalog_Mode
|
|
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();
|
@@ -93,14 +97,14 @@ class Catalin_SEO_Model_Catalog_Layer_Filter_Attribute extends Mage_Catalog_Mode
|
|
93 |
if (!empty($optionsCount[$option['value']])) {
|
94 |
$data[] = array(
|
95 |
'label' => $option['label'],
|
96 |
-
'value' => $option['
|
97 |
'count' => $optionsCount[$option['value']],
|
98 |
);
|
99 |
}
|
100 |
} else {
|
101 |
$data[] = array(
|
102 |
'label' => $option['label'],
|
103 |
-
'value' => $option['
|
104 |
'count' => isset($optionsCount[$option['value']]) ? $optionsCount[$option['value']] : 0,
|
105 |
);
|
106 |
}
|
@@ -114,6 +118,7 @@ class Catalin_SEO_Model_Catalog_Layer_Filter_Attribute extends Mage_Catalog_Mode
|
|
114 |
$tags = $this->getLayer()->getStateTags($tags);
|
115 |
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
|
116 |
}
|
|
|
117 |
return $data;
|
118 |
}
|
119 |
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
49 |
$this->_values = explode(Catalin_SEO_Helper_Data::MULTIPLE_FILTERS_DELIMITER, $filter);
|
50 |
|
51 |
if (!empty($this->_values)) {
|
52 |
+
$attrUrlKeyModel = Mage::getResourceModel('catalin_seo/attribute_urlkey');
|
53 |
$this->_getResource()->applyFilterToCollection($this, $this->_values);
|
54 |
foreach ($this->_values as $filter) {
|
55 |
+
$optionId = $attrUrlKeyModel->getOptionId($this->getAttributeModel()->getId(), $filter);
|
56 |
+
$text = $this->_getOptionText($optionId);
|
57 |
+
$this->getLayer()->getState()->addFilter($this->_createItem($text, $filter));
|
58 |
// process all items if multiple choice is enabled
|
59 |
if (!Mage::helper('catalin_seo')->isMultipleChoiceFiltersEnabled()) {
|
60 |
$this->_items = array();
|
83 |
$data = $this->getLayer()->getAggregator()->getCacheData($key);
|
84 |
|
85 |
if ($data === null) {
|
86 |
+
$attrUrlKeyModel = Mage::getResourceModel('catalin_seo/attribute_urlkey');
|
87 |
$options = $attribute->getFrontend()->getSelectOptions();
|
88 |
$optionsCount = $this->_getResource()->getCount($this);
|
89 |
$data = array();
|
97 |
if (!empty($optionsCount[$option['value']])) {
|
98 |
$data[] = array(
|
99 |
'label' => $option['label'],
|
100 |
+
'value' => $attrUrlKeyModel->getUrlKey($attribute->getId(), $option['value']),
|
101 |
'count' => $optionsCount[$option['value']],
|
102 |
);
|
103 |
}
|
104 |
} else {
|
105 |
$data[] = array(
|
106 |
'label' => $option['label'],
|
107 |
+
'value' => $attrUrlKeyModel->getUrlKey($attribute->getId(), $option['value']),
|
108 |
'count' => isset($optionsCount[$option['value']]) ? $optionsCount[$option['value']] : 0,
|
109 |
);
|
110 |
}
|
118 |
$tags = $this->getLayer()->getStateTags($tags);
|
119 |
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
|
120 |
}
|
121 |
+
|
122 |
return $data;
|
123 |
}
|
124 |
|
app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Category.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Model/Catalog/Layer/Filter/Item.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
@@ -41,6 +41,8 @@ class Catalin_SEO_Model_Catalog_Layer_Filter_Item extends Mage_Catalog_Model_Lay
|
|
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();
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
41 |
$values = $this->getFilter()->getValues();
|
42 |
if (!empty($values)) {
|
43 |
$tmp = array_merge($values, array($this->getValue()));
|
44 |
+
// Sort filters - small SEO improvement
|
45 |
+
asort($tmp);
|
46 |
$values = implode(Catalin_SEO_Helper_Data::MULTIPLE_FILTERS_DELIMITER, $tmp);
|
47 |
} else {
|
48 |
$values = $this->getValue();
|
app/code/community/Catalin/SEO/Model/Catalog/Resource/Layer/Filter/Attribute.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
@@ -40,7 +40,8 @@ class Catalin_SEO_Model_Catalog_Resource_Layer_Filter_Attribute extends Mage_Cat
|
|
40 |
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId()),
|
41 |
);
|
42 |
|
43 |
-
$
|
|
|
44 |
if (!is_array($value)) {
|
45 |
foreach ($options as $option) {
|
46 |
if ($option['label'] == $value) {
|
@@ -51,11 +52,7 @@ class Catalin_SEO_Model_Catalog_Resource_Layer_Filter_Attribute extends Mage_Cat
|
|
51 |
} else {
|
52 |
$conditions[] = "{$tableAlias}.value in ( ";
|
53 |
foreach ($value as $v) {
|
54 |
-
|
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], ',');
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
40 |
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId()),
|
41 |
);
|
42 |
|
43 |
+
$attrUrlKeyModel = Mage::getResourceModel('catalin_seo/attribute_urlkey');
|
44 |
+
//$options = $attribute->getSource()->getAllOptions(false);
|
45 |
if (!is_array($value)) {
|
46 |
foreach ($options as $option) {
|
47 |
if ($option['label'] == $value) {
|
52 |
} else {
|
53 |
$conditions[] = "{$tableAlias}.value in ( ";
|
54 |
foreach ($value as $v) {
|
55 |
+
$v = $attrUrlKeyModel->getOptionId($attribute->getId(), $v);
|
|
|
|
|
|
|
|
|
56 |
$conditions[count($conditions) - 1] .= $connection->quoteInto("?", $v) . ' ,';
|
57 |
}
|
58 |
$conditions[count($conditions) - 1] = rtrim($conditions[count($conditions) - 1], ',');
|
app/code/community/Catalin/SEO/Model/CatalogSearch/Layer.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) 2013 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 extends Catalin_SEO_Model_Catalog_Layer
|
18 |
+
{
|
19 |
+
|
20 |
+
const XML_PATH_DISPLAY_LAYER_COUNT = 'catalog/search/use_layered_navigation_count';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Get current layer product collection
|
24 |
+
*
|
25 |
+
* @return Mage_Catalog_Model_Resource_Eav_Resource_Product_Collection
|
26 |
+
*/
|
27 |
+
public function getProductCollection()
|
28 |
+
{
|
29 |
+
if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
|
30 |
+
$collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
|
31 |
+
} else {
|
32 |
+
$collection = Mage::getResourceModel('catalogsearch/fulltext_collection');
|
33 |
+
$this->prepareProductCollection($collection);
|
34 |
+
$this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
|
35 |
+
}
|
36 |
+
return $collection;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Prepare product collection
|
41 |
+
*
|
42 |
+
* @param Mage_Catalog_Model_Resource_Eav_Resource_Product_Collection $collection
|
43 |
+
* @return Mage_Catalog_Model_Layer
|
44 |
+
*/
|
45 |
+
public function prepareProductCollection($collection)
|
46 |
+
{
|
47 |
+
$collection
|
48 |
+
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
|
49 |
+
->addSearchFilter(Mage::helper('catalogsearch')->getQuery()->getQueryText())
|
50 |
+
->setStore(Mage::app()->getStore())
|
51 |
+
->addMinimalPrice()
|
52 |
+
->addFinalPrice()
|
53 |
+
->addTaxPercents()
|
54 |
+
->addStoreFilter()
|
55 |
+
->addUrlRewrite();
|
56 |
+
|
57 |
+
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
|
58 |
+
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($collection);
|
59 |
+
|
60 |
+
return $this;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Get layer state key
|
65 |
+
*
|
66 |
+
* @return string
|
67 |
+
*/
|
68 |
+
public function getStateKey()
|
69 |
+
{
|
70 |
+
if ($this->_stateKey === null) {
|
71 |
+
$this->_stateKey = 'Q_' . Mage::helper('catalogsearch')->getQuery()->getId()
|
72 |
+
. '_' . parent::getStateKey();
|
73 |
+
}
|
74 |
+
return $this->_stateKey;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Get default tags for current layer state
|
79 |
+
*
|
80 |
+
* @param array $additionalTags
|
81 |
+
* @return array
|
82 |
+
*/
|
83 |
+
public function getStateTags(array $additionalTags = array())
|
84 |
+
{
|
85 |
+
$additionalTags = parent::getStateTags($additionalTags);
|
86 |
+
$additionalTags[] = Mage_CatalogSearch_Model_Query::CACHE_TAG;
|
87 |
+
return $additionalTags;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Add filters to attribute collection
|
92 |
+
*
|
93 |
+
* @param Mage_Catalog_Model_Resource_Eav_Resource_Product_Attribute_Collection $collection
|
94 |
+
* @return Mage_Catalog_Model_Resource_Eav_Resource_Product_Attribute_Collection
|
95 |
+
*/
|
96 |
+
protected function _prepareAttributeCollection($collection)
|
97 |
+
{
|
98 |
+
$collection->addIsFilterableInSearchFilter()
|
99 |
+
->addVisibleFilter();
|
100 |
+
return $collection;
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Prepare attribute for use in layered navigation
|
105 |
+
*
|
106 |
+
* @param Mage_Eav_Model_Entity_Attribute $attribute
|
107 |
+
* @return Mage_Eav_Model_Entity_Attribute
|
108 |
+
*/
|
109 |
+
protected function _prepareAttribute($attribute)
|
110 |
+
{
|
111 |
+
$attribute = parent::_prepareAttribute($attribute);
|
112 |
+
$attribute->setIsFilterable(Mage_Catalog_Model_Layer_Filter_Attribute::OPTIONS_ONLY_WITH_RESULTS);
|
113 |
+
return $attribute;
|
114 |
+
}
|
115 |
+
|
116 |
+
}
|
app/code/community/Catalin/SEO/Model/CatalogSearch/Layer/Filter/Attribute.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Model/Indexer/Attribute.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) 2013 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_Indexer_Attribute extends Mage_Index_Model_Indexer_Abstract
|
18 |
+
{
|
19 |
+
|
20 |
+
protected $_matchedEntities = array(
|
21 |
+
Mage_Catalog_Model_Resource_Eav_Attribute::ENTITY => array(
|
22 |
+
Mage_Index_Model_Event::TYPE_SAVE,
|
23 |
+
),
|
24 |
+
);
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Initialize model
|
28 |
+
*
|
29 |
+
*/
|
30 |
+
protected function _construct()
|
31 |
+
{
|
32 |
+
$this->_init('catalin_seo/indexer_attribute');
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Process event based on event state data
|
37 |
+
*
|
38 |
+
* @param Mage_Index_Model_Event $event
|
39 |
+
*/
|
40 |
+
protected function _processEvent(Mage_Index_Model_Event $event)
|
41 |
+
{
|
42 |
+
$this->callEventHandler($event);
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Register indexer required data inside event object
|
47 |
+
*
|
48 |
+
* @param Mage_Index_Model_Event $event
|
49 |
+
*/
|
50 |
+
protected function _registerEvent(Mage_Index_Model_Event $event)
|
51 |
+
{
|
52 |
+
return $this;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Get Indexer name
|
57 |
+
*
|
58 |
+
* @return string
|
59 |
+
*/
|
60 |
+
public function getName()
|
61 |
+
{
|
62 |
+
return Mage::helper('catalin_seo')->__('Catalin SEO');
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Get Indexer description
|
67 |
+
*
|
68 |
+
* @return string
|
69 |
+
*/
|
70 |
+
public function getDescription()
|
71 |
+
{
|
72 |
+
return Mage::helper('catalin_seo')->__('Index attribute options for layered navigation filters');
|
73 |
+
}
|
74 |
+
|
75 |
+
}
|
app/code/community/Catalin/SEO/Model/Resource/Attribute/Urlkey.php
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) 2013 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_Resource_Attribute_Urlkey extends Mage_Core_Model_Resource_Db_Abstract
|
18 |
+
{
|
19 |
+
|
20 |
+
protected static $_cachedResults;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Initialize resource model
|
24 |
+
*
|
25 |
+
*/
|
26 |
+
protected function _construct()
|
27 |
+
{
|
28 |
+
$this->_init('catalin_seo/attribute_url_key', 'id');
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Retrieve urk_key for specific option
|
33 |
+
*
|
34 |
+
* @param int $attributeId
|
35 |
+
* @param int $optionId
|
36 |
+
* @param int $storeId
|
37 |
+
* @return int|string
|
38 |
+
*/
|
39 |
+
public function getUrlKey($attributeId, $optionId, $storeId = null)
|
40 |
+
{
|
41 |
+
foreach ($this->_getOptions($attributeId, $storeId) as $result) {
|
42 |
+
if ($result['option_id'] == $optionId) {
|
43 |
+
return $result['url_key'];
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
return $optionId;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Retrieve option_id for specific url_key
|
52 |
+
*
|
53 |
+
* @param int $attributeId
|
54 |
+
* @param string $urlKey
|
55 |
+
* @param int $storeId
|
56 |
+
* @return int|string
|
57 |
+
*/
|
58 |
+
public function getOptionId($attributeId, $urlKey, $storeId = null)
|
59 |
+
{
|
60 |
+
foreach ($this->_getOptions($attributeId, $storeId) as $result) {
|
61 |
+
if ($result['url_key'] == $urlKey) {
|
62 |
+
return $result['option_id'];
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
return $urlKey;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Retrieve options url keys for specific attribute
|
71 |
+
* Use this as it caches for each attribute all possible values
|
72 |
+
*
|
73 |
+
* @todo Implement a method to detect all available filters and
|
74 |
+
* the ones used so we can do just one query - Ideal case
|
75 |
+
*
|
76 |
+
* @param int $attributeId
|
77 |
+
* @param int $storeId
|
78 |
+
* @return array
|
79 |
+
*/
|
80 |
+
protected function _getOptions($attributeId, $storeId)
|
81 |
+
{
|
82 |
+
if ($storeId === null) {
|
83 |
+
$storeId = Mage::app()->getStore()->getId();
|
84 |
+
}
|
85 |
+
|
86 |
+
if (!isset(self::$_cachedResults[$attributeId][$storeId])) {
|
87 |
+
$readAdapter = $this->_getReadAdapter();
|
88 |
+
$select = $readAdapter->select()
|
89 |
+
->from($this->getMainTable())
|
90 |
+
->where('`store_id` = ?', $storeId)
|
91 |
+
->where("`attribute_id` = ?", $attributeId);
|
92 |
+
$data = $readAdapter->fetchAll($select);
|
93 |
+
|
94 |
+
self::$_cachedResults[$attributeId][$storeId] = $data;
|
95 |
+
}
|
96 |
+
|
97 |
+
return self::$_cachedResults[$attributeId][$storeId];
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Load attributes options from the database
|
102 |
+
*
|
103 |
+
* @param Mage_Catalog_Model_Resource_Product_Attribute_Collection $collection
|
104 |
+
* @return Catalin_SEO_Model_Resource_Attribute_Urlkey
|
105 |
+
*/
|
106 |
+
public function preloadAttributesOptions(Mage_Catalog_Model_Resource_Product_Attribute_Collection $collection, $storeId = null)
|
107 |
+
{
|
108 |
+
if ($storeId === null) {
|
109 |
+
$storeId = Mage::app()->getStore()->getId();
|
110 |
+
}
|
111 |
+
|
112 |
+
$attributesIds = array();
|
113 |
+
foreach ($collection as $attribute) {
|
114 |
+
$attributesIds[] = $attribute->getId();
|
115 |
+
}
|
116 |
+
|
117 |
+
$readAdapter = $this->_getReadAdapter();
|
118 |
+
$select = $readAdapter->select()
|
119 |
+
->from($this->getMainTable())
|
120 |
+
->where('`store_id` = ?', $storeId)
|
121 |
+
->where('`attribute_id` IN (?)', array('in' => $attributesIds));
|
122 |
+
|
123 |
+
$data = $readAdapter->fetchAll($select);
|
124 |
+
foreach ($data as $attr) {
|
125 |
+
self::$_cachedResults[$attr['attribute_id']][$attr['store_id']][] = $attr;
|
126 |
+
}
|
127 |
+
|
128 |
+
// Fill with empty array for the attributes ids that have no values in database
|
129 |
+
// Prevents from doing suplimentary querys
|
130 |
+
foreach ($attributesIds as $attributeId) {
|
131 |
+
if (!isset(self::$_cachedResults[$attributeId][$storeId])) {
|
132 |
+
self::$_cachedResults[$attributeId][$storeId] = array();
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
return $this;
|
137 |
+
}
|
138 |
+
|
139 |
+
}
|
app/code/community/Catalin/SEO/Model/Resource/Indexer/Attribute.php
ADDED
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) 2013 Catalin Ciobanu
|
15 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
16 |
+
*/
|
17 |
+
class Catalin_SEO_Model_Resource_Indexer_Attribute extends Mage_Index_Model_Resource_Abstract
|
18 |
+
{
|
19 |
+
|
20 |
+
protected $_storesIds;
|
21 |
+
protected $_helper;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Initialize resource model
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
protected function _construct()
|
28 |
+
{
|
29 |
+
$this->_init('catalin_seo/attribute_url_key', 'id');
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Reindex all
|
34 |
+
*
|
35 |
+
* @return Catalin_SEO_Model_Resource_Indexer_Attribute
|
36 |
+
*/
|
37 |
+
public function reindexAll()
|
38 |
+
{
|
39 |
+
$this->reindexSeoUrlKeys();
|
40 |
+
return $this;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Generate SEO values for catalog product attributes options
|
45 |
+
*
|
46 |
+
* @param int $attributeId - transmit this to limit processing to one specific attribute
|
47 |
+
* @return Catalin_SEO_Model_Resource_Indexer_Attribute
|
48 |
+
*/
|
49 |
+
public function reindexSeoUrlKeys($attributeId = null)
|
50 |
+
{
|
51 |
+
$attributes = $this->_getAttributes($attributeId);
|
52 |
+
$stores = $this->_getAllStoresIds();
|
53 |
+
|
54 |
+
$data = array();
|
55 |
+
foreach ($attributes as $attribute) {
|
56 |
+
if ($attribute->usesSource()) {
|
57 |
+
foreach ($stores as $storeId) {
|
58 |
+
$result = $this->_getInsertValues($attribute, $storeId);
|
59 |
+
$data = array_merge($data, $result);
|
60 |
+
}
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
if (!empty($attributeId)) {
|
65 |
+
$this->_saveData($data, array("`attribute_id` = ?" => $attributeId));
|
66 |
+
} else {
|
67 |
+
$this->_saveData($data);
|
68 |
+
}
|
69 |
+
|
70 |
+
return $this;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Save data into database
|
75 |
+
*
|
76 |
+
* @param array $data
|
77 |
+
* @param array $deleteWhere
|
78 |
+
*/
|
79 |
+
protected function _saveData(array $data, array $deleteWhere = array())
|
80 |
+
{
|
81 |
+
// Continue only if we have something to insert
|
82 |
+
if (empty($data)) {
|
83 |
+
return $this;
|
84 |
+
}
|
85 |
+
|
86 |
+
// Do it in one transaction
|
87 |
+
$this->beginTransaction();
|
88 |
+
|
89 |
+
try {
|
90 |
+
$writeAdapter = $this->_getWriteAdapter();
|
91 |
+
$writeAdapter->delete($this->getMainTable(), $deleteWhere);
|
92 |
+
$writeAdapter->insertMultiple($this->getMainTable(), $data);
|
93 |
+
|
94 |
+
$this->commit();
|
95 |
+
} catch (Exception $e) {
|
96 |
+
$this->rollBack();
|
97 |
+
throw $e;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Retrieve product attributes with frontend input type 'select' and 'multiselect'
|
103 |
+
*
|
104 |
+
* @return Mage_Eav_Model_Resource_Entity_Attribute_Collection
|
105 |
+
*/
|
106 |
+
protected function _getAttributes($attributeId = null)
|
107 |
+
{
|
108 |
+
$collection = Mage::getSingleton('eav/config')
|
109 |
+
->getEntityType(Mage_Catalog_Model_Product::ENTITY)
|
110 |
+
->getAttributeCollection()
|
111 |
+
->addFieldToFilter('`main_table`.`frontend_input`', array('in' => array('select', 'multiselect')));
|
112 |
+
//->addSetInfo();
|
113 |
+
if (!empty($attributeId)) {
|
114 |
+
$collection->addFieldToFilter('`main_table`.`attribute_id`', $attributeId);
|
115 |
+
}
|
116 |
+
|
117 |
+
return $collection;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Retrieve data to be insterted after processing attribute
|
122 |
+
*
|
123 |
+
* @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
|
124 |
+
* @param int $storeId
|
125 |
+
* @return array
|
126 |
+
*/
|
127 |
+
protected function _getInsertValues($attribute, $storeId)
|
128 |
+
{
|
129 |
+
|
130 |
+
$collection = Mage::getResourceModel('eav/entity_attribute_option_collection')
|
131 |
+
->setStoreFilter($storeId)
|
132 |
+
->setPositionOrder('asc')
|
133 |
+
->setAttributeFilter($attribute->getId())
|
134 |
+
->load();
|
135 |
+
$options = $collection->toOptionArray();
|
136 |
+
|
137 |
+
$data = array();
|
138 |
+
foreach ($options as $option) {
|
139 |
+
// Replace accents and remove all non-aplhanumerical characters
|
140 |
+
$urlKey = $this->_getHelper()->removeAccents($option['label']);
|
141 |
+
$urlKey = strtolower($urlKey);
|
142 |
+
$urlKey = preg_replace('/([^a-zA-Z0-9])/', '-', $urlKey);
|
143 |
+
$urlKey = preg_replace('/([-]{2,})/', '-', $urlKey);
|
144 |
+
$urlKey = trim($urlKey, '-');
|
145 |
+
|
146 |
+
$data[] = array(
|
147 |
+
'attribute_code' => $attribute->getAttributeCode(),
|
148 |
+
'attribute_id' => $attribute->getId(),
|
149 |
+
'store_id' => $storeId,
|
150 |
+
'option_id' => $option['value'],
|
151 |
+
'url_key' => $urlKey
|
152 |
+
);
|
153 |
+
}
|
154 |
+
|
155 |
+
return $data;
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Retrieve all stores ids
|
160 |
+
*
|
161 |
+
* @return array
|
162 |
+
*/
|
163 |
+
protected function _getAllStoresIds()
|
164 |
+
{
|
165 |
+
if ($this->_storesIds === null) {
|
166 |
+
$this->_storesIds = array();
|
167 |
+
$stores = Mage::app()->getStores();
|
168 |
+
foreach ($stores as $storeId => $store) {
|
169 |
+
$this->_storesIds[] = $storeId;
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
return $this->_storesIds;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Retrieve helper object
|
178 |
+
*
|
179 |
+
* @return Catalin_SEO_Helper_Data
|
180 |
+
*/
|
181 |
+
protected function _getHelper()
|
182 |
+
{
|
183 |
+
if ($this->_helper === null) {
|
184 |
+
$this->_helper = Mage::helper('catalin_seo');
|
185 |
+
}
|
186 |
+
|
187 |
+
return $this->_helper;
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Reindex attribute options on attribute save event
|
192 |
+
*
|
193 |
+
* @param Mage_Index_Model_Event $event
|
194 |
+
* @return Catalin_SEO_Model_Resource_Indexer_Attribute
|
195 |
+
*/
|
196 |
+
public function catalogEavAttributeSave(Mage_Index_Model_Event $event)
|
197 |
+
{
|
198 |
+
$attribute = $event->getDataObject();
|
199 |
+
$this->reindexSeoUrlKeys($attribute->getId());
|
200 |
+
|
201 |
+
return $this;
|
202 |
+
}
|
203 |
+
|
204 |
+
}
|
app/code/community/Catalin/SEO/Model/System/Config/Backend/Seo/Catalog.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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
|
app/code/community/Catalin/SEO/Model/System/Config/Source/Slider/Submit/Type.php
CHANGED
@@ -1,5 +1,19 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
class Catalin_SEO_Model_System_Config_Source_Slider_Submit_Type
|
4 |
{
|
5 |
|
@@ -22,8 +36,8 @@ class Catalin_SEO_Model_System_Config_Source_Slider_Submit_Type
|
|
22 |
self::SUBMIT_BUTTON => $helper->__('Submit button')
|
23 |
);
|
24 |
}
|
25 |
-
|
26 |
-
return
|
27 |
}
|
28 |
|
29 |
}
|
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) 2013 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_Source_Slider_Submit_Type
|
18 |
{
|
19 |
|
36 |
self::SUBMIT_BUTTON => $helper->__('Submit button')
|
37 |
);
|
38 |
}
|
39 |
+
|
40 |
+
return $this->_options;
|
41 |
}
|
42 |
|
43 |
}
|
app/code/community/Catalin/SEO/controllers/CategoryController.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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';
|
@@ -65,7 +65,7 @@ class Catalin_Seo_CategoryController extends Mage_Catalog_CategoryController
|
|
65 |
|
66 |
if (($root = $this->getLayout()->getBlock('root'))) {
|
67 |
$root->addBodyClass('categorypath-' . $category->getUrlPath())
|
68 |
-
|
69 |
}
|
70 |
|
71 |
$this->_initLayoutMessages('catalog/session');
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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';
|
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');
|
app/code/community/Catalin/SEO/controllers/ResultController.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
-
* @copyright Copyright (c)
|
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';
|
11 |
* http://opensource.org/licenses/osl-3.0.php
|
12 |
*
|
13 |
* @package Catalin_Seo
|
14 |
+
* @copyright Copyright (c) 2013 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';
|
app/code/community/Catalin/SEO/etc/config.xml
CHANGED
@@ -1,14 +1,15 @@
|
|
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>
|
@@ -16,6 +17,7 @@
|
|
16 |
</catalog>
|
17 |
<catalogsearch>
|
18 |
<rewrite>
|
|
|
19 |
<layer_filter_attribute>Catalin_SEO_Model_CatalogSearch_Layer_Filter_Attribute</layer_filter_attribute>
|
20 |
</rewrite>
|
21 |
</catalogsearch>
|
@@ -26,8 +28,24 @@
|
|
26 |
</catalog_resource>
|
27 |
<catalin_seo>
|
28 |
<class>Catalin_SEO_Model</class>
|
|
|
29 |
</catalin_seo>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
</models>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
<blocks>
|
32 |
<catalog>
|
33 |
<rewrite>
|
@@ -61,6 +79,13 @@
|
|
61 |
</observers>
|
62 |
</controller_front_init_routers>
|
63 |
</events>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
</global>
|
65 |
<frontend>
|
66 |
<routers>
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
3 |
+
<modules>
|
4 |
+
<Catalin_SEO>
|
5 |
+
<version>2.0.0</version>
|
6 |
+
</Catalin_SEO>
|
7 |
+
</modules>
|
8 |
<global>
|
|
|
|
|
|
|
|
|
|
|
9 |
<models>
|
10 |
<catalog>
|
11 |
<rewrite>
|
12 |
+
<layer>Catalin_SEO_Model_Catalog_Layer</layer>
|
13 |
<layer_filter_item>Catalin_SEO_Model_Catalog_Layer_Filter_Item</layer_filter_item>
|
14 |
<layer_filter_category>Catalin_SEO_Model_Catalog_Layer_Filter_Category</layer_filter_category>
|
15 |
<layer_filter_attribute>Catalin_SEO_Model_Catalog_Layer_Filter_Attribute</layer_filter_attribute>
|
17 |
</catalog>
|
18 |
<catalogsearch>
|
19 |
<rewrite>
|
20 |
+
<layer>Catalin_SEO_Model_CatalogSearch_Layer</layer>
|
21 |
<layer_filter_attribute>Catalin_SEO_Model_CatalogSearch_Layer_Filter_Attribute</layer_filter_attribute>
|
22 |
</rewrite>
|
23 |
</catalogsearch>
|
28 |
</catalog_resource>
|
29 |
<catalin_seo>
|
30 |
<class>Catalin_SEO_Model</class>
|
31 |
+
<resourceModel>catalin_seo_resource</resourceModel>
|
32 |
</catalin_seo>
|
33 |
+
<catalin_seo_resource>
|
34 |
+
<class>Catalin_SEO_Model_Resource</class>
|
35 |
+
<entities>
|
36 |
+
<attribute_url_key>
|
37 |
+
<table>catalin_seo_attribute_url_key</table>
|
38 |
+
</attribute_url_key>
|
39 |
+
</entities>
|
40 |
+
</catalin_seo_resource>
|
41 |
</models>
|
42 |
+
<resources>
|
43 |
+
<catalin_seo_setup>
|
44 |
+
<setup>
|
45 |
+
<module>Catalin_SEO</module>
|
46 |
+
</setup>
|
47 |
+
</catalin_seo_setup>
|
48 |
+
</resources>
|
49 |
<blocks>
|
50 |
<catalog>
|
51 |
<rewrite>
|
79 |
</observers>
|
80 |
</controller_front_init_routers>
|
81 |
</events>
|
82 |
+
<index>
|
83 |
+
<indexer>
|
84 |
+
<catalin_seo_attribute>
|
85 |
+
<model>catalin_seo/indexer_attribute</model>
|
86 |
+
</catalin_seo_attribute>
|
87 |
+
</indexer>
|
88 |
+
</index>
|
89 |
</global>
|
90 |
<frontend>
|
91 |
<routers>
|
app/code/community/Catalin/SEO/sql/catalin_seo_setup/install-2.0.0.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
4 |
+
$installer = $this;
|
5 |
+
|
6 |
+
$installer->startSetup();
|
7 |
+
|
8 |
+
$tableName = $installer->getTable('catalin_seo/attribute_url_key');
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Drop table - needed for reinstall to work
|
12 |
+
*/
|
13 |
+
$installer->getConnection()->dropTable($tableName);
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Create table 'catalin_seo/attribute_url_key'
|
17 |
+
*/
|
18 |
+
$table = $installer->getConnection()
|
19 |
+
->newTable($tableName)
|
20 |
+
->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
21 |
+
'unsigned' => true,
|
22 |
+
'nullable' => false,
|
23 |
+
'primary' => true,
|
24 |
+
'auto_increment' => true,
|
25 |
+
), 'Id')
|
26 |
+
->addColumn('attribute_code', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array(
|
27 |
+
), 'Attribute Code')
|
28 |
+
->addColumn('attribute_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
29 |
+
'unsigned' => true,
|
30 |
+
), 'Attribute Id')
|
31 |
+
->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
32 |
+
'unsigned' => true,
|
33 |
+
), 'Store Id')
|
34 |
+
->addColumn('option_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
35 |
+
'unsigned' => true,
|
36 |
+
), 'Option Id')
|
37 |
+
->addColumn('url_key', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array(
|
38 |
+
), 'Url Key')
|
39 |
+
->setComment('Tag');
|
40 |
+
$installer->getConnection()->createTable($table);
|
41 |
+
|
42 |
+
$installer->endSetup();
|
package.xml
CHANGED
@@ -1,183 +1,27 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Catalin_Seo</name>
|
4 |
-
<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
|
10 |
-
<description><
|
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>
|
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 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
</
|
25 |
-
<
|
26 |
-
<authors>
|
27 |
-
<author>
|
28 |
-
<name>Catalin Ciobanu</name>
|
29 |
-
<user>catalin_ciobanu</user>
|
30 |
-
<email>ciobanu.catalin@yahoo.com</email>
|
31 |
-
</author>
|
32 |
-
</authors>
|
33 |
-
<date>2012-12-14</date>
|
34 |
-
<time>18:31:03</time>
|
35 |
-
<contents>
|
36 |
-
<target name="magecommunity">
|
37 |
-
<dir name="Catalin">
|
38 |
-
<dir name="SEO">
|
39 |
-
<dir name="Block">
|
40 |
-
<dir name="Catalog">
|
41 |
-
<dir name="Layer">
|
42 |
-
<dir name="Filter">
|
43 |
-
<file name="Attribute.php" hash="b0fb7deaeec0d46bc170e510c3d6f73a"/>
|
44 |
-
<file name="Price.php" hash="73fe2b9d21dab816474ee8d662a530bd"/>
|
45 |
-
</dir>
|
46 |
-
<file name="State.php" hash="fece6cd5534ae48f0f9f9233a7f714af"/>
|
47 |
-
</dir>
|
48 |
-
<dir name="Product">
|
49 |
-
<dir name="List">
|
50 |
-
<file name="Pager.php" hash="5f41fc06bddb70fc2f7de3792c933879"/>
|
51 |
-
<file name="Toolbar.php" hash="6db34892e1937dd1e527c8ac2fda4746"/>
|
52 |
-
</dir>
|
53 |
-
</dir>
|
54 |
-
</dir>
|
55 |
-
<dir name="CatalogSearch">
|
56 |
-
<dir name="Layer">
|
57 |
-
<dir name="Filter">
|
58 |
-
<file name="Attribute.php" hash="120da8cc984bf1d55428ee4cfeaedca5"/>
|
59 |
-
</dir>
|
60 |
-
</dir>
|
61 |
-
</dir>
|
62 |
-
</dir>
|
63 |
-
<dir name="Controller">
|
64 |
-
<file name="Router.php" hash="71c67346a0c3e89775e5d7762c8a3588"/>
|
65 |
-
</dir>
|
66 |
-
<dir name="Helper">
|
67 |
-
<file name="Data.php" hash="47a5e37ea96a12615ad1818f919d634f"/>
|
68 |
-
</dir>
|
69 |
-
<dir name="Model">
|
70 |
-
<dir name="Catalog">
|
71 |
-
<dir name="Layer">
|
72 |
-
<dir name="Filter">
|
73 |
-
<file name="Attribute.php" hash="cd5ef92601544ed236617881b0dd6352"/>
|
74 |
-
<file name="Category.php" hash="bc5df542ef28c4e7a9583ae441c550c8"/>
|
75 |
-
<file name="Item.php" hash="9d89a99bebad467ca14e50333c556649"/>
|
76 |
-
</dir>
|
77 |
-
</dir>
|
78 |
-
<dir name="Resource">
|
79 |
-
<dir name="Layer">
|
80 |
-
<dir name="Filter">
|
81 |
-
<file name="Attribute.php" hash="ab59cb798f1069786a98408f6ebaf948"/>
|
82 |
-
</dir>
|
83 |
-
</dir>
|
84 |
-
</dir>
|
85 |
-
</dir>
|
86 |
-
<dir name="CatalogSearch">
|
87 |
-
<dir name="Layer">
|
88 |
-
<dir name="Filter">
|
89 |
-
<file name="Attribute.php" hash="137c0b3795d3eea4da8442db3e05e7a0"/>
|
90 |
-
</dir>
|
91 |
-
</dir>
|
92 |
-
</dir>
|
93 |
-
<dir name="System">
|
94 |
-
<dir name="Config">
|
95 |
-
<dir name="Backend">
|
96 |
-
<dir name="Seo">
|
97 |
-
<file name="Catalog.php" hash="ea4cd41cf4e919935919585a22dfea29"/>
|
98 |
-
</dir>
|
99 |
-
</dir>
|
100 |
-
<dir name="Source">
|
101 |
-
<dir name="Slider">
|
102 |
-
<dir name="Submit">
|
103 |
-
<file name="Type.php" hash="6d656f04657b303f989022ee305e6b00"/>
|
104 |
-
</dir>
|
105 |
-
</dir>
|
106 |
-
</dir>
|
107 |
-
</dir>
|
108 |
-
</dir>
|
109 |
-
</dir>
|
110 |
-
<dir name="controllers">
|
111 |
-
<file name="CategoryController.php" hash="3f3404592e64ffc3d3e302a92e76dc06"/>
|
112 |
-
<file name="ResultController.php" hash="660c07990539e5605112cb42e24c02d6"/>
|
113 |
-
</dir>
|
114 |
-
<dir name="etc">
|
115 |
-
<file name="adminhtml.xml" hash="240f607b0156d1de84667b382ba3f73c"/>
|
116 |
-
<file name="config.xml" hash="9e2487e6c0eb5b09c43f65c01db3d882"/>
|
117 |
-
<file name="system.xml" hash="9fd01148901e15950868e312b96dbfde"/>
|
118 |
-
</dir>
|
119 |
-
</dir>
|
120 |
-
</dir>
|
121 |
-
</target>
|
122 |
-
<target name="mageskin">
|
123 |
-
<dir name="frontend">
|
124 |
-
<dir name="default">
|
125 |
-
<dir name="default">
|
126 |
-
<dir name="css">
|
127 |
-
<dir name="price_slider">
|
128 |
-
<file name="style.css" hash="61d0b59ed239bc64deaf4aed969652cd"/>
|
129 |
-
</dir>
|
130 |
-
</dir>
|
131 |
-
<dir name="images">
|
132 |
-
<dir name="price_slider">
|
133 |
-
<file name="bkg_slider.png" hash="1b7a1eb7add1d2b2002501f4602c3d3e"/>
|
134 |
-
<file name="slider.png" hash="d77b417b68ba91402c3b7180b165110c"/>
|
135 |
-
</dir>
|
136 |
-
</dir>
|
137 |
-
</dir>
|
138 |
-
</dir>
|
139 |
-
</dir>
|
140 |
-
</target>
|
141 |
-
<target name="mageetc">
|
142 |
-
<dir name="modules">
|
143 |
-
<file name="Catalin_SEO.xml" hash="e0ad01abfe976aefb6587fcfb3bf0d2b"/>
|
144 |
-
</dir>
|
145 |
-
</target>
|
146 |
-
<target name="magedesign">
|
147 |
-
<dir name="frontend">
|
148 |
-
<dir name="default">
|
149 |
-
<dir name="default">
|
150 |
-
<dir name="template">
|
151 |
-
<dir name="catalin_seo">
|
152 |
-
<dir>
|
153 |
-
<dir name="catalog">
|
154 |
-
<dir name="layer">
|
155 |
-
<file name="filter.phtml" hash="dd1d3278e691814f0cd242179e5bf53f"/>
|
156 |
-
<file name="price.phtml" hash="19f1583df9e7f14d81318c633b334a88"/>
|
157 |
-
<file name="view.phtml" hash="bc5f21109be4dab996b152e7a756fe03"/>
|
158 |
-
</dir>
|
159 |
-
<dir name="product">
|
160 |
-
<file name="list.phtml" hash="bd332a192ed36c56c00968e13b599cd3"/>
|
161 |
-
</dir>
|
162 |
-
</dir>
|
163 |
-
</dir>
|
164 |
-
</dir>
|
165 |
-
</dir>
|
166 |
-
<dir name="layout">
|
167 |
-
<file name="catalin_seo.xml" hash="61db4d9d696f2d12c562ae70a5164e4c"/>
|
168 |
-
</dir>
|
169 |
-
</dir>
|
170 |
-
</dir>
|
171 |
-
</dir>
|
172 |
-
</target>
|
173 |
-
</contents>
|
174 |
<compatible/>
|
175 |
-
<dependencies>
|
176 |
-
<required>
|
177 |
-
<php>
|
178 |
-
<min>5.2.0</min>
|
179 |
-
<max>6.0.0</max>
|
180 |
-
</php>
|
181 |
-
</required>
|
182 |
-
</dependencies>
|
183 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Catalin_Seo</name>
|
4 |
+
<version>2.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>Layered Navigation SEO: ajax, seo urls, price slider, multiple filters for the same attribute.</summary>
|
10 |
+
<description><p>ajax, seo urls, price slider, multiple selection for the same attribute.</p>
|
|
|
11 |
<h2>Features</h2>
|
12 |
<ul>
|
13 |
+
<li>ajax navigation using history pushState/popState (only for HTML5 browsers)</li>
|
14 |
+
<li>price slider with auto update or submit button</li>
|
15 |
<li>SEO URLs (http://www.example.com/apparel/shoes/list/color/Brown,Blue/shoe_type/Sandal.html)</li>
|
16 |
<li>multiple filters for the same attribute</li>
|
17 |
</ul>
|
18 |
+
<p>All the above features can be enabled/disabled from backend from "System -> Configuration -> Catalin SEO -> Catalog Layered Navigation"</p></description>
|
19 |
+
<notes>- Fixed the issue: in attribute values "," (comma) and "/" (slash) cannot be used.
|
20 |
+
- Disabled History for browsers HTML4 browsers.</notes>
|
21 |
+
<authors><author><name>Catalin Ciobanu</name><user>catalin_ciobanu</user><email>ciobanu.catalin@yahoo.com</email></author></authors>
|
22 |
+
<date>2013-01-26</date>
|
23 |
+
<time>13:46:10</time>
|
24 |
+
<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="decdc5633827964ff7aba28f8e8f89ff"/><file name="Price.php" hash="fb413c30cfd742818757beb88264fd68"/></dir><file name="State.php" hash="fd21c5a6603427ae81e7eddbef3d827f"/></dir><dir name="Product"><dir name="List"><file name="Pager.php" hash="7720a417475b5a512d383fd06242e43a"/><file name="Toolbar.php" hash="1624c89efb4f94ed1f35622c70fd3d9a"/></dir></dir></dir><dir name="CatalogSearch"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="008e737de084f5a400518bda4dda09f8"/></dir></dir></dir></dir><dir name="Controller"><file name="Router.php" hash="959ddeb429ee3ce85c5b8d9e24e01dc0"/></dir><dir name="Helper"><file name="Data.php" hash="fe35a0e29057133e6e9d2ca1a7dbddc6"/></dir><dir name="Model"><dir name="Catalog"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="17dde650381b5a65dd1c3fc6d942bb2a"/><file name="Category.php" hash="5a5b4213e521b0fd33cc7623435dd3aa"/><file name="Item.php" hash="293783ab05520a197ff02ad44bdd9ed6"/></dir></dir><file name="Layer.php" hash="32e0397c7eea8dacc421f3f2e1b5273a"/><dir name="Resource"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="7f235b63e342d77b18da3ffffd97de10"/></dir></dir></dir></dir><dir name="CatalogSearch"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="9dda0e593ace29efbba4c84b683d9377"/></dir></dir><file name="Layer.php" hash="3f980ee1a82354d0bd65edde410a2818"/></dir><dir name="Indexer"><file name="Attribute.php" hash="9d5bd74b9c9204c4aee3fd6f0478688b"/></dir><dir name="Resource"><dir name="Attribute"><file name="Urlkey.php" hash="485538d19fad7b7b5b647feb220e5c03"/></dir><dir name="Indexer"><file name="Attribute.php" hash="645ebc0fe5ee7a461c06d805a529b678"/></dir></dir><dir name="System"><dir name="Config"><dir name="Backend"><dir name="Seo"><file name="Catalog.php" hash="233ca11b938d6198b5a4400a2c5e1d61"/></dir></dir><dir name="Source"><dir name="Slider"><dir name="Submit"><file name="Type.php" hash="cb2383c3568982b09e4878735e598fca"/></dir></dir></dir></dir></dir></dir><dir name="controllers"><file name="CategoryController.php" hash="64cf21a1dfef461a2bf52c7a184192c8"/><file name="ResultController.php" hash="fdecd53c83673edf32e768737492aee4"/></dir><dir name="etc"><file name="adminhtml.xml" hash="240f607b0156d1de84667b382ba3f73c"/><file name="config.xml" hash="f492966665665d3594f5a84ace4b4abd"/><file name="system.xml" hash="92e698eebc986af7d98f9676138730cd"/></dir><dir name="sql"><dir name="catalin_seo_setup"><file name="install-2.0.0.php" hash="1f1e47269b9658b4a3f53cb17ba728e1"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="catalin_seo.xml" hash="17f80ca298cc0093ef29f69d02e8117b"/></dir><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="e853f8d1045abd7fa45051eb87fc1ba0"/><file name="view.phtml" hash="bc5f21109be4dab996b152e7a756fe03"/></dir><dir name="product"><file name="list.phtml" hash="9dd7e5ffd7a994a5036bf4eb378c8178"/></dir></dir></dir></dir></dir></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 name="js"><dir name="catalin_seo"><file name="native.history.js" hash="ee04bc106db73bdbe17a0eac44497df1"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Catalin_SEO.xml" hash="e0ad01abfe976aefb6587fcfb3bf0d2b"/></dir></target></contents>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
<compatible/>
|
26 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
</package>
|
skin/frontend/default/default/js/catalin_seo/native.history.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
window.JSON||(window.JSON={}),function(){function f(a){return a<10?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c<f;c+=1)h[c]=str(c,i)||"null";return e=h.length===0?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]",gap=g,e}if(rep&&typeof rep=="object"){f=rep.length;for(c=0;c<f;c+=1)d=rep[c],typeof d=="string"&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e))}else for(d in i)Object.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));return e=h.length===0?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}",gap=g,e}}"use strict",typeof Date.prototype.toJSON!="function"&&(Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()});var JSON=window.JSON,cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;typeof JSON.stringify!="function"&&(JSON.stringify=function(a,b,c){var d;gap="",indent="";if(typeof c=="number")for(d=0;d<c;d+=1)indent+=" ";else typeof c=="string"&&(indent=c);rep=b;if(!b||typeof b=="function"||typeof b=="object"&&typeof b.length=="number")return str("",{"":a});throw new Error("JSON.stringify")}),typeof JSON.parse!="function"&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&typeof e=="object")for(c in e)Object.hasOwnProperty.call(e,c)&&(d=walk(e,c),d!==undefined?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),typeof reviver=="function"?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(),function(a,b){"use strict";var c=a.History=a.History||{};if(typeof c.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");c.Adapter={handlers:{},_uid:1,uid:function(a){return a._uid||(a._uid=c.Adapter._uid++)},bind:function(a,b,d){var e=c.Adapter.uid(a);c.Adapter.handlers[e]=c.Adapter.handlers[e]||{},c.Adapter.handlers[e][b]=c.Adapter.handlers[e][b]||[],c.Adapter.handlers[e][b].push(d),a["on"+b]=function(a,b){return function(d){c.Adapter.trigger(a,b,d)}}(a,b)},trigger:function(a,b,d){d=d||{};var e=c.Adapter.uid(a),f,g;c.Adapter.handlers[e]=c.Adapter.handlers[e]||{},c.Adapter.handlers[e][b]=c.Adapter.handlers[e][b]||[];for(f=0,g=c.Adapter.handlers[e][b].length;f<g;++f)c.Adapter.handlers[e][b][f].apply(this,[d])},extractEventData:function(a,c){var d=c&&c[a]||b;return d},onDomLoad:function(b){var c=a.setTimeout(function(){b()},2e3);a.onload=function(){clearTimeout(c),b()}}},typeof c.init!="undefined"&&c.init()}(window),function(a,b){"use strict";var c=a.document,d=a.setTimeout||d,e=a.clearTimeout||e,f=a.setInterval||f,g=a.History=a.History||{};if(typeof g.initHtml4!="undefined")throw new Error("History.js HTML4 Support has already been loaded...");g.initHtml4=function(){if(typeof g.initHtml4.initialized!="undefined")return!1;g.initHtml4.initialized=!0,g.enabled=!0,g.savedHashes=[],g.isLastHash=function(a){var b=g.getHashByIndex(),c;return c=a===b,c},g.saveHash=function(a){return g.isLastHash(a)?!1:(g.savedHashes.push(a),!0)},g.getHashByIndex=function(a){var b=null;return typeof a=="undefined"?b=g.savedHashes[g.savedHashes.length-1]:a<0?b=g.savedHashes[g.savedHashes.length+a]:b=g.savedHashes[a],b},g.discardedHashes={},g.discardedStates={},g.discardState=function(a,b,c){var d=g.getHashByState(a),e;return e={discardedState:a,backState:c,forwardState:b},g.discardedStates[d]=e,!0},g.discardHash=function(a,b,c){var d={discardedHash:a,backState:c,forwardState:b};return g.discardedHashes[a]=d,!0},g.discardedState=function(a){var b=g.getHashByState(a),c;return c=g.discardedStates[b]||!1,c},g.discardedHash=function(a){var b=g.discardedHashes[a]||!1;return b},g.recycleState=function(a){var b=g.getHashByState(a);return g.discardedState(a)&&delete g.discardedStates[b],!0},g.emulated.hashChange&&(g.hashChangeInit=function(){g.checkerFunction=null;var b="",d,e,h,i;return g.isInternetExplorer()?(d="historyjs-iframe",e=c.createElement("iframe"),e.setAttribute("id",d),e.style.display="none",c.body.appendChild(e),e.contentWindow.document.open(),e.contentWindow.document.close(),h="",i=!1,g.checkerFunction=function(){if(i)return!1;i=!0;var c=g.getHash()||"",d=g.unescapeHash(e.contentWindow.document.location.hash)||"";return c!==b?(b=c,d!==c&&(h=d=c,e.contentWindow.document.open(),e.contentWindow.document.close(),e.contentWindow.document.location.hash=g.escapeHash(c)),g.Adapter.trigger(a,"hashchange")):d!==h&&(h=d,g.setHash(d,!1)),i=!1,!0}):g.checkerFunction=function(){var c=g.getHash();return c!==b&&(b=c,g.Adapter.trigger(a,"hashchange")),!0},g.intervalList.push(f(g.checkerFunction,g.options.hashChangeInterval)),!0},g.Adapter.onDomLoad(g.hashChangeInit)),g.emulated.pushState&&(g.onHashChange=function(b){var d=b&&b.newURL||c.location.href,e=g.getHashByUrl(d),f=null,h=null,i=null,j;return g.isLastHash(e)?(g.busy(!1),!1):(g.doubleCheckComplete(),g.saveHash(e),e&&g.isTraditionalAnchor(e)?(g.Adapter.trigger(a,"anchorchange"),g.busy(!1),!1):(f=g.extractState(g.getFullUrl(e||c.location.href,!1),!0),g.isLastSavedState(f)?(g.busy(!1),!1):(h=g.getHashByState(f),j=g.discardedState(f),j?(g.getHashByIndex(-2)===g.getHashByState(j.forwardState)?g.back(!1):g.forward(!1),!1):(g.pushState(f.data,f.title,f.url,!1),!0))))},g.Adapter.bind(a,"hashchange",g.onHashChange),g.pushState=function(b,d,e,f){if(g.getHashByUrl(e))throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==!1&&g.busy())return g.pushQueue({scope:g,callback:g.pushState,args:arguments,queue:f}),!1;g.busy(!0);var h=g.createStateObject(b,d,e),i=g.getHashByState(h),j=g.getState(!1),k=g.getHashByState(j),l=g.getHash();return g.storeState(h),g.expectedStateId=h.id,g.recycleState(h),g.setTitle(h),i===k?(g.busy(!1),!1):i!==l&&i!==g.getShortUrl(c.location.href)?(g.setHash(i,!1),!1):(g.saveState(h),g.Adapter.trigger(a,"statechange"),g.busy(!1),!0)},g.replaceState=function(a,b,c,d){if(g.getHashByUrl(c))throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(d!==!1&&g.busy())return g.pushQueue({scope:g,callback:g.replaceState,args:arguments,queue:d}),!1;g.busy(!0);var e=g.createStateObject(a,b,c),f=g.getState(!1),h=g.getStateByIndex(-2);return g.discardState(f,e,h),g.pushState(e.data,e.title,e.url,!1),!0}),g.emulated.pushState&&g.getHash()&&!g.emulated.hashChange&&g.Adapter.onDomLoad(function(){g.Adapter.trigger(a,"hashchange")})},typeof g.init!="undefined"&&g.init()}(window),function(a,b){"use strict";var c=a.console||b,d=a.document,e=a.navigator,f=a.sessionStorage||!1,g=a.setTimeout,h=a.clearTimeout,i=a.setInterval,j=a.clearInterval,k=a.JSON,l=a.alert,m=a.History=a.History||{},n=a.history;k.stringify=k.stringify||k.encode,k.parse=k.parse||k.decode;if(typeof m.init!="undefined")throw new Error("History.js Core has already been loaded...");m.init=function(){return typeof m.Adapter=="undefined"?!1:(typeof m.initCore!="undefined"&&m.initCore(),typeof m.initHtml4!="undefined"&&m.initHtml4(),!0)},m.initCore=function(){if(typeof m.initCore.initialized!="undefined")return!1;m.initCore.initialized=!0,m.options=m.options||{},m.options.hashChangeInterval=m.options.hashChangeInterval||100,m.options.safariPollInterval=m.options.safariPollInterval||500,m.options.doubleCheckInterval=m.options.doubleCheckInterval||500,m.options.storeInterval=m.options.storeInterval||1e3,m.options.busyDelay=m.options.busyDelay||250,m.options.debug=m.options.debug||!1,m.options.initialTitle=m.options.initialTitle||d.title,m.intervalList=[],m.clearAllIntervals=function(){var a,b=m.intervalList;if(typeof b!="undefined"&&b!==null){for(a=0;a<b.length;a++)j(b[a]);m.intervalList=null}},m.debug=function(){(m.options.debug||!1)&&m.log.apply(m,arguments)},m.log=function(){var a=typeof c!="undefined"&&typeof c.log!="undefined"&&typeof c.log.apply!="undefined",b=d.getElementById("log"),e,f,g,h,i;a?(h=Array.prototype.slice.call(arguments),e=h.shift(),typeof c.debug!="undefined"?c.debug.apply(c,[e,h]):c.log.apply(c,[e,h])):e="\n"+arguments[0]+"\n";for(f=1,g=arguments.length;f<g;++f){i=arguments[f];if(typeof i=="object"&&typeof k!="undefined")try{i=k.stringify(i)}catch(j){}e+="\n"+i+"\n"}return b?(b.value+=e+"\n-----\n",b.scrollTop=b.scrollHeight-b.clientHeight):a||l(e),!0},m.getInternetExplorerMajorVersion=function(){var a=m.getInternetExplorerMajorVersion.cached=typeof m.getInternetExplorerMajorVersion.cached!="undefined"?m.getInternetExplorerMajorVersion.cached:function(){var a=3,b=d.createElement("div"),c=b.getElementsByTagName("i");while((b.innerHTML="<!--[if gt IE "+ ++a+"]><i></i><![endif]-->")&&c[0]);return a>4?a:!1}();return a},m.isInternetExplorer=function(){var a=m.isInternetExplorer.cached=typeof m.isInternetExplorer.cached!="undefined"?m.isInternetExplorer.cached:Boolean(m.getInternetExplorerMajorVersion());return a},m.emulated={pushState:!Boolean(a.history&&a.history.pushState&&a.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)),hashChange:Boolean(!("onhashchange"in a||"onhashchange"in d)||m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8)},m.enabled=!m.emulated.pushState,m.bugs={setHash:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),safariPoll:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),ieDoubleCheck:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<7)},m.isEmptyObject=function(a){for(var b in a)return!1;return!0},m.cloneObject=function(a){var b,c;return a?(b=k.stringify(a),c=k.parse(b)):c={},c},m.getRootUrl=function(){var a=d.location.protocol+"//"+(d.location.hostname||d.location.host);if(d.location.port||!1)a+=":"+d.location.port;return a+="/",a},m.getBaseHref=function(){var a=d.getElementsByTagName("base"),b=null,c="";return a.length===1&&(b=a[0],c=b.href.replace(/[^\/]+$/,"")),c=c.replace(/\/+$/,""),c&&(c+="/"),c},m.getBaseUrl=function(){var a=m.getBaseHref()||m.getBasePageUrl()||m.getRootUrl();return a},m.getPageUrl=function(){var a=m.getState(!1,!1),b=(a||{}).url||d.location.href,c;return c=b.replace(/\/+$/,"").replace(/[^\/]+$/,function(a,b,c){return/\./.test(a)?a:a+"/"}),c},m.getBasePageUrl=function(){var a=d.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,function(a,b,c){return/[^\/]$/.test(a)?"":a}).replace(/\/+$/,"")+"/";return a},m.getFullUrl=function(a,b){var c=a,d=a.substring(0,1);return b=typeof b=="undefined"?!0:b,/[a-z]+\:\/\//.test(a)||(d==="/"?c=m.getRootUrl()+a.replace(/^\/+/,""):d==="#"?c=m.getPageUrl().replace(/#.*/,"")+a:d==="?"?c=m.getPageUrl().replace(/[\?#].*/,"")+a:b?c=m.getBaseUrl()+a.replace(/^(\.\/)+/,""):c=m.getBasePageUrl()+a.replace(/^(\.\/)+/,"")),c.replace(/\#$/,"")},m.getShortUrl=function(a){var b=a,c=m.getBaseUrl(),d=m.getRootUrl();return m.emulated.pushState&&(b=b.replace(c,"")),b=b.replace(d,"/"),m.isTraditionalAnchor(b)&&(b="./"+b),b=b.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),b},m.store={},m.idToState=m.idToState||{},m.stateToId=m.stateToId||{},m.urlToId=m.urlToId||{},m.storedStates=m.storedStates||[],m.savedStates=m.savedStates||[],m.normalizeStore=function(){m.store.idToState=m.store.idToState||{},m.store.urlToId=m.store.urlToId||{},m.store.stateToId=m.store.stateToId||{}},m.getState=function(a,b){typeof a=="undefined"&&(a=!0),typeof b=="undefined"&&(b=!0);var c=m.getLastSavedState();return!c&&b&&(c=m.createStateObject()),a&&(c=m.cloneObject(c),c.url=c.cleanUrl||c.url),c},m.getIdByState=function(a){var b=m.extractId(a.url),c;if(!b){c=m.getStateString(a);if(typeof m.stateToId[c]!="undefined")b=m.stateToId[c];else if(typeof m.store.stateToId[c]!="undefined")b=m.store.stateToId[c];else{for(;;){b=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof m.idToState[b]=="undefined"&&typeof m.store.idToState[b]=="undefined")break}m.stateToId[c]=b,m.idToState[b]=a}}return b},m.normalizeState=function(a){var b,c;if(!a||typeof a!="object")a={};if(typeof a.normalized!="undefined")return a;if(!a.data||typeof a.data!="object")a.data={};b={},b.normalized=!0,b.title=a.title||"",b.url=m.getFullUrl(m.unescapeString(a.url||d.location.href)),b.hash=m.getShortUrl(b.url),b.data=m.cloneObject(a.data),b.id=m.getIdByState(b),b.cleanUrl=b.url.replace(/\??\&_suid.*/,""),b.url=b.cleanUrl,c=!m.isEmptyObject(b.data);if(b.title||c)b.hash=m.getShortUrl(b.url).replace(/\??\&_suid.*/,""),/\?/.test(b.hash)||(b.hash+="?"),b.hash+="&_suid="+b.id;return b.hashedUrl=m.getFullUrl(b.hash),(m.emulated.pushState||m.bugs.safariPoll)&&m.hasUrlDuplicate(b)&&(b.url=b.hashedUrl),b},m.createStateObject=function(a,b,c){var d={data:a,title:b,url:c};return d=m.normalizeState(d),d},m.getStateById=function(a){a=String(a);var c=m.idToState[a]||m.store.idToState[a]||b;return c},m.getStateString=function(a){var b,c,d;return b=m.normalizeState(a),c={data:b.data,title:a.title,url:a.url},d=k.stringify(c),d},m.getStateId=function(a){var b,c;return b=m.normalizeState(a),c=b.id,c},m.getHashByState=function(a){var b,c;return b=m.normalizeState(a),c=b.hash,c},m.extractId=function(a){var b,c,d;return c=/(.*)\&_suid=([0-9]+)$/.exec(a),d=c?c[1]||a:a,b=c?String(c[2]||""):"",b||!1},m.isTraditionalAnchor=function(a){var b=!/[\/\?\.]/.test(a);return b},m.extractState=function(a,b){var c=null,d,e;return b=b||!1,d=m.extractId(a),d&&(c=m.getStateById(d)),c||(e=m.getFullUrl(a),d=m.getIdByUrl(e)||!1,d&&(c=m.getStateById(d)),!c&&b&&!m.isTraditionalAnchor(a)&&(c=m.createStateObject(null,null,e))),c},m.getIdByUrl=function(a){var c=m.urlToId[a]||m.store.urlToId[a]||b;return c},m.getLastSavedState=function(){return m.savedStates[m.savedStates.length-1]||b},m.getLastStoredState=function(){return m.storedStates[m.storedStates.length-1]||b},m.hasUrlDuplicate=function(a){var b=!1,c;return c=m.extractState(a.url),b=c&&c.id!==a.id,b},m.storeState=function(a){return m.urlToId[a.url]=a.id,m.storedStates.push(m.cloneObject(a)),a},m.isLastSavedState=function(a){var b=!1,c,d,e;return m.savedStates.length&&(c=a.id,d=m.getLastSavedState(),e=d.id,b=c===e),b},m.saveState=function(a){return m.isLastSavedState(a)?!1:(m.savedStates.push(m.cloneObject(a)),!0)},m.getStateByIndex=function(a){var b=null;return typeof a=="undefined"?b=m.savedStates[m.savedStates.length-1]:a<0?b=m.savedStates[m.savedStates.length+a]:b=m.savedStates[a],b},m.getHash=function(){var a=m.unescapeHash(d.location.hash);return a},m.unescapeString=function(b){var c=b,d;for(;;){d=a.unescape(c);if(d===c)break;c=d}return c},m.unescapeHash=function(a){var b=m.normalizeHash(a);return b=m.unescapeString(b),b},m.normalizeHash=function(a){var b=a.replace(/[^#]*#/,"").replace(/#.*/,"");return b},m.setHash=function(a,b){var c,e,f;return b!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.setHash,args:arguments,queue:b}),!1):(c=m.escapeHash(a),m.busy(!0),e=m.extractState(a,!0),e&&!m.emulated.pushState?m.pushState(e.data,e.title,e.url,!1):d.location.hash!==c&&(m.bugs.setHash?(f=m.getPageUrl(),m.pushState(null,null,f+"#"+c,!1)):d.location.hash=c),m)},m.escapeHash=function(b){var c=m.normalizeHash(b);return c=a.escape(c),m.bugs.hashEscape||(c=c.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),c},m.getHashByUrl=function(a){var b=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return b=m.unescapeHash(b),b},m.setTitle=function(a){var b=a.title,c;b||(c=m.getStateByIndex(0),c&&c.url===a.url&&(b=c.title||m.options.initialTitle));try{d.getElementsByTagName("title")[0].innerHTML=b.replace("<","<").replace(">",">").replace(" & "," & ")}catch(e){}return d.title=b,m},m.queues=[],m.busy=function(a){typeof a!="undefined"?m.busy.flag=a:typeof m.busy.flag=="undefined"&&(m.busy.flag=!1);if(!m.busy.flag){h(m.busy.timeout);var b=function(){var a,c,d;if(m.busy.flag)return;for(a=m.queues.length-1;a>=0;--a){c=m.queues[a];if(c.length===0)continue;d=c.shift(),m.fireQueueItem(d),m.busy.timeout=g(b,m.options.busyDelay)}};m.busy.timeout=g(b,m.options.busyDelay)}return m.busy.flag},m.busy.flag=!1,m.fireQueueItem=function(a){return a.callback.apply(a.scope||m,a.args||[])},m.pushQueue=function(a){return m.queues[a.queue||0]=m.queues[a.queue||0]||[],m.queues[a.queue||0].push(a),m},m.queue=function(a,b){return typeof a=="function"&&(a={callback:a}),typeof b!="undefined"&&(a.queue=b),m.busy()?m.pushQueue(a):m.fireQueueItem(a),m},m.clearQueue=function(){return m.busy.flag=!1,m.queues=[],m},m.stateChanged=!1,m.doubleChecker=!1,m.doubleCheckComplete=function(){return m.stateChanged=!0,m.doubleCheckClear(),m},m.doubleCheckClear=function(){return m.doubleChecker&&(h(m.doubleChecker),m.doubleChecker=!1),m},m.doubleCheck=function(a){return m.stateChanged=!1,m.doubleCheckClear(),m.bugs.ieDoubleCheck&&(m.doubleChecker=g(function(){return m.doubleCheckClear(),m.stateChanged||a(),!0},m.options.doubleCheckInterval)),m},m.safariStatePoll=function(){var b=m.extractState(d.location.href),c;if(!m.isLastSavedState(b))c=b;else return;return c||(c=m.createStateObject()),m.Adapter.trigger(a,"popstate"),m},m.back=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.back,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.back(!1)}),n.go(-1),!0)},m.forward=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.forward,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.forward(!1)}),n.go(1),!0)},m.go=function(a,b){var c;if(a>0)for(c=1;c<=a;++c)m.forward(b);else{if(!(a<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(c=-1;c>=a;--c)m.back(b)}return m};if(m.emulated.pushState){var o=function(){};m.pushState=m.pushState||o,m.replaceState=m.replaceState||o}else m.onPopState=function(b,c){var e=!1,f=!1,g,h;return m.doubleCheckComplete(),g=m.getHash(),g?(h=m.extractState(g||d.location.href,!0),h?m.replaceState(h.data,h.title,h.url,!1):(m.Adapter.trigger(a,"anchorchange"),m.busy(!1)),m.expectedStateId=!1,!1):(e=m.Adapter.extractEventData("state",b,c)||!1,e?f=m.getStateById(e):m.expectedStateId?f=m.getStateById(m.expectedStateId):f=m.extractState(d.location.href),f||(f=m.createStateObject(null,null,d.location.href)),m.expectedStateId=!1,m.isLastSavedState(f)?(m.busy(!1),!1):(m.storeState(f),m.saveState(f),m.setTitle(f),m.Adapter.trigger(a,"statechange"),m.busy(!1),!0))},m.Adapter.bind(a,"popstate",m.onPopState),m.pushState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.pushState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.pushState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0},m.replaceState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.replaceState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.replaceState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0};if(f){try{m.store=k.parse(f.getItem("History.store"))||{}}catch(p){m.store={}}m.normalizeStore()}else m.store={},m.normalizeStore();m.Adapter.bind(a,"beforeunload",m.clearAllIntervals),m.Adapter.bind(a,"unload",m.clearAllIntervals),m.saveState(m.storeState(m.extractState(d.location.href,!0))),f&&(m.onUnload=function(){var a,b;try{a=k.parse(f.getItem("History.store"))||{}}catch(c){a={}}a.idToState=a.idToState||{},a.urlToId=a.urlToId||{},a.stateToId=a.stateToId||{};for(b in m.idToState){if(!m.idToState.hasOwnProperty(b))continue;a.idToState[b]=m.idToState[b]}for(b in m.urlToId){if(!m.urlToId.hasOwnProperty(b))continue;a.urlToId[b]=m.urlToId[b]}for(b in m.stateToId){if(!m.stateToId.hasOwnProperty(b))continue;a.stateToId[b]=m.stateToId[b]}m.store=a,m.normalizeStore(),f.setItem("History.store",k.stringify(a))},m.intervalList.push(i(m.onUnload,m.options.storeInterval)),m.Adapter.bind(a,"beforeunload",m.onUnload),m.Adapter.bind(a,"unload",m.onUnload));if(!m.emulated.pushState){m.bugs.safariPoll&&m.intervalList.push(i(m.safariStatePoll,m.options.safariPollInterval));if(e.vendor==="Apple Computer, Inc."||(e.appCodeName||"")==="Mozilla")m.Adapter.bind(a,"hashchange",function(){m.Adapter.trigger(a,"popstate")}),m.getHash()&&m.Adapter.onDomLoad(function(){m.Adapter.trigger(a,"hashchange")})}},m.init()}(window)
|
1 |
+
(function(a,b){"use strict";var c=a.History=a.History||{};if(typeof c.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");c.Adapter={handlers:{},_uid:1,uid:function(a){return a._uid||(a._uid=c.Adapter._uid++)},bind:function(a,b,d){var e=c.Adapter.uid(a);c.Adapter.handlers[e]=c.Adapter.handlers[e]||{},c.Adapter.handlers[e][b]=c.Adapter.handlers[e][b]||[],c.Adapter.handlers[e][b].push(d),a["on"+b]=function(a,b){return function(d){c.Adapter.trigger(a,b,d)}}(a,b)},trigger:function(a,b,d){d=d||{};var e=c.Adapter.uid(a),f,g;c.Adapter.handlers[e]=c.Adapter.handlers[e]||{},c.Adapter.handlers[e][b]=c.Adapter.handlers[e][b]||[];for(f=0,g=c.Adapter.handlers[e][b].length;f<g;++f)c.Adapter.handlers[e][b][f].apply(this,[d])},extractEventData:function(a,c){var d=c&&c[a]||b;return d},onDomLoad:function(b){var c=a.setTimeout(function(){b()},2e3);a.onload=function(){clearTimeout(c),b()}}},typeof c.init!="undefined"&&c.init()})(window),function(a,b){"use strict";var c=a.console||b,d=a.document,e=a.navigator,f=a.sessionStorage||!1,g=a.setTimeout,h=a.clearTimeout,i=a.setInterval,j=a.clearInterval,k=a.JSON,l=a.alert,m=a.History=a.History||{},n=a.history;k.stringify=k.stringify||k.encode,k.parse=k.parse||k.decode;if(typeof m.init!="undefined")throw new Error("History.js Core has already been loaded...");m.init=function(){return typeof m.Adapter=="undefined"?!1:(typeof m.initCore!="undefined"&&m.initCore(),typeof m.initHtml4!="undefined"&&m.initHtml4(),!0)},m.initCore=function(){if(typeof m.initCore.initialized!="undefined")return!1;m.initCore.initialized=!0,m.options=m.options||{},m.options.hashChangeInterval=m.options.hashChangeInterval||100,m.options.safariPollInterval=m.options.safariPollInterval||500,m.options.doubleCheckInterval=m.options.doubleCheckInterval||500,m.options.storeInterval=m.options.storeInterval||1e3,m.options.busyDelay=m.options.busyDelay||250,m.options.debug=m.options.debug||!1,m.options.initialTitle=m.options.initialTitle||d.title,m.intervalList=[],m.clearAllIntervals=function(){var a,b=m.intervalList;if(typeof b!="undefined"&&b!==null){for(a=0;a<b.length;a++)j(b[a]);m.intervalList=null}},m.debug=function(){(m.options.debug||!1)&&m.log.apply(m,arguments)},m.log=function(){var a=typeof c!="undefined"&&typeof c.log!="undefined"&&typeof c.log.apply!="undefined",b=d.getElementById("log"),e,f,g,h,i;a?(h=Array.prototype.slice.call(arguments),e=h.shift(),typeof c.debug!="undefined"?c.debug.apply(c,[e,h]):c.log.apply(c,[e,h])):e="\n"+arguments[0]+"\n";for(f=1,g=arguments.length;f<g;++f){i=arguments[f];if(typeof i=="object"&&typeof k!="undefined")try{i=k.stringify(i)}catch(j){}e+="\n"+i+"\n"}return b?(b.value+=e+"\n-----\n",b.scrollTop=b.scrollHeight-b.clientHeight):a||l(e),!0},m.getInternetExplorerMajorVersion=function(){var a=m.getInternetExplorerMajorVersion.cached=typeof m.getInternetExplorerMajorVersion.cached!="undefined"?m.getInternetExplorerMajorVersion.cached:function(){var a=3,b=d.createElement("div"),c=b.getElementsByTagName("i");while((b.innerHTML="<!--[if gt IE "+ ++a+"]><i></i><![endif]-->")&&c[0]);return a>4?a:!1}();return a},m.isInternetExplorer=function(){var a=m.isInternetExplorer.cached=typeof m.isInternetExplorer.cached!="undefined"?m.isInternetExplorer.cached:Boolean(m.getInternetExplorerMajorVersion());return a},m.emulated={pushState:!Boolean(a.history&&a.history.pushState&&a.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)),hashChange:Boolean(!("onhashchange"in a||"onhashchange"in d)||m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8)},m.enabled=!m.emulated.pushState,m.bugs={setHash:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),safariPoll:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),ieDoubleCheck:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<7)},m.isEmptyObject=function(a){for(var b in a)return!1;return!0},m.cloneObject=function(a){var b,c;return a?(b=k.stringify(a),c=k.parse(b)):c={},c},m.getRootUrl=function(){var a=d.location.protocol+"//"+(d.location.hostname||d.location.host);if(d.location.port||!1)a+=":"+d.location.port;return a+="/",a},m.getBaseHref=function(){var a=d.getElementsByTagName("base"),b=null,c="";return a.length===1&&(b=a[0],c=b.href.replace(/[^\/]+$/,"")),c=c.replace(/\/+$/,""),c&&(c+="/"),c},m.getBaseUrl=function(){var a=m.getBaseHref()||m.getBasePageUrl()||m.getRootUrl();return a},m.getPageUrl=function(){var a=m.getState(!1,!1),b=(a||{}).url||d.location.href,c;return c=b.replace(/\/+$/,"").replace(/[^\/]+$/,function(a,b,c){return/\./.test(a)?a:a+"/"}),c},m.getBasePageUrl=function(){var a=d.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,function(a,b,c){return/[^\/]$/.test(a)?"":a}).replace(/\/+$/,"")+"/";return a},m.getFullUrl=function(a,b){var c=a,d=a.substring(0,1);return b=typeof b=="undefined"?!0:b,/[a-z]+\:\/\//.test(a)||(d==="/"?c=m.getRootUrl()+a.replace(/^\/+/,""):d==="#"?c=m.getPageUrl().replace(/#.*/,"")+a:d==="?"?c=m.getPageUrl().replace(/[\?#].*/,"")+a:b?c=m.getBaseUrl()+a.replace(/^(\.\/)+/,""):c=m.getBasePageUrl()+a.replace(/^(\.\/)+/,"")),c.replace(/\#$/,"")},m.getShortUrl=function(a){var b=a,c=m.getBaseUrl(),d=m.getRootUrl();return m.emulated.pushState&&(b=b.replace(c,"")),b=b.replace(d,"/"),m.isTraditionalAnchor(b)&&(b="./"+b),b=b.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),b},m.store={},m.idToState=m.idToState||{},m.stateToId=m.stateToId||{},m.urlToId=m.urlToId||{},m.storedStates=m.storedStates||[],m.savedStates=m.savedStates||[],m.normalizeStore=function(){m.store.idToState=m.store.idToState||{},m.store.urlToId=m.store.urlToId||{},m.store.stateToId=m.store.stateToId||{}},m.getState=function(a,b){typeof a=="undefined"&&(a=!0),typeof b=="undefined"&&(b=!0);var c=m.getLastSavedState();return!c&&b&&(c=m.createStateObject()),a&&(c=m.cloneObject(c),c.url=c.cleanUrl||c.url),c},m.getIdByState=function(a){var b=m.extractId(a.url),c;if(!b){c=m.getStateString(a);if(typeof m.stateToId[c]!="undefined")b=m.stateToId[c];else if(typeof m.store.stateToId[c]!="undefined")b=m.store.stateToId[c];else{for(;;){b=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof m.idToState[b]=="undefined"&&typeof m.store.idToState[b]=="undefined")break}m.stateToId[c]=b,m.idToState[b]=a}}return b},m.normalizeState=function(a){var b,c;if(!a||typeof a!="object")a={};if(typeof a.normalized!="undefined")return a;if(!a.data||typeof a.data!="object")a.data={};b={},b.normalized=!0,b.title=a.title||"",b.url=m.getFullUrl(m.unescapeString(a.url||d.location.href)),b.hash=m.getShortUrl(b.url),b.data=m.cloneObject(a.data),b.id=m.getIdByState(b),b.cleanUrl=b.url.replace(/\??\&_suid.*/,""),b.url=b.cleanUrl,c=!m.isEmptyObject(b.data);if(b.title||c)b.hash=m.getShortUrl(b.url).replace(/\??\&_suid.*/,""),/\?/.test(b.hash)||(b.hash+="?"),b.hash+="&_suid="+b.id;return b.hashedUrl=m.getFullUrl(b.hash),(m.emulated.pushState||m.bugs.safariPoll)&&m.hasUrlDuplicate(b)&&(b.url=b.hashedUrl),b},m.createStateObject=function(a,b,c){var d={data:a,title:b,url:c};return d=m.normalizeState(d),d},m.getStateById=function(a){a=String(a);var c=m.idToState[a]||m.store.idToState[a]||b;return c},m.getStateString=function(a){var b,c,d;return b=m.normalizeState(a),c={data:b.data,title:a.title,url:a.url},d=k.stringify(c),d},m.getStateId=function(a){var b,c;return b=m.normalizeState(a),c=b.id,c},m.getHashByState=function(a){var b,c;return b=m.normalizeState(a),c=b.hash,c},m.extractId=function(a){var b,c,d;return c=/(.*)\&_suid=([0-9]+)$/.exec(a),d=c?c[1]||a:a,b=c?String(c[2]||""):"",b||!1},m.isTraditionalAnchor=function(a){var b=!/[\/\?\.]/.test(a);return b},m.extractState=function(a,b){var c=null,d,e;return b=b||!1,d=m.extractId(a),d&&(c=m.getStateById(d)),c||(e=m.getFullUrl(a),d=m.getIdByUrl(e)||!1,d&&(c=m.getStateById(d)),!c&&b&&!m.isTraditionalAnchor(a)&&(c=m.createStateObject(null,null,e))),c},m.getIdByUrl=function(a){var c=m.urlToId[a]||m.store.urlToId[a]||b;return c},m.getLastSavedState=function(){return m.savedStates[m.savedStates.length-1]||b},m.getLastStoredState=function(){return m.storedStates[m.storedStates.length-1]||b},m.hasUrlDuplicate=function(a){var b=!1,c;return c=m.extractState(a.url),b=c&&c.id!==a.id,b},m.storeState=function(a){return m.urlToId[a.url]=a.id,m.storedStates.push(m.cloneObject(a)),a},m.isLastSavedState=function(a){var b=!1,c,d,e;return m.savedStates.length&&(c=a.id,d=m.getLastSavedState(),e=d.id,b=c===e),b},m.saveState=function(a){return m.isLastSavedState(a)?!1:(m.savedStates.push(m.cloneObject(a)),!0)},m.getStateByIndex=function(a){var b=null;return typeof a=="undefined"?b=m.savedStates[m.savedStates.length-1]:a<0?b=m.savedStates[m.savedStates.length+a]:b=m.savedStates[a],b},m.getHash=function(){var a=m.unescapeHash(d.location.hash);return a},m.unescapeString=function(b){var c=b,d;for(;;){d=a.unescape(c);if(d===c)break;c=d}return c},m.unescapeHash=function(a){var b=m.normalizeHash(a);return b=m.unescapeString(b),b},m.normalizeHash=function(a){var b=a.replace(/[^#]*#/,"").replace(/#.*/,"");return b},m.setHash=function(a,b){var c,e,f;return b!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.setHash,args:arguments,queue:b}),!1):(c=m.escapeHash(a),m.busy(!0),e=m.extractState(a,!0),e&&!m.emulated.pushState?m.pushState(e.data,e.title,e.url,!1):d.location.hash!==c&&(m.bugs.setHash?(f=m.getPageUrl(),m.pushState(null,null,f+"#"+c,!1)):d.location.hash=c),m)},m.escapeHash=function(b){var c=m.normalizeHash(b);return c=a.escape(c),m.bugs.hashEscape||(c=c.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),c},m.getHashByUrl=function(a){var b=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return b=m.unescapeHash(b),b},m.setTitle=function(a){var b=a.title,c;b||(c=m.getStateByIndex(0),c&&c.url===a.url&&(b=c.title||m.options.initialTitle));try{d.getElementsByTagName("title")[0].innerHTML=b.replace("<","<").replace(">",">").replace(" & "," & ")}catch(e){}return d.title=b,m},m.queues=[],m.busy=function(a){typeof a!="undefined"?m.busy.flag=a:typeof m.busy.flag=="undefined"&&(m.busy.flag=!1);if(!m.busy.flag){h(m.busy.timeout);var b=function(){var a,c,d;if(m.busy.flag)return;for(a=m.queues.length-1;a>=0;--a){c=m.queues[a];if(c.length===0)continue;d=c.shift(),m.fireQueueItem(d),m.busy.timeout=g(b,m.options.busyDelay)}};m.busy.timeout=g(b,m.options.busyDelay)}return m.busy.flag},m.busy.flag=!1,m.fireQueueItem=function(a){return a.callback.apply(a.scope||m,a.args||[])},m.pushQueue=function(a){return m.queues[a.queue||0]=m.queues[a.queue||0]||[],m.queues[a.queue||0].push(a),m},m.queue=function(a,b){return typeof a=="function"&&(a={callback:a}),typeof b!="undefined"&&(a.queue=b),m.busy()?m.pushQueue(a):m.fireQueueItem(a),m},m.clearQueue=function(){return m.busy.flag=!1,m.queues=[],m},m.stateChanged=!1,m.doubleChecker=!1,m.doubleCheckComplete=function(){return m.stateChanged=!0,m.doubleCheckClear(),m},m.doubleCheckClear=function(){return m.doubleChecker&&(h(m.doubleChecker),m.doubleChecker=!1),m},m.doubleCheck=function(a){return m.stateChanged=!1,m.doubleCheckClear(),m.bugs.ieDoubleCheck&&(m.doubleChecker=g(function(){return m.doubleCheckClear(),m.stateChanged||a(),!0},m.options.doubleCheckInterval)),m},m.safariStatePoll=function(){var b=m.extractState(d.location.href),c;if(!m.isLastSavedState(b))c=b;else return;return c||(c=m.createStateObject()),m.Adapter.trigger(a,"popstate"),m},m.back=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.back,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.back(!1)}),n.go(-1),!0)},m.forward=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.forward,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.forward(!1)}),n.go(1),!0)},m.go=function(a,b){var c;if(a>0)for(c=1;c<=a;++c)m.forward(b);else{if(!(a<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(c=-1;c>=a;--c)m.back(b)}return m};if(m.emulated.pushState){var o=function(){};m.pushState=m.pushState||o,m.replaceState=m.replaceState||o}else m.onPopState=function(b,c){var e=!1,f=!1,g,h;return m.doubleCheckComplete(),g=m.getHash(),g?(h=m.extractState(g||d.location.href,!0),h?m.replaceState(h.data,h.title,h.url,!1):(m.Adapter.trigger(a,"anchorchange"),m.busy(!1)),m.expectedStateId=!1,!1):(e=m.Adapter.extractEventData("state",b,c)||!1,e?f=m.getStateById(e):m.expectedStateId?f=m.getStateById(m.expectedStateId):f=m.extractState(d.location.href),f||(f=m.createStateObject(null,null,d.location.href)),m.expectedStateId=!1,m.isLastSavedState(f)?(m.busy(!1),!1):(m.storeState(f),m.saveState(f),m.setTitle(f),m.Adapter.trigger(a,"statechange"),m.busy(!1),!0))},m.Adapter.bind(a,"popstate",m.onPopState),m.pushState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.pushState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.pushState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0},m.replaceState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.replaceState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.replaceState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0};if(f){try{m.store=k.parse(f.getItem("History.store"))||{}}catch(p){m.store={}}m.normalizeStore()}else m.store={},m.normalizeStore();m.Adapter.bind(a,"beforeunload",m.clearAllIntervals),m.Adapter.bind(a,"unload",m.clearAllIntervals),m.saveState(m.storeState(m.extractState(d.location.href,!0))),f&&(m.onUnload=function(){var a,b;try{a=k.parse(f.getItem("History.store"))||{}}catch(c){a={}}a.idToState=a.idToState||{},a.urlToId=a.urlToId||{},a.stateToId=a.stateToId||{};for(b in m.idToState){if(!m.idToState.hasOwnProperty(b))continue;a.idToState[b]=m.idToState[b]}for(b in m.urlToId){if(!m.urlToId.hasOwnProperty(b))continue;a.urlToId[b]=m.urlToId[b]}for(b in m.stateToId){if(!m.stateToId.hasOwnProperty(b))continue;a.stateToId[b]=m.stateToId[b]}m.store=a,m.normalizeStore(),f.setItem("History.store",k.stringify(a))},m.intervalList.push(i(m.onUnload,m.options.storeInterval)),m.Adapter.bind(a,"beforeunload",m.onUnload),m.Adapter.bind(a,"unload",m.onUnload));if(!m.emulated.pushState){m.bugs.safariPoll&&m.intervalList.push(i(m.safariStatePoll,m.options.safariPollInterval));if(e.vendor==="Apple Computer, Inc."||(e.appCodeName||"")==="Mozilla")m.Adapter.bind(a,"hashchange",function(){m.Adapter.trigger(a,"popstate")}),m.getHash()&&m.Adapter.onDomLoad(function(){m.Adapter.trigger(a,"hashchange")})}},m.init()}(window)
|