Version Notes
Generate Simple Products for Configurable Product (WebAndPeople.com)
Download this release
Release Info
Developer | Magento Core Team |
Extension | wp_generate_simple_products |
Version | 1.0.1 |
Comparing to | |
See all releases |
Version 1.0.1
- app/code/local/WP/GenerateSimpleProducts/Block/About.php +202 -0
- app/code/local/WP/GenerateSimpleProducts/Block/Config.php +42 -0
- app/code/local/WP/GenerateSimpleProducts/Helper/Data.php +6 -0
- app/code/local/WP/GenerateSimpleProducts/controllers/IndexController.php +327 -0
- app/code/local/WP/GenerateSimpleProducts/etc/config.xml +115 -0
- app/code/local/WP/GenerateSimpleProducts/etc/system.xml +58 -0
- app/design/adminhtml/default/WP/layout/generatesimpleproducts.xml +8 -0
- app/design/adminhtml/default/WP/template/generatesimpleproducts/config.phtml +42 -0
- app/design/adminhtml/default/WP/template/generatesimpleproducts/popup.phtml +87 -0
- app/etc/modules/WP_GenerateSimpleProducts.xml +9 -0
- package.xml +18 -0
- skin/adminhtml/default/WP/generatesimpleproducts/style.css +56 -0
app/code/local/WP/GenerateSimpleProducts/Block/About.php
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WP_GenerateSimpleProducts_Block_About
|
4 |
+
extends Mage_Adminhtml_Block_Abstract
|
5 |
+
implements Varien_Data_Form_Element_Renderer_Interface
|
6 |
+
{
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Render fieldset html
|
10 |
+
*
|
11 |
+
* @param Varien_Data_Form_Element_Abstract $element
|
12 |
+
* @return string
|
13 |
+
*/
|
14 |
+
public function render(Varien_Data_Form_Element_Abstract $element)
|
15 |
+
{
|
16 |
+
$default = <<<HTML
|
17 |
+
<div style="background-color:#EAF0EE;border:1px solid #CCCCCC;margin-bottom:10px;padding:20px;">
|
18 |
+
<p>
|
19 |
+
<b style="font-size:12px;">WebAndPeople</b>, a family of niche sites, provides small businesses with everything they need to start selling online.
|
20 |
+
</p>
|
21 |
+
<p>
|
22 |
+
<strong>PREMIUM and FREE MAGENTO TEMPALTES and EXTENSIONS</strong><br />
|
23 |
+
<a href="http://web-experiment.info" target="_blank">Web-Experiment.info</a> offers a wide choice of nice-looking and easily editable free and premium Magento Themes. At Web-Experiment, you can find free downloads or buy premium tempaltes for the extremely popular Magento eCommerce platform.<br />
|
24 |
+
<strong>MAGENTO HOSTING</strong></strong><br />
|
25 |
+
<a href="http://magenting.com" target="_blank">Magenting.com</a>, a new and improved hosting solution, is allowing you to easily create, promote, and manage your online store with Magento. Magenting users will receive a valuable set of tools and features, including automatic Magento eCommerce installation, automatic Magento template installation and a free or paid professional Magento hosting account.<br />
|
26 |
+
<strong>WEB DEVELOPMENT</strong><br />
|
27 |
+
<a href="http://webandpeople.com" target="_blank">WebAndPeople.com</a> is a team of professional Web developers and designers who are some of the best in the industry. WebAndPeople provides Web application development, custom Magento theme designs, and Website design services.<br />
|
28 |
+
<br />
|
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:info@webandpeople.com">info@webandpeople.com</a>
|
33 |
+
<br />
|
34 |
+
</p>
|
35 |
+
</div>
|
36 |
+
HTML;
|
37 |
+
$default = json_encode($default);
|
38 |
+
$html = '<div id="wp_aboutus_content"></div>
|
39 |
+
|
40 |
+
<script type="text/javascript"> //<![CDATA[
|
41 |
+
|
42 |
+
/* JSON-P implementation for Prototype.js somewhat by Dan Dean (http://www.dandean.com)
|
43 |
+
*
|
44 |
+
* *HEAVILY* based on Tobie Langel\'s version: http://gist.github.com/145466.
|
45 |
+
* Might as well just call this an iteration.
|
46 |
+
*
|
47 |
+
* This version introduces:
|
48 |
+
* - Support for predefined callbacks (Necessary for OAuth signed requests, by @rboyce)
|
49 |
+
* - Partial integration with Ajax.Responders (Thanks to @sr3d for the kick in this direction)
|
50 |
+
* - Compatibility with Prototype 1.7 (Thanks to @soung3 for the bug report)
|
51 |
+
* - Will not break if page lacks a <head> element
|
52 |
+
*
|
53 |
+
* See examples in README for usage
|
54 |
+
*
|
55 |
+
* VERSION 1.1.2
|
56 |
+
*
|
57 |
+
* new Ajax.JSONRequest(url, options);
|
58 |
+
* - url (String): JSON-P endpoint url.
|
59 |
+
* - options (Object): Configuration options for the request.
|
60 |
+
*/
|
61 |
+
Ajax.JSONRequest = Class.create(Ajax.Base, (function() {
|
62 |
+
var id = 0, head = document.getElementsByTagName(\'head\')[0] || document.body;
|
63 |
+
return {
|
64 |
+
initialize: function($super, url, options) {
|
65 |
+
$super(options);
|
66 |
+
this.options.url = url;
|
67 |
+
this.options.callbackParamName = this.options.callbackParamName || \'callback\';
|
68 |
+
this.options.timeout = this.options.timeout || 10; // Default timeout: 10 seconds
|
69 |
+
this.options.invokeImmediately = (!Object.isUndefined(this.options.invokeImmediately)) ? this.options.invokeImmediately : true ;
|
70 |
+
|
71 |
+
if (!Object.isUndefined(this.options.parameters) && Object.isString(this.options.parameters)) {
|
72 |
+
this.options.parameters = this.options.parameters.toQueryParams();
|
73 |
+
}
|
74 |
+
|
75 |
+
if (this.options.invokeImmediately) {
|
76 |
+
this.request();
|
77 |
+
}
|
78 |
+
},
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Ajax.JSONRequest#_cleanup() -> undefined
|
82 |
+
* Cleans up after the request
|
83 |
+
**/
|
84 |
+
_cleanup: function() {
|
85 |
+
if (this.timeout) {
|
86 |
+
clearTimeout(this.timeout);
|
87 |
+
this.timeout = null;
|
88 |
+
}
|
89 |
+
if (this.transport && Object.isElement(this.transport)) {
|
90 |
+
this.transport.remove();
|
91 |
+
this.transport = null;
|
92 |
+
}
|
93 |
+
},
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Ajax.JSONRequest#request() -> undefined
|
97 |
+
* Invokes the JSON-P request lifecycle
|
98 |
+
**/
|
99 |
+
request: function() {
|
100 |
+
|
101 |
+
// Define local vars
|
102 |
+
var response = new Ajax.JSONResponse(this);
|
103 |
+
var key = this.options.callbackParamName,
|
104 |
+
name = \'_prototypeJSONPCallback_\' + (id++),
|
105 |
+
complete = function() {
|
106 |
+
if (Object.isFunction(this.options.onComplete)) {
|
107 |
+
this.options.onComplete.call(this, response);
|
108 |
+
}
|
109 |
+
Ajax.Responders.dispatch(\'onComplete\', this, response);
|
110 |
+
}.bind(this);
|
111 |
+
|
112 |
+
// If the callback parameter is already defined, use that
|
113 |
+
if (this.options.parameters[key] !== undefined) {
|
114 |
+
name = this.options.parameters[key];
|
115 |
+
}
|
116 |
+
// Otherwise, add callback as a parameter
|
117 |
+
else {
|
118 |
+
this.options.parameters[key] = name;
|
119 |
+
}
|
120 |
+
|
121 |
+
// Build request URL
|
122 |
+
this.options.parameters[key] = name;
|
123 |
+
var url = this.options.url + ((this.options.url.include(\'?\') ? \'&\' : \'?\') + Object.toQueryString(this.options.parameters));
|
124 |
+
|
125 |
+
// Define callback function
|
126 |
+
window[name] = function(json) {
|
127 |
+
this._cleanup(); // Garbage collection
|
128 |
+
window[name] = undefined;
|
129 |
+
|
130 |
+
response.status = 200;
|
131 |
+
response.statusText = "OK";
|
132 |
+
response.setResponseContent(json);
|
133 |
+
|
134 |
+
if (Object.isFunction(this.options.onSuccess)) {
|
135 |
+
this.options.onSuccess.call(this, response);
|
136 |
+
}
|
137 |
+
Ajax.Responders.dispatch(\'onSuccess\', this, response);
|
138 |
+
|
139 |
+
complete();
|
140 |
+
|
141 |
+
}.bind(this);
|
142 |
+
|
143 |
+
this.transport = new Element(\'script\', { type: \'text/javascript\', src: url });
|
144 |
+
|
145 |
+
if (Object.isFunction(this.options.onCreate)) {
|
146 |
+
this.options.onCreate.call(this, response);
|
147 |
+
}
|
148 |
+
Ajax.Responders.dispatch(\'onCreate\', this);
|
149 |
+
|
150 |
+
head.appendChild(this.transport);
|
151 |
+
|
152 |
+
this.timeout = setTimeout(function() {
|
153 |
+
this._cleanup();
|
154 |
+
window[name] = Prototype.emptyFunction;
|
155 |
+
if (Object.isFunction(this.options.onFailure)) {
|
156 |
+
response.status = 504;
|
157 |
+
response.statusText = "Gateway Timeout";
|
158 |
+
this.options.onFailure.call(this, response);
|
159 |
+
}
|
160 |
+
complete();
|
161 |
+
}.bind(this), this.options.timeout * 1000);
|
162 |
+
},
|
163 |
+
toString: function() { return "[object Ajax.JSONRequest]"; }
|
164 |
+
};
|
165 |
+
})());
|
166 |
+
|
167 |
+
Ajax.JSONResponse = Class.create({
|
168 |
+
initialize: function(request) {
|
169 |
+
this.request = request;
|
170 |
+
},
|
171 |
+
request: undefined,
|
172 |
+
status: 0,
|
173 |
+
statusText: \'\',
|
174 |
+
responseJSON: undefined,
|
175 |
+
responseText: undefined,
|
176 |
+
setResponseContent: function(json) {
|
177 |
+
this.responseJSON = json;
|
178 |
+
this.responseText = Object.toJSON(json);
|
179 |
+
},
|
180 |
+
getTransport: function() {
|
181 |
+
if (this.request) return this.request.transport;
|
182 |
+
},
|
183 |
+
toString: function() { return "[object Ajax.JSONResponse]"; }
|
184 |
+
});
|
185 |
+
|
186 |
+
window.onload = function(){
|
187 |
+
var html = ' . $default . ';
|
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;
|
194 |
+
}
|
195 |
+
Element.replace(\'wp_aboutus_content\', html);
|
196 |
+
}
|
197 |
+
});
|
198 |
+
};
|
199 |
+
//]]></script>';
|
200 |
+
return $html;
|
201 |
+
}
|
202 |
+
}
|
app/code/local/WP/GenerateSimpleProducts/Block/Config.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WP_GenerateSimpleProducts_Block_Config extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config
|
4 |
+
{
|
5 |
+
public function __construct()
|
6 |
+
{
|
7 |
+
parent::__construct();
|
8 |
+
$this->setTemplate('generatesimpleproducts/config.phtml');
|
9 |
+
}
|
10 |
+
|
11 |
+
protected function _prepareLayout()
|
12 |
+
{
|
13 |
+
if ($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 / Assign All Combinations of Simple Products'),
|
18 |
+
'class' => 'add',
|
19 |
+
'onclick' => 'wpGenerateSimpleProducts();'
|
20 |
+
))
|
21 |
+
);
|
22 |
+
}
|
23 |
+
return parent::_prepareLayout();
|
24 |
+
}
|
25 |
+
|
26 |
+
public function getProductId()
|
27 |
+
{
|
28 |
+
return $this->_getProduct()->getId();
|
29 |
+
}
|
30 |
+
|
31 |
+
public function getReloadUrl()
|
32 |
+
{
|
33 |
+
return $this->getUrl(
|
34 |
+
'*/*/edit',
|
35 |
+
array(
|
36 |
+
'id' => $this->getProductId(),
|
37 |
+
'back' => 'edit',
|
38 |
+
'tab' => 'product_info_tabs_configurable',
|
39 |
+
)
|
40 |
+
);
|
41 |
+
}
|
42 |
+
}
|
app/code/local/WP/GenerateSimpleProducts/Helper/Data.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WP_GenerateSimpleProducts_Helper_Data extends Mage_Core_Helper_Abstract
|
4 |
+
{
|
5 |
+
|
6 |
+
}
|
app/code/local/WP/GenerateSimpleProducts/controllers/IndexController.php
ADDED
@@ -0,0 +1,327 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WP_GenerateSimpleProducts_IndexController extends Mage_Adminhtml_Controller_action
|
4 |
+
{
|
5 |
+
const COMBINATIONS_MAXIMUM = 200002;
|
6 |
+
const PORTION_COUNT = 10;
|
7 |
+
|
8 |
+
private $_configurableAttributes = null;
|
9 |
+
private $_existingCombinations = null;
|
10 |
+
private $_configurableProduct = null;
|
11 |
+
private $_baseData = null;
|
12 |
+
private $_configurableAttributesIterator = null;
|
13 |
+
|
14 |
+
public function indexAction()
|
15 |
+
{
|
16 |
+
$json = array();
|
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) = $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 |
+
// --- / save statistic ---
|
31 |
+
// --- save data ---
|
32 |
+
Mage::getSingleton('admin/session')->setGenerateMainData(array(
|
33 |
+
$this->_configurableAttributes,
|
34 |
+
$this->_existingCombinations,
|
35 |
+
$this->_baseData,
|
36 |
+
$this->_configurableAttributesIterator
|
37 |
+
));
|
38 |
+
// --- / save data ---
|
39 |
+
if ($done >= $count || $done >= self::COMBINATIONS_MAXIMUM) $json['finish'] = true;
|
40 |
+
$json['text'] = sprintf(
|
41 |
+
'Process: %d of %d<br />Found Simple Products: %d<br />Created Simple Products: %d',
|
42 |
+
$done, $count, $fndCount, $crtCount);
|
43 |
+
Mage::getSingleton('admin/session')->setGenerateSPBlocked(0);
|
44 |
+
}
|
45 |
+
$this->getResponse()->setBody(Zend_Json::encode($json));
|
46 |
+
}
|
47 |
+
|
48 |
+
private function _generateMissingSimpleProducts($data)
|
49 |
+
{
|
50 |
+
list($done, $count, $fndCount, $crtCount, $productIds) = $this->_initData($data);
|
51 |
+
$i = 0; $combination = $this->_readCurrentCombination();
|
52 |
+
while ($combination)
|
53 |
+
{
|
54 |
+
$productId = $this->_getProductIdByCombination($combination);
|
55 |
+
if ($productId)
|
56 |
+
{
|
57 |
+
$productIds[] = $productId;
|
58 |
+
$fndCount++;
|
59 |
+
}
|
60 |
+
else
|
61 |
+
{
|
62 |
+
// --- create Simple Product ---
|
63 |
+
$productIds[] = $this->_createSimpleProduct($combination);
|
64 |
+
$crtCount++;
|
65 |
+
}
|
66 |
+
$combination = $this->_getNextCombination();
|
67 |
+
$done++; $i++;
|
68 |
+
if ($i >= self::PORTION_COUNT || $done >= self::COMBINATIONS_MAXIMUM) break;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Save product relations
|
73 |
+
*/
|
74 |
+
if (count($productIds))
|
75 |
+
{
|
76 |
+
Mage::getResourceModel('catalog/product_type_configurable')
|
77 |
+
->saveProducts($this->_configurableProduct, $productIds);
|
78 |
+
|
79 |
+
Mage::getSingleton('admin/session')->setGenerateSPProductIds($productIds);
|
80 |
+
}
|
81 |
+
|
82 |
+
return array($done, $count, $fndCount, $crtCount);
|
83 |
+
}
|
84 |
+
|
85 |
+
private function _initData($data)
|
86 |
+
{
|
87 |
+
$startProcess = isset($data['startProcess']) && $data['startProcess'] ? 1 : 0;
|
88 |
+
$productId = $data['productId'];
|
89 |
+
$this->_configurableProduct = Mage::getModel('catalog/product')->load($productId);
|
90 |
+
if ($startProcess)
|
91 |
+
{
|
92 |
+
$confProduct = $this->_configurableProduct;
|
93 |
+
$attributeSetId = $confProduct->getAttributeSetId();
|
94 |
+
// --- get attributes of conf. product ---
|
95 |
+
$baseAttributes = $confProduct->getAttributes();
|
96 |
+
$baseData = $confProduct->getData();
|
97 |
+
foreach ($baseAttributes as $attr)
|
98 |
+
{
|
99 |
+
$attrCode = $attr->getAttributeCode();
|
100 |
+
if (isset($baseData[$attrCode]))
|
101 |
+
{
|
102 |
+
$attributes[$attrCode] = $baseData[$attrCode];
|
103 |
+
}
|
104 |
+
}
|
105 |
+
// --- exclude attributes ---
|
106 |
+
unset($attributes['entity_id']);
|
107 |
+
unset($attributes['type_id']);
|
108 |
+
unset($attributes['entity_type_id']);
|
109 |
+
unset($attributes['url_key']);
|
110 |
+
unset($attributes['url_path']);
|
111 |
+
unset($attributes['required_options']);
|
112 |
+
unset($attributes['has_options']);
|
113 |
+
unset($attributes['created_at']);
|
114 |
+
unset($attributes['updated_at']);
|
115 |
+
unset($attributes['thumbnail']);
|
116 |
+
unset($attributes['small_image']);
|
117 |
+
unset($attributes['image']);
|
118 |
+
unset($attributes['media_gallery']);
|
119 |
+
$this->_baseData = $attributes;
|
120 |
+
// --- / get attributes by set ---
|
121 |
+
$collection = Mage::getModel('catalog/product')->getCollection()
|
122 |
+
->addAttributeToFilter('attribute_set_id', $attributeSetId);
|
123 |
+
$attrCodes = $iterator = array();
|
124 |
+
$maximum = 1;
|
125 |
+
foreach ($confProduct->getTypeInstance()->getConfigurableAttributes() as $attribute)
|
126 |
+
{
|
127 |
+
$attrCode = $attribute->getProductAttribute()->getAttributeCode();
|
128 |
+
$collection->addAttributeToFilter($attrCode, array('neq' => ''));
|
129 |
+
$values = self::_getAttributeValues($attribute->getProductAttribute()->getSource()->getAllOptions());
|
130 |
+
$attrCodes[$attrCode] = array(
|
131 |
+
'id' => $attribute->getId(),
|
132 |
+
'label' => $attribute->getLabel(),
|
133 |
+
'position' => $attribute->getPosition(),
|
134 |
+
'attribute_id' => $attribute->getProductAttribute()->getId(),
|
135 |
+
'attribute_code' => $attribute->getProductAttribute()->getAttributeCode(),
|
136 |
+
'frontend_label' => $attribute->getProductAttribute()->getFrontend()->getLabel(),
|
137 |
+
'store_label' => $attribute->getProductAttribute()->getStoreLabel(),
|
138 |
+
'values' => $values,
|
139 |
+
);
|
140 |
+
$maximum *= count($values);
|
141 |
+
$iterator[$attrCode] = array(
|
142 |
+
'code' => $attrCode,
|
143 |
+
'index' => 0,
|
144 |
+
'count' => count($values),
|
145 |
+
'values' => array_keys($values)
|
146 |
+
);
|
147 |
+
}
|
148 |
+
$this->_configurableAttributesIterator = $iterator;
|
149 |
+
$this->_configurableAttributes = $attrCodes;
|
150 |
+
$existingCombinations = array();
|
151 |
+
foreach ($collection as $item)
|
152 |
+
{
|
153 |
+
$itemData = $item->getData();
|
154 |
+
$key = $this->_getCombinationKey($itemData);
|
155 |
+
#Mage::log(array($itemData, $key));
|
156 |
+
if (!$key) continue;
|
157 |
+
$existingCombinations[$key] = $itemData['entity_id'];
|
158 |
+
}
|
159 |
+
$this->_existingCombinations = $existingCombinations;
|
160 |
+
$done = $fndCount = $crtCount = 0; $count = $maximum;
|
161 |
+
$productIds = array();
|
162 |
+
}
|
163 |
+
else // --- read from session ---
|
164 |
+
{
|
165 |
+
// --- data ---
|
166 |
+
list(
|
167 |
+
$this->_configurableAttributes,
|
168 |
+
$this->_existingCombinations,
|
169 |
+
$this->_baseData,
|
170 |
+
$this->_configurableAttributesIterator
|
171 |
+
) = Mage::getSingleton('admin/session')->getGenerateMainData();
|
172 |
+
// --- statistic ---
|
173 |
+
$done = Mage::getSingleton('admin/session')->getGenerateSPDone();
|
174 |
+
$count = Mage::getSingleton('admin/session')->getGenerateSPCount();
|
175 |
+
$fndCount = Mage::getSingleton('admin/session')->getGenerateSPFndCount();
|
176 |
+
$crtCount = Mage::getSingleton('admin/session')->getGenerateSPCrtCount();
|
177 |
+
$productIds = Mage::getSingleton('admin/session')->getGenerateSPProductIds();
|
178 |
+
}
|
179 |
+
return array($done, $count, $fndCount, $crtCount, $productIds);
|
180 |
+
}
|
181 |
+
|
182 |
+
private static function _getAttributeValues($data)
|
183 |
+
{
|
184 |
+
$values = array();
|
185 |
+
foreach ($data as $info)
|
186 |
+
{
|
187 |
+
if (!$info['value']) continue;
|
188 |
+
$values[$info['value']] = $info['label'];
|
189 |
+
}
|
190 |
+
return $values;
|
191 |
+
}
|
192 |
+
|
193 |
+
private function _getCombinationKey($data)
|
194 |
+
{
|
195 |
+
$keyParts = array();
|
196 |
+
foreach ($this->_configurableAttributes as $attrCode => $info)
|
197 |
+
{
|
198 |
+
if (isset($data[$attrCode]))
|
199 |
+
{
|
200 |
+
$values = array_keys($info['values']);
|
201 |
+
if (in_array($data[$attrCode], $values))
|
202 |
+
{
|
203 |
+
$keyParts[] = $data[$attrCode];
|
204 |
+
}
|
205 |
+
}
|
206 |
+
else
|
207 |
+
{
|
208 |
+
return;
|
209 |
+
}
|
210 |
+
}
|
211 |
+
$key = implode('-', $keyParts);
|
212 |
+
return $key;
|
213 |
+
}
|
214 |
+
|
215 |
+
private function _getProductIdByCombination($combination)
|
216 |
+
{
|
217 |
+
$key = $this->_getCombinationKey($combination);
|
218 |
+
if (isset($this->_existingCombinations[$key])) return $this->_existingCombinations[$key];
|
219 |
+
return false;
|
220 |
+
}
|
221 |
+
|
222 |
+
private function _readCurrentCombination()
|
223 |
+
{
|
224 |
+
$combination = array(); $iterator = $this->_configurableAttributesIterator;
|
225 |
+
foreach ($this->_configurableAttributesIterator as $attrCode => $info)
|
226 |
+
{
|
227 |
+
if (isset($info['values'][$info['index']]))
|
228 |
+
{
|
229 |
+
$combination[$attrCode] = $info['values'][$info['index']];
|
230 |
+
}
|
231 |
+
else
|
232 |
+
{
|
233 |
+
return;
|
234 |
+
}
|
235 |
+
}
|
236 |
+
return $combination;
|
237 |
+
}
|
238 |
+
|
239 |
+
private function _getNextCombination()
|
240 |
+
{
|
241 |
+
$iterator = $this->_configurableAttributesIterator;
|
242 |
+
$lastItem = end($iterator);
|
243 |
+
$item = reset($iterator); $i = 0; $max = self::COMBINATIONS_MAXIMUM * 2;
|
244 |
+
while ($item && $i < $max)
|
245 |
+
{
|
246 |
+
$attrCode = $item['code'];
|
247 |
+
$iterator[$attrCode]['index']++;
|
248 |
+
if ($iterator[$attrCode]['index'] > $iterator[$attrCode]['count']-1 && $lastItem['code'] != $attrCode)
|
249 |
+
{
|
250 |
+
$iterator[$attrCode]['index'] = 0;
|
251 |
+
$item = next($iterator);
|
252 |
+
}
|
253 |
+
else
|
254 |
+
{
|
255 |
+
$item = false;
|
256 |
+
}
|
257 |
+
$i++;
|
258 |
+
}
|
259 |
+
$this->_configurableAttributesIterator = $iterator;
|
260 |
+
return $this->_readCurrentCombination();
|
261 |
+
}
|
262 |
+
|
263 |
+
private function _createSimpleProduct($combination)
|
264 |
+
{
|
265 |
+
$product = Mage::getModel('catalog/product');
|
266 |
+
// --- set data ---
|
267 |
+
$data = $this->_getSimpleProductDataByCombination($combination);
|
268 |
+
$product->setData($data);
|
269 |
+
$product->setWebsiteIds(self::_getWebsiteIds());
|
270 |
+
// --- add stock info ---
|
271 |
+
$stockData = $product->getStockData();
|
272 |
+
$stockData['qty'] = 1000;
|
273 |
+
$stockData['is_in_stock'] = 1;
|
274 |
+
$product->setStockData($stockData);
|
275 |
+
// --- / add stock info ---
|
276 |
+
$product->save();
|
277 |
+
return $product->getId();
|
278 |
+
}
|
279 |
+
|
280 |
+
private function _getSimpleProductDataByCombination($combination)
|
281 |
+
{
|
282 |
+
list($skuPrefix, $namePrefix) = $this->_getSimpleProductPrefixes($combination);
|
283 |
+
$data = $this->_baseData;
|
284 |
+
$data['sku'] = $data['sku'] . $skuPrefix;
|
285 |
+
$data['name'] = $data['name'] . $namePrefix;
|
286 |
+
$data['type_id'] = Mage_Catalog_Model_Product_Type::DEFAULT_TYPE; // Simple
|
287 |
+
$data['weight'] = 1.0;
|
288 |
+
$data['visibility'] = 1; // Not Visible Individually
|
289 |
+
$data['status'] = 1; // enabled
|
290 |
+
foreach ($combination as $attrCode => $value)
|
291 |
+
{
|
292 |
+
$data[$attrCode] = $value;
|
293 |
+
}
|
294 |
+
#Mage::log($data);
|
295 |
+
return $data;
|
296 |
+
}
|
297 |
+
|
298 |
+
private function _getSimpleProductPrefixes($combination)
|
299 |
+
{
|
300 |
+
$skuPrefixParts = $namePrefixParts = array();
|
301 |
+
$configurableAttributes = $this->_configurableAttributes;
|
302 |
+
foreach ($combination as $attrCode => $value)
|
303 |
+
{
|
304 |
+
// --- generate Name of the Simple Product ---
|
305 |
+
$prefix = $configurableAttributes[$attrCode]['label'] . ' ' . $configurableAttributes[$attrCode]['values'][$value];
|
306 |
+
$namePrefixParts[] = $prefix;
|
307 |
+
$skuPrefixParts[] = str_replace(' ', '-', $prefix);
|
308 |
+
}
|
309 |
+
$skuPrefix = '-' . implode('-', $skuPrefixParts);
|
310 |
+
$namePrefix = ' - ' . implode(' - ', $namePrefixParts);
|
311 |
+
return array($skuPrefix, $namePrefix);
|
312 |
+
}
|
313 |
+
|
314 |
+
private static function _getWebsiteIds()
|
315 |
+
{
|
316 |
+
$websiteIds = Mage::getSingleton('admin/session')->getProductWebsiteIds();
|
317 |
+
if (is_null($websiteIds))
|
318 |
+
{
|
319 |
+
$websites = Mage::app()->getWebsites();
|
320 |
+
$websiteIds = array();
|
321 |
+
foreach ($websites as $website)
|
322 |
+
$websiteIds[] = $website->getId();
|
323 |
+
Mage::getSingleton('admin/session')->setProductWebsiteIds($websiteIds);
|
324 |
+
}
|
325 |
+
return $websiteIds;
|
326 |
+
}
|
327 |
+
}
|
app/code/local/WP/GenerateSimpleProducts/etc/config.xml
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<WP_GenerateSimpleProducts>
|
5 |
+
<version>1.0.1</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>
|
23 |
+
<use>admin</use>
|
24 |
+
<args>
|
25 |
+
<module>WP_GenerateSimpleProducts</module>
|
26 |
+
<frontName>generatesimpleproducts</frontName>
|
27 |
+
</args>
|
28 |
+
</generatesimpleproducts>
|
29 |
+
</routers>
|
30 |
+
</admin>
|
31 |
+
<adminhtml>
|
32 |
+
<layout>
|
33 |
+
<updates>
|
34 |
+
<amazonimportproducts>
|
35 |
+
<file>generatesimpleproducts.xml</file>
|
36 |
+
</amazonimportproducts>
|
37 |
+
</updates>
|
38 |
+
</layout>
|
39 |
+
</adminhtml>
|
40 |
+
<global>
|
41 |
+
<blocks>
|
42 |
+
<adminhtml>
|
43 |
+
<rewrite>
|
44 |
+
<catalog_product_edit_tab_super_config>WP_GenerateSimpleProducts_Block_Config</catalog_product_edit_tab_super_config>
|
45 |
+
</rewrite>
|
46 |
+
</adminhtml>
|
47 |
+
</blocks>
|
48 |
+
<helpers>
|
49 |
+
<generatesimpleproducts>
|
50 |
+
<class>WP_GenerateSimpleProducts_Helper</class>
|
51 |
+
</generatesimpleproducts>
|
52 |
+
</helpers>
|
53 |
+
</global>
|
54 |
+
<adminhtml>
|
55 |
+
<acl>
|
56 |
+
<resources>
|
57 |
+
<all>
|
58 |
+
<title>Allow Everything</title>
|
59 |
+
</all>
|
60 |
+
<admin>
|
61 |
+
<children>
|
62 |
+
<system>
|
63 |
+
<children>
|
64 |
+
<config>
|
65 |
+
<children>
|
66 |
+
<generate_simple_products translate="title" module="generatesimpleproducts">
|
67 |
+
<title><![CDATA[Web & People: Generate Simple Products]]></title>
|
68 |
+
<sort_order>2000</sort_order>
|
69 |
+
</generate_simple_products>
|
70 |
+
</children>
|
71 |
+
</config>
|
72 |
+
</children>
|
73 |
+
</system>
|
74 |
+
</children>
|
75 |
+
</admin>
|
76 |
+
</resources>
|
77 |
+
</acl>
|
78 |
+
</adminhtml>
|
79 |
+
<default>
|
80 |
+
<generate_simple_products>
|
81 |
+
<general>
|
82 |
+
<version>1.0.1</version>
|
83 |
+
</general>
|
84 |
+
</generate_simple_products>
|
85 |
+
</default>
|
86 |
+
<adminhtml>
|
87 |
+
<acl>
|
88 |
+
<resources>
|
89 |
+
<admin>
|
90 |
+
<children>
|
91 |
+
<system>
|
92 |
+
<children>
|
93 |
+
<config>
|
94 |
+
<children>
|
95 |
+
<about_webandpeople translate="title" module="copycustomoptions">
|
96 |
+
<title><![CDATA[Web & People: About Us]]></title>
|
97 |
+
<sort_order>1000</sort_order>
|
98 |
+
</about_webandpeople>
|
99 |
+
</children>
|
100 |
+
</config>
|
101 |
+
</children>
|
102 |
+
</system>
|
103 |
+
</children>
|
104 |
+
</admin>
|
105 |
+
</resources>
|
106 |
+
</acl>
|
107 |
+
</adminhtml>
|
108 |
+
<global>
|
109 |
+
<blocks>
|
110 |
+
<copycustomoptions>
|
111 |
+
<class>WP_GenerateSimpleProducts_Block</class>
|
112 |
+
</copycustomoptions>
|
113 |
+
</blocks>
|
114 |
+
</global>
|
115 |
+
</config>
|
app/code/local/WP/GenerateSimpleProducts/etc/system.xml
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<tabs>
|
4 |
+
<web_and_people translate="label" module="generatesimpleproducts">
|
5 |
+
<label>Web-And-People</label>
|
6 |
+
<sort_order>150</sort_order>
|
7 |
+
</web_and_people>
|
8 |
+
</tabs>
|
9 |
+
<sections>
|
10 |
+
<generate_simple_products translate="label" module="generatesimpleproducts">
|
11 |
+
<label>Generate Simple Products</label>
|
12 |
+
<tab>web_and_people</tab>
|
13 |
+
<frontend_type>text</frontend_type>
|
14 |
+
<sort_order>200</sort_order>
|
15 |
+
<show_in_default>1</show_in_default>
|
16 |
+
<show_in_website>1</show_in_website>
|
17 |
+
<show_in_store>1</show_in_store>
|
18 |
+
<groups>
|
19 |
+
<general translate="label">
|
20 |
+
<label>General</label>
|
21 |
+
<frontend_type>text</frontend_type>
|
22 |
+
<sort_order>10</sort_order>
|
23 |
+
<show_in_default>1</show_in_default>
|
24 |
+
<show_in_website>1</show_in_website>
|
25 |
+
<show_in_store>1</show_in_store>
|
26 |
+
<fields>
|
27 |
+
<version translate="label">
|
28 |
+
<label>Extension Release</label>
|
29 |
+
<frontend_type>label</frontend_type>
|
30 |
+
<sort_order>100</sort_order>
|
31 |
+
<show_in_default>1</show_in_default>
|
32 |
+
<show_in_website>1</show_in_website>
|
33 |
+
<show_in_store>1</show_in_store>
|
34 |
+
</version>
|
35 |
+
</fields>
|
36 |
+
</general>
|
37 |
+
</groups>
|
38 |
+
</generate_simple_products>
|
39 |
+
<about_webandpeople translate="label" module="copycustomoptions">
|
40 |
+
<label>About Us</label>
|
41 |
+
<tab>web_and_people</tab>
|
42 |
+
<frontend_type>text</frontend_type>
|
43 |
+
<sort_order>99</sort_order>
|
44 |
+
<show_in_default>1</show_in_default>
|
45 |
+
<show_in_website>1</show_in_website>
|
46 |
+
<show_in_store>1</show_in_store>
|
47 |
+
<groups>
|
48 |
+
<info>
|
49 |
+
<frontend_model>copycustomoptions/about</frontend_model>
|
50 |
+
<sort_order>10</sort_order>
|
51 |
+
<show_in_default>1</show_in_default>
|
52 |
+
<show_in_website>1</show_in_website>
|
53 |
+
<show_in_store>1</show_in_store>
|
54 |
+
</info>
|
55 |
+
</groups>
|
56 |
+
</about_webandpeople>
|
57 |
+
</sections>
|
58 |
+
</config>
|
app/design/adminhtml/default/WP/layout/generatesimpleproducts.xml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<layout>
|
3 |
+
<adminhtml_catalog_product_edit>
|
4 |
+
<reference name="head">
|
5 |
+
<action method="addCss"><stylesheet>generatesimpleproducts/style.css</stylesheet></action>
|
6 |
+
</reference>
|
7 |
+
</adminhtml_catalog_product_edit>
|
8 |
+
</layout>
|
app/design/adminhtml/default/WP/template/generatesimpleproducts/config.phtml
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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/template/generatesimpleproducts/popup.phtml
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div id="spagen-popup-window-mask" style="display:none;"></div>
|
2 |
+
<div id="spagen-popup-window" class="message-popup">
|
3 |
+
<div class="message-popup-head">
|
4 |
+
<h2 id="spagen-popup-process-title"></h2>
|
5 |
+
</div>
|
6 |
+
<div class="message-popup-content">
|
7 |
+
<div class="message spagen-message-box">
|
8 |
+
<div class="spagen-load-box" id="spagen-img-loader">
|
9 |
+
<img src="<?php echo $this->getSkinUrl('images/ajax-loader-tr.gif') ?>" alt="<?php echo $this->__('Process...') ?>" />
|
10 |
+
</div>
|
11 |
+
<div class="spagen-popup-process-info">
|
12 |
+
<p id="spagen-popup-process-message"></p>
|
13 |
+
<p id="spagen-popup-process-error"></p>
|
14 |
+
</div>
|
15 |
+
</div>
|
16 |
+
<div class="spagen-load-stop">
|
17 |
+
<button id="spagen-popup-process-stop-button" onclick="wpStopGenerate(); return false;" class="scalable delete" type="button"><span id="spagen-load-stop-message"><?php echo $this->__('Stop') ?></span></button>
|
18 |
+
<button id="spagen-popup-process-finish-button" onclick="wpReloadPage(); return false;" class="scalable nodisp" type="button"><span><?php echo $this->__('Close') ?></span></button>
|
19 |
+
</div>
|
20 |
+
</div>
|
21 |
+
</div>
|
22 |
+
|
23 |
+
<script type="text/javascript">//<![CDATA[
|
24 |
+
var wpTimeoutNext = 1000;
|
25 |
+
var wpGeneratePopupParams = {};
|
26 |
+
|
27 |
+
function wpOpenGeneratePopup()
|
28 |
+
{
|
29 |
+
$('spagen-popup-process-message').innerHTML = wpGeneratePopupParams.startText;
|
30 |
+
$('spagen-popup-process-title').innerHTML = wpGeneratePopupParams.title;
|
31 |
+
// ---
|
32 |
+
var height = $('html-body').getHeight();
|
33 |
+
$('spagen-popup-window-mask').setStyle({'height':height+'px'});
|
34 |
+
toggleSelectsUnderBlock($('spagen-popup-window-mask'), false);
|
35 |
+
Element.show('spagen-popup-window-mask');
|
36 |
+
$('spagen-popup-window-mask').scrollTo();
|
37 |
+
$('spagen-popup-window').addClassName('show');
|
38 |
+
// ---
|
39 |
+
wpGeneratePopupParams.stop = false;
|
40 |
+
wpGeneratePopupParams.next = true;
|
41 |
+
wpGeneratePopupParams.iteration = setInterval(function() {
|
42 |
+
if (!wpGeneratePopupParams.next) return;
|
43 |
+
wpProcessGenerate();
|
44 |
+
}, wpTimeoutNext);
|
45 |
+
}
|
46 |
+
|
47 |
+
function wpProcessGenerate()
|
48 |
+
{
|
49 |
+
if (wpGeneratePopupParams.stop)
|
50 |
+
{
|
51 |
+
wpFinishProcess();
|
52 |
+
return;
|
53 |
+
}
|
54 |
+
wpGeneratePopupParams.next = false;
|
55 |
+
new Ajax.Request(wpGeneratePopupParams.url, {
|
56 |
+
method: 'post',
|
57 |
+
loaderArea: false,
|
58 |
+
parameters: wpGeneratePopupParams.data,
|
59 |
+
onComplete: function(transport) {
|
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 |
+
}
|
68 |
+
|
69 |
+
function wpStopGenerate()
|
70 |
+
{
|
71 |
+
wpGeneratePopupParams.stop = true;
|
72 |
+
$('spagen-load-stop-message').innerHTML = '<?php echo $this->__('The process is being stopped...') ?>';
|
73 |
+
}
|
74 |
+
|
75 |
+
function wpReloadPage()
|
76 |
+
{
|
77 |
+
setLocation(wpGeneratePopupParams.reloadUrl);
|
78 |
+
}
|
79 |
+
|
80 |
+
function wpFinishProcess()
|
81 |
+
{
|
82 |
+
clearInterval(wpGeneratePopupParams.iteration);
|
83 |
+
Element.hide('spagen-popup-process-stop-button');
|
84 |
+
$('spagen-img-loader').style.display = 'none';
|
85 |
+
$('spagen-popup-process-finish-button').removeClassName('nodisp');
|
86 |
+
}
|
87 |
+
//]]></script>
|
app/etc/modules/WP_GenerateSimpleProducts.xml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<WP_GenerateSimpleProducts>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>local</codePool>
|
7 |
+
</WP_GenerateSimpleProducts>
|
8 |
+
</modules>
|
9 |
+
</config>
|
package.xml
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>wp_generate_simple_products</name>
|
4 |
+
<version>1.0.1</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>Generate Simple Products for Configurable Product (WebAndPeople.com)</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-05</date>
|
14 |
+
<time>18:55:26</time>
|
15 |
+
<contents><target name="mageweb"><dir name="app"><dir name="code"><dir name="local"><dir name="WP"><dir name="GenerateSimpleProducts"><dir name="Block"><file name="About.php" hash="74c3e699788c6fcefa2830136bd58cce"/><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="b592196e14f2d8c25f81559687309e73"/></dir><dir name="etc"><file name="config.xml" hash="f81afaae8872b4c385b307e61a835330"/><file name="system.xml" hash="e9a8dfc8fc4fc884befe6819c8ea434d"/></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="a04121bc4e2bf5a2f6463b56b4bada1b"/></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>
|
skin/adminhtml/default/WP/generatesimpleproducts/style.css
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#spagen-popup-window{
|
2 |
+
z-index: 111111;
|
3 |
+
}
|
4 |
+
|
5 |
+
#spagen-popup-window-mask, #spagen-catselector-window-mask {
|
6 |
+
background-color: #EFEFEF;
|
7 |
+
bottom: 0;
|
8 |
+
height: 100%;
|
9 |
+
left: 0;
|
10 |
+
opacity: 0.5;
|
11 |
+
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
|
12 |
+
filter: alpha(opacity=50);
|
13 |
+
position: absolute;
|
14 |
+
right: 0;
|
15 |
+
top: 0;
|
16 |
+
width: 100%;
|
17 |
+
z-index: 9999;
|
18 |
+
}
|
19 |
+
|
20 |
+
.spagen-popup-process-info {
|
21 |
+
float: left;
|
22 |
+
}
|
23 |
+
|
24 |
+
.spagen-popup-process-info p {
|
25 |
+
margin: 0;
|
26 |
+
}
|
27 |
+
|
28 |
+
.spagen-load-box {
|
29 |
+
margin: 0 10px 0;
|
30 |
+
width: 35px;
|
31 |
+
float :left;
|
32 |
+
}
|
33 |
+
|
34 |
+
.spagen-load-stop {
|
35 |
+
text-align: right;
|
36 |
+
}
|
37 |
+
|
38 |
+
p.spagen-attention {
|
39 |
+
background: url("images/error_msg_icon.gif") no-repeat scroll 0 0;
|
40 |
+
line-height: 16px;
|
41 |
+
padding: 0 0 0 20px;
|
42 |
+
}
|
43 |
+
|
44 |
+
p.spagen-notification {
|
45 |
+
background: url("images/note_msg_icon.gif") no-repeat scroll 0 0;
|
46 |
+
line-height: 16px;
|
47 |
+
padding: 0 0 0 20px;
|
48 |
+
}
|
49 |
+
|
50 |
+
div.message.spagen-message-box {
|
51 |
+
margin-bottom: 10px;
|
52 |
+
}
|
53 |
+
|
54 |
+
.nodisp {
|
55 |
+
display:none;
|
56 |
+
}
|