alsoviewed - Version 1.3.0

Version Notes

View release notes at https://github.com/vovayatsyuk/magento-alsoviewed/releases/tag/1.3.0

- Security fix to _isAllowed method (strtolower)
- Removed non-working "Save" button from relations page
- Search crawlers and bots are no longer affects product relations
- Added ability to ignore specific IP addresses
- Added ability to create new and manage existing relations from backend `Product Edit` page

Download this release

Release Info

Developer Vova Yatsyuk
Extension alsoviewed
Version 1.3.0
Comparing to
See all releases


Code changes from version 1.2.0 to 1.3.0

app/code/community/Yavva/Alsoviewed/Block/Adminhtml/Catalog/Product/Edit/Tab/Relations.php ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Yavva_Alsoviewed_Block_Adminhtml_Catalog_Product_Edit_Tab_Relations extends Mage_Adminhtml_Block_Widget_Grid
4
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
5
+ {
6
+ public function __construct()
7
+ {
8
+ parent::__construct();
9
+ $this->setId('alsoviewed_product_grid');
10
+ $this->setDefaultSort('weight');
11
+ $this->setSkipGenerateContent(true);
12
+ $this->setUseAjax(true);
13
+ if ($this->_getProduct()->getId()) {
14
+ $this->setDefaultFilter(array('in_products' => 1));
15
+ }
16
+
17
+ $this->setAdditionalJavaScript("
18
+ // added click on selectbox support
19
+ serializerController.prototype.rowClick = serializerController.prototype.rowClick.wrap(function(o, grid, event) {
20
+ var tagName = Event.element(event).tagName
21
+ isSelect = (tagName == 'SELECT' || tagName == 'OPTION');
22
+
23
+ if (!isSelect) {
24
+ o(grid, event);
25
+ }
26
+ });
27
+ ");
28
+ }
29
+
30
+ protected function _addColumnFilterToCollection($column)
31
+ {
32
+ if ($column->getId() == 'in_products') {
33
+ $value = $column->getFilter()->getValue();
34
+ if ($value == 1) {
35
+ $this->getCollection()->addFieldToFilter('alsoviewed_relation', array('notnull' => true));
36
+ } elseif ($value == 0) {
37
+ $this->getCollection()->addFieldToFilter('alsoviewed_relation', array('null' => true));
38
+ }
39
+ } else {
40
+ parent::_addColumnFilterToCollection($column);
41
+ }
42
+
43
+ return $this;
44
+ }
45
+
46
+ protected function _prepareCollection()
47
+ {
48
+ $collection = Mage::getResourceModel('catalog/product_collection');
49
+ $collection->addAttributeToSelect('*');
50
+ $collection->joinTable(
51
+ array('alsoviewed' => 'alsoviewed/relation'),
52
+ 'related_product_id=entity_id',
53
+ array(
54
+ 'alsoviewed_relation' => 'relation_id',
55
+ 'alsoviewed_weight' => 'weight',
56
+ 'alsoviewed_position' => 'position',
57
+ 'alsoviewed_status' => 'status'
58
+ ),
59
+ array(
60
+ 'product_id' => $this->_getProduct()->getId()
61
+ ),
62
+ 'left'
63
+ );
64
+
65
+ if ($this->getIsReadonly() === true) {
66
+ $collection->addFieldToFilter('entity_id', array('in' => $this->_getSelectedProducts()));
67
+ }
68
+ $this->setCollection($collection);
69
+ return parent::_prepareCollection();
70
+ }
71
+
72
+ protected function _prepareColumns()
73
+ {
74
+ $this->addColumn('in_products', array(
75
+ 'header_css_class' => 'a-center',
76
+ 'type' => 'checkbox',
77
+ 'name' => 'in_products',
78
+ 'values' => $this->_getSelectedProducts(),
79
+ 'align' => 'center',
80
+ 'index' => 'entity_id'
81
+ ));
82
+
83
+ $this->addColumn('entity_id', array(
84
+ 'header' => Mage::helper('catalog')->__('ID'),
85
+ 'sortable' => true,
86
+ 'width' => '60px',
87
+ 'index' => 'entity_id'
88
+ ));
89
+ $this->addColumn('name', array(
90
+ 'header' => Mage::helper('catalog')->__('Name'),
91
+ 'index' => 'name'
92
+ ));
93
+ $this->addColumn('sku', array(
94
+ 'header' => Mage::helper('catalog')->__('SKU'),
95
+ 'width' => '80px',
96
+ 'index' => 'sku'
97
+ ));
98
+ $this->addColumn('price', array(
99
+ 'header' => Mage::helper('catalog')->__('Price'),
100
+ 'type' => 'currency',
101
+ 'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE),
102
+ 'index' => 'price'
103
+ ));
104
+
105
+ $this->addColumn('weight', array(
106
+ 'header' => Mage::helper('sales')->__('Weight'),
107
+ 'name' => 'weight',
108
+ 'type' => 'number',
109
+ 'validate_class' => 'validate-number',
110
+ 'index' => 'alsoviewed_weight',
111
+ 'width' => '1',
112
+ 'editable' => true,
113
+ 'edit_only' => !$this->_getProduct()->getId()
114
+ ));
115
+
116
+ $this->addColumn('position', array(
117
+ 'header' => Mage::helper('catalog')->__('Position'),
118
+ 'name' => 'position',
119
+ 'type' => 'number',
120
+ 'validate_class' => 'validate-number',
121
+ 'index' => 'alsoviewed_position',
122
+ 'width' => '1',
123
+ 'editable' => true,
124
+ 'edit_only' => !$this->_getProduct()->getId()
125
+ ));
126
+
127
+ $this->addColumn('status', array(
128
+ 'header' => Mage::helper('catalog')->__('Status'),
129
+ 'name' => 'status',
130
+ 'type' => 'select',
131
+ 'options' => array(
132
+ 1 => Mage::helper('catalog')->__('Enabled'),
133
+ 0 => Mage::helper('catalog')->__('Disabled')
134
+ ),
135
+ 'index' => 'alsoviewed_status',
136
+ 'width' => '1',
137
+ 'editable' => true,
138
+ 'edit_only' => !$this->_getProduct()->getId()
139
+ ));
140
+
141
+ return parent::_prepareColumns();
142
+ }
143
+
144
+ /**
145
+ * @return Mage_Catalog_Model_Product
146
+ */
147
+ protected function _getProduct()
148
+ {
149
+ return Mage::registry('current_product');
150
+ }
151
+
152
+ public function getGridUrl()
153
+ {
154
+ return $this->getUrl('adminhtml/alsoviewed_product/relationsgrid', array('_current'=>true));
155
+ }
156
+
157
+ public function getTabUrl()
158
+ {
159
+ return $this->getUrl('adminhtml/alsoviewed_product/relations', array('_current'=>true));
160
+ }
161
+
162
+ /**
163
+ * Retrieve selected alsoviewed products
164
+ *
165
+ * @return array
166
+ */
167
+ protected function _getSelectedProducts()
168
+ {
169
+ $products = $this->getProductsAlsoviewed();
170
+ if (!is_array($products)) {
171
+ $products = array_keys($this->getSelectedAlsoviewedProducts());
172
+ }
173
+ return $products;
174
+ }
175
+
176
+ /**
177
+ * Retrieve alsoviewed products
178
+ *
179
+ * @return array
180
+ */
181
+ public function getSelectedAlsoviewedProducts()
182
+ {
183
+ $relations = Mage::getResourceModel('alsoviewed/relation_collection')
184
+ ->addFieldToFilter('product_id', $this->_getProduct()->getId());
185
+ $products = array();
186
+ foreach ($relations as $relation) {
187
+ $products[$relation->getRelatedProductId()] = array(
188
+ 'weight' => $relation->getWeight(),
189
+ 'position' => $relation->getPosition(),
190
+ 'status' => $relation->getStatus()
191
+ );
192
+ }
193
+ return $products;
194
+ }
195
+
196
+ public function getTabClass()
197
+ {
198
+ return 'ajax';
199
+ }
200
+
201
+ public function getTabLabel()
202
+ {
203
+ return Mage::helper('alsoviewed')->__('Also Viewed Products');
204
+ }
205
+
206
+ public function getTabTitle()
207
+ {
208
+ return Mage::helper('alsoviewed')->__('Also Viewed Products');
209
+ }
210
+
211
+ public function canShowTab()
212
+ {
213
+ return true;
214
+ }
215
+
216
+ public function isHidden()
217
+ {
218
+ return false;
219
+ }
220
+ }
app/code/community/Yavva/Alsoviewed/Block/Adminhtml/Relations.php CHANGED
@@ -11,13 +11,6 @@ class Yavva_Alsoviewed_Block_Adminhtml_Relations extends Mage_Adminhtml_Block_Wi
11
  parent::__construct();
12
 
13
  $this->_removeButton('add');
14
-
15
- if ($this->_isAllowedAction('save')) {
16
- $this->_addButton('save', array(
17
- 'label' => Mage::helper('alsoviewed')->__('Save'),
18
- 'onclick' => 'setLocation(\'' . $this->getUrl('*/*/saveMultiple') .'\')'
19
- ));
20
- }
21
  }
22
 
23
  /**
11
  parent::__construct();
12
 
13
  $this->_removeButton('add');
 
 
 
 
 
 
 
14
  }
15
 
16
  /**
app/code/community/Yavva/Alsoviewed/Helper/Data.php CHANGED
@@ -2,5 +2,43 @@
2
 
3
  class Yavva_Alsoviewed_Helper_Data extends Mage_Core_Helper_Abstract
4
  {
 
 
 
 
 
 
 
 
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  }
2
 
3
  class Yavva_Alsoviewed_Helper_Data extends Mage_Core_Helper_Abstract
4
  {
5
+ public function isIpAddressIgnored($ip = null)
6
+ {
7
+ if (!Mage::getStoreConfig('alsoviewed/log/ignore_ip_address')) {
8
+ return false;
9
+ }
10
+ if (!$ignoredIps = Mage::getStoreConfig('alsoviewed/log/ignored_ip_address')) {
11
+ return false;
12
+ }
13
 
14
+ if (null === $ip) {
15
+ $ip = Mage::helper('core/http')->getRemoteAddr();
16
+ if (!$ip) {
17
+ return false;
18
+ }
19
+ }
20
+
21
+ $ignoredIps = explode(',', $ignoredIps);
22
+ return in_array($ip, $ignoredIps);
23
+ }
24
+
25
+ public function isUserAgentIgnored($userAgent = null)
26
+ {
27
+ if (!Mage::getStoreConfig('alsoviewed/log/ignore_user_agent')) {
28
+ return false;
29
+ }
30
+ if (!$ignoredUserArgents = Mage::getStoreConfig('alsoviewed/log/ignored_user_agent')) {
31
+ return false;
32
+ }
33
+
34
+ if (null === $userAgent) {
35
+ $userAgent = Mage::helper('core/http')->getHttpUserAgent();
36
+ if (!$userAgent) {
37
+ return false;
38
+ }
39
+ }
40
+
41
+ $regexp = '/' . trim($ignoredUserArgents, '/') . '/';
42
+ return @preg_match($regexp, $userAgent);
43
+ }
44
  }
app/code/community/Yavva/Alsoviewed/Model/Observer.php CHANGED
@@ -14,6 +14,11 @@ class Yavva_Alsoviewed_Model_Observer
14
  */
15
  public function catalogProductView(Varien_Event_Observer $observer)
16
  {
 
 
 
 
 
17
  $session = $this->_getSession();
18
  $productId = $observer->getControllerAction()->getRequest()->getParam('id');
19
  $viewedIds = $session->getViewedProductIds();
@@ -52,4 +57,68 @@ class Yavva_Alsoviewed_Model_Observer
52
  }
53
  }
54
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  }
14
  */
15
  public function catalogProductView(Varien_Event_Observer $observer)
16
  {
17
+ $helper = Mage::helper('alsoviewed');
18
+ if ($helper->isIpAddressIgnored() || $helper->isUserAgentIgnored()) {
19
+ return;
20
+ }
21
+
22
  $session = $this->_getSession();
23
  $productId = $observer->getControllerAction()->getRequest()->getParam('id');
24
  $viewedIds = $session->getViewedProductIds();
57
  }
58
  }
59
  }
60
+
61
+ public function prepareProductSave($observer)
62
+ {
63
+ $request = $observer->getEvent()->getRequest();
64
+ $product = $observer->getEvent()->getProduct();
65
+
66
+ if ($alsoviewed = $request->getPost('alsoviewed')) {
67
+ $relations = Mage::helper('adminhtml/js')->decodeGridSerializedInput($alsoviewed['relations']);
68
+ foreach ($relations as $key => $relation) {
69
+ if (!is_numeric($relation['weight'])) {
70
+ $relations[$key]['weight'] = 1;
71
+ }
72
+ if (!is_numeric($relation['position'])) {
73
+ $relations[$key]['position'] = 50;
74
+ }
75
+ }
76
+ $product->setAlsoviewedData($relations);
77
+ }
78
+ }
79
+
80
+ public function catalogProductSaveAfter($observer)
81
+ {
82
+ $product = $observer->getEvent()->getProduct();
83
+ $relations = $product->getAlsoviewedData();
84
+ if (!is_array($relations)) {
85
+ return;
86
+ }
87
+
88
+ $collection = Mage::getResourceModel('alsoviewed/relation_collection')
89
+ ->addFieldToFilter('product_id', $product->getId());
90
+
91
+ if (!$relations && !$collection->getSize()) {
92
+ return;
93
+ }
94
+
95
+ $model = Mage::getResourceModel('alsoviewed/relation');
96
+
97
+ // remove relations
98
+ if (!$relations) {
99
+ $relationsToRemove = $collection->getAllIds();
100
+ } else {
101
+ $relationsToRemove = array();
102
+ $relatedProductIds = array_keys($relations);
103
+ foreach ($collection as $relation) {
104
+ if (!in_array($relation->getRelatedProductId(), $relatedProductIds)) {
105
+ $relationsToRemove[] = $relation->getId();
106
+ }
107
+ }
108
+ }
109
+ if ($relationsToRemove) {
110
+ $model->deleteMultiple($relationsToRemove);
111
+ }
112
+
113
+ if (!$relations) {
114
+ return;
115
+ }
116
+
117
+ // update relations
118
+ foreach ($relations as $relatedProductId => $values) {
119
+ $relations[$relatedProductId]['product_id'] = $product->getId();
120
+ $relations[$relatedProductId]['related_product_id'] = $relatedProductId;
121
+ }
122
+ $model->saveRelations($relations, true);
123
+ }
124
  }
app/code/community/Yavva/Alsoviewed/Model/Resource/Relation.php CHANGED
@@ -43,6 +43,36 @@ class Yavva_Alsoviewed_Model_Resource_Relation extends Mage_Core_Model_Resource_
43
  ));
44
  }
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  /**
47
  * Update multiple relations at once
48
  *
43
  ));
44
  }
45
 
46
+ /**
47
+ * Insert new and update existing relations according to $relationsData
48
+ * Unlike updateRelations, this method does not respect previous value
49
+ * of the weight column of the duplicate relation.
50
+ *
51
+ * @param array $relationsData
52
+ * @param boolean $bidirectional
53
+ * @return int Number of affected rows
54
+ */
55
+ public function saveRelations($relationsData, $bidirectional = true)
56
+ {
57
+ $data = $relationsData;
58
+
59
+ if ($bidirectional) {
60
+ foreach ($relationsData as $relation) {
61
+ $_tmp = $relation;
62
+ $_tmp['product_id'] = $relation['related_product_id'];
63
+ $_tmp['related_product_id'] = $relation['product_id'];
64
+ $data[] = $_tmp;
65
+ }
66
+ }
67
+
68
+ $adapter = $this->_getWriteAdapter();
69
+ return $adapter->insertOnDuplicate($this->getMainTable(), $data, array(
70
+ 'weight' => new Zend_Db_Expr('VALUES(weight)'),
71
+ 'position' => new Zend_Db_Expr('VALUES(position)'),
72
+ 'status' => new Zend_Db_Expr('VALUES(status)')
73
+ ));
74
+ }
75
+
76
  /**
77
  * Update multiple relations at once
78
  *
app/code/community/Yavva/Alsoviewed/controllers/Adminhtml/Alsoviewed/LogController.php CHANGED
@@ -49,7 +49,8 @@ class Yavva_Alsoviewed_Adminhtml_Alsoviewed_LogController extends Mage_Adminhtml
49
  */
50
  protected function _isAllowed()
51
  {
52
- switch ($this->getRequest()->getActionName()) {
 
53
  case 'process':
54
  return Mage::getSingleton('admin/session')->isAllowed('yavva/alsoviewed/alsoviewed_log/process');
55
  break;
49
  */
50
  protected function _isAllowed()
51
  {
52
+ $action = strtolower($this->getRequest()->getActionName());
53
+ switch ($action) {
54
  case 'process':
55
  return Mage::getSingleton('admin/session')->isAllowed('yavva/alsoviewed/alsoviewed_log/process');
56
  break;
app/code/community/Yavva/Alsoviewed/controllers/Adminhtml/Alsoviewed/ProductController.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'Mage/Adminhtml/controllers/Catalog/ProductController.php';
4
+
5
+ class Yavva_Alsoviewed_Adminhtml_Alsoviewed_ProductController extends Mage_Adminhtml_Catalog_ProductController
6
+ {
7
+ public function relationsAction()
8
+ {
9
+ $this->_initProduct();
10
+ $this->loadLayout();
11
+ $this->getLayout()->getBlock('catalog.product.edit.tab.alsoviewed')
12
+ ->setProductsAlsoviewed($this->getRequest()->getPost('products_alsoviewed', null));
13
+ $this->renderLayout();
14
+ }
15
+
16
+ public function relationsGridAction()
17
+ {
18
+ $this->_initProduct();
19
+ $this->loadLayout();
20
+ $this->getLayout()->getBlock('catalog.product.edit.tab.alsoviewed')
21
+ ->setProductsAlsoviewed($this->getRequest()->getPost('products_alsoviewed', null));
22
+ $this->renderLayout();
23
+ }
24
+ }
app/code/community/Yavva/Alsoviewed/controllers/Adminhtml/Alsoviewed/RelationsController.php CHANGED
@@ -168,13 +168,14 @@ class Yavva_Alsoviewed_Adminhtml_Alsoviewed_RelationsController extends Mage_Adm
168
  */
169
  protected function _isAllowed()
170
  {
171
- switch ($this->getRequest()->getActionName()) {
 
172
  case 'delete':
173
- case 'massDelete':
174
  return Mage::getSingleton('admin/session')->isAllowed('yavva/alsoviewed/alsoviewed_relations/delete');
175
  break;
176
  case 'save':
177
- case 'massStatus':
178
  return Mage::getSingleton('admin/session')->isAllowed('yavva/alsoviewed/alsoviewed_relations/save');
179
  break;
180
  default:
168
  */
169
  protected function _isAllowed()
170
  {
171
+ $action = strtolower($this->getRequest()->getActionName());
172
+ switch ($action) {
173
  case 'delete':
174
+ case 'massdelete':
175
  return Mage::getSingleton('admin/session')->isAllowed('yavva/alsoviewed/alsoviewed_relations/delete');
176
  break;
177
  case 'save':
178
+ case 'massstatus':
179
  return Mage::getSingleton('admin/session')->isAllowed('yavva/alsoviewed/alsoviewed_relations/save');
180
  break;
181
  default:
app/code/community/Yavva/Alsoviewed/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Yavva_Alsoviewed>
5
- <version>1.2.0</version>
6
  </Yavva_Alsoviewed>
7
  </modules>
8
 
@@ -101,6 +101,24 @@
101
  </alsoviewed>
102
  </updates>
103
  </layout>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  </adminhtml>
105
 
106
  <crontab>
@@ -148,6 +166,12 @@
148
  <perfomance>
149
  <chunk_size>500</chunk_size>
150
  </perfomance>
 
 
 
 
 
 
151
  </alsoviewed>
152
  </default>
153
  </config>
2
  <config>
3
  <modules>
4
  <Yavva_Alsoviewed>
5
+ <version>1.3.0</version>
6
  </Yavva_Alsoviewed>
7
  </modules>
8
 
101
  </alsoviewed>
102
  </updates>
103
  </layout>
104
+ <events>
105
+ <catalog_product_prepare_save>
106
+ <observers>
107
+ <alsoviewed>
108
+ <class>alsoviewed/observer</class>
109
+ <method>prepareProductSave</method>
110
+ </alsoviewed>
111
+ </observers>
112
+ </catalog_product_prepare_save>
113
+ <catalog_product_save_after>
114
+ <observers>
115
+ <alsoviewed>
116
+ <class>alsoviewed/observer</class>
117
+ <method>catalogProductSaveAfter</method>
118
+ </alsoviewed>
119
+ </observers>
120
+ </catalog_product_save_after>
121
+ </events>
122
  </adminhtml>
123
 
124
  <crontab>
166
  <perfomance>
167
  <chunk_size>500</chunk_size>
168
  </perfomance>
169
+ <log>
170
+ <ignore_user_agent>1</ignore_user_agent>
171
+ <ignored_user_agent><![CDATA[008|Applebot|bingbot|facebookexternalhit|FlipboardProxy|googlebot|Googlebot|MetaURI|msnbot|redditbot|slurp|tm_crawler|TweetmemeBot|Twitterbot|Yandex]]></ignored_user_agent>
172
+ <ignore_ip_address>0</ignore_ip_address>
173
+ <ignored_ip_address></ignored_ip_address>
174
+ </log>
175
  </alsoviewed>
176
  </default>
177
  </config>
app/code/community/Yavva/Alsoviewed/etc/system.xml CHANGED
@@ -244,6 +244,51 @@
244
  </chunk_size>
245
  </fields>
246
  </perfomance>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  </groups>
248
  </alsoviewed>
249
  </sections>
244
  </chunk_size>
245
  </fields>
246
  </perfomance>
247
+ <log>
248
+ <label>Log Settings</label>
249
+ <sort_order>50</sort_order>
250
+ <show_in_default>1</show_in_default>
251
+ <show_in_website>0</show_in_website>
252
+ <show_in_store>0</show_in_store>
253
+ <fields>
254
+ <ignore_user_agent>
255
+ <label>Ignore crawlers</label>
256
+ <frontend_type>select</frontend_type>
257
+ <source_model>adminhtml/system_config_source_yesno</source_model>
258
+ <sort_order>10</sort_order>
259
+ <show_in_default>1</show_in_default>
260
+ </ignore_user_agent>
261
+ <ignored_user_agent>
262
+ <label>Crawler's user agent regex</label>
263
+ <frontend_type>text</frontend_type>
264
+ <sort_order>11</sort_order>
265
+ <depends>
266
+ <ignore_user_agent>
267
+ <value>1</value>
268
+ </ignore_user_agent>
269
+ </depends>
270
+ <show_in_default>1</show_in_default>
271
+ </ignored_user_agent>
272
+ <ignore_ip_address>
273
+ <label>Ignore specific ip addresses</label>
274
+ <frontend_type>select</frontend_type>
275
+ <source_model>adminhtml/system_config_source_yesno</source_model>
276
+ <sort_order>20</sort_order>
277
+ <show_in_default>1</show_in_default>
278
+ </ignore_ip_address>
279
+ <ignored_ip_address>
280
+ <label>Ip addresses (comma separated)</label>
281
+ <frontend_type>text</frontend_type>
282
+ <sort_order>21</sort_order>
283
+ <depends>
284
+ <ignore_ip_address>
285
+ <value>1</value>
286
+ </ignore_ip_address>
287
+ </depends>
288
+ <show_in_default>1</show_in_default>
289
+ </ignored_ip_address>
290
+ </fields>
291
+ </log>
292
  </groups>
293
  </alsoviewed>
294
  </sections>
app/design/adminhtml/base/default/layout/yavva/alsoviewed.xml CHANGED
@@ -21,4 +21,42 @@
21
  <block type="alsoviewed/adminhtml_log" name="alsoviewed_log"/>
22
  </reference>
23
  </adminhtml_alsoviewed_log_index>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  </layout>
21
  <block type="alsoviewed/adminhtml_log" name="alsoviewed_log"/>
22
  </reference>
23
  </adminhtml_alsoviewed_log_index>
24
+
25
+ <!-- Product edit page integration -->
26
+ <adminhtml_catalog_product_edit>
27
+ <reference name="product_tabs">
28
+ <action method="addTabAfter">
29
+ <name>alsoviewed</name>
30
+ <block>alsoviewed/adminhtml_catalog_product_edit_tab_relations</block>
31
+ <after>crosssell</after>
32
+ </action>
33
+ </reference>
34
+ </adminhtml_catalog_product_edit>
35
+
36
+ <adminhtml_alsoviewed_product_relations>
37
+ <block type="core/text_list" name="root" output="toHtml">
38
+ <block type="alsoviewed/adminhtml_catalog_product_edit_tab_relations" name="catalog.product.edit.tab.alsoviewed"/>
39
+ <block type="adminhtml/widget_grid_serializer" name="related_grid_serializer">
40
+ <reference name="related_grid_serializer">
41
+ <action method="initSerializerBlock">
42
+ <grid_block_name>catalog.product.edit.tab.alsoviewed</grid_block_name>
43
+ <data_callback>getSelectedAlsoviewedProducts</data_callback>
44
+ <hidden_input_name>alsoviewed[relations]</hidden_input_name>
45
+ <reload_param_name>products_alsoviewed</reload_param_name>
46
+ </action>
47
+ <action method="addColumnInputName">
48
+ <input_name>weight</input_name>
49
+ <input_name>position</input_name>
50
+ <input_name>status</input_name>
51
+ </action>
52
+ </reference>
53
+ </block>
54
+ </block>
55
+ </adminhtml_alsoviewed_product_relations>
56
+
57
+ <adminhtml_alsoviewed_product_relationsgrid>
58
+ <block type="core/text_list" name="root" output="toHtml">
59
+ <block type="alsoviewed/adminhtml_catalog_product_edit_tab_relations" name="catalog.product.edit.tab.alsoviewed"/>
60
+ </block>
61
+ </adminhtml_alsoviewed_product_relationsgrid>
62
  </layout>
app/design/frontend/base/default/layout/yavva/alsoviewed.xml CHANGED
@@ -38,37 +38,4 @@
38
  </block>
39
  </reference>
40
  </catalog_product_view>
41
-
42
- <!-- Move to the RWD tabs -->
43
- <!-- Copy and uncomment the code to your theme local.xml -->
44
- <!--
45
- <catalog_product_view>
46
- <reference name="product.info.additional">
47
- <action method="unsetChild"><name>alsoviewed.content.wrapper</name></action>
48
- </reference>
49
- <reference name="product.info">
50
- <action method="append"><name>alsoviewed.content.wrapper</name></action>
51
- </reference>
52
- <reference name="alsoviewed.content.wrapper">
53
- <action method="addToParentGroup"><group>detailed_info</group></action>
54
- <action method="setTitle" translate="value"><value>People who viewed this product also viewed</value></action>
55
- </reference>
56
- </catalog_product_view>
57
- -->
58
-
59
- <!-- Move to the Argento tabs -->
60
- <!-- Copy and uncomment the code to your theme custom.xml -->
61
- <!--
62
- <catalog_product_view>
63
- <reference name="product.info.additional">
64
- <action method="unsetChild"><name>alsoviewed.content.wrapper</name></action>
65
- </reference>
66
- <reference name="product.info.tabs">
67
- <action method="addTab" translate="title" module="alsoviewed" ifconfig="alsoviewed/content/enabled">
68
- <alias>alsoviewed.content.wrapper</alias>
69
- <title><![CDATA[You may also like]]></title>
70
- </action>
71
- </reference>
72
- </catalog_product_view>
73
- -->
74
  </layout>
38
  </block>
39
  </reference>
40
  </catalog_product_view>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  </layout>
app/locale/en_US/Yavva_Alsoviewed.csv CHANGED
@@ -33,3 +33,8 @@
33
  "Perfomance","Perfomance"
34
  "Relations count to process per one query","Relations count to process per one query"
35
  "You may need to decrease this value, if you found the ""Got a packet bigger than 'max_allowed_packet' bytes"" error in log","You may need to decrease this value, if you found the ""Got a packet bigger than 'max_allowed_packet' bytes"" error in log"
 
 
 
 
 
33
  "Perfomance","Perfomance"
34
  "Relations count to process per one query","Relations count to process per one query"
35
  "You may need to decrease this value, if you found the ""Got a packet bigger than 'max_allowed_packet' bytes"" error in log","You may need to decrease this value, if you found the ""Got a packet bigger than 'max_allowed_packet' bytes"" error in log"
36
+ "Log Settings","Log Settings"
37
+ "Ignore crawlers","Ignore crawlers"
38
+ "Crawler's user agent regex","Crawler's user agent regex"
39
+ "Ignore specific ip addresses","Ignore specific ip addresses"
40
+ "Ip addresses (comma separated)","Ip addresses (comma separated)"
package.xml CHANGED
@@ -1,15 +1,15 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>alsoviewed</name>
4
- <version>1.2.0</version>
5
  <stability>stable</stability>
6
  <license>GPL</license>
7
  <channel>community</channel>
8
  <extends/>
9
- <summary>Magento module that displays products, viewed by visitors, who viewed this product. It can also show recommendations based on viewed, compared and shopping cart products.</summary>
10
  <description>Magento module that displays products, viewed by visitors, who viewed this&#xD;
11
  product. It can also show recommendations based on viewed, compared and shopping&#xD;
12
- cart products (see [widget](#widget) section).&#xD;
13
  &#xD;
14
  #### How it works?&#xD;
15
  Every time the client is looking at some product, module update relations between&#xD;
@@ -21,43 +21,39 @@ Yes, store administrator can manually change the relation sort order or even&#xD
21
  disable the relation to hide it from the frontend.&#xD;
22
  &#xD;
23
  #### Configuration&#xD;
24
- You can easely place the suggested products block to the one of the following&#xD;
25
- places on product page:&#xD;
26
  &#xD;
 
27
  - Product additional information&#xD;
28
- - Left column&#xD;
29
- - Right column&#xD;
30
  &#xD;
31
- &gt; Configuration blocks - are the blocks that shows recommendations based on&#xD;
32
- &gt; currently viewed product only.&#xD;
33
- &#xD;
34
- &gt; If you wish to show recommendations based on customer history (viewed, compared),&#xD;
35
- &gt; use the [widget](#widget) instead.&#xD;
36
  &#xD;
37
  #### Widget&#xD;
38
- Since 1.1.0 you can use Alsoviewed Recommendations widget on any page.&#xD;
39
- Widget provides ability to recommend products by additional activities:&#xD;
40
  &#xD;
41
- - Recently Viewed Products&#xD;
42
- - Recently Compared Products&#xD;
43
- - Shopping Cart products&#xD;
44
  &#xD;
45
  #### The main features&#xD;
46
  - 100% free and open source&#xD;
47
  - High perfomance&#xD;
48
  - Simple and clean design&#xD;
49
  - Responsive css&#xD;
50
- &#xD;
51
- &gt; Module functionality relies on cron. Make sure you configure it properly.&#xD;
52
  </description>
53
- <notes>* Better third-party themes compatibility&#xD;
54
- * Added new perfomance setting: **chunk_size**. (It can be used when &#xD;
55
- mysql 'max_allowed_packet' size is too small and you need to decrease &#xD;
56
- query size, or it can be increased to decrease queries count during cronjob)</notes>
 
 
 
57
  <authors><author><name>Vova Yatsyuk</name><user>VovaYatsyuk</user><email>vova.yatsyuk@gmail.com</email></author></authors>
58
- <date>2015-04-08</date>
59
- <time>18:36:26</time>
60
- <contents><target name="magecommunity"><dir name="Yavva"><dir name="Alsoviewed"><dir name="Block"><dir name="Adminhtml"><dir name="Log"><file name="Grid.php" hash="6661435fdb8e525775adf990a90d11c4"/></dir><file name="Log.php" hash="cb3cca5ff29b80044e7943d376dc5993"/><dir name="Relations"><dir name="Edit"><file name="Form.php" hash="0ad20532cb04c4c850fe1398598e6588"/></dir><file name="Edit.php" hash="1afce837cf4bd29beb1cc8f38d4065b6"/><file name="Grid.php" hash="e10da78030dbfb1ecbb32f6df82ddfa1"/></dir><file name="Relations.php" hash="6561a0acaacc1bc8e5046be59da888b6"/></dir><file name="Products.php" hash="68240b69f626dd3c6283d1144d18e214"/><dir name="Widget"><file name="Products.php" hash="4fad1d2e4c32ed756c3b5fc988edd5a2"/></dir></dir><dir name="Helper"><file name="Data.php" hash="d8057e1e4731c53a6b1e72a626ce9ac3"/></dir><dir name="Model"><file name="Basis.php" hash="ff0ba6ceadd3b99d5ac4825ae109a6b0"/><file name="Observer.php" hash="c01e1caf0df63b73e59cb2035a0585a1"/><file name="Relation.php" hash="506d2fa53e2e342030bdfb976a2f0e00"/><dir name="Resource"><dir name="Collection"><file name="Abstract.php" hash="6d996d6b7643f1b3cc3c0db3d5440011"/></dir><dir name="Log"><file name="Collection.php" hash="790509f4a4e74cc007adae600c0d8a1b"/></dir><file name="Log.php" hash="d79d4a97ba3303dfa3e042ec34c2e0e3"/><dir name="Relation"><file name="Collection.php" hash="be05b1351c8703f1157b6f552612ffa8"/></dir><file name="Relation.php" hash="c154166a4318331e47b755749965a045"/></dir><file name="Session.php" hash="9ba3b43dec9458cc13cb6c6e7efbef05"/><dir name="System"><dir name="Config"><dir name="Source"><file name="ListMode.php" hash="d3480dc016dc0ff9e2e23ab210cf9756"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Alsoviewed"><file name="LogController.php" hash="2f585270cff1904618f8dea31133b6e0"/><file name="RelationsController.php" hash="de5a35329a09477a79ec65c57a4280ca"/></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="ff26af98f8e1eef8d902eca84da6d3aa"/><file name="config.xml" hash="0ef35056d358da48ba5e62b16a714843"/><file name="system.xml" hash="9dc125f86fef4e939ccbc631f5285ccb"/><file name="widget.xml" hash="7d8c523d78cc46b203f440cc9be9a356"/></dir><dir name="sql"><dir name="yavva_alsoviewed_setup"><file name="install-1.0.0.php" hash="8ed81d46895731990b7c2066bfcc353d"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="base"><dir name="default"><dir name="layout"><dir name="yavva"><file name="alsoviewed.xml" hash="53473beb4db371b273400ae8fa223a32"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="yavva"><file name="alsoviewed.xml" hash="bbd75b6b9b5639c7a54a77216e3afeb5"/></dir></dir><dir name="template"><dir name="yavva"><dir name="alsoviewed"><file name="products.phtml" hash="d55af4e92a7fbe929c10b81a804ddffe"/><dir name="wrapper"><file name="block.phtml" hash="ec9cb02d52f4ea8756a24438d26def64"/><file name="collateral.phtml" hash="0354a4c8f3466edc2d3bb5fb0a0b75f7"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Yavva_Alsoviewed.xml" hash="4eedb69f4c1fc39a1e4170694a19c3f8"/></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="Yavva_Alsoviewed.csv" hash="59c50c66ff06abb0ef30ca182b7517fa"/></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="yavva"><dir name="alsoviewed"><dir name="css"><file name="alsoviewed.css" hash="2eea21636a6bf099f2387c4f992b4c31"/></dir><file name=".DS_Store" hash="47b2bb12e2c4c4275ce2349d6b4570d0"/></dir></dir></dir></dir></dir></target></contents>
61
  <compatible/>
62
- <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
63
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>alsoviewed</name>
4
+ <version>1.3.0</version>
5
  <stability>stable</stability>
6
  <license>GPL</license>
7
  <channel>community</channel>
8
  <extends/>
9
+ <summary>Products recommendation module, that shows products viewed by customers who viewed this product.</summary>
10
  <description>Magento module that displays products, viewed by visitors, who viewed this&#xD;
11
  product. It can also show recommendations based on viewed, compared and shopping&#xD;
12
+ cart products.&#xD;
13
  &#xD;
14
  #### How it works?&#xD;
15
  Every time the client is looking at some product, module update relations between&#xD;
21
  disable the relation to hide it from the frontend.&#xD;
22
  &#xD;
23
  #### Configuration&#xD;
24
+ Module configuration provides ability to show Also Viewed Products in&#xD;
25
+ one of the following containers:&#xD;
26
  &#xD;
27
+ - Left or Right column&#xD;
28
  - Product additional information&#xD;
 
 
29
  &#xD;
30
+ Each of the sections has options that allows to configure title, list mode,&#xD;
31
+ products count, columns count (in case of grid mode) and image dimensions.&#xD;
 
 
 
32
  &#xD;
33
  #### Widget&#xD;
34
+ Widget provides ability to recommend products on any page by additional activities:&#xD;
 
35
  &#xD;
36
+ - Recently Viewed Products&#xD;
37
+ - Recently Compared Products&#xD;
38
+ - Shopping Cart products&#xD;
39
  &#xD;
40
  #### The main features&#xD;
41
  - 100% free and open source&#xD;
42
  - High perfomance&#xD;
43
  - Simple and clean design&#xD;
44
  - Responsive css&#xD;
 
 
45
  </description>
46
+ <notes>View release notes at https://github.com/vovayatsyuk/magento-alsoviewed/releases/tag/1.3.0&#xD;
47
+ &#xD;
48
+ - Security fix to _isAllowed method (strtolower)&#xD;
49
+ - Removed non-working "Save" button from relations page&#xD;
50
+ - Search crawlers and bots are no longer affects product relations&#xD;
51
+ - Added ability to ignore specific IP addresses&#xD;
52
+ - Added ability to create new and manage existing relations from backend `Product Edit` page</notes>
53
  <authors><author><name>Vova Yatsyuk</name><user>VovaYatsyuk</user><email>vova.yatsyuk@gmail.com</email></author></authors>
54
+ <date>2015-08-13</date>
55
+ <time>20:06:45</time>
56
+ <contents><target name="magecommunity"><dir name="Yavva"><dir name="Alsoviewed"><dir name="Block"><dir name="Adminhtml"><dir name="Catalog"><dir name="Product"><dir name="Edit"><dir name="Tab"><file name="Relations.php" hash="cc7fa402cb6e41f0d445e13a35c28c05"/></dir></dir></dir></dir><dir name="Log"><file name="Grid.php" hash="6661435fdb8e525775adf990a90d11c4"/></dir><file name="Log.php" hash="cb3cca5ff29b80044e7943d376dc5993"/><dir name="Relations"><dir name="Edit"><file name="Form.php" hash="0ad20532cb04c4c850fe1398598e6588"/></dir><file name="Edit.php" hash="1afce837cf4bd29beb1cc8f38d4065b6"/><file name="Grid.php" hash="e10da78030dbfb1ecbb32f6df82ddfa1"/></dir><file name="Relations.php" hash="5a8504dde3a69da03151bd75c0a59120"/></dir><file name="Products.php" hash="68240b69f626dd3c6283d1144d18e214"/><dir name="Widget"><file name="Products.php" hash="4fad1d2e4c32ed756c3b5fc988edd5a2"/></dir></dir><dir name="Helper"><file name="Data.php" hash="4712c5c02e1873ffbb21a18d4b6084bc"/></dir><dir name="Model"><file name="Basis.php" hash="ff0ba6ceadd3b99d5ac4825ae109a6b0"/><file name="Observer.php" hash="d4a7929679224d67fa18c2054c93a847"/><file name="Relation.php" hash="506d2fa53e2e342030bdfb976a2f0e00"/><dir name="Resource"><dir name="Collection"><file name="Abstract.php" hash="6d996d6b7643f1b3cc3c0db3d5440011"/></dir><dir name="Log"><file name="Collection.php" hash="790509f4a4e74cc007adae600c0d8a1b"/></dir><file name="Log.php" hash="d79d4a97ba3303dfa3e042ec34c2e0e3"/><dir name="Relation"><file name="Collection.php" hash="be05b1351c8703f1157b6f552612ffa8"/></dir><file name="Relation.php" hash="f25eeeb7330853418226ca65baa47846"/></dir><file name="Session.php" hash="9ba3b43dec9458cc13cb6c6e7efbef05"/><dir name="System"><dir name="Config"><dir name="Source"><file name="ListMode.php" hash="d3480dc016dc0ff9e2e23ab210cf9756"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Alsoviewed"><file name="LogController.php" hash="34ae25cc085adf4875be235feb4d9d63"/><file name="ProductController.php" hash="39c67faecdc13547714a63237487d831"/><file name="RelationsController.php" hash="6ba4c0a8b073c0dbf604932250d0e054"/></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="ff26af98f8e1eef8d902eca84da6d3aa"/><file name="config.xml" hash="848be336a98730fca7503720c4e7725f"/><file name="system.xml" hash="ed3e157796335dbcf9e6cc96f57ada25"/><file name="widget.xml" hash="7d8c523d78cc46b203f440cc9be9a356"/></dir><dir name="sql"><dir name="yavva_alsoviewed_setup"><file name="install-1.0.0.php" hash="8ed81d46895731990b7c2066bfcc353d"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="base"><dir name="default"><dir name="layout"><dir name="yavva"><file name="alsoviewed.xml" hash="cdc76c11b4dd573f4d891042714e92cf"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="yavva"><file name="alsoviewed.xml" hash="df953c9808d2e6ca186f36bc8ca4aac4"/></dir></dir><dir name="template"><dir name="yavva"><dir name="alsoviewed"><file name="products.phtml" hash="d55af4e92a7fbe929c10b81a804ddffe"/><dir name="wrapper"><file name="block.phtml" hash="ec9cb02d52f4ea8756a24438d26def64"/><file name="collateral.phtml" hash="0354a4c8f3466edc2d3bb5fb0a0b75f7"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Yavva_Alsoviewed.xml" hash="4eedb69f4c1fc39a1e4170694a19c3f8"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Yavva_Alsoviewed.csv" hash="abdd5870a9969bf9eb6ee89019b5ebb7"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="yavva"><dir name="alsoviewed"><dir name="css"><file name="alsoviewed.css" hash="2eea21636a6bf099f2387c4f992b4c31"/></dir></dir></dir></dir></dir></dir></target></contents>
57
  <compatible/>
58
+ <dependencies><required><php><min>5.1.0</min><max>7.0.0</max></php></required></dependencies>
59
  </package>
skin/frontend/base/default/yavva/alsoviewed/.DS_Store DELETED
Binary file