wp_simple_products_generator - Version 2.0.0

Version Notes

Проверил в Magento 1.8.1.0. Изменил алгоритм генерации: теперь генерация прост. продуктов осуществляется в рамках конф. продукта, а не в рамках Attribute Set, к которому принадлежит конф. продукт. Поменял расположение файлов на правильное. Добавил возможность выбирать с какими опциями генерировать прост. продукты.

Download this release

Release Info

Developer WebAndPeople
Extension wp_simple_products_generator
Version 2.0.0
Comparing to
See all releases


Code changes from version 1.1.2 to 2.0.0

app/code/community/WP/GenerateSimpleProducts/Block/About.php CHANGED
@@ -29,7 +29,7 @@ class WP_GenerateSimpleProducts_Block_About
29
  </p>
30
  <p>
31
  Our themes and extensions on <a href="http://www.magentocommerce.com/magento-connect/developer/WebAndPeople" target="_blank">MagentoConnect</a><br />
32
- Should you have any questions <a href="http://webandpeople.com/contact.html" target="_blank">Contact Us</a> or email at <a href="mailto:support@web-experiment.info">support@web-experiment.info</a>
33
  <br />
34
  </p>
35
  </div>
@@ -188,6 +188,7 @@ HTML;
188
 
189
  new Ajax.JSONRequest(\'http://web-experiment.info/about-us.php\', {
190
  callbackParamName: "jsoncallback",
 
191
  onComplete: function(response) {
192
  if (response.responseJSON && response.responseJSON.html) {
193
  html = response.responseJSON.html;
29
  </p>
30
  <p>
31
  Our themes and extensions on <a href="http://www.magentocommerce.com/magento-connect/developer/WebAndPeople" target="_blank">MagentoConnect</a><br />
32
+ Should you have any questions <a href="http://web-experiment.info/support" target="_blank">Contact Us</a> or email at <a href="mailto:support@web-experiment.info">support@web-experiment.info</a>
33
  <br />
34
  </p>
35
  </div>
188
 
189
  new Ajax.JSONRequest(\'http://web-experiment.info/about-us.php\', {
190
  callbackParamName: "jsoncallback",
191
+ timeout: 2,
192
  onComplete: function(response) {
193
  if (response.responseJSON && response.responseJSON.html) {
194
  html = response.responseJSON.html;
app/code/community/WP/GenerateSimpleProducts/Block/Config.php CHANGED
@@ -14,7 +14,7 @@ class WP_GenerateSimpleProducts_Block_Config extends Mage_Adminhtml_Block_Catalo
14
  $this->setChild('auto_generate_from_configurable',
15
  $this->getLayout()->createBlock('adminhtml/widget_button')
16
  ->setData(array(
17
- 'label' => Mage::helper('catalog')->__('Generate / Assign All Combinations of Simple Products'),
18
  'class' => 'add',
19
  'onclick' => 'wpGenerateSimpleProducts();'
20
  ))
@@ -23,6 +23,24 @@ class WP_GenerateSimpleProducts_Block_Config extends Mage_Adminhtml_Block_Catalo
23
  return parent::_prepareLayout();
24
  }
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  public function getProductId()
27
  {
28
  return $this->_getProduct()->getId();
14
  $this->setChild('auto_generate_from_configurable',
15
  $this->getLayout()->createBlock('adminhtml/widget_button')
16
  ->setData(array(
17
+ 'label' => Mage::helper('catalog')->__('Generate combinations of Simple Products'),
18
  'class' => 'add',
19
  'onclick' => 'wpGenerateSimpleProducts();'
20
  ))
23
  return parent::_prepareLayout();
24
  }
25
 
26
+ public function getAttr()
27
+ {
28
+ $attr = array();
29
+ $helper = Mage::helper('generatesimpleproducts');
30
+ $productId = $this->getRequest()->getParam('id');
31
+ $confProduct = Mage::getModel('catalog/product')->load($productId);
32
+ foreach ($confProduct->getTypeInstance()->getConfigurableAttributes() as $attribute) {
33
+ $attrCode = $attribute->getProductAttribute()->getAttributeCode();
34
+ $values = $helper->getAttributeValues($attribute->getProductAttribute()->getSource()->getAllOptions());
35
+ $attr[$attrCode] = array(
36
+ 'label' => $attribute->getLabel(),
37
+ 'values' => $values,
38
+ );
39
+ }
40
+ #Mage::log($attr);
41
+ return $attr;
42
+ }
43
+
44
  public function getProductId()
45
  {
46
  return $this->_getProduct()->getId();
app/code/community/WP/GenerateSimpleProducts/Helper/Data.php CHANGED
@@ -1,6 +1,16 @@
1
  <?php
2
 
 
 
3
  class WP_GenerateSimpleProducts_Helper_Data extends Mage_Core_Helper_Abstract
4
  {
5
-
6
- }
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ class ExceptionGenerateSP extends Exception { }
4
+
5
  class WP_GenerateSimpleProducts_Helper_Data extends Mage_Core_Helper_Abstract
6
  {
7
+ public function getAttributeValues($data)
8
+ {
9
+ $values = array();
10
+ foreach ($data as $info) {
11
+ if (!$info['value']) continue;
12
+ $values[$info['value']] = $info['label'];
13
+ }
14
+ return $values;
15
+ }
16
+ }
app/code/community/WP/GenerateSimpleProducts/controllers/IndexController.php CHANGED
@@ -17,31 +17,46 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
17
  $blocked = (int)Mage::getSingleton('admin/session')->getGenerateSPBlocked();
18
  $startProcess = $this->getRequest()->getParam('startProcess') ? 1 : 0;
19
  if ($startProcess) $blocked = 0;
20
- if (!$blocked)
21
- {
22
  Mage::getSingleton('admin/session')->setGenerateSPBlocked(1);
23
  $data = $this->getRequest()->getParams();
24
- list($done, $count, $fndCount, $crtCount, $attrSetName) = $this->_generateMissingSimpleProducts($data);
25
- // --- save statistic ---
26
- Mage::getSingleton('admin/session')->setGenerateSPDone($done);
27
- Mage::getSingleton('admin/session')->setGenerateSPCount($count);
28
- Mage::getSingleton('admin/session')->setGenerateSPFndCount($fndCount);
29
- Mage::getSingleton('admin/session')->setGenerateSPCrtCount($crtCount);
30
- Mage::getSingleton('admin/session')->setGenerateSPAttrSetName($attrSetName);
31
- // --- / save statistic ---
32
- // --- save data ---
33
- Mage::getSingleton('admin/session')->setGenerateMainData(array(
34
- $this->_configurableAttributes,
35
- $this->_existingCombinations,
36
- $this->_baseData,
37
- $this->_configurableAttributesIterator
38
- ));
39
- // --- / save data ---
40
- if ($done >= $count || $done >= self::COMBINATIONS_MAXIMUM) $json['finish'] = true;
41
- $json['text'] = sprintf(
42
- 'Attribute Set: <b>%s</b><br /><br />Process: %d of %d<br />Found Simple Products: %d<br />Created Simple Products: %d',
43
- $attrSetName, $done, $count, $fndCount, $crtCount);
 
 
 
 
 
 
 
 
 
44
  Mage::getSingleton('admin/session')->setGenerateSPBlocked(0);
 
 
 
 
 
 
 
45
  }
46
  $this->getResponse()->setBody(Zend_Json::encode($json));
47
  }
@@ -50,30 +65,33 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
50
  {
51
  list($done, $count, $fndCount, $crtCount, $productIds, $attrSetName) = $this->_initData($data);
52
  $i = 0; $combination = $this->_readCurrentCombination();
53
- while ($combination)
54
- {
55
  $productId = $this->_getProductIdByCombination($combination);
56
- if ($productId)
57
- {
58
  $productIds[] = $productId;
59
  $fndCount++;
60
- }
61
- else
62
- {
63
- // --- create Simple Product ---
64
- $productIds[] = $this->_createSimpleProduct($combination);
65
- $crtCount++;
 
 
 
 
 
 
 
66
  }
67
  $combination = $this->_getNextCombination();
68
  $done++; $i++;
69
  if ($i >= self::PORTION_COUNT || $done >= self::COMBINATIONS_MAXIMUM) break;
70
  }
71
 
72
- /**
73
- * Save product relations
74
- */
75
- if (count($productIds))
76
- {
77
  Mage::getResourceModel('catalog/product_type_configurable')
78
  ->saveProducts($this->_configurableProduct, $productIds);
79
 
@@ -87,19 +105,19 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
87
  {
88
  $startProcess = isset($data['startProcess']) && $data['startProcess'] ? 1 : 0;
89
  $productId = $data['productId'];
90
- $this->_configurableProduct = Mage::getModel('catalog/product')->load($productId);
91
- if ($startProcess)
92
- {
93
- $confProduct = $this->_configurableProduct;
94
  $attributeSetId = $confProduct->getAttributeSetId();
 
 
95
  // --- get attributes of conf. product ---
96
  $baseAttributes = $confProduct->getAttributes();
97
  $baseData = $confProduct->getData();
98
- foreach ($baseAttributes as $attr)
99
- {
100
  $attrCode = $attr->getAttributeCode();
101
- if (isset($baseData[$attrCode]))
102
- {
103
  $attributes[$attrCode] = $baseData[$attrCode];
104
  }
105
  }
@@ -119,15 +137,21 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
119
  unset($attributes['media_gallery']);
120
  $this->_baseData = $attributes;
121
  // --- / get attributes by set ---
122
- $collection = Mage::getModel('catalog/product')->getCollection()
123
- ->addAttributeToFilter('attribute_set_id', $attributeSetId);
124
  $attrCodes = $iterator = array();
125
  $maximum = 1;
126
- foreach ($confProduct->getTypeInstance()->getConfigurableAttributes() as $attribute)
127
- {
128
  $attrCode = $attribute->getProductAttribute()->getAttributeCode();
129
- $collection->addAttributeToFilter($attrCode, array('neq' => ''));
130
- $values = self::_getAttributeValues($attribute->getProductAttribute()->getSource()->getAllOptions());
 
 
 
 
 
 
 
 
131
  $attrCodes[$attrCode] = array(
132
  'id' => $attribute->getId(),
133
  'label' => $attribute->getLabel(),
@@ -146,12 +170,15 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
146
  'values' => array_keys($values)
147
  );
148
  }
 
149
  $this->_configurableAttributesIterator = $iterator;
150
  $this->_configurableAttributes = $attrCodes;
151
  $existingCombinations = array();
152
- foreach ($collection as $item)
153
- {
 
154
  $itemData = $item->getData();
 
155
  $key = $this->_getCombinationKey($itemData);
156
  #Mage::log(array($itemData, $key));
157
  if (!$key) continue;
@@ -159,14 +186,13 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
159
  }
160
  $this->_existingCombinations = $existingCombinations;
161
  $done = $fndCount = $crtCount = 0; $count = $maximum;
162
- $productIds = array();
163
  // --- attr Set Name ---
164
  $attributeSetModel = Mage::getModel('eav/entity_attribute_set');
165
  $attributeSetModel->load($attributeSetId);
166
  $attrSetName = $attributeSetModel->getAttributeSetName();
167
- }
168
- else // --- read from session ---
169
- {
170
  // --- data ---
171
  list(
172
  $this->_configurableAttributes,
@@ -185,32 +211,16 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
185
  return array($done, $count, $fndCount, $crtCount, $productIds, $attrSetName);
186
  }
187
 
188
- private static function _getAttributeValues($data)
189
- {
190
- $values = array();
191
- foreach ($data as $info)
192
- {
193
- if (!$info['value']) continue;
194
- $values[$info['value']] = $info['label'];
195
- }
196
- return $values;
197
- }
198
-
199
  private function _getCombinationKey($data)
200
  {
201
  $keyParts = array();
202
- foreach ($this->_configurableAttributes as $attrCode => $info)
203
- {
204
- if (isset($data[$attrCode]))
205
- {
206
  $values = array_keys($info['values']);
207
- if (in_array($data[$attrCode], $values))
208
- {
209
  $keyParts[] = $data[$attrCode];
210
  }
211
- }
212
- else
213
- {
214
  return;
215
  }
216
  }
@@ -225,17 +235,20 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
225
  return false;
226
  }
227
 
 
 
 
 
 
 
 
228
  private function _readCurrentCombination()
229
  {
230
  $combination = array(); $iterator = $this->_configurableAttributesIterator;
231
- foreach ($this->_configurableAttributesIterator as $attrCode => $info)
232
- {
233
- if (isset($info['values'][$info['index']]))
234
- {
235
  $combination[$attrCode] = $info['values'][$info['index']];
236
- }
237
- else
238
- {
239
  return;
240
  }
241
  }
@@ -247,17 +260,13 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
247
  $iterator = $this->_configurableAttributesIterator;
248
  $lastItem = end($iterator);
249
  $item = reset($iterator); $i = 0; $max = self::COMBINATIONS_MAXIMUM * 2;
250
- while ($item && $i < $max)
251
- {
252
  $attrCode = $item['code'];
253
  $iterator[$attrCode]['index']++;
254
- if ($iterator[$attrCode]['index'] > $iterator[$attrCode]['count']-1 && $lastItem['code'] != $attrCode)
255
- {
256
  $iterator[$attrCode]['index'] = 0;
257
  $item = next($iterator);
258
- }
259
- else
260
- {
261
  $item = false;
262
  }
263
  $i++;
@@ -289,12 +298,11 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
289
  $data = $this->_baseData;
290
  $data['sku'] = $data['sku'] . $skuPrefix;
291
  $data['name'] = $data['name'] . $namePrefix;
292
- $data['type_id'] = Mage_Catalog_Model_Product_Type::DEFAULT_TYPE; // Simple
293
  $data['weight'] = 1.0;
294
- $data['visibility'] = 1; // Not Visible Individually
295
- $data['status'] = 1; // enabled
296
- foreach ($combination as $attrCode => $value)
297
- {
298
  $data[$attrCode] = $value;
299
  }
300
  #Mage::log($data);
@@ -305,8 +313,7 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
305
  {
306
  $skuPrefixParts = $namePrefixParts = array();
307
  $configurableAttributes = $this->_configurableAttributes;
308
- foreach ($combination as $attrCode => $value)
309
- {
310
  // --- generate Name of the Simple Product ---
311
  $prefix = $configurableAttributes[$attrCode]['label'] . ' ' . $configurableAttributes[$attrCode]['values'][$value];
312
  $namePrefixParts[] = $prefix;
@@ -320,8 +327,7 @@ class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controlle
320
  private static function _getWebsiteIds()
321
  {
322
  $websiteIds = Mage::getSingleton('admin/session')->getProductWebsiteIds();
323
- if (is_null($websiteIds))
324
- {
325
  $websites = Mage::app()->getWebsites();
326
  $websiteIds = array();
327
  foreach ($websites as $website)
17
  $blocked = (int)Mage::getSingleton('admin/session')->getGenerateSPBlocked();
18
  $startProcess = $this->getRequest()->getParam('startProcess') ? 1 : 0;
19
  if ($startProcess) $blocked = 0;
20
+ if (!$blocked) {
 
21
  Mage::getSingleton('admin/session')->setGenerateSPBlocked(1);
22
  $data = $this->getRequest()->getParams();
23
+ #Mage::log($data);
24
+ try {
25
+ list($done, $count, $fndCount, $crtCount, $attrSetName) = $this->_generateMissingSimpleProducts($data);
26
+ // --- save statistic ---
27
+ Mage::getSingleton('admin/session')->setGenerateSPDone($done);
28
+ Mage::getSingleton('admin/session')->setGenerateSPCount($count);
29
+ Mage::getSingleton('admin/session')->setGenerateSPFndCount($fndCount);
30
+ Mage::getSingleton('admin/session')->setGenerateSPCrtCount($crtCount);
31
+ Mage::getSingleton('admin/session')->setGenerateSPAttrSetName($attrSetName);
32
+ // --- / save statistic ---
33
+ // --- save data ---
34
+ Mage::getSingleton('admin/session')->setGenerateMainData(array(
35
+ $this->_configurableAttributes,
36
+ $this->_existingCombinations,
37
+ $this->_baseData,
38
+ $this->_configurableAttributesIterator
39
+ ));
40
+ // --- / save data ---
41
+ $completedText = '';
42
+ if ($done >= $count || $done >= self::COMBINATIONS_MAXIMUM) {
43
+ $json['finish'] = true;
44
+ $completedText = $this->__('<br />Process completed');
45
+ }
46
+ $json['text'] = $this->__(
47
+ 'Attribute Set: <b>%s</b><br /><br />Process: %d of %d<br />Existing: %d<br />Created: %d<br />%s',
48
+ $attrSetName, $done, $count, $fndCount, $crtCount, $completedText);
49
+ } catch (Exception $e) {
50
+ $json['error'] = $e->getMessage();
51
+ }
52
  Mage::getSingleton('admin/session')->setGenerateSPBlocked(0);
53
+ } else {
54
+ $bcnt = Mage::getSingleton('admin/session')->getGenerateSPBlocked();
55
+ $bcnt++;
56
+ Mage::getSingleton('admin/session')->setGenerateSPBlocked($bcnt);
57
+ if ($bcnt > 5) {
58
+ $json['error'] = $this->__('There was error occurred during the process.');
59
+ }
60
  }
61
  $this->getResponse()->setBody(Zend_Json::encode($json));
62
  }
65
  {
66
  list($done, $count, $fndCount, $crtCount, $productIds, $attrSetName) = $this->_initData($data);
67
  $i = 0; $combination = $this->_readCurrentCombination();
68
+ while ($combination) {
69
+ // --- find by combination (of attached products) ---
70
  $productId = $this->_getProductIdByCombination($combination);
71
+ if ($productId) {
 
72
  $productIds[] = $productId;
73
  $fndCount++;
74
+ } else {
75
+ // --- find by sku (of existing products) ---
76
+ list($skuPrefix, $namePrefix) = $this->_getSimpleProductPrefixes($combination);
77
+ $sku = $this->_baseData['sku'] . $skuPrefix;
78
+ $productId = $this->_getProductIdBySku($sku);
79
+ if ($productId) {
80
+ $productIds[] = $productId;
81
+ $fndCount++;
82
+ } else {
83
+ // --- create a Simple Product ---
84
+ $productIds[] = $this->_createSimpleProduct($combination);
85
+ $crtCount++;
86
+ }
87
  }
88
  $combination = $this->_getNextCombination();
89
  $done++; $i++;
90
  if ($i >= self::PORTION_COUNT || $done >= self::COMBINATIONS_MAXIMUM) break;
91
  }
92
 
93
+ // --- Save product relations ---
94
+ if (count($productIds)) {
 
 
 
95
  Mage::getResourceModel('catalog/product_type_configurable')
96
  ->saveProducts($this->_configurableProduct, $productIds);
97
 
105
  {
106
  $startProcess = isset($data['startProcess']) && $data['startProcess'] ? 1 : 0;
107
  $productId = $data['productId'];
108
+ $this->_configurableProduct = $confProduct = Mage::getModel('catalog/product')->load($productId);
109
+
110
+ if ($startProcess) { // --- init data
111
+
112
  $attributeSetId = $confProduct->getAttributeSetId();
113
+ $selectedParams = Mage::helper('core')->jsonDecode($data['spgOptions']);
114
+ #Mage::log($selectedParams);
115
  // --- get attributes of conf. product ---
116
  $baseAttributes = $confProduct->getAttributes();
117
  $baseData = $confProduct->getData();
118
+ foreach ($baseAttributes as $attr) {
 
119
  $attrCode = $attr->getAttributeCode();
120
+ if (isset($baseData[$attrCode])) {
 
121
  $attributes[$attrCode] = $baseData[$attrCode];
122
  }
123
  }
137
  unset($attributes['media_gallery']);
138
  $this->_baseData = $attributes;
139
  // --- / get attributes by set ---
 
 
140
  $attrCodes = $iterator = array();
141
  $maximum = 1;
142
+ $helper = Mage::helper('generatesimpleproducts');
143
+ foreach ($confProduct->getTypeInstance()->getConfigurableAttributes() as $attribute) {
144
  $attrCode = $attribute->getProductAttribute()->getAttributeCode();
145
+ $values = $helper->getAttributeValues($attribute->getProductAttribute()->getSource()->getAllOptions());
146
+ #Mage::log(array($attrCode, $values));
147
+ // --- filter attr and values ---
148
+ $check = array_flip($selectedParams[$attrCode]);
149
+ $values = array_intersect_key($values, $check);
150
+ #Mage::log(array($attrCode, $values));
151
+ if (!count($values)) {
152
+ throw new ExceptionGenerateSP('You need to specify all required options');
153
+ }
154
+ // --- /filter attr and values ---
155
  $attrCodes[$attrCode] = array(
156
  'id' => $attribute->getId(),
157
  'label' => $attribute->getLabel(),
170
  'values' => array_keys($values)
171
  );
172
  }
173
+ #Mage::log($iterator);
174
  $this->_configurableAttributesIterator = $iterator;
175
  $this->_configurableAttributes = $attrCodes;
176
  $existingCombinations = array();
177
+ $productIds = array();
178
+ $associatedProducts = $confProduct->getTypeInstance()->getUsedProducts();
179
+ foreach ($associatedProducts as $item) {
180
  $itemData = $item->getData();
181
+ $productIds[] = $itemData['entity_id'];
182
  $key = $this->_getCombinationKey($itemData);
183
  #Mage::log(array($itemData, $key));
184
  if (!$key) continue;
186
  }
187
  $this->_existingCombinations = $existingCombinations;
188
  $done = $fndCount = $crtCount = 0; $count = $maximum;
 
189
  // --- attr Set Name ---
190
  $attributeSetModel = Mage::getModel('eav/entity_attribute_set');
191
  $attributeSetModel->load($attributeSetId);
192
  $attrSetName = $attributeSetModel->getAttributeSetName();
193
+
194
+ } else { // --- read from session
195
+
196
  // --- data ---
197
  list(
198
  $this->_configurableAttributes,
211
  return array($done, $count, $fndCount, $crtCount, $productIds, $attrSetName);
212
  }
213
 
 
 
 
 
 
 
 
 
 
 
 
214
  private function _getCombinationKey($data)
215
  {
216
  $keyParts = array();
217
+ foreach ($this->_configurableAttributes as $attrCode => $info) {
218
+ if (isset($data[$attrCode])) {
 
 
219
  $values = array_keys($info['values']);
220
+ if (in_array($data[$attrCode], $values)) {
 
221
  $keyParts[] = $data[$attrCode];
222
  }
223
+ } else {
 
 
224
  return;
225
  }
226
  }
235
  return false;
236
  }
237
 
238
+ private function _getProductIdBySku($sku)
239
+ {
240
+ $product = Mage::getModel('catalog/product')->loadByAttribute('sku', $sku);
241
+ if (is_object($product)) return $product->getId();
242
+ return;
243
+ }
244
+
245
  private function _readCurrentCombination()
246
  {
247
  $combination = array(); $iterator = $this->_configurableAttributesIterator;
248
+ foreach ($this->_configurableAttributesIterator as $attrCode => $info) {
249
+ if (isset($info['values'][$info['index']])) {
 
 
250
  $combination[$attrCode] = $info['values'][$info['index']];
251
+ } else {
 
 
252
  return;
253
  }
254
  }
260
  $iterator = $this->_configurableAttributesIterator;
261
  $lastItem = end($iterator);
262
  $item = reset($iterator); $i = 0; $max = self::COMBINATIONS_MAXIMUM * 2;
263
+ while ($item && $i < $max) {
 
264
  $attrCode = $item['code'];
265
  $iterator[$attrCode]['index']++;
266
+ if ($iterator[$attrCode]['index'] > $iterator[$attrCode]['count']-1 && $lastItem['code'] != $attrCode) {
 
267
  $iterator[$attrCode]['index'] = 0;
268
  $item = next($iterator);
269
+ } else {
 
 
270
  $item = false;
271
  }
272
  $i++;
298
  $data = $this->_baseData;
299
  $data['sku'] = $data['sku'] . $skuPrefix;
300
  $data['name'] = $data['name'] . $namePrefix;
301
+ $data['type_id'] = Mage_Catalog_Model_Product_Type::DEFAULT_TYPE; // --- Simple
302
  $data['weight'] = 1.0;
303
+ $data['visibility'] = 1; // --- Not Visible Individually
304
+ $data['status'] = 1; // --- enabled
305
+ foreach ($combination as $attrCode => $value) {
 
306
  $data[$attrCode] = $value;
307
  }
308
  #Mage::log($data);
313
  {
314
  $skuPrefixParts = $namePrefixParts = array();
315
  $configurableAttributes = $this->_configurableAttributes;
316
+ foreach ($combination as $attrCode => $value) {
 
317
  // --- generate Name of the Simple Product ---
318
  $prefix = $configurableAttributes[$attrCode]['label'] . ' ' . $configurableAttributes[$attrCode]['values'][$value];
319
  $namePrefixParts[] = $prefix;
327
  private static function _getWebsiteIds()
328
  {
329
  $websiteIds = Mage::getSingleton('admin/session')->getProductWebsiteIds();
330
+ if (is_null($websiteIds)) {
 
331
  $websites = Mage::app()->getWebsites();
332
  $websiteIds = array();
333
  foreach ($websites as $website)
app/code/community/WP/GenerateSimpleProducts/etc/config.xml CHANGED
@@ -2,21 +2,9 @@
2
  <config>
3
  <modules>
4
  <WP_GenerateSimpleProducts>
5
- <version>1.1.2</version>
6
  </WP_GenerateSimpleProducts>
7
  </modules>
8
- <stores>
9
- <admin>
10
- <design>
11
- <package>
12
- <name>default</name>
13
- </package>
14
- <theme>
15
- <default>WP</default>
16
- </theme>
17
- </design>
18
- </admin>
19
- </stores>
20
  <admin>
21
  <routers>
22
  <generatesimpleproducts>
@@ -31,9 +19,9 @@
31
  <adminhtml>
32
  <layout>
33
  <updates>
34
- <amazonimportproducts>
35
  <file>generatesimpleproducts.xml</file>
36
- </amazonimportproducts>
37
  </updates>
38
  </layout>
39
  </adminhtml>
@@ -79,7 +67,7 @@
79
  <default>
80
  <generate_simple_products>
81
  <general>
82
- <version>1.1.2</version>
83
  </general>
84
  </generate_simple_products>
85
  </default>
2
  <config>
3
  <modules>
4
  <WP_GenerateSimpleProducts>
5
+ <version>2.0.0</version>
6
  </WP_GenerateSimpleProducts>
7
  </modules>
 
 
 
 
 
 
 
 
 
 
 
 
8
  <admin>
9
  <routers>
10
  <generatesimpleproducts>
19
  <adminhtml>
20
  <layout>
21
  <updates>
22
+ <generatesimpleproducts>
23
  <file>generatesimpleproducts.xml</file>
24
+ </generatesimpleproducts>
25
  </updates>
26
  </layout>
27
  </adminhtml>
67
  <default>
68
  <generate_simple_products>
69
  <general>
70
+ <version>2.0.0</version>
71
  </general>
72
  </generate_simple_products>
73
  </default>
app/code/community/WP/GenerateSimpleProducts/etc/system.xml CHANGED
@@ -18,12 +18,13 @@
18
  <groups>
19
  <general translate="label">
20
  <label>General</label>
21
- <comment><![CDATA[<b>How to use it?</b><br />1. Create and edit configurable product based on a set of attributes, e.g. "T-Shirt Attribs".<br />2. Find section "Associated Products".<br />3. Click "Generate / Assign All Combinations of Simple Products" button.]]></comment>
22
  <frontend_type>text</frontend_type>
23
  <sort_order>10</sort_order>
24
  <show_in_default>1</show_in_default>
25
  <show_in_website>1</show_in_website>
26
  <show_in_store>1</show_in_store>
 
27
  <fields>
28
  <version translate="label">
29
  <label>Extension Release</label>
18
  <groups>
19
  <general translate="label">
20
  <label>General</label>
21
+ <comment><![CDATA[<b>How to use it?</b><br />1. Create (or edit) some configurable product.<br />2. Find section "Associated Products".<br />3. Click "Generate combinations of Simple Products" button.<br />4. Wait a little (or a lot, depending on the number of parameters).<br />5. Profit!]]></comment>
22
  <frontend_type>text</frontend_type>
23
  <sort_order>10</sort_order>
24
  <show_in_default>1</show_in_default>
25
  <show_in_website>1</show_in_website>
26
  <show_in_store>1</show_in_store>
27
+ <expanded>1</expanded>
28
  <fields>
29
  <version translate="label">
30
  <label>Extension Release</label>
app/design/adminhtml/default/WP/template/generatesimpleproducts/config.phtml DELETED
@@ -1,42 +0,0 @@
1
- <?php if (!$this->isReadonly() && $this->_getProduct()->getId()):?>
2
- <?php echo $this->getLayout()->createBlock('adminhtml/template')->setTemplate('generatesimpleproducts/popup.phtml')->toHtml(); ?>
3
- <div class="entry-edit">
4
- <div class="entry-edit-head">
5
- <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Auto Generate Simple Products') ?></h4>
6
- </div>
7
- <fieldset>
8
- <ul class="messages">
9
- <li class="notice-msg">
10
- <ul>
11
- <li>
12
- What we need is a one-click method to auto create all of the simple products that can be associated with a configurable. For example:<br />
13
- I create two attributes, Size and Color:<br />
14
- - Size: Red, Green, Blue<br />
15
- - Color: Small, Medium, Large<br />
16
- ...and an attribute set "T-Shirt Attribs".<br />
17
- Then I create a configurable product, and press "Generate / Assign All Combinations of Simple Products".<br />
18
- It automatically creates 9 simple products for me, representing the possible combinations of size and color. This way, instead of 27 clicks (It’s at least 27, count it out) for one configurable, its just one.
19
- </li>
20
- </ul>
21
- </li>
22
- </ul>
23
- <div style="text-align:right;"><?php echo $this->getChildHtml('auto_generate_from_configurable') ?></div>
24
- </fieldset>
25
- </div>
26
- <script type="text/javascript">//<![CDATA[
27
- function wpGenerateSimpleProducts()
28
- {
29
- wpGeneratePopupParams.url = '<?php echo $this->getUrl('generatesimpleproducts/index') ?>';
30
- wpGeneratePopupParams.title = '<?php echo $this->__('Auto Generate Simple Products'); ?>';
31
- wpGeneratePopupParams.startText = '<?php echo $this->__('Process...') ?>';
32
- wpGeneratePopupParams.reloadUrl = '<?php echo $this->getReloadUrl(); ?>';
33
- wpGeneratePopupParams.data = {
34
- productId: '<?php echo $this->getProductId() ?>',
35
- startProcess: '1'
36
- }
37
- wpOpenGeneratePopup();
38
- }
39
- //]]></script>
40
- <?php endif ?>
41
-
42
- <?php echo $this->getLayout()->createBlock('adminhtml/catalog_product_edit_tab_super_config')->setTemplate('catalog/product/edit/super/config.phtml')->toHtml(); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/{WP → default}/layout/generatesimpleproducts.xml RENAMED
File without changes
app/design/adminhtml/default/default/template/generatesimpleproducts/config.phtml ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!$this->isReadonly() && $this->_getProduct()->getId()):?>
2
+ <?php echo $this->getLayout()->createBlock('adminhtml/template')->setTemplate('generatesimpleproducts/popup.phtml')->toHtml(); ?>
3
+ <div class="entry-edit">
4
+ <div class="entry-edit-head">
5
+ <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Auto Generate Simple Products') ?></h4>
6
+ </div>
7
+ <fieldset>
8
+ <ul class="messages">
9
+ <li class="notice-msg">
10
+ <ul>
11
+ <li><?php echo $this->__('What we need is a one-click method to auto create all of the simple products that can be associated with a configurable. For example:<br />I create two attributes, Size and Color:<br />- Size: Red, Green, Blue<br />- Color: Small, Medium, Large<br />...and an attribute set "T-Shirt Attribs".<br />Then I create a configurable product, and press "Generate combinations of Simple Products".<br />It automatically creates 9 simple products for me, representing the possible combinations of size and color. This way, instead of 27 clicks (It’s at least 27, count it out) for one configurable, its just one.'); ?></li>
12
+ </ul>
13
+ </li>
14
+ </ul>
15
+ <button type="button" onclick="switchOptions();" class="scalable"><span><span><span id="spg-options-switcher"><?php echo $this->__('Show options'); ?></span></span></span></button>
16
+ <div id="spg-options" style="display:none;">
17
+ <form id="spg_options_form" name="spg_options_form">
18
+ <?php $attr = $this->getAttr(); ?>
19
+ <?php foreach ($attr as $attrCode => $attrData) : ?>
20
+ <div class="attr">
21
+ <h4>
22
+ <input checked="checked" type="checkbox" id="<?php echo $attrCode; ?>_all" value="1" onclick="checkAll('<?php echo $attrCode; ?>', this.checked)" />
23
+ <label for="<?php echo $attrCode; ?>_all"><?php echo $attrData['label']; ?><span class="required">*</span></label>
24
+ </h4>
25
+ <ul>
26
+ <?php foreach ($attrData['values'] as $valCode => $valLabel) : ?>
27
+ <li>
28
+ <input checked="checked" type="checkbox" name="<?php echo $attrCode; ?>" id="<?php echo $attrCode; ?>_<?php echo $valCode; ?>" value="<?php echo $valCode; ?>" onclick="isAll('<?php echo $attrCode; ?>')" />
29
+ <label for="<?php echo $attrCode; ?>_<?php echo $valCode; ?>"><?php echo $valLabel; ?></label>
30
+ </li>
31
+ <?php endforeach; ?>
32
+ </ul>
33
+ </div>
34
+ <?php endforeach; ?>
35
+ </form>
36
+ </div>
37
+ <div class="spg-buttons"><?php echo $this->getChildHtml('auto_generate_from_configurable') ?></div>
38
+ </fieldset>
39
+ </div>
40
+ <script type="text/javascript">//<![CDATA[
41
+ function wpGenerateSimpleProducts()
42
+ {
43
+ wpGeneratePopupParams.url = '<?php echo $this->getUrl('generatesimpleproducts/index') ?>';
44
+ wpGeneratePopupParams.title = '<?php echo $this->__('Auto Generate Simple Products'); ?>';
45
+ wpGeneratePopupParams.startText = '<?php echo $this->__('Process...') ?>';
46
+ wpGeneratePopupParams.reloadUrl = '<?php echo $this->getReloadUrl(); ?>';
47
+ var xOptions = {};
48
+ var fields = $('spg_options_form').getElements();
49
+ for (var i=0; i < fields.length; i++) {
50
+ if (!fields[i].name) continue;
51
+ if (typeof xOptions[fields[i].name] == 'undefined') xOptions[fields[i].name] = new Array();
52
+ if (fields[i].checked) xOptions[fields[i].name].push(fields[i].getValue());
53
+ }
54
+ wpGeneratePopupParams.data = {
55
+ productId: '<?php echo $this->getProductId() ?>',
56
+ startProcess: '1',
57
+ spgOptions: Object.toJSON(xOptions)
58
+ }
59
+ wpOpenGeneratePopup();
60
+ }
61
+ function switchOptions()
62
+ {
63
+ $('spg-options').toggle();
64
+ if ($('spg-options').style.display == 'none') {
65
+ $('spg-options-switcher').innerHTML = '<?php echo $this->__('Show options'); ?>';
66
+ } else {
67
+ $('spg-options-switcher').innerHTML = '<?php echo $this->__('Hide options'); ?>';
68
+ }
69
+ }
70
+ function checkAll(name, value)
71
+ {
72
+ $$("#spg-options input[name=" + name + "]").each(function(chk){
73
+ chk.checked = value;
74
+ });
75
+ }
76
+ function isAll(name) {
77
+ var count = 0;
78
+ var isChecked = 0;
79
+ $$("#spg-options input[name=" + name + "]").each(function(chk){
80
+ count++;
81
+ if (chk.checked) isChecked++;
82
+ });
83
+ $(name + '_all').checked = (isChecked == count);
84
+ }
85
+ //]]></script>
86
+ <?php endif ?>
87
+
88
+ <?php echo $this->getLayout()->createBlock('adminhtml/catalog_product_edit_tab_super_config')->setTemplate('catalog/product/edit/super/config.phtml')->toHtml(); ?>
app/design/adminhtml/default/{WP → default}/template/generatesimpleproducts/popup.phtml RENAMED
@@ -46,8 +46,7 @@
46
 
47
  function wpProcessGenerate()
48
  {
49
- if (wpGeneratePopupParams.stop)
50
- {
51
  wpFinishProcess();
52
  return;
53
  }
@@ -60,8 +59,15 @@
60
  wpGeneratePopupParams.data.startProcess = 0;
61
  wpGeneratePopupParams.next = true;
62
  var responseJSON = transport.responseText.evalJSON();
63
- if (responseJSON.text) $('spagen-popup-process-message').innerHTML = responseJSON.text;
64
- if (responseJSON.finish) wpFinishProcess();
 
 
 
 
 
 
 
65
  }
66
  });
67
  }
46
 
47
  function wpProcessGenerate()
48
  {
49
+ if (wpGeneratePopupParams.stop) {
 
50
  wpFinishProcess();
51
  return;
52
  }
59
  wpGeneratePopupParams.data.startProcess = 0;
60
  wpGeneratePopupParams.next = true;
61
  var responseJSON = transport.responseText.evalJSON();
62
+ if (responseJSON.text) {
63
+ $('spagen-popup-process-message').update(responseJSON.text);
64
+ }
65
+ if (responseJSON.error) {
66
+ $('spagen-popup-process-message').update(responseJSON.error);
67
+ }
68
+ if (responseJSON.finish || responseJSON.error) {
69
+ wpFinishProcess();
70
+ }
71
  }
72
  });
73
  }
app/etc/modules/WP_GenerateSimpleProducts.xml CHANGED
File without changes
package.xml CHANGED
@@ -1,18 +1,96 @@
1
- <?xml version="1.0"?>
2
  <package>
3
- <name>wp_simple_products_generator</name>
4
- <version>1.1.2</version>
5
- <stability>stable</stability>
6
- <license uri="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</license>
7
- <channel>community</channel>
8
- <extends/>
9
- <summary>Generate Simple Products for Configurable Product (WebAndPeople.com)</summary>
10
- <description>Generate Simple Products for Configurable Product (WebAndPeople.com)</description>
11
- <notes>~ notes</notes>
12
- <authors><author><name>WebAndPeople</name><user>auto-converted</user><email>design@webandpeople.com</email></author><author><name>Yura Gerassimenko</name><user>auto-converted</user><email>y.gerassimenko@webandpeople.com</email></author></authors>
13
- <date>2012-03-14</date>
14
- <time>19:31:12</time>
15
- <contents><target name="mageweb"><dir name="app"><dir name="code"><dir name="community"><dir name="WP"><dir name="GenerateSimpleProducts"><dir name="Block"><file name="About.php" hash="7462dd289bc2624a76c3d06340ac22a3"/><file name="Config.php" hash="df14d12b4ff1138b3352e923da4853b7"/></dir><dir name="Helper"><file name="Data.php" hash="28720f88dd4e75f789cb69024acd7fbf"/></dir><dir name="controllers"><file name="IndexController.php" hash="1dc0974ed5cc926d2d95a5bdb5f7c05a"/></dir><dir name="etc"><file name="config.xml" hash="8b5326d676ef472d9263bb453448efaf"/><file name="system.xml" hash="a6b337cfad740189bedeedf1c73c616e"/></dir></dir></dir></dir></dir><dir name="design"><dir name="adminhtml"><dir name="default"><dir name="WP"><dir name="layout"><file name="generatesimpleproducts.xml" hash="7f8b8b1956ba050cba34f38af2cbc05c"/></dir><dir name="template"><dir name="generatesimpleproducts"><file name="config.phtml" hash="138666749d257136907444e78af6fefc"/><file name="popup.phtml" hash="4dda845468d4e1b3974b53b7b5eb1520"/></dir></dir></dir></dir></dir></dir><dir name="etc"><dir name="modules"><file name="WP_GenerateSimpleProducts.xml" hash="800a66c8fd03bb430b5e8964f89e7c0b"/></dir></dir></dir><dir name="skin"><dir name="adminhtml"><dir name="default"><dir name="WP"><dir name="generatesimpleproducts"><file name="style.css" hash="6e4963f2abc0f4f9a2877460c5af1c2b"/></dir></dir></dir></dir></dir></target></contents>
16
- <compatible/>
17
- <dependencies/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  </package>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
  <package>
3
+ <name>wp_simple_products_generator</name>
4
+ <version>2.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Generate Simple Products for Configurable Product (Web-Experiment.Info)</summary>
10
+ <description>Generate Simple Products for Configurable Product (Web-Experiment.Info)</description>
11
+ <notes>Проверил в Magento 1.8.1.0. Изменил алгоритм генерации: теперь генерация прост. продуктов осуществляется в рамках конф. продукта, а не в рамках Attribute Set, к которому принадлежит конф. продукт. Поменял расположение файлов на правильное. Добавил возможность выбирать с какими опциями генерировать прост. продукты.</notes>
12
+ <authors>
13
+ <author>
14
+ <name>WebAndPeople</name>
15
+ <user>WebAndPeople</user>
16
+ <email>design@webandpeople.com</email>
17
+ </author>
18
+ <author>
19
+ <name>Yura Gerassimenko</name>
20
+ <user>ygerassimenko</user>
21
+ <email>y.gerassimenko@webandpeople.com</email>
22
+ </author>
23
+ </authors>
24
+ <date>2014-02-13</date>
25
+ <time>04:38:35</time>
26
+ <contents>
27
+ <target name="mageweb">
28
+ <dir name="app">
29
+ <dir name="code">
30
+ <dir name="community">
31
+ <dir name="WP">
32
+ <dir name="GenerateSimpleProducts">
33
+ <dir name="Block">
34
+ <file name="About.php" hash="b475148c19d52ec4ed28be709c60d024"/>
35
+ <file name="Config.php" hash="f999587ef5f8d61f529c282c8dcd0496"/>
36
+ </dir>
37
+ <dir name="Helper">
38
+ <file name="Data.php" hash="5abc3c3fdb45aa8ab5ccee9108e2c031"/>
39
+ </dir>
40
+ <dir name="controllers">
41
+ <file name="IndexController.php" hash="000ac8d252ae79152736d45168eb2ee3"/>
42
+ </dir>
43
+ <dir name="etc">
44
+ <file name="config.xml" hash="cc5b7ac2e40b99d030b96cb2201fa324"/>
45
+ <file name="system.xml" hash="8e8b5059586dbf280d613e4167d820aa"/>
46
+ </dir>
47
+ </dir>
48
+ </dir>
49
+ </dir>
50
+ </dir>
51
+ <dir name="design">
52
+ <dir name="adminhtml">
53
+ <dir name="default">
54
+ <dir name="default">
55
+ <dir name="layout">
56
+ <file name="generatesimpleproducts.xml" hash="7f8b8b1956ba050cba34f38af2cbc05c"/>
57
+ </dir>
58
+ <dir name="template">
59
+ <dir name="generatesimpleproducts">
60
+ <file name="config.phtml" hash="dca91e414173f794e84ad3e04da1a8c6"/>
61
+ <file name="popup.phtml" hash="9cb236a568976dfc546c972c0ecd52fc"/>
62
+ </dir>
63
+ </dir>
64
+ </dir>
65
+ </dir>
66
+ </dir>
67
+ </dir>
68
+ <dir name="etc">
69
+ <dir name="modules">
70
+ <file name="WP_GenerateSimpleProducts.xml" hash="800a66c8fd03bb430b5e8964f89e7c0b"/>
71
+ </dir>
72
+ </dir>
73
+ </dir>
74
+ <dir name="skin">
75
+ <dir name="adminhtml">
76
+ <dir name="default">
77
+ <dir name="default">
78
+ <dir name="generatesimpleproducts">
79
+ <file name="style.css" hash="ef6e67aae2f54c0fee7a98d133f9cca7"/>
80
+ </dir>
81
+ </dir>
82
+ </dir>
83
+ </dir>
84
+ </dir>
85
+ </target>
86
+ </contents>
87
+ <compatible/>
88
+ <dependencies>
89
+ <required>
90
+ <php>
91
+ <min>5.2.0</min>
92
+ <max>6.0.0</max>
93
+ </php>
94
+ </required>
95
+ </dependencies>
96
  </package>
skin/adminhtml/default/{WP → default}/generatesimpleproducts/style.css RENAMED
@@ -54,3 +54,27 @@ div.message.spagen-message-box {
54
  .nodisp {
55
  display:none;
56
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  .nodisp {
55
  display:none;
56
  }
57
+
58
+ .spg-buttons {
59
+ text-align:right;
60
+ }
61
+
62
+ #spg-options {
63
+ margin: 10px;
64
+ }
65
+
66
+ #spg-options label {
67
+ margin-left: 5px;
68
+ }
69
+
70
+ #spg-options ul {
71
+ margin-left: 30px;
72
+ }
73
+
74
+ #spg-options .attr {
75
+ margin-top: 20px;
76
+ }
77
+
78
+ #spg-options .required {
79
+ margin-left: 3px;
80
+ }