Iksanika_Productrelater - Version 1.0.2

Version Notes

SUPEE routing fixes

Download this release

Release Info

Developer Iksanika
Extension Iksanika_Productrelater
Version 1.0.2
Comparing to
See all releases


Code changes from version 1.0.1.1 to 1.0.2

app/code/community/Iksanika/Productrelater/Block/Catalog/Product.php CHANGED
@@ -16,4 +16,19 @@
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
- class Iksanika_Productrelater_Block_Catalog_Product extends Mage_Adminhtml_Block_Catalog_Product {public function __construct() {parent::__construct();$this->_headerText = Mage::helper('productrelater')->__('Mass Product Relater');} protected function _prepareLayout(){parent::_prepareLayout();$this->setTemplate('iksanika/productrelater/catalog/product.phtml');$this->setChild('grid', $this->getLayout()->createBlock('productrelater/catalog_product_grid', 'product.productrelater'));}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
+ class Iksanika_Productrelater_Block_Catalog_Product extends Mage_Adminhtml_Block_Catalog_Product
20
+ {
21
+
22
+ public function __construct()
23
+ {
24
+ parent::__construct();
25
+ $this->_headerText = Mage::helper('productrelater')->__('Mass Product Relater');
26
+ }
27
+
28
+ protected function _prepareLayout()
29
+ {
30
+ parent::_prepareLayout();
31
+ $this->setTemplate('iksanika/productrelater/catalog/product.phtml');
32
+ $this->setChild('grid', $this->getLayout()->createBlock('productrelater/catalog_product_grid', 'product.productrelater'));
33
+ }
34
+ }
app/code/community/Iksanika/Productrelater/Block/Catalog/Product/Grid.php CHANGED
@@ -16,5 +16,468 @@
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
- class Iksanika_Productrelater_Block_Catalog_Product_Grid extends Iksanika_Productrelater_Block_Widget_Grid {protected static $columnType = array( 'id' => array('type'=>'number'), 'product' => array('type'=>'checkbox'), 'name' => array('type'=>'text'), 'type_id' => array('type'=>'text'), 'attribute_set_id' => array('type'=>'text'), 'sku' => array('type'=>'text'), 'price' => array('type'=>'text'), 'qty' => array('type'=>'text'), 'is_in_stock' => array('type'=>'text'), 'visibility' => array('type'=>'text'), 'status' => array('type'=>'text'), 'websites' => array('type'=>'text'), 'related_ids' => array('type'=>'input'), 'cross_sell_ids' => array('type'=>'input'), 'up_sell_ids' => array('type'=>'input'),);public function __construct(){parent::__construct();$this->setId('productGrid');$this->prepareDefaults();$this->setSaveParametersInSession(true);$this->setUseAjax(true);$this->setTemplate('iksanika/productrelater/catalog/product/grid.phtml');$this->setMassactionBlockName('productrelater/widget_grid_massaction');}private function prepareDefaults(){$this->setDefaultLimit(20);$this->setDefaultPage(1);$this->setDefaultSort('id');$this->setDefaultDir('desc');}protected function _prepareCollection(){$collection = $this->getCollection();$collection = !$collection ? Mage::getModel('catalog/product')->getCollection() : $collection;$store = $this->_getStore();$collection->joinField('qty','cataloginventory/stock_item','qty','product_id=entity_id','{{table}}.stock_id=1','left')->joinField('related_ids','catalog/product_link','linked_product_id','product_id=entity_id','{{table}}.link_type_id=1','left')->joinField('cross_sell_ids','catalog/product_link','linked_product_id','product_id=entity_id','{{table}}.link_type_id=5','left')->joinField('up_sell_ids','catalog/product_link','linked_product_id','product_id=entity_id','{{table}}.link_type_id=4','left');$collection->groupByAttribute('entity_id');if ($store->getId()){$collection->addStoreFilter($store);$collection->joinAttribute('custom_name', 'catalog_product/name', 'entity_id', null, 'inner', $store->getId());$collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner', $store->getId());$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner', $store->getId());$collection->joinAttribute('price', 'catalog_product/price', 'entity_id', null, 'left', $store->getId());} else {$collection->addAttributeToSelect('price');$collection->addAttributeToSelect('status');$collection->addAttributeToSelect('visibility');}foreach(self::$columnType as $col => $true){if($col == 'related_ids' || $col == 'cross_sell_ids' || $col == 'up_sell_ids'){$filter = $this->getParam($this->getVarNameFilter());if($filter){$filter_data = Mage::helper('adminhtml')->prepareFilterString($filter);if(isset($filter_data[$col])){if(trim($filter_data[$col])=='')continue;$relatedIds = explode(',', $filter_data[$col]);$relatedIdsArray = array();foreach($relatedIds as $relatedId){$relatedIdsArray[] = intval($relatedId);}$collection->addAttributeToFilter($col, array( 'in' => $relatedIdsArray));}}} if($col == 'qty' || $col == 'websites' || $col=='id'|| $col=='related_ids'|| $col=='cross_sell_ids'|| $col=='up_sell_ids') continue; else $collection->addAttributeToSelect($col);}$this->setCollection($collection);parent::_prepareCollection();$collection->addWebsiteNamesToResult();return $this;}protected function _getStore(){$storeId = (int) $this->getRequest()->getParam('store', 0);return Mage::app()->getStore($storeId);}protected function _addColumnFilterToCollection($column){if ($this->getCollection()) {if ($column->getId() == 'websites') {$this->getCollection()->joinField('websites','catalog/product_website','website_id','product_id=entity_id',null,'left');}}return parent::_addColumnFilterToCollection($column);}public function _applyMyFilter($column){}protected function _prepareColumns(){$store = $this->_getStore();$this->addColumn('id',array('header'=> Mage::helper('catalog')->__('ID'),'width' => '50px','type' => 'number','index' => 'entity_id',));$this->addColumn('name',array('header'=> Mage::helper('catalog')->__('Name'),'name' => 'pu_name[]','index' => 'name'));$store = $this->_getStore();if ($store->getId()) {$this->addColumn('custom_name',array('header'=> Mage::helper('catalog')->__('Name In %s', $store->getName()),'index' => 'custom_name','width' => '150px'));}$this->addColumn('sku',array('header'=> Mage::helper('catalog')->__('SKU'),'width' => '80px','index' => 'sku','name' => 'pu_sku[]',));$this->addColumn('price',array('header'=> Mage::helper('catalog')->__('Price'),'type' => 'price','currency_code' => $store->getBaseCurrency()->getCode(),'index' => 'price','name' => 'pu_price[]',));$this->addColumn('qty',array('header'=> Mage::helper('catalog')->__('Qty'),'width' => '100px','type' => 'number','index' => 'qty','name' => 'pu_qty[]',));$this->addColumn('visibility',array('header'=> Mage::helper('catalog')->__('Visibility'),'width' => '70px','index' => 'visibility','type' => 'options','options' => Mage::getModel('catalog/product_visibility')->getOptionArray(),));$this->addColumn('status',array('header'=> Mage::helper('catalog')->__('Status'),'width' => '70px','index' => 'status','type' => 'options','options' => Mage::getSingleton('catalog/product_status')->getOptionArray(),));if (!Mage::app()->isSingleStoreMode()) {$this->addColumn('websites',array('header'=> Mage::helper('catalog')->__('Websites'),'width' => '100px','sortable' => false,'index' => 'websites','type' => 'options','options' => Mage::getModel('core/website')->getCollection()->toOptionHash(),));}$this->addColumn('related_ids',array('type'=>'input','index' => 'related_ids','width'=>'80px','filter_condition_callback' => array($this, '_applyMyFilter'),'header'=> Mage::helper('catalog')->__('Related IDs'),));$this->addColumn('cross_sell_ids',array('type'=>'input','index' => 'cross_sell_ids','width'=>'80px','filter_condition_callback' => array($this, '_applyMyFilter'),'header'=> Mage::helper('catalog')->__('Cross-Sell IDs'),));$this->addColumn('up_sell_ids',array('type'=>'input','index' => 'up_sell_ids','width'=>'80px','filter_condition_callback' => array($this, '_applyMyFilter'),'header'=> Mage::helper('catalog')->__('Up-Sell IDs'),));$this->addColumn('action',array('header' => Mage::helper('catalog')->__('Action'),'width' => '50px','type' => 'action','getter' => 'getId','filter' => false,'sortable' => false,'index' => 'stores','actions' => array(array('caption' => Mage::helper('catalog')->__('Edit'),'id' => "editlink",'url' => array('base'=>'adminhtml/*/edit','params'=>array('store'=>$this->getRequest()->getParam('store'))),'field' => 'id')),));$this->addRssList('rss/catalog/notifystock', Mage::helper('catalog')->__('Notify Low Stock RSS'));$this->setDestElementId('edit_form');return parent::_prepareColumns();}protected function _prepareMassaction(){$this->setMassactionIdField('entity_id');$this->getMassactionBlock()->setFormFieldName('product');$this->getMassactionBlock()->addItem('delete', array('label'=> Mage::helper('catalog')->__('Delete'),'url' => $this->getUrl('*/*/massDelete'),'confirm' => Mage::helper('catalog')->__('Are you sure?')));$statuses = Mage::getSingleton('catalog/product_status')->getOptionArray();array_unshift($statuses, array('label'=>'', 'value'=>''));$this->getMassactionBlock()->addItem('status', array('label'=> Mage::helper('catalog')->__('Change status'),'url' => $this->getUrl('*/*/massStatus', array('_current' => true)),'additional' => array('visibility' => array('name' => 'status','type' => 'select','class' => 'required-entry','label' => Mage::helper('catalog')->__('Status'),'values' => $statuses))));$this->getMassactionBlock()->addItem('attributes',array('label' => Mage::helper('catalog')->__('Update attributes'),'url' => $this->getUrl('*/catalog_product_action_attribute/edit', array('_current'=>true))));$this->getMassactionBlock()->addItem('otherDivider', $this->getDivider("Other"));$this->getMassactionBlock()->addItem('save',array('label' => Mage::helper('catalog')->__('Update'),'url' => $this->getUrl('*/*/massUpdateProducts', array('_current'=>true)),'fields' => array(0=>'product', 1=>'related_ids', 2=> 'cross_sell_ids', 3=> 'up_sell_ids')));$this->getMassactionBlock()->addItem('relatedDivider', $this->getCleanDivider());$this->getMassactionBlock()->addItem('otherDividerSalesMotivation', $this->getDivider("Product Relator"));$this->getMassactionBlock()->addItem('relatedEachOther', array('label' => $this->__('Related: To Each Other'),'url' => $this->getUrl('*/*/massRelatedEachOther', array('_current'=>true)),'callback' => 'specifyRelatedEachOther()',));$this->getMassactionBlock()->addItem('relatedTo', array('label' => $this->__('Related: Add ..'),'url' => $this->getUrl('*/*/massRelatedTo', array('_current'=>true)),'callback' => 'specifyRelatedProducts()'));$this->getMassactionBlock()->addItem('relatedClean', array('label' => $this->__('Related: Clear'),'url' => $this->getUrl('*/*/massRelatedClean', array('_current'=>true)),'callback' => 'specifyRelatedClean()'));$this->getMassactionBlock()->addItem('crossSellDivider', $this->getCleanDivider());$this->getMassactionBlock()->addItem('crossSellEachOther', array('label' => $this->__('Cross-Sell: To Each Other'),'url' => $this->getUrl('*/*/massCrossSellEachOther', array('_current'=>true)),'callback' => 'specifyCrossSellEachOther()',));$this->getMassactionBlock()->addItem('crossSellTo', array('label' => $this->__('Cross-Sell: Add ..'),'url' => $this->getUrl('*/*/massCrossSellTo', array('_current'=>true)),'callback' => 'chooseWhatToCrossSellTo()'));$this->getMassactionBlock()->addItem('crossSellClear', array('label' => $this->__('Cross-Sell: Clear'),'url' => $this->getUrl('*/*/massCrossSellClear', array('_current'=>true)),'callback' => 'specifyCrossSellClean()',));$this->getMassactionBlock()->addItem('upSellDivider', $this->getCleanDivider());$this->getMassactionBlock()->addItem('upSellTo', array('label' => $this->__('Up-Sells: Add ..'),'url' => $this->getUrl('*/*/massUpSellTo', array('_current'=>true)),'callback' => 'chooseWhatToUpSellTo()'));$this->getMassactionBlock()->addItem('upSellClear', array('label' => $this->__('Up-Sells: Clear'),'url' => $this->getUrl('*/*/massUpSellClear', array('_current'=>true)),'callback' => 'specifyUpSellClean()',));return $this;}public function getRowUrl($row){return $this->getUrl('adminhtml/catalog_product/edit', array('store'=>$this->getRequest()->getParam('store'),'id'=>$row->getId()));}public function getGridUrl(){return $this->getUrl('*/*/grid', array('_current'=>true));}protected function getDivider($divider="*******") {$dividerTemplate = array('label' => '********'.$this->__($divider).'********','url' => $this->getUrl('*/*/index', array('_current'=>true)),'callback' => "null");return $dividerTemplate;}protected function getSubDivider($divider="-------") {$dividerTemplate = array('label' => '--------'.$this->__($divider).'--------','url' => $this->getUrl('*/*/index', array('_current'=>true)),'callback' => "null");return $dividerTemplate;}protected function getCleanDivider() {$dividerTemplate = array('label' => ' ','url' => $this->getUrl('*/*/index', array('_current'=>true)),'callback' => "null");return $dividerTemplate;}}
20
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
+ class Iksanika_Productrelater_Block_Catalog_Product_Grid extends Iksanika_Productrelater_Block_Widget_Grid
20
+ {
21
+ protected static $columnType = array(
22
+ 'id' => array('type'=>'number'),
23
+ 'product' => array('type'=>'checkbox'),
24
+ 'name' => array('type'=>'text'),
25
+ 'type_id' => array('type'=>'text'),
26
+ 'attribute_set_id' => array('type'=>'text'),
27
+ 'sku' => array('type'=>'text'),
28
+ 'price' => array('type'=>'text'),
29
+ 'qty' => array('type'=>'text'),
30
+ 'is_in_stock' => array('type'=>'text'),
31
+ 'visibility' => array('type'=>'text'),
32
+ 'status' => array('type'=>'text'),
33
+ 'websites' => array('type'=>'text'),
34
+
35
+ 'related_ids' => array('type'=>'input'),
36
+ 'cross_sell_ids' => array('type'=>'input'),
37
+ 'up_sell_ids' => array('type'=>'input'),
38
+ );
39
+
40
+
41
+ public function __construct()
42
+ {
43
+ parent::__construct();
44
+ $this->setId('productGrid');
45
+ $this->prepareDefaults();
46
+ $this->setSaveParametersInSession(true);
47
+ $this->setUseAjax(true);
48
+ $this->setTemplate('iksanika/productrelater/catalog/product/grid.phtml');
49
+ $this->setMassactionBlockName('productrelater/widget_grid_massaction');
50
+ }
51
+
52
+ private function prepareDefaults()
53
+ {
54
+ $this->setDefaultLimit(20);
55
+ $this->setDefaultPage(1);
56
+ $this->setDefaultSort('id');
57
+ $this->setDefaultDir('desc');
58
+ }
59
+
60
+ protected function _prepareCollection()
61
+ {
62
+
63
+ $collection = $this->getCollection();
64
+ $collection = !$collection ? Mage::getModel('catalog/product')->getCollection() : $collection;
65
+
66
+ $store = $this->_getStore();
67
+ $collection
68
+ ->joinField(
69
+ 'qty',
70
+ 'cataloginventory/stock_item',
71
+ 'qty',
72
+ 'product_id=entity_id',
73
+ '{{table}}.stock_id=1',
74
+ 'left')
75
+ ->joinField(
76
+ 'related_ids',
77
+ 'catalog/product_link',
78
+ 'linked_product_id',
79
+ 'product_id=entity_id',
80
+ '{{table}}.link_type_id=1', // 1- relation, 4 - up_sell, 5 - cross_sell
81
+ 'left')
82
+ ->joinField(
83
+ 'cross_sell_ids',
84
+ 'catalog/product_link',
85
+ 'linked_product_id',
86
+ 'product_id=entity_id',
87
+ '{{table}}.link_type_id=5', // 1- relation, 4 - up_sell, 5 - cross_sell
88
+ 'left')
89
+ ->joinField(
90
+ 'up_sell_ids',
91
+ 'catalog/product_link',
92
+ 'linked_product_id',
93
+ 'product_id=entity_id',
94
+ '{{table}}.link_type_id=4', // 1- relation, 4 - up_sell, 5 - cross_sell
95
+ 'left');
96
+
97
+ $collection->groupByAttribute('entity_id');
98
+
99
+ if ($store->getId())
100
+ {
101
+ //$collection->setStoreId($store->getId());
102
+ $collection->addStoreFilter($store);
103
+ $collection->joinAttribute('custom_name', 'catalog_product/name', 'entity_id', null, 'inner', $store->getId());
104
+ $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner', $store->getId());
105
+ $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner', $store->getId());
106
+ $collection->joinAttribute('price', 'catalog_product/price', 'entity_id', null, 'left', $store->getId());
107
+ }
108
+ else {
109
+ $collection->addAttributeToSelect('price');
110
+ $collection->addAttributeToSelect('status');
111
+ $collection->addAttributeToSelect('visibility');
112
+ }
113
+
114
+ foreach(self::$columnType as $col => $true)
115
+ {
116
+ if($col == 'related_ids' || $col == 'cross_sell_ids' || $col == 'up_sell_ids')
117
+ {
118
+ $filter = $this->getParam($this->getVarNameFilter());
119
+ if($filter)
120
+ {
121
+ $filter_data = Mage::helper('adminhtml')->prepareFilterString($filter);
122
+ if(isset($filter_data[$col]))
123
+ {
124
+ if(trim($filter_data[$col])=='')
125
+ continue;
126
+ $relatedIds = explode(',', $filter_data[$col]);
127
+ $relatedIdsArray = array();
128
+ foreach($relatedIds as $relatedId)
129
+ {
130
+ //$collection->addCategoryFilter(Mage::getModel('catalog/category')->load($categoryId));
131
+ $relatedIdsArray[] = intval($relatedId);
132
+ }
133
+ $collection->addAttributeToFilter($col, array( 'in' => $relatedIdsArray));
134
+ }
135
+ }
136
+ }
137
+ if($col == 'qty' || $col == 'websites' || $col=='id'|| $col=='related_ids'|| $col=='cross_sell_ids'|| $col=='up_sell_ids')
138
+ continue;
139
+ else
140
+ $collection->addAttributeToSelect($col);
141
+ }
142
+
143
+ $this->setCollection($collection);
144
+
145
+ parent::_prepareCollection();
146
+
147
+ $collection->addWebsiteNamesToResult();
148
+
149
+ return $this;
150
+ }
151
+
152
+
153
+ protected function _getStore()
154
+ {
155
+ $storeId = (int) $this->getRequest()->getParam('store', 0);
156
+ return Mage::app()->getStore($storeId);
157
+ }
158
+
159
+ protected function _addColumnFilterToCollection($column)
160
+ {
161
+ if ($this->getCollection()) {
162
+ if ($column->getId() == 'websites') {
163
+ $this->getCollection()->joinField('websites',
164
+ 'catalog/product_website',
165
+ 'website_id',
166
+ 'product_id=entity_id',
167
+ null,
168
+ 'left');
169
+ }
170
+ }
171
+ return parent::_addColumnFilterToCollection($column);
172
+ }
173
+
174
+ public function _applyMyFilter($column)
175
+ {
176
+ // empty filter condition to avoid standard magento conditions
177
+ }
178
+
179
+ protected function _prepareColumns()
180
+ {
181
+ $store = $this->_getStore();
182
+
183
+ $this->addColumn('id',
184
+ array(
185
+ 'header'=> Mage::helper('catalog')->__('ID'),
186
+ 'width' => '50px',
187
+ 'type' => 'number',
188
+ 'index' => 'entity_id',
189
+ ));
190
+ $this->addColumn('name',
191
+ array(
192
+ 'header'=> Mage::helper('catalog')->__('Name'),
193
+ 'name' => 'pu_name[]',
194
+ 'index' => 'name'/*,
195
+ 'width' => '150px'*/
196
+ ));
197
+ $store = $this->_getStore();
198
+ if ($store->getId()) {
199
+ $this->addColumn('custom_name',
200
+ array(
201
+ 'header'=> Mage::helper('catalog')->__('Name In %s', $store->getName()),
202
+ 'index' => 'custom_name',
203
+ 'width' => '150px'
204
+ ));
205
+ }
206
+ /*
207
+ $this->addColumn('type',
208
+ array(
209
+ 'header'=> Mage::helper('catalog')->__('Type'),
210
+ 'width' => '60px',
211
+ 'index' => 'type_id',
212
+ 'type' => 'options',
213
+ 'options' => Mage::getSingleton('catalog/product_type')->getOptionArray(),
214
+ ));
215
+ */
216
+ /*
217
+ $sets = Mage::getResourceModel('eav/entity_attribute_set_collection')
218
+ ->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
219
+ ->load()
220
+ ->toOptionHash();
221
+
222
+ $this->addColumn('set_name',
223
+ array(
224
+ 'header'=> Mage::helper('catalog')->__('Attrib. Set Name'),
225
+ 'width' => '100px',
226
+ 'index' => 'attribute_set_id',
227
+ 'type' => 'options',
228
+ 'options' => $sets,
229
+ ));
230
+ */
231
+ $this->addColumn('sku',
232
+ array(
233
+ 'header'=> Mage::helper('catalog')->__('SKU'),
234
+ 'width' => '80px',
235
+ 'index' => 'sku',
236
+ 'name' => 'pu_sku[]',
237
+ ));
238
+ $this->addColumn('price',
239
+ array(
240
+ 'header'=> Mage::helper('catalog')->__('Price'),
241
+ 'type' => 'price',
242
+ 'currency_code' => $store->getBaseCurrency()->getCode(),
243
+ 'index' => 'price',
244
+ 'name' => 'pu_price[]',
245
+ ));
246
+ $this->addColumn('qty',
247
+ array(
248
+ 'header'=> Mage::helper('catalog')->__('Qty'),
249
+ 'width' => '100px',
250
+ 'type' => 'number',
251
+ 'index' => 'qty',
252
+ 'name' => 'pu_qty[]',
253
+ ));
254
+ $this->addColumn('visibility',
255
+ array(
256
+ 'header'=> Mage::helper('catalog')->__('Visibility'),
257
+ 'width' => '70px',
258
+ 'index' => 'visibility',
259
+ 'type' => 'options',
260
+ 'options' => Mage::getModel('catalog/product_visibility')->getOptionArray(),
261
+ ));
262
+ $this->addColumn('status',
263
+ array(
264
+ 'header'=> Mage::helper('catalog')->__('Status'),
265
+ 'width' => '70px',
266
+ 'index' => 'status',
267
+ 'type' => 'options',
268
+ 'options' => Mage::getSingleton('catalog/product_status')->getOptionArray(),
269
+ ));
270
+ if (!Mage::app()->isSingleStoreMode()) {
271
+ $this->addColumn('websites',
272
+ array(
273
+ 'header'=> Mage::helper('catalog')->__('Websites'),
274
+ 'width' => '100px',
275
+ 'sortable' => false,
276
+ 'index' => 'websites',
277
+ 'type' => 'options',
278
+ 'options' => Mage::getModel('core/website')->getCollection()->toOptionHash(),
279
+ ));
280
+ }
281
+
282
+ $this->addColumn('related_ids',
283
+ array(
284
+ 'type'=>'input',
285
+ 'index' => 'related_ids',
286
+ 'width'=>'80px',
287
+ 'filter_condition_callback' => array($this, '_applyMyFilter'),
288
+ 'header'=> Mage::helper('catalog')->__('Related IDs'),
289
+ ));
290
+ $this->addColumn('cross_sell_ids',
291
+ array(
292
+ 'type'=>'input',
293
+ 'index' => 'cross_sell_ids',
294
+ 'width'=>'80px',
295
+ 'filter_condition_callback' => array($this, '_applyMyFilter'),
296
+ 'header'=> Mage::helper('catalog')->__('Cross-Sell IDs'),
297
+ ));
298
+ $this->addColumn('up_sell_ids',
299
+ array(
300
+ 'type'=>'input',
301
+ 'index' => 'up_sell_ids',
302
+ 'width'=>'80px',
303
+ 'filter_condition_callback' => array($this, '_applyMyFilter'),
304
+ 'header'=> Mage::helper('catalog')->__('Up-Sell IDs'),
305
+ ));
306
+
307
+ $this->addColumn('action',
308
+ array(
309
+ 'header' => Mage::helper('catalog')->__('Action'),
310
+ 'width' => '50px',
311
+ 'type' => 'action',
312
+ 'getter' => 'getId',
313
+ 'filter' => false,
314
+ 'sortable' => false,
315
+ 'index' => 'stores',
316
+ 'actions' => array(
317
+ array(
318
+ 'caption' => Mage::helper('catalog')->__('Edit'),
319
+ 'id' => "editlink",
320
+ 'url' => array(
321
+ 'base'=>'adminhtml/*/edit',
322
+ 'params'=>array('store'=>$this->getRequest()->getParam('store'))
323
+ ),
324
+ 'field' => 'id'
325
+ )
326
+ ),
327
+ ));
328
+
329
+ $this->addRssList('rss/catalog/notifystock', Mage::helper('catalog')->__('Notify Low Stock RSS'));
330
+
331
+ $this->setDestElementId('edit_form');
332
+
333
+ return parent::_prepareColumns();
334
+ }
335
+
336
+ protected function _prepareMassaction()
337
+ {
338
+ $this->setMassactionIdField('entity_id');
339
+ $this->getMassactionBlock()->setFormFieldName('product');
340
+
341
+ $this->getMassactionBlock()->addItem('delete', array(
342
+ 'label'=> Mage::helper('catalog')->__('Delete'),
343
+ 'url' => $this->getUrl('*/*/massDelete'),
344
+ 'confirm' => Mage::helper('catalog')->__('Are you sure?')
345
+ ));
346
+
347
+ $statuses = Mage::getSingleton('catalog/product_status')->getOptionArray();
348
+
349
+ array_unshift($statuses, array('label'=>'', 'value'=>''));
350
+
351
+ $this->getMassactionBlock()->addItem('status', array(
352
+ 'label'=> Mage::helper('catalog')->__('Change status'),
353
+ 'url' => $this->getUrl('*/*/massStatus', array('_current' => true)),
354
+ 'additional' => array(
355
+ 'visibility' => array(
356
+ 'name' => 'status',
357
+ 'type' => 'select',
358
+ 'class' => 'required-entry',
359
+ 'label' => Mage::helper('catalog')->__('Status'),
360
+ 'values' => $statuses
361
+ )
362
+ )
363
+ ));
364
+
365
+ $this->getMassactionBlock()->addItem('attributes',
366
+ array(
367
+ 'label' => Mage::helper('catalog')->__('Update attributes'),
368
+ 'url' => $this->getUrl('*/catalog_product_action_attribute/edit', array('_current'=>true))
369
+ )
370
+ );
371
+
372
+ $this->getMassactionBlock()->addItem('otherDivider', $this->getDivider("Other"));
373
+
374
+ /*
375
+ * Prepare list of column for update
376
+ */
377
+ $this->getMassactionBlock()->addItem('save',
378
+ array(
379
+ 'label' => Mage::helper('catalog')->__('Update'),
380
+ 'url' => $this->getUrl('*/*/massUpdateProducts', array('_current'=>true)),
381
+ 'fields' => array(0=>'product', 1=>'related_ids', 2=> 'cross_sell_ids', 3=> 'up_sell_ids')
382
+ )
383
+ );
384
+
385
+
386
+ $this->getMassactionBlock()->addItem('relatedDivider', $this->getCleanDivider());
387
+
388
+ $this->getMassactionBlock()->addItem('otherDividerSalesMotivation', $this->getDivider("Product Relator"));
389
+
390
+ $this->getMassactionBlock()->addItem('relatedEachOther', array(
391
+ 'label' => $this->__('Related: To Each Other'),
392
+ 'url' => $this->getUrl('*/*/massRelatedEachOther', array('_current'=>true)),
393
+ 'callback' => 'specifyRelatedEachOther()',
394
+ ));
395
+ $this->getMassactionBlock()->addItem('relatedTo', array(
396
+ 'label' => $this->__('Related: Add ..'),
397
+ 'url' => $this->getUrl('*/*/massRelatedTo', array('_current'=>true)),
398
+ 'callback' => 'specifyRelatedProducts()'
399
+ ));
400
+ $this->getMassactionBlock()->addItem('relatedClean', array(
401
+ 'label' => $this->__('Related: Clear'),
402
+ 'url' => $this->getUrl('*/*/massRelatedClean', array('_current'=>true)),
403
+ 'callback' => 'specifyRelatedClean()'
404
+ ));
405
+
406
+
407
+ $this->getMassactionBlock()->addItem('crossSellDivider', $this->getCleanDivider());
408
+
409
+ $this->getMassactionBlock()->addItem('crossSellEachOther', array(
410
+ 'label' => $this->__('Cross-Sell: To Each Other'),
411
+ 'url' => $this->getUrl('*/*/massCrossSellEachOther', array('_current'=>true)),
412
+ 'callback' => 'specifyCrossSellEachOther()',
413
+ ));
414
+ $this->getMassactionBlock()->addItem('crossSellTo', array(
415
+ 'label' => $this->__('Cross-Sell: Add ..'),
416
+ 'url' => $this->getUrl('*/*/massCrossSellTo', array('_current'=>true)),
417
+ 'callback' => 'chooseWhatToCrossSellTo()'
418
+ ));
419
+ $this->getMassactionBlock()->addItem('crossSellClear', array(
420
+ 'label' => $this->__('Cross-Sell: Clear'),
421
+ 'url' => $this->getUrl('*/*/massCrossSellClear', array('_current'=>true)),
422
+ 'callback' => 'specifyCrossSellClean()',
423
+ ));
424
+
425
+
426
+ $this->getMassactionBlock()->addItem('upSellDivider', $this->getCleanDivider());
427
+
428
+ $this->getMassactionBlock()->addItem('upSellTo', array(
429
+ 'label' => $this->__('Up-Sells: Add ..'),
430
+ 'url' => $this->getUrl('*/*/massUpSellTo', array('_current'=>true)),
431
+ 'callback' => 'chooseWhatToUpSellTo()'
432
+ ));
433
+ $this->getMassactionBlock()->addItem('upSellClear', array(
434
+ 'label' => $this->__('Up-Sells: Clear'),
435
+ 'url' => $this->getUrl('*/*/massUpSellClear', array('_current'=>true)),
436
+ 'callback' => 'specifyUpSellClean()',
437
+ ));
438
+
439
+ return $this;
440
+ }
441
+
442
+ public function getRowUrl($row)
443
+ {
444
+ return $this->getUrl('adminhtml/catalog_product/edit', array(
445
+ 'store'=>$this->getRequest()->getParam('store'),
446
+ 'id'=>$row->getId())
447
+ );
448
+ }
449
+
450
+ public function getGridUrl()
451
+ {
452
+ return $this->getUrl('*/*/grid', array('_current'=>true));
453
+ }
454
+
455
+ protected function getDivider($divider="*******") {
456
+ $dividerTemplate = array(
457
+ 'label' => '********'.$this->__($divider).'********',
458
+ 'url' => $this->getUrl('*/*/index', array('_current'=>true)),
459
+ 'callback' => "null"
460
+ );
461
+ return $dividerTemplate;
462
+ }
463
+
464
+ protected function getSubDivider($divider="-------") {
465
+ $dividerTemplate = array(
466
+ 'label' => '--------'.$this->__($divider).'--------',
467
+ 'url' => $this->getUrl('*/*/index', array('_current'=>true)),
468
+ 'callback' => "null"
469
+ );
470
+ return $dividerTemplate;
471
+ }
472
+
473
+ protected function getCleanDivider() {
474
+ $dividerTemplate = array(
475
+ 'label' => ' ',
476
+ 'url' => $this->getUrl('*/*/index', array('_current'=>true)),
477
+ 'callback' => "null"
478
+ );
479
+ return $dividerTemplate;
480
+ }
481
+
482
+
483
+ }
app/code/community/Iksanika/Productrelater/Block/Widget/Grid.php CHANGED
@@ -16,4 +16,12 @@
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
- class Iksanika_Productrelater_Block_Widget_Grid extends Mage_Adminhtml_Block_Widget_Grid {public function getJsObjectName(){return $this->getId().'JsObjectIKSProductrelater';}}
 
 
 
 
 
 
 
 
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
+ class Iksanika_Productrelater_Block_Widget_Grid extends Mage_Adminhtml_Block_Widget_Grid
20
+ {
21
+
22
+ public function getJsObjectName()
23
+ {
24
+ return $this->getId().'JsObjectIKSProductrelater';
25
+ }
26
+
27
+ }
app/code/community/Iksanika/Productrelater/Block/Widget/Grid/Column/Renderer/Number.php CHANGED
@@ -16,4 +16,15 @@
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
- class Iksanika_Productrelater_Block_Widget_Grid_Column_Renderer_Number extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Number {public function render(Varien_Object $row){$html = '<input type="text" ';$html .= 'name="' . $this->getColumn()->getId() . '" ';$html .= 'value="' . parent::_getValue($row) . '"';$html .= 'class="input-text ' . $this->getColumn()->getInlineCss() . '"/>';return $html;}}
 
 
 
 
 
 
 
 
 
 
 
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
+ class Iksanika_Productrelater_Block_Widget_Grid_Column_Renderer_Number
20
+ extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Number
21
+ {
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $html = '<input type="text" ';
25
+ $html .= 'name="' . $this->getColumn()->getId() . '" ';
26
+ $html .= 'value="' . parent::_getValue($row) . '"';
27
+ $html .= 'class="input-text ' . $this->getColumn()->getInlineCss() . '"/>';
28
+ return $html;
29
+ }
30
+ }
app/code/community/Iksanika/Productrelater/Block/Widget/Grid/Massaction.php CHANGED
@@ -16,4 +16,22 @@
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
- class Iksanika_Productrelater_Block_Widget_Grid_Massaction extends Mage_Adminhtml_Block_Widget_Grid_Massaction {public function getJsObjectName(){return $this->getHtmlId() . 'JsObjectIKSProductrelater';}public function getJavaScript() {return " var {$this->getJsObjectName()} = new varienGridMassactionIksanikaProductrelater('{$this->getHtmlId()}', ". "{$this->getGridJsObjectName()}, '{$this->getSelectedJson()}'". ", '{$this->getFormFieldNameInternal()}', '{$this->getFormFieldName()}');". "{$this->getJsObjectName()}.setItems({$this->getItemsJson()}); ". "{$this->getJsObjectName()}.setGridIds('{$this->getGridIdsJson()}');". ($this->getUseAjax() ? "{$this->getJsObjectName()}.setUseAjax(true);" : ''). ($this->getUseSelectAll() ? "{$this->getJsObjectName()}.setUseSelectAll(true);" : ''). "{$this->getJsObjectName()}.errorText = '{$this->getErrorText()}';";}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
+ class Iksanika_Productrelater_Block_Widget_Grid_Massaction extends Mage_Adminhtml_Block_Widget_Grid_Massaction
20
+ {
21
+ public function getJsObjectName()
22
+ {
23
+ return $this->getHtmlId() . 'JsObjectIKSProductrelater';
24
+ }
25
+
26
+ public function getJavaScript() {
27
+ return " var {$this->getJsObjectName()} = new varienGridMassactionIksanikaProductrelater('{$this->getHtmlId()}', "
28
+ . "{$this->getGridJsObjectName()}, '{$this->getSelectedJson()}'"
29
+ . ", '{$this->getFormFieldNameInternal()}', '{$this->getFormFieldName()}');"
30
+ . "{$this->getJsObjectName()}.setItems({$this->getItemsJson()}); "
31
+ . "{$this->getJsObjectName()}.setGridIds('{$this->getGridIdsJson()}');"
32
+ . ($this->getUseAjax() ? "{$this->getJsObjectName()}.setUseAjax(true);" : '')
33
+ . ($this->getUseSelectAll() ? "{$this->getJsObjectName()}.setUseSelectAll(true);" : '')
34
+ . "{$this->getJsObjectName()}.errorText = '{$this->getErrorText()}';";
35
+ }
36
+
37
+ }
app/code/community/Iksanika/Productrelater/Model/Resource/Eav/Mysql4/Product/Collection.php CHANGED
@@ -16,4 +16,28 @@
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
- class Iksanika_Productrelater_Model_Resource_Eav_Mysql4_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection {public function getSelectCountSql(){$this->_renderFilters();$countSelect = clone $this->getSelect();$countSelect->reset(Zend_Db_Select::ORDER);$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);$countSelect->reset(Zend_Db_Select::COLUMNS);if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0){$countSelect->reset(Zend_Db_Select::GROUP);$countSelect->distinct(true);$group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);$countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");} else {$countSelect->columns('COUNT(*)');}return $countSelect;}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
+ class Iksanika_Productrelater_Model_Resource_Eav_Mysql4_Product_Collection
20
+ extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
21
+ {
22
+
23
+ public function getSelectCountSql()
24
+ {
25
+ $this->_renderFilters();
26
+ $countSelect = clone $this->getSelect();
27
+ $countSelect->reset(Zend_Db_Select::ORDER);
28
+ $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
29
+ $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
30
+ $countSelect->reset(Zend_Db_Select::COLUMNS);
31
+ if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0)
32
+ {
33
+ $countSelect->reset(Zend_Db_Select::GROUP);
34
+ $countSelect->distinct(true);
35
+ $group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
36
+ $countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
37
+ } else {
38
+ $countSelect->columns('COUNT(*)');
39
+ }
40
+ return $countSelect;
41
+ }
42
+
43
+ }
app/code/community/Iksanika/Productrelater/controllers/Adminhtml/ProductrelaterController.php ADDED
@@ -0,0 +1,431 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Iksanika llc.
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the EULA
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://www.iksanika.com/products/IKS-LICENSE.txt
12
+ *
13
+ * @category Iksanika
14
+ * @package Iksanika_Productrelater
15
+ * @copyright Copyright (c) 2013 Iksanika llc. (http://www.iksanika.com)
16
+ * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
+ */
18
+
19
+ include_once "Mage/Adminhtml/controllers/Catalog/ProductController.php";
20
+
21
+ class Iksanika_Productrelater_Adminhtml_ProductrelaterController extends Mage_Adminhtml_Catalog_ProductController
22
+ {
23
+ protected function _construct()
24
+ {
25
+ $this->setUsedModuleName('Iksanika_Productrelater');
26
+ }
27
+
28
+ public function indexAction()
29
+ {
30
+ $this->loadLayout();
31
+ $this->_setActiveMenu('catalog/productrelater');
32
+ $this->_addContent($this->getLayout()->createBlock('productrelater/catalog_product'));
33
+ $this->renderLayout();
34
+ }
35
+
36
+ public function gridAction()
37
+ {
38
+ $this->loadLayout();
39
+ $this->getResponse()->setBody($this->getLayout()->createBlock('productrelater/catalog_product_grid')->toHtml());
40
+ }
41
+
42
+ protected function _isAllowed()
43
+ {
44
+ return Mage::getSingleton('admin/session')->isAllowed('catalog/products');
45
+ }
46
+
47
+ public function massUpdateProductsAction()
48
+ {
49
+ $productIds = $this->getRequest()->getParam('product');
50
+
51
+ if (is_array($productIds))
52
+ {
53
+ try {
54
+
55
+ foreach ($productIds as $itemId => $productId)
56
+ {
57
+ $product = Mage::getModel('catalog/product')->load($productId);
58
+ $productBefore = $product;
59
+
60
+ // event was not dispached by some reasons ??? so the code to prove product is below
61
+ // if ($this->massactionEventDispatchEnabled)
62
+ // Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
63
+
64
+ $columnForUpdate = array('related_ids', 'cross_sell_ids', 'up_sell_ids');
65
+
66
+ foreach($columnForUpdate as $columnName)
67
+ {
68
+ $columnValuesForUpdate = $this->getRequest()->getParam($columnName);
69
+ // handle exceptional situation or related tables savings
70
+ if($columnName == 'related_ids')
71
+ {
72
+ $relatedIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();
73
+ $link = $this->getRelatedLinks($relatedIds, array(), $productId);
74
+ $product->setRelatedLinkData($link);
75
+ }else
76
+ if($columnName == 'cross_sell_ids')
77
+ {
78
+ $crossSellIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();
79
+ $link = $this->getRelatedLinks($crossSellIds, array(), $productId);
80
+ $product->setCrossSellLinkData($link);
81
+ }else
82
+ if($columnName == 'up_sell_ids')
83
+ {
84
+ $upSellIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();
85
+ $link = $this->getRelatedLinks($upSellIds, array(), $productId);
86
+ $product->setUpSellLinkData($link);
87
+ }
88
+ }
89
+ $product->save();
90
+ }
91
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully refreshed.', count($productIds)));
92
+ } catch (Exception $e)
93
+ {
94
+ $this->_getSession()->addError($e->getMessage());
95
+ }
96
+ }else
97
+ {
98
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
99
+ }
100
+ $this->_redirect('*/*/index');
101
+ }
102
+
103
+
104
+
105
+ public function getRelatedLinks($productIds, $existProducts, $productId)
106
+ {
107
+ $link = array();
108
+ foreach ($productIds as $relatedToId)
109
+ {
110
+ if ($productId != $relatedToId)
111
+ {
112
+ $link[$relatedToId] = array('position' => null);
113
+ }
114
+ }
115
+ // Fetch and append to already related products.
116
+ foreach($existProducts as $existProduct)
117
+ {
118
+ $link[$existProduct->getId()] = array('position' => null);
119
+ }
120
+ return $link;
121
+ }
122
+
123
+ /**************************************************************************
124
+ ** MAKE PRODUCTS RELATED
125
+ **************************************************************************/
126
+
127
+
128
+ /**
129
+ * Action make cheched products list related to each other.
130
+ **/
131
+ public function massRelatedEachOtherAction()
132
+ {
133
+ $productIds = $this->getRequest()->getParam('product');
134
+ if (is_array($productIds))
135
+ {
136
+ try {
137
+ foreach ($productIds as $productId)
138
+ {
139
+ //echo '<br/>step 1: '.$productId;
140
+ $product = Mage::getModel('catalog/product')->load($productId);
141
+ $link = $this->getRelatedLinks($productIds, $product->getRelatedProducts(), $productId);
142
+ $product->setRelatedLinkData($link);
143
+ //echo '<br/>step 2: '.$productId;
144
+
145
+ if ($this->massactionEventDispatchEnabled)
146
+ {
147
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
148
+ }
149
+ //echo '<br/>step 3: '.$productId;
150
+ $product->save();
151
+ //echo '<br/>step 4: '.$productId;
152
+ }
153
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully related to each other.', count($productIds)));
154
+ } catch (Exception $e)
155
+ {
156
+ //var_dump($productIds);
157
+ //die();
158
+ $this->_getSession()->addError($e->getMessage());
159
+ }
160
+ }else
161
+ {
162
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
163
+ }
164
+ //die();
165
+ $this->_redirect('*/*/index');
166
+ }
167
+
168
+
169
+
170
+ /**
171
+ * Action which make selected products to specified products list (IDs)
172
+ **/
173
+ public function massRelatedToAction()
174
+ {
175
+ $productIds = $this->getRequest()->getParam('product');
176
+ $productIds2List = $this->getRequest()->getParam('callbackval');
177
+ $productIds2 = explode(',', $productIds2List);
178
+
179
+ if (is_array($productIds))
180
+ {
181
+ try {
182
+ foreach ($productIds as $productId)
183
+ {
184
+ $product = Mage::getModel('catalog/product')->load($productId);
185
+ $link = $this->getRelatedLinks($productIds2, $product->getRelatedProducts(), $productId);
186
+ $product->setRelatedLinkData($link);
187
+
188
+ if ($this->massactionEventDispatchEnabled)
189
+ {
190
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
191
+ }
192
+ $product->save();
193
+ }
194
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully related to products('.$productIds2List.').', count($productIds)));
195
+ } catch (Exception $e)
196
+ {
197
+ $this->_getSession()->addError($e->getMessage());
198
+ }
199
+ }else
200
+ {
201
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
202
+ }
203
+ $this->_redirect('*/*/index');
204
+ }
205
+
206
+
207
+
208
+ /**
209
+ * Action remove all relation in checked products list.
210
+ **/
211
+ public function massRelatedCleanAction()
212
+ {
213
+ $productIds = $this->getRequest()->getParam('product');
214
+ if (is_array($productIds))
215
+ {
216
+ try {
217
+ foreach ($productIds as $productId)
218
+ {
219
+ $product = Mage::getModel('catalog/product')->load($productId);
220
+ $product->setRelatedLinkData(array());
221
+ if ($this->massactionEventDispatchEnabled)
222
+ {
223
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
224
+ }
225
+ $product->save();
226
+ }
227
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) are no longer related to any other products.', count($productIds)));
228
+ } catch (Exception $e)
229
+ {
230
+ $this->_getSession()->addError($e->getMessage());
231
+ }
232
+ }else
233
+ {
234
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
235
+ }
236
+ $this->_redirect('*/*/index');
237
+ }
238
+
239
+
240
+
241
+
242
+
243
+
244
+
245
+ /***************************************************************************
246
+ ** Cross-Selling
247
+ **************************************************************************/
248
+
249
+
250
+ /**
251
+ * This will cross sell all products with each other.
252
+ **/
253
+ public function massCrossSellEachOtherAction()
254
+ {
255
+ $productIds = $this->getRequest()->getParam('product');
256
+ if (is_array($productIds))
257
+ {
258
+ try {
259
+ foreach ($productIds as $productId)
260
+ {
261
+ $product = Mage::getModel('catalog/product')->load($productId);
262
+ $link = $this->getRelatedLinks($productIds, $product->getCrossSellProducts(), $productId);
263
+ $product->setCrossSellLinkData($link);
264
+
265
+ if ($this->massactionEventDispatchEnabled)
266
+ {
267
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
268
+ }
269
+ $product->save();
270
+ }
271
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully cross-related to each other.', count($productIds)));
272
+ } catch (Exception $e)
273
+ {
274
+ $this->_getSession()->addError($e->getMessage());
275
+ }
276
+ }else
277
+ {
278
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
279
+ }
280
+ $this->_redirect('*/*/index');
281
+ }
282
+
283
+
284
+
285
+ /**
286
+ * This will relate all products to a specifc list of products
287
+ **/
288
+ public function massCrossSellToAction()
289
+ {
290
+ $productIds = $this->getRequest()->getParam('product');
291
+ $productIds2List = $this->getRequest()->getParam('callbackval');
292
+ $productIds2 = explode(',', $productIds2List);
293
+
294
+ if (is_array($productIds))
295
+ {
296
+ try {
297
+ foreach ($productIds as $productId)
298
+ {
299
+ $product = Mage::getModel('catalog/product')->load($productId);
300
+ $link = $this->getRelatedLinks($productIds2, $product->getCrossSellProducts(), $productId);
301
+ $product->setCrossSellLinkData($link);
302
+
303
+ if ($this->massactionEventDispatchEnabled)
304
+ {
305
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
306
+ }
307
+ $product->save();
308
+ }
309
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully set as cross-sells by products('.$productIds2List.').', count($productIds)));
310
+ } catch (Exception $e)
311
+ {
312
+ $this->_getSession()->addError($e->getMessage());
313
+ }
314
+ }else
315
+ {
316
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
317
+ }
318
+ $this->_redirect('*/*/index');
319
+ }
320
+
321
+
322
+ /**
323
+ * This will unrelate related product's relations.
324
+ **/
325
+ public function massCrossSellClearAction()
326
+ {
327
+ $productIds = $this->getRequest()->getParam('product');
328
+ if (is_array($productIds))
329
+ {
330
+ try {
331
+ foreach ($productIds as $productId)
332
+ {
333
+ $product = Mage::getModel('catalog/product')->load($productId);
334
+ $product->setCrossSellLinkData(array());
335
+ if ($this->massactionEventDispatchEnabled)
336
+ {
337
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
338
+ }
339
+ $product->save();
340
+ }
341
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) now have no products as cross sell links.', count($productIds)));
342
+ } catch (Exception $e)
343
+ {
344
+ $this->_getSession()->addError($e->getMessage());
345
+ }
346
+ }else
347
+ {
348
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
349
+ }
350
+ $this->_redirect('*/*/index');
351
+ }
352
+
353
+
354
+
355
+
356
+
357
+ /***************************************************************************
358
+ ** Up-Selling
359
+ **************************************************************************/
360
+
361
+
362
+ /**
363
+ * This will relate all products to a specifc list of products
364
+ **/
365
+ public function massUpSellToAction()
366
+ {
367
+ $productIds = $this->getRequest()->getParam('product');
368
+ $productIds2List = $this->getRequest()->getParam('callbackval');
369
+ $productIds2 = explode(',', $productIds2List);
370
+
371
+ if (is_array($productIds))
372
+ {
373
+ try {
374
+ foreach ($productIds as $productId)
375
+ {
376
+ $product = Mage::getModel('catalog/product')->load($productId);
377
+ $link = $this->getRelatedLinks($productIds2, $product->getUpSellProducts(), $productId);
378
+ $product->setUpSellLinkData($link);
379
+
380
+ if ($this->massactionEventDispatchEnabled)
381
+ {
382
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
383
+ }
384
+ $product->save();
385
+ }
386
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) are now up-sold by products('.$productIds2List.').', count($productIds)));
387
+ } catch (Exception $e)
388
+ {
389
+ $this->_getSession()->addError($e->getMessage());
390
+ }
391
+ }else
392
+ {
393
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
394
+ }
395
+ $this->_redirect('*/*/index');
396
+ }
397
+
398
+
399
+
400
+ /**
401
+ * This will unrelate related product's relations.
402
+ **/
403
+ public function massUpSellClearAction()
404
+ {
405
+ $productIds = $this->getRequest()->getParam('product');
406
+ if (is_array($productIds))
407
+ {
408
+ try {
409
+ foreach ($productIds as $productId)
410
+ {
411
+ $product = Mage::getModel('catalog/product')->load($productId);
412
+ $product->setUpSellLinkData(array());
413
+ if ($this->massactionEventDispatchEnabled)
414
+ {
415
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
416
+ }
417
+ $product->save();
418
+ }
419
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) now have 0 up-sells', count($productIds)));
420
+ } catch (Exception $e)
421
+ {
422
+ $this->_getSession()->addError($e->getMessage());
423
+ }
424
+ }else
425
+ {
426
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
427
+ }
428
+ $this->_redirect('*/*/index');
429
+ }
430
+
431
+ }
app/code/community/Iksanika/Productrelater/controllers/Catalog/ProductController.php CHANGED
@@ -16,5 +16,409 @@
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
- include_once "Mage/Adminhtml/controllers/Catalog/ProductController.php";class Iksanika_Productrelater_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController {protected function _construct(){$this->setUsedModuleName('Iksanika_Productrelater');}public function indexAction(){$this->loadLayout();$this->_setActiveMenu('catalog/productrelater');$this->_addContent($this->getLayout()->createBlock('productrelater/catalog_product'));$this->renderLayout();} public function gridAction() {$this->loadLayout();$this->getResponse()->setBody($this->getLayout()->createBlock('productrelater/catalog_product_grid')->toHtml());}protected function _isAllowed(){return Mage::getSingleton('admin/session')->isAllowed('catalog/products');}public function massUpdateProductsAction(){$productIds = $this->getRequest()->getParam('product');if (is_array($productIds)){try {foreach ($productIds as $itemId => $productId){$product = Mage::getModel('catalog/product')->load($productId);$productBefore = $product;$columnForUpdate = array('related_ids', 'cross_sell_ids', 'up_sell_ids');foreach($columnForUpdate as $columnName){$columnValuesForUpdate = $this->getRequest()->getParam($columnName);if($columnName == 'related_ids'){$relatedIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();$link = $this->getRelatedLinks($relatedIds, array(), $productId);$product->setRelatedLinkData($link);}else if($columnName == 'cross_sell_ids'){$crossSellIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();$link = $this->getRelatedLinks($crossSellIds, array(), $productId);$product->setCrossSellLinkData($link);}else if($columnName == 'up_sell_ids'){$upSellIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();$link = $this->getRelatedLinks($upSellIds, array(), $productId);$product->setUpSellLinkData($link);}}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully refreshed.', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));}$this->_redirect('*/*/index');}public function getRelatedLinks($productIds, $existProducts, $productId){$link = array();foreach ($productIds as $relatedToId){if ($productId != $relatedToId){$link[$relatedToId] = array('position' => null);}}foreach($existProducts as $existProduct){$link[$existProduct->getId()] = array('position' => null);}return $link;} public function massRelatedEachOtherAction(){$productIds = $this->getRequest()->getParam('product');if (is_array($productIds)){try {foreach ($productIds as $productId){$product = Mage::getModel('catalog/product')->load($productId);$link = $this->getRelatedLinks($productIds, $product->getRelatedProducts(), $productId);$product->setRelatedLinkData($link);if ($this->massactionEventDispatchEnabled){Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully related to each other.', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));}$this->_redirect('*/*/index');}public function massRelatedToAction(){$productIds = $this->getRequest()->getParam('product');$productIds2List = $this->getRequest()->getParam('callbackval');$productIds2 = explode(',', $productIds2List);if (is_array($productIds)){try {foreach ($productIds as $productId){$product = Mage::getModel('catalog/product')->load($productId);$link = $this->getRelatedLinks($productIds2, $product->getRelatedProducts(), $productId);$product->setRelatedLinkData($link);if ($this->massactionEventDispatchEnabled){Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully related to products('.$productIds2List.').', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));}$this->_redirect('*/*/index');}public function massRelatedCleanAction(){$productIds = $this->getRequest()->getParam('product');if (is_array($productIds)){try {foreach ($productIds as $productId){$product = Mage::getModel('catalog/product')->load($productId);$product->setRelatedLinkData(array());if ($this->massactionEventDispatchEnabled){Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) are no longer related to any other products.', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));}$this->_redirect('*/*/index');}public function massCrossSellEachOtherAction(){$productIds = $this->getRequest()->getParam('product');if (is_array($productIds)){try {foreach ($productIds as $productId){$product = Mage::getModel('catalog/product')->load($productId);$link = $this->getRelatedLinks($productIds, $product->getCrossSellProducts(), $productId);$product->setCrossSellLinkData($link);if ($this->massactionEventDispatchEnabled){Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully cross-related to each other.', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));}$this->_redirect('*/*/index');}public function massCrossSellToAction(){$productIds = $this->getRequest()->getParam('product');$productIds2List = $this->getRequest()->getParam('callbackval');$productIds2 = explode(',', $productIds2List);if (is_array($productIds)){try {foreach ($productIds as $productId){$product = Mage::getModel('catalog/product')->load($productId);$link = $this->getRelatedLinks($productIds2, $product->getCrossSellProducts(), $productId);$product->setCrossSellLinkData($link);if ($this->massactionEventDispatchEnabled){Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully set as cross-sells by products('.$productIds2List.').', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));}$this->_redirect('*/*/index');}public function massCrossSellClearAction(){$productIds = $this->getRequest()->getParam('product');if (is_array($productIds)){try {foreach ($productIds as $productId){$product = Mage::getModel('catalog/product')->load($productId);$product->setCrossSellLinkData(array());if ($this->massactionEventDispatchEnabled){Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) now have no products as cross sell links.', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)'));}$this->_redirect('*/*/index');} public function massUpSellToAction(){$productIds = $this->getRequest()->getParam('product');$productIds2List = $this->getRequest()->getParam('callbackval');$productIds2 = explode(',', $productIds2List);if (is_array($productIds)){try {foreach ($productIds as $productId){$product = Mage::getModel('catalog/product')->load($productId);$link = $this->getRelatedLinks($productIds2, $product->getUpSellProducts(), $productId);$product->setUpSellLinkData($link);if ($this->massactionEventDispatchEnabled){Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) are now up-sold by products('.$productIds2List.').', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));}$this->_redirect('*/*/index');} public function massUpSellClearAction(){$productIds = $this->getRequest()->getParam('product');if (is_array($productIds)){try {foreach ($productIds as $productId){$product = Mage::getModel('catalog/product')->load($productId);$product->setUpSellLinkData(array());if ($this->massactionEventDispatchEnabled){Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));}$product->save();}$this->_getSession()->addSuccess($this->__('Total of %d record(s) now have 0 up-sells', count($productIds)));} catch (Exception $e){$this->_getSession()->addError($e->getMessage());}}else{$this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));}$this->_redirect('*/*/index');}}
20
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  * @license http://www.iksanika.com/products/IKS-LICENSE.txt
17
  */
18
 
19
+ include_once "Mage/Adminhtml/controllers/Catalog/ProductController.php";
20
+
21
+ class Iksanika_Productrelater_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController
22
+ {
23
+ protected function _construct()
24
+ {
25
+ $this->setUsedModuleName('Iksanika_Productrelater');
26
+ }
27
+
28
+ public function indexAction()
29
+ {
30
+ $this->loadLayout();
31
+ $this->_setActiveMenu('catalog/productrelater');
32
+ $this->_addContent($this->getLayout()->createBlock('productrelater/catalog_product'));
33
+ $this->renderLayout();
34
+ }
35
+
36
+ public function gridAction()
37
+ {
38
+ $this->loadLayout();
39
+ $this->getResponse()->setBody($this->getLayout()->createBlock('productrelater/catalog_product_grid')->toHtml());
40
+ }
41
+
42
+ protected function _isAllowed()
43
+ {
44
+ return Mage::getSingleton('admin/session')->isAllowed('catalog/products');
45
+ }
46
+
47
+ public function massUpdateProductsAction()
48
+ {
49
+ $productIds = $this->getRequest()->getParam('product');
50
+
51
+ if (is_array($productIds))
52
+ {
53
+ try {
54
+
55
+ foreach ($productIds as $itemId => $productId)
56
+ {
57
+ $product = Mage::getModel('catalog/product')->load($productId);
58
+ $productBefore = $product;
59
+
60
+ // event was not dispached by some reasons ??? so the code to prove product is below
61
+ // if ($this->massactionEventDispatchEnabled)
62
+ // Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
63
+
64
+ $columnForUpdate = array('related_ids', 'cross_sell_ids', 'up_sell_ids');
65
+
66
+ foreach($columnForUpdate as $columnName)
67
+ {
68
+ $columnValuesForUpdate = $this->getRequest()->getParam($columnName);
69
+ // handle exceptional situation or related tables savings
70
+ if($columnName == 'related_ids')
71
+ {
72
+ $relatedIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();
73
+ $link = $this->getRelatedLinks($relatedIds, array(), $productId);
74
+ $product->setRelatedLinkData($link);
75
+ }else
76
+ if($columnName == 'cross_sell_ids')
77
+ {
78
+ $crossSellIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();
79
+ $link = $this->getRelatedLinks($crossSellIds, array(), $productId);
80
+ $product->setCrossSellLinkData($link);
81
+ }else
82
+ if($columnName == 'up_sell_ids')
83
+ {
84
+ $upSellIds = trim($columnValuesForUpdate[$itemId]) != "" ? explode(',', trim($columnValuesForUpdate[$itemId])) : array();
85
+ $link = $this->getRelatedLinks($upSellIds, array(), $productId);
86
+ $product->setUpSellLinkData($link);
87
+ }
88
+ }
89
+ $product->save();
90
+ }
91
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully refreshed.', count($productIds)));
92
+ } catch (Exception $e)
93
+ {
94
+ $this->_getSession()->addError($e->getMessage());
95
+ }
96
+ }else
97
+ {
98
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
99
+ }
100
+ $this->_redirect('*/*/index');
101
+ }
102
+
103
+
104
+
105
+ public function getRelatedLinks($productIds, $existProducts, $productId)
106
+ {
107
+ $link = array();
108
+ foreach ($productIds as $relatedToId)
109
+ {
110
+ if ($productId != $relatedToId)
111
+ {
112
+ $link[$relatedToId] = array('position' => null);
113
+ }
114
+ }
115
+ // Fetch and append to already related products.
116
+ foreach($existProducts as $existProduct)
117
+ {
118
+ $link[$existProduct->getId()] = array('position' => null);
119
+ }
120
+ return $link;
121
+ }
122
+
123
+ /**************************************************************************
124
+ ** MAKE PRODUCTS RELATED
125
+ **************************************************************************/
126
+
127
+
128
+ /**
129
+ * Action make cheched products list related to each other.
130
+ **/
131
+ public function massRelatedEachOtherAction()
132
+ {
133
+ $productIds = $this->getRequest()->getParam('product');
134
+ if (is_array($productIds))
135
+ {
136
+ try {
137
+ foreach ($productIds as $productId)
138
+ {
139
+ $product = Mage::getModel('catalog/product')->load($productId);
140
+ $link = $this->getRelatedLinks($productIds, $product->getRelatedProducts(), $productId);
141
+ $product->setRelatedLinkData($link);
142
+
143
+ if ($this->massactionEventDispatchEnabled)
144
+ {
145
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
146
+ }
147
+ $product->save();
148
+ }
149
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully related to each other.', count($productIds)));
150
+ } catch (Exception $e)
151
+ {
152
+ $this->_getSession()->addError($e->getMessage());
153
+ }
154
+ }else
155
+ {
156
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
157
+ }
158
+ $this->_redirect('*/*/index');
159
+ }
160
+
161
+
162
+
163
+ /**
164
+ * Action which make selected products to specified products list (IDs)
165
+ **/
166
+ public function massRelatedToAction()
167
+ {
168
+ $productIds = $this->getRequest()->getParam('product');
169
+ $productIds2List = $this->getRequest()->getParam('callbackval');
170
+ $productIds2 = explode(',', $productIds2List);
171
+
172
+ if (is_array($productIds))
173
+ {
174
+ try {
175
+ foreach ($productIds as $productId)
176
+ {
177
+ $product = Mage::getModel('catalog/product')->load($productId);
178
+ $link = $this->getRelatedLinks($productIds2, $product->getRelatedProducts(), $productId);
179
+ $product->setRelatedLinkData($link);
180
+
181
+ if ($this->massactionEventDispatchEnabled)
182
+ {
183
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
184
+ }
185
+ $product->save();
186
+ }
187
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully related to products('.$productIds2List.').', count($productIds)));
188
+ } catch (Exception $e)
189
+ {
190
+ $this->_getSession()->addError($e->getMessage());
191
+ }
192
+ }else
193
+ {
194
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
195
+ }
196
+ $this->_redirect('*/*/index');
197
+ }
198
+
199
+
200
+
201
+ /**
202
+ * Action remove all relation in checked products list.
203
+ **/
204
+ public function massRelatedCleanAction()
205
+ {
206
+ $productIds = $this->getRequest()->getParam('product');
207
+ if (is_array($productIds))
208
+ {
209
+ try {
210
+ foreach ($productIds as $productId)
211
+ {
212
+ $product = Mage::getModel('catalog/product')->load($productId);
213
+ $product->setRelatedLinkData(array());
214
+ if ($this->massactionEventDispatchEnabled)
215
+ {
216
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
217
+ }
218
+ $product->save();
219
+ }
220
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) are no longer related to any other products.', count($productIds)));
221
+ } catch (Exception $e)
222
+ {
223
+ $this->_getSession()->addError($e->getMessage());
224
+ }
225
+ }else
226
+ {
227
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
228
+ }
229
+ $this->_redirect('*/*/index');
230
+ }
231
+
232
+
233
+
234
+
235
+
236
+
237
+
238
+ /***************************************************************************
239
+ ** Cross-Selling
240
+ **************************************************************************/
241
+
242
+
243
+ /**
244
+ * This will cross sell all products with each other.
245
+ **/
246
+ public function massCrossSellEachOtherAction()
247
+ {
248
+ $productIds = $this->getRequest()->getParam('product');
249
+ if (is_array($productIds))
250
+ {
251
+ try {
252
+ foreach ($productIds as $productId)
253
+ {
254
+ $product = Mage::getModel('catalog/product')->load($productId);
255
+ $link = $this->getRelatedLinks($productIds, $product->getCrossSellProducts(), $productId);
256
+ $product->setCrossSellLinkData($link);
257
+
258
+ if ($this->massactionEventDispatchEnabled)
259
+ {
260
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
261
+ }
262
+ $product->save();
263
+ }
264
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully cross-related to each other.', count($productIds)));
265
+ } catch (Exception $e)
266
+ {
267
+ $this->_getSession()->addError($e->getMessage());
268
+ }
269
+ }else
270
+ {
271
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
272
+ }
273
+ $this->_redirect('*/*/index');
274
+ }
275
+
276
+
277
+
278
+ /**
279
+ * This will relate all products to a specifc list of products
280
+ **/
281
+ public function massCrossSellToAction()
282
+ {
283
+ $productIds = $this->getRequest()->getParam('product');
284
+ $productIds2List = $this->getRequest()->getParam('callbackval');
285
+ $productIds2 = explode(',', $productIds2List);
286
+
287
+ if (is_array($productIds))
288
+ {
289
+ try {
290
+ foreach ($productIds as $productId)
291
+ {
292
+ $product = Mage::getModel('catalog/product')->load($productId);
293
+ $link = $this->getRelatedLinks($productIds2, $product->getCrossSellProducts(), $productId);
294
+ $product->setCrossSellLinkData($link);
295
+
296
+ if ($this->massactionEventDispatchEnabled)
297
+ {
298
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
299
+ }
300
+ $product->save();
301
+ }
302
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully set as cross-sells by products('.$productIds2List.').', count($productIds)));
303
+ } catch (Exception $e)
304
+ {
305
+ $this->_getSession()->addError($e->getMessage());
306
+ }
307
+ }else
308
+ {
309
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
310
+ }
311
+ $this->_redirect('*/*/index');
312
+ }
313
+
314
+
315
+ /**
316
+ * This will unrelate related product's relations.
317
+ **/
318
+ public function massCrossSellClearAction()
319
+ {
320
+ $productIds = $this->getRequest()->getParam('product');
321
+ if (is_array($productIds))
322
+ {
323
+ try {
324
+ foreach ($productIds as $productId)
325
+ {
326
+ $product = Mage::getModel('catalog/product')->load($productId);
327
+ $product->setCrossSellLinkData(array());
328
+ if ($this->massactionEventDispatchEnabled)
329
+ {
330
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
331
+ }
332
+ $product->save();
333
+ }
334
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) now have no products as cross sell links.', count($productIds)));
335
+ } catch (Exception $e)
336
+ {
337
+ $this->_getSession()->addError($e->getMessage());
338
+ }
339
+ }else
340
+ {
341
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
342
+ }
343
+ $this->_redirect('*/*/index');
344
+ }
345
+
346
+
347
+
348
+
349
+
350
+ /***************************************************************************
351
+ ** Up-Selling
352
+ **************************************************************************/
353
+
354
+
355
+ /**
356
+ * This will relate all products to a specifc list of products
357
+ **/
358
+ public function massUpSellToAction()
359
+ {
360
+ $productIds = $this->getRequest()->getParam('product');
361
+ $productIds2List = $this->getRequest()->getParam('callbackval');
362
+ $productIds2 = explode(',', $productIds2List);
363
+
364
+ if (is_array($productIds))
365
+ {
366
+ try {
367
+ foreach ($productIds as $productId)
368
+ {
369
+ $product = Mage::getModel('catalog/product')->load($productId);
370
+ $link = $this->getRelatedLinks($productIds2, $product->getUpSellProducts(), $productId);
371
+ $product->setUpSellLinkData($link);
372
+
373
+ if ($this->massactionEventDispatchEnabled)
374
+ {
375
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
376
+ }
377
+ $product->save();
378
+ }
379
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) are now up-sold by products('.$productIds2List.').', count($productIds)));
380
+ } catch (Exception $e)
381
+ {
382
+ $this->_getSession()->addError($e->getMessage());
383
+ }
384
+ }else
385
+ {
386
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
387
+ }
388
+ $this->_redirect('*/*/index');
389
+ }
390
+
391
+
392
+
393
+ /**
394
+ * This will unrelate related product's relations.
395
+ **/
396
+ public function massUpSellClearAction()
397
+ {
398
+ $productIds = $this->getRequest()->getParam('product');
399
+ if (is_array($productIds))
400
+ {
401
+ try {
402
+ foreach ($productIds as $productId)
403
+ {
404
+ $product = Mage::getModel('catalog/product')->load($productId);
405
+ $product->setUpSellLinkData(array());
406
+ if ($this->massactionEventDispatchEnabled)
407
+ {
408
+ Mage::dispatchEvent('catalog_product_prepare_save', array('product' => $product, 'request' => $this->getRequest()));
409
+ }
410
+ $product->save();
411
+ }
412
+ $this->_getSession()->addSuccess($this->__('Total of %d record(s) now have 0 up-sells', count($productIds)));
413
+ } catch (Exception $e)
414
+ {
415
+ $this->_getSession()->addError($e->getMessage());
416
+ }
417
+ }else
418
+ {
419
+ $this->_getSession()->addError($this->__('Please select product(s)').'. '.$this->__('You should select checkboxes for each product row which should be updated. You can click on checkboxes or use CTRL+Click on product row which should be selected.'));
420
+ }
421
+ $this->_redirect('*/*/index');
422
+ }
423
+
424
+ }
app/code/community/Iksanika/Productrelater/etc/config.xml CHANGED
@@ -2,20 +2,29 @@
2
  <config>
3
  <modules>
4
  <Iksanika_Productrelater>
5
- <version>1.0.0</version>
6
  </Iksanika_Productrelater>
7
  </modules>
8
  <admin>
9
  <routers>
 
 
 
 
 
 
 
 
10
  <productrelater>
11
- <!-- should be set to "admin" when overloading admin stuff (?) -->
12
  <use>admin</use>
13
  <args>
14
  <module>Iksanika_Productrelater</module>
15
- <!-- This is used when "catching" the rewrite above -->
16
  <frontName>productrelater</frontName>
17
  </args>
18
  </productrelater>
 
19
  </routers>
20
  </admin>
21
  <global>
@@ -60,7 +69,8 @@
60
  <productrelater module="productrelater">
61
  <title>Mass Product Relater</title>
62
  <sort_order>0</sort_order>
63
- <action>productrelater/catalog_product</action>
 
64
  </productrelater>
65
  </children>
66
  </catalog>
2
  <config>
3
  <modules>
4
  <Iksanika_Productrelater>
5
+ <version>1.0.2</version>
6
  </Iksanika_Productrelater>
7
  </modules>
8
  <admin>
9
  <routers>
10
+ <adminhtml>
11
+ <args>
12
+ <modules>
13
+ <productrelater after="Mage_Adminhtml">Iksanika_Productrelater_Adminhtml</productrelater>
14
+ </modules>
15
+ </args>
16
+ </adminhtml>
17
+ <!--
18
  <productrelater>
19
+ < ! - - should be set to "admin" when overloading admin stuff (?) - - >
20
  <use>admin</use>
21
  <args>
22
  <module>Iksanika_Productrelater</module>
23
+ < ! - - This is used when "catching" the rewrite above - - >
24
  <frontName>productrelater</frontName>
25
  </args>
26
  </productrelater>
27
+ -->
28
  </routers>
29
  </admin>
30
  <global>
69
  <productrelater module="productrelater">
70
  <title>Mass Product Relater</title>
71
  <sort_order>0</sort_order>
72
+ <!-- <action>productrelater/catalog_product</action> -->
73
+ <action>adminhtml/productrelater/index</action>
74
  </productrelater>
75
  </children>
76
  </catalog>
app/code/community/Iksanika/Productrelater/etc/config.xml.0.nblh~ ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Iksanika_ProductUpdater>
5
+ <version>0.1.0</version>
6
+ </Iksanika_ProductUpdater>
7
+ </modules>
8
+ <admin>
9
+ <routers>
10
+ <Iksanika_ProductUpdater>
11
+ <use>admin</use>
12
+ <args>
13
+ <module>Iksanika_ProductUpdater</module>
14
+ <frontName>product_updater</frontName>
15
+ </args>
16
+ </Iksanika_ProductUpdater>
17
+ </routers>
18
+ </admin>
19
+ <adminhtml>
20
+ <acl>
21
+ <resources>
22
+ <all>
23
+ <title>Allow Everything</title>
24
+ </all>
25
+ <admin>
26
+ <children>
27
+ <Iksanika_ProductUpdater>
28
+ <title>Product Updater Module</title>
29
+ <sort_order>10</sort_order>
30
+ </Iksanika_ProductUpdater>
31
+ </children>
32
+ </admin>
33
+ </resources>
34
+ </acl>
35
+ <layout>
36
+ <updates>
37
+ <Iksanika_ProductUpdater>
38
+ <file>product_updater.xml</file>
39
+ </Iksanika_ProductUpdater>
40
+ </updates>
41
+ </layout>
42
+ </adminhtml>
43
+ <global>
44
+ <blocks>
45
+ <Iksanika_ProductUpdater>
46
+ <class>Iksanika_ProductUpdater_Block</class>
47
+ </Iksanika_ProductUpdater>
48
+ </blocks>
49
+ <helpers>
50
+ <Iksanika_ProductUpdater>
51
+ <class>Iksanika_ProductUpdater_Base_Helper</class>
52
+ </Iksanika_ProductUpdater>
53
+ </helpers>
54
+ </global>
55
+ </config>
app/design/adminhtml/default/default/layout/iksanika_productrelater.xml CHANGED
@@ -1,7 +1,14 @@
1
  <?xml version="1.0"?>
2
  <layout>
3
- <default>
 
4
  <reference name="head">
 
 
 
 
 
 
5
  <action method="addJs">
6
  <script>Iksanika/productrelater/jquery-1.9.1.min.js</script>
7
  </action>
@@ -18,6 +25,8 @@
18
  <type>js_css</type>
19
  <name>Iksanika/productrelater/resources/css/productrelater.css</name>
20
  </action>
 
21
  </reference>
22
- </default>
 
23
  </layout>
1
  <?xml version="1.0"?>
2
  <layout>
3
+ <adminhtml_productrelater_index>
4
+ <!-- <default> -->
5
  <reference name="head">
6
+ <action method="addJs"><js>Iksanika/productrelater/jquery-1.9.1.min.js</js></action>
7
+ <action method="addJs"><js>Iksanika/productrelater/relaterproducts.js</js></action>
8
+ <action method="addJs"><js>Iksanika/productrelater/relatergrid.js</js></action>
9
+ <action method="addJs"><js>Iksanika/productrelater/egsupplemental.js</js></action>
10
+ <action method="addCss"><css>Iksanika/productrelater/resources/css/productrelater.css</css></action>
11
+ <!--
12
  <action method="addJs">
13
  <script>Iksanika/productrelater/jquery-1.9.1.min.js</script>
14
  </action>
25
  <type>js_css</type>
26
  <name>Iksanika/productrelater/resources/css/productrelater.css</name>
27
  </action>
28
+ -->
29
  </reference>
30
+ <!-- </default> -->
31
+ </adminhtml_productrelater_index>
32
  </layout>
media/iksanika/productrelater/iksanika-logo.png DELETED
Binary file
package.xml CHANGED
@@ -1,21 +1,20 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Iksanika_Productrelater</name>
4
- <version>1.0.1.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.iksanika.com/products/IKS-LICENSE.txt">IKS-LICENSE</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Mass assign up-sell, cross-sell and related products easily - hands, 2-way, multi-way algorithms available.</summary>
10
- <description>Save up to 98% of your time and grow up revenue up to additional 40% on cross-, up- and related - sell products in your Magento store. &#xD;
11
- &#xD;
12
- * One Page Bulk Products Update With In-grid Editable Fields for Up-Sell, Cross-Sell and Related products ids fields which allow you easy filter by cross-sell,up-sell, related products and add, change, delete cross-sell,up-sell, related products on one page for list of products and with one click update feature.&#xD;
13
  * Mass Product Relater actions: Mass Relating Products: One-way relate, multi-relate, or un-relate Mass Cross-selling Products: Mass cross-selling products: One-way cross-sell, multi-cross-sell, or un-cross-sell Mass Up-selling Products: One-way up-sell, un-up-sell</description>
14
- <notes>Pagination hot fix</notes>
15
  <authors><author><name>Iksanika</name><user>iksanika</user><email>info@iksanika.com</email></author></authors>
16
- <date>2013-06-10</date>
17
- <time>22:40:36</time>
18
- <contents><target name="magecommunity"><dir name="Iksanika"><dir name="Productrelater"><dir name="Block"><dir name="Catalog"><dir name="Product"><file name="Grid.php" hash="a0e67eacaa45eb0acf00ed95117d5403"/></dir><file name="Product.php" hash="3f4c56185d797622cdac7b2a9e0dfe30"/></dir><dir name="Widget"><dir name="Grid"><dir name="Column"><dir name="Renderer"><file name="Number.php" hash="ff71da7c2f74726dd0efccd752e393f6"/></dir></dir><file name="Column.php" hash="20d990d79cdd6e975428f6e99d2f2641"/><file name="Massaction.php" hash="a2dcb48c8b1bf5039e72bbff0f81b82e"/></dir><file name="Grid.php" hash="3700b8298380428295d717571565fe8c"/></dir></dir><dir name="Helper"><file name="Data.php" hash="06e4facd290ef54099d3776851a3672a"/></dir><dir name="Model"><dir name="Resource"><dir name="Eav"><dir name="Mysql4"><dir name="Product"><file name="Collection.php" hash="28767c33cd5e5914e9aad1a84e79d7df"/></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Catalog"><file name="ProductController.php" hash="51082ba930014cc627de308261196733"/></dir></dir><dir name="etc"><file name="config.xml" hash="86d21f138cadff8f481dd4e4f827b451"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="iksanika_productrelater.xml" hash="35d21da2b8a52584954952725f64ded6"/></dir><dir name="template"><dir name="iksanika"><dir name="productrelater"><dir name="catalog"><dir name="product"><file name="grid.phtml" hash="246728ccd775d3d2b63874f515398b6e"/></dir><file name="product.phtml" hash="28aa8996480973a016117af744f7c3aa"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Iksanika_Productrelater.xml" hash="e904533beb0e0dc4f819fb271726bd58"/></dir></target><target name="mage"><dir name="js"><dir name="Iksanika"><dir name="productrelater"><file name="egsupplemental.js" hash="22e901dc1b8b22ae69c4c6241781c783"/><file name="jquery-1.9.1.min.js" hash="bcaf50298ada678da29e7cfa62470db5"/><file name="relatergrid.js" hash="0b8f50918dee4ee6fc76198473e6ddb7"/><file name="relaterproducts.js" hash="0045b5bcda3c95981d042aa135864192"/><dir name="resources"><dir name="css"><file name="productrelater.css" hash="a219b0e656329f2407835dbe346f81d3"/></dir></dir></dir></dir></dir><dir name="media"><dir name="iksanika"><dir name="productrelater"><file name="iksanika-logo.png" hash="445fc3621ed89dc3faa37202185e81b0"/></dir></dir></dir></target></contents>
19
  <compatible/>
20
- <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
21
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Iksanika_Productrelater</name>
4
+ <version>1.0.2</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.iksanika.com/products/IKS-LICENSE.txt">IKS-LICENSE</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Mass assign up-sell, cross-sell and related products easily - hands, 2-way, multi-way algorithms available.</summary>
10
+ <description>Save up to 98% of your time and grow up revenue up to additional 40% on cross-, up- and related - sell products in your Magento store.&#xD;
11
+ * One Page Bulk Products Update With In-grid Editable Fields for Up-Sell, Cross-Sell and Related products ids fields which allow you easy filter by cross-sell,up-sell, related products and add, change, delete cross-sell,up-sell, related products on one page for list of products and with one click update feature.&amp;#xD;&#xD;
 
12
  * Mass Product Relater actions: Mass Relating Products: One-way relate, multi-relate, or un-relate Mass Cross-selling Products: Mass cross-selling products: One-way cross-sell, multi-cross-sell, or un-cross-sell Mass Up-selling Products: One-way up-sell, un-up-sell</description>
13
+ <notes>SUPEE routing fixes</notes>
14
  <authors><author><name>Iksanika</name><user>iksanika</user><email>info@iksanika.com</email></author></authors>
15
+ <date>2016-01-14</date>
16
+ <time>19:02:12</time>
17
+ <contents><target name="magecommunity"><dir name="Iksanika"><dir name="Productrelater"><dir><dir name="Block"><dir name="Catalog"><dir name="Product"><file name="Grid.php" hash="a679ed740bdb799e855e26ccbcd7996d"/></dir><file name="Product.php" hash="4d57150fecbec6c8cf568f2738b9a64f"/></dir><dir name="Widget"><dir name="Grid"><dir name="Column"><dir name="Renderer"><file name="Number.php" hash="7929c9fd3a266412f4c0dc3b3343f1b7"/></dir></dir><file name="Column.php" hash="20d990d79cdd6e975428f6e99d2f2641"/><file name="Massaction.php" hash="f5205d1bfa618b7d358498d8b670b372"/></dir><file name="Grid.php" hash="95c04980754bd8da7e937e1667b3cad7"/></dir></dir><dir name="Helper"><file name="Data.php" hash="06e4facd290ef54099d3776851a3672a"/></dir><dir name="Model"><dir name="Resource"><dir name="Eav"><dir name="Mysql4"><dir name="Product"><file name="Collection.php" hash="0e6654868eb324b4d1f7e4a36304078f"/></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="ProductrelaterController.php" hash="e911d0cd46964eca5e2a9dc1b3ea4012"/></dir><dir name="Catalog"><file name="ProductController.php" hash="f8e687ff941203d146f856be3a8fbd5b"/></dir></dir><dir name="etc"><file name="config.xml" hash="cbfd94e230c8168c050839e055680bab"/><file name="config.xml.0.nblh~" hash="2c4e2e32e16c523c9d4e4ebda5939e73"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="iksanika_productrelater.xml" hash="06a83c5fa3781988cb2bba1605fbb367"/></dir><dir name="template"><dir name="iksanika"><dir name="productrelater"><dir><dir name="catalog"><dir name="product"><file name="grid.phtml" hash="246728ccd775d3d2b63874f515398b6e"/></dir><file name="product.phtml" hash="28aa8996480973a016117af744f7c3aa"/></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageweb"><dir name="js"><dir name="Iksanika"><dir name="productrelater"><file name="egsupplemental.js" hash="22e901dc1b8b22ae69c4c6241781c783"/><file name="jquery-1.9.1.min.js" hash="bcaf50298ada678da29e7cfa62470db5"/><file name="relatergrid.js" hash="0b8f50918dee4ee6fc76198473e6ddb7"/><file name="relaterproducts.js" hash="0045b5bcda3c95981d042aa135864192"/><dir><dir name="resources"><dir name="css"><file name="productrelater.css" hash="a219b0e656329f2407835dbe346f81d3"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Iksanika_Productrelater.xml" hash="e904533beb0e0dc4f819fb271726bd58"/></dir></target></contents>
18
  <compatible/>
19
+ <dependencies><required><php><min>5.1.0</min><max>9.0.0</max></php></required></dependencies>
20
  </package>