store_dependency - Version 1.0.0

Version Notes

Initial release.

Download this release

Release Info

Developer Severin Klingler
Extension store_dependency
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

Files changed (24) hide show
  1. app/code/local/Customweb/Dependency/Helper/Config.php +332 -0
  2. app/code/local/Customweb/Dependency/Helper/Data.php +65 -0
  3. app/code/local/Customweb/Dependency/Helper/Element.php +223 -0
  4. app/code/local/Customweb/Dependency/Model/Category.php +16 -0
  5. app/code/local/Customweb/Dependency/Model/Config.php +17 -0
  6. app/code/local/Customweb/Dependency/Model/ConfigObserver.php +364 -0
  7. app/code/local/Customweb/Dependency/Model/Mysql4/Category.php +14 -0
  8. app/code/local/Customweb/Dependency/Model/Mysql4/Category/Collection.php +14 -0
  9. app/code/local/Customweb/Dependency/Model/Mysql4/Config.php +15 -0
  10. app/code/local/Customweb/Dependency/Model/Mysql4/Config/Collection.php +14 -0
  11. app/code/local/Customweb/Dependency/Model/Mysql4/Product.php +15 -0
  12. app/code/local/Customweb/Dependency/Model/Mysql4/Product/Collection.php +15 -0
  13. app/code/local/Customweb/Dependency/Model/Product.php +17 -0
  14. app/code/local/Customweb/Dependency/Model/Resource/Setup.php +12 -0
  15. app/code/local/Customweb/Dependency/controllers/TestController.php +12 -0
  16. app/code/local/Customweb/Dependency/etc/config.xml +108 -0
  17. app/code/local/Customweb/Dependency/sql/dependency_setup/mysql4-install-1.0.0.php +45 -0
  18. app/code/local/Mage/Core/Model/Config.php +1625 -0
  19. app/code/local/Varien/Data/Form/Element/Abstract.php +314 -0
  20. app/design/adminhtml/default/default/layout/dependency.xml +11 -0
  21. app/etc/modules/Customweb_Dependency.xml +11 -0
  22. js/customweb/dependency.js +116 -0
  23. package.xml +27 -0
  24. skin/adminhtml/base/default/css/dependency.css +76 -0
app/code/local/Customweb/Dependency/Helper/Config.php ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependency
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Helper_Config extends Mage_Core_Helper_Abstract
10
+ {
11
+ /**
12
+ * Get all edges as a adjacency list where result[a] contains
13
+ * all the nodes that depend on a
14
+ *
15
+ * @param string $path
16
+ * @return array
17
+ */
18
+ public function getDependentConfigEdges($path)
19
+ {
20
+ $edges = array();
21
+ $attributeCollection = Mage::getModel('dependency/config')->getCollection();
22
+ $attributeCollection->addFieldToFilter('path', $path);
23
+
24
+ foreach($attributeCollection as $att)
25
+ {
26
+ $edges[$att->getDependsOnScope() . '_' . $att->getDependsOnScopeId()][] = $att->getScope() . '_' . $att->getScopeId();
27
+ }
28
+ return $edges;
29
+ }
30
+
31
+
32
+ /**
33
+ * Get all edges as a adjacency list where result[a] contains
34
+ * all the nodes that a depends on
35
+ *
36
+ * @param string $path
37
+ * @return array
38
+ */
39
+ public function getDependeeConfigEdges($path)
40
+ {
41
+ $edges = array();
42
+ $attributeCollection = Mage::getModel('dependency/config')->getCollection();
43
+ $attributeCollection->addFieldToFilter('path', $path);
44
+
45
+ foreach($attributeCollection as $att)
46
+ {
47
+ $edges[$att->getScope() . '_' . $att->getScopeId()] = $att->getDependsOnScope() . '_' . $att->getDependsOnScopeId();
48
+ }
49
+ return $edges;
50
+ }
51
+
52
+ /**
53
+ * Returns the dependency of an configuration entry.
54
+ *
55
+ * @param string $path
56
+ * @param string $scope
57
+ * @param string $scope_id
58
+ * @return Customweb_Dependency_Model_Config
59
+ */
60
+ public function getConfigDependency($path,$scope,$scope_id)
61
+ {
62
+ $configCollection = Mage::getModel('dependency/config')->getCollection();
63
+ $configCollection->addFieldToFilter('path', $path)
64
+ ->addFieldToFilter('scope', $scope)
65
+ ->addFieldToFilter('scope_id', intval($scope_id));
66
+ $configDependency = $configCollection->getFirstItem();
67
+ if(!$configDependency->getId())
68
+ {
69
+ $configDependency = Mage::getModel('dependency/config');
70
+ $configDependency->setPath($path);
71
+ $configDependency->setScope($scope);
72
+ $configDependency->setScopeId($scope_id);
73
+ }
74
+ return $configDependency;
75
+ }
76
+
77
+ /**
78
+ * Translates between website and store names and corresponding
79
+ * IDs.
80
+ *
81
+ * @param string $websiteName
82
+ * @param string $storeName
83
+ */
84
+ public function getConfigId($websiteName, $storeName)
85
+ {
86
+ $this->initTranslateArrays();
87
+
88
+ if($storeName == null)
89
+ {
90
+ return $this->websiteNameToCode[$websiteName];
91
+ }
92
+ else
93
+ {
94
+ return $this->storeNameToCode[$storeName];
95
+ }
96
+
97
+ }
98
+
99
+ /**
100
+ * Translates the select identifier value to a pair of
101
+ * scope and scopeId.
102
+ *
103
+ * This code is based on Mage_Adminhtml_Model_Config_Data::_getScope()
104
+ *
105
+ * @param string $string
106
+ * @return array
107
+ */
108
+ public function getScope($string)
109
+ {
110
+ try {
111
+ $parts = explode('_',$string,2);
112
+ } catch (Exception $e) {
113
+ throw new Exception(print_r($string,true) . $e->getMessage());
114
+ }
115
+
116
+ if(count($parts) == 2)
117
+ {
118
+ $scope = $parts[0] . 's';
119
+ $scopeCode = $parts[1];
120
+ $scopeId = (int)Mage::getConfig()->getNode($scope . '/' . $scopeCode . '/system/' . $parts[0] . '/id');
121
+ }
122
+ else
123
+ {
124
+ $scope = 'default';
125
+ $scopeId = 0;
126
+ }
127
+ return array('scope' => $scope, 'scope_id' => $scopeId);
128
+ }
129
+
130
+ /**
131
+ * Splits a website/store identifier string of the form "stores_2" into an array.
132
+ *
133
+ * @param string $string website/store identifier
134
+ * @return array
135
+ */
136
+ public function splitScopeString($string)
137
+ {
138
+ $parts = explode('_',$string,2);
139
+ return array('scope' => $parts[0], 'scope_id' => $parts[1]);
140
+ }
141
+
142
+
143
+ /**
144
+ * Create the mappings between website/store identifier strings and the website/store
145
+ * codes.
146
+ */
147
+ private function initTranslateArrays()
148
+ {
149
+ $storeModel = Mage::getSingleton('adminhtml/system_store');
150
+
151
+ if($this->websiteNameToCode == null)
152
+ {
153
+ $this->websiteNameToCode = array();
154
+ foreach ($storeModel->getWebsiteCollection() as $website)
155
+ {
156
+ $this->websiteNameToCode[$website->getCode()] = $this->getScope('website_' . $website->getCode());
157
+ $scope = $this->getScope('website_' . $website->getCode());
158
+ $this->websiteCodeToName[$scope['scope_id']] = $website->getCode();
159
+ }
160
+ }
161
+ if($this->storeNameToCode == null)
162
+ {
163
+ $this->storeNameToCode = array();
164
+ foreach ($storeModel->getStoreCollection() as $store)
165
+ {
166
+ $this->storeNameToCode[$store->getCode()] = $this->getScope('store_' . $store->getCode());
167
+ $scope = $this->getScope('store_' . $store->getCode());
168
+ $this->storeCodeToName[$scope['scope_id']] = $store->getCode();
169
+ }
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Checks for loops if we add the given new dependency.
175
+ *
176
+ * @param mixed $dependency
177
+ * @param string $type
178
+ * @return boolean True if the dependency graph does not contain a cylce starting at the specified node
179
+ */
180
+ public function doesYieldNoLoop($dependency){
181
+
182
+ $edgesToDependent = $this->getDependentConfigEdges(
183
+ $dependency->getPath());
184
+
185
+ $node = $dependency->getScope() . '_' . $dependency->getScopeId();
186
+ $newDependency = $dependency->getDependsOnScope() . '_' . $dependency->getDependsOnScopeId();
187
+
188
+
189
+
190
+ // Only add the dependency if it does not already exist.
191
+ if(isset($edgesToDependent[$newDependency]))
192
+ {
193
+ if(!in_array($node,
194
+ $edgesToDependent[$newDependency]))
195
+ {
196
+ $edgesToDependent[$newDependency][] = $node;
197
+ }
198
+ }
199
+ else
200
+ {
201
+ $edgesToDependent[$newDependency] = array($node);
202
+ }
203
+
204
+ return Mage::helper('dependency')->dfs($node,$edgesToDependent);
205
+ }
206
+
207
+ /**
208
+ * Returns the path of the config value extracted from the html id and the element name
209
+ * of the respective form element.
210
+ *
211
+ * @param string $htmlId
212
+ * @param string $elementName
213
+ * @return string
214
+ */
215
+ public function getPath($htmlId, $elementName)
216
+ {
217
+ preg_match('/groups\[(.*)\]\[fields\]\[(.*)\]\[value/i', $elementName, $m);
218
+
219
+ $group = $m[1];
220
+ $entry = $m[2];
221
+ preg_match('/(.*)\_' . $m[1] . '/', $htmlId, $m);
222
+ $base = $m[1];
223
+
224
+ return $this->createPath($base,$group,$entry);
225
+ }
226
+
227
+ /**
228
+ * Delete the dependency from the config value given, if any.
229
+ *
230
+ * @param string $path
231
+ * @param string $scope
232
+ * @param string $scopeId
233
+ */
234
+ public function deleteDependenyOf($path, $scope, $scopeId)
235
+ {
236
+ $dependency = $this->getConfigDependency($path,$scope,$scopeId);
237
+ if($dependency->getId())
238
+ {
239
+ $dependency->delete();
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Creates the correct path to the config value. Especially it handles custom
245
+ * defined field paths.
246
+ * Code taken from Mage_Adminhtml_Model_Config_Data::save()
247
+ *
248
+ * @param string $section
249
+ * @param string $group
250
+ * @param string $name
251
+ * @return string
252
+ */
253
+ public function createPath($section,$group,$name)
254
+ {
255
+ $path = $section . '/' . $group . '/' . $name;
256
+ $fieldConfig = $this->getSections()->descend($section.'/groups/'.$group.'/fields/'.$name);
257
+
258
+ /**
259
+ * Look for custom defined field path
260
+ */
261
+ if (is_object($fieldConfig)) {
262
+ $configPath = (string)$fieldConfig->config_path;
263
+ if (!empty($configPath) && strrpos($configPath, '/') > 0) {
264
+ $path = $configPath;
265
+ }
266
+ }
267
+ return $path;
268
+ }
269
+
270
+ /**
271
+ * Returns the store name based on the store code
272
+ * @param int $code
273
+ * @return string
274
+ */
275
+ public function getStoreName($code)
276
+ {
277
+ $this->initTranslateArrays();
278
+ return $this->storeCodeToName[$code];
279
+ }
280
+
281
+ /**
282
+ * Returns the website name based on the website code.
283
+ * @param int $code
284
+ * @return string
285
+ */
286
+ public function getWebsiteName($code)
287
+ {
288
+ $this->initTranslateArrays();
289
+ return $this->websiteCodeToName[$code];
290
+ }
291
+
292
+ /**
293
+ * Makes sure the dependency is valid. This does not check for loops in the
294
+ * dependency graphs it only makes sure no dependencies from website level to store level
295
+ * are possible.
296
+ *
297
+ * @param Customweb_Dependency_Model_Config $dependency
298
+ * @param string $throwException True(default) the method throws an exception, false the method returns false on invalid dependencies.
299
+ * @throws Exception
300
+ * @return boolean
301
+ */
302
+ public function validateDependency(Customweb_Dependency_Model_Config $dependency, $throwException=true)
303
+ {
304
+ if($dependency->getScope() == 'websites' && $dependency->getDependsOnScope() == 'stores')
305
+ {
306
+ if($throwException)
307
+ {
308
+ throw new Exception(Mage::helper('dependency')->__("A website cannot depend on a store view."));
309
+ }
310
+ return false;
311
+ }
312
+ return true;
313
+ }
314
+
315
+ /**
316
+ * Returns all configuration sections.
317
+ */
318
+ private function getSections()
319
+ {
320
+ if($this->sections == null){
321
+ $this->sections = Mage::getModel('adminhtml/config')->getSections();
322
+ }
323
+ return $this->sections;
324
+ }
325
+
326
+ protected $storeNameToCode = null;
327
+ protected $websiteNameToCode = null;
328
+ protected $storeCodeToName = null;
329
+ protected $websiteCodeToName = null;
330
+ protected $sections = null;
331
+
332
+ }
app/code/local/Customweb/Dependency/Helper/Data.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependency
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Helper_Data extends Mage_Core_Helper_Abstract
10
+ {
11
+
12
+
13
+ /**
14
+ * Traverses the graph provided by $edges starting at node $node and looks for
15
+ * cycles.
16
+ *
17
+ * @param int $node
18
+ * @param array $edges
19
+ * @return boolean True if graph contains no cylces starting at $node
20
+ */
21
+ public function dfs($node,$edges)
22
+ {
23
+ static $visited = array();
24
+ $noLoop = true;
25
+ if(array_key_exists($node,$visited) && $visited[$node] == 1)
26
+ {
27
+ return false;
28
+ }
29
+ else
30
+ {
31
+ $visited[$node] = 1;
32
+
33
+ if(isset($edges[$node]))
34
+ {
35
+ foreach($edges[$node] as $nextNode)
36
+ {
37
+ $noLoop = $noLoop && $this->dfs($nextNode,$edges);
38
+ }
39
+ }
40
+ }
41
+
42
+ $visited[$node] = 0;
43
+ return $noLoop;
44
+ }
45
+
46
+
47
+
48
+ /**
49
+ * Returns an array of all store ids.
50
+ *
51
+ * @return array List of store ids.
52
+ */
53
+ public function getAllStoreIds()
54
+ {
55
+ return array_keys(Mage::app()->getStores());
56
+ }
57
+
58
+
59
+
60
+ /**
61
+ * Stores the mapping from type names to model names.
62
+ * @var array
63
+ */
64
+ protected $typeToModel = null;
65
+ }
app/code/local/Customweb/Dependency/Helper/Element.php ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependency
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Helper_Element extends Mage_Core_Helper_Abstract
10
+ {
11
+
12
+ private $name = null;
13
+ private $htmlId = null;
14
+ private $elementId = null;
15
+ private $params = null;
16
+
17
+ /**
18
+ * Returns a HTML suffix that is added to every element of applicable admin forms.
19
+ * The suffix contains a select field that allows the user to select on what store view/website
20
+ * the element is dependent.
21
+ *
22
+ * @param string $name Name of the element
23
+ * @param string $htmlId HTML ID of the element
24
+ * @param string $elementId ID of the element
25
+ * @param array $params HTTP Request parameters
26
+ * @return string
27
+ */
28
+ public function getElementSuffix($name,$htmlId,$elementId,$params)
29
+ {
30
+ $this->name = $name;
31
+ $this->htmlId = $htmlId;
32
+ $this->elementId = $elementId;
33
+ $this->params = $params;
34
+ $suffix = "";
35
+
36
+
37
+
38
+
39
+ $suffix = $this->getSuffixForConfigElement();
40
+
41
+ return $suffix;
42
+ }
43
+
44
+
45
+
46
+
47
+ /**
48
+ * Returns the select field for configuration elements.
49
+ *
50
+ * @return string HTML suffix
51
+ */
52
+ private function getSuffixForConfigElement()
53
+ {
54
+ $suffix = "";
55
+
56
+ if(isset($this->params['website']))
57
+ {
58
+ $websiteName = $this->params['website'];
59
+ $storeName = (isset($this->params['store']) ? $this->params['store'] : null);
60
+ $helper = Mage::helper('dependency/config');
61
+
62
+ if(preg_match('/groups\[(.*)\]\[fields\]\[(.*)\]\[value/i',$this->name))
63
+ {
64
+ $dependency = Mage::getModel('dependency/config');
65
+ $path = $helper->getPath($this->htmlId, $this->name);
66
+ $scope = $helper->getConfigId($websiteName,$storeName);
67
+ $dependsOn = $helper->getConfigDependency($path,$scope['scope'],$scope['scope_id']);
68
+
69
+ $type = 'config';
70
+
71
+ $selectName = preg_replace('/^(.*)\[value\]/i', '$1[source]' ,$this->name);
72
+ $dependencyName = preg_replace('/^(.*)\[value\]/i', '$1[dependency]' ,$this->name);
73
+
74
+ $selectHtml = $this->createScopeDependencySelect($selectName,$dependsOn);
75
+
76
+ $suffix = '<input type="hidden" name="' . $dependencyName . '" value="1" />';
77
+ $suffix .= '<div class="dependency-box"><div class="dependency-select">' . $selectHtml . '</div></div>';
78
+ }
79
+ }
80
+ return $suffix;
81
+ }
82
+
83
+ /**
84
+ * Creates a select element that looks like the standard magento store switcher select
85
+ * for configurations.
86
+ * This code is partly taken from template/system/config/switcher.phtml
87
+ */
88
+ private function createScopeDependencySelect($name,$selected)
89
+ {
90
+ $dependsOnWebsite = false;
91
+ $dependsOnStore = false;
92
+ $scope = $selected->getDependsOnScope();
93
+ $helper = Mage::helper('dependency/config');
94
+
95
+
96
+
97
+ if($scope == 'websites')
98
+ {
99
+ $dependsOnWebsite = $helper->getWebsiteName($selected->getDependsOnScopeId());
100
+ }
101
+ elseif ($scope == 'stores')
102
+ {
103
+ $dependsOnStore = $helper->getStoreName($selected->getDependsOnScopeId());
104
+ }
105
+
106
+ $html = '<select id="store_switcher" class="config-dependency-selector" dependencyfor="' . $this->htmlId .'" name="' . $name . '" onchange="' . $this->getUpdateJsString() .'" >';
107
+ foreach ($this->getStoreSelectOptions($dependsOnStore,$dependsOnWebsite) as $_value => $_option)
108
+ {
109
+ if (isset($_option['is_group']))
110
+ {
111
+ if ($_option['is_close'])
112
+ {
113
+ $html .= '</optgroup>';
114
+ }
115
+ else
116
+ {
117
+ $html .= '<optgroup label="' . $this->escapeHtml($_option['label']) . '" style="' . $_option['style'] . '">';
118
+ }
119
+ continue;
120
+ }
121
+ // Check for dependency
122
+ $scope = $helper->getScope($_value);
123
+ $selected->setDependsOnScope($scope['scope']);
124
+ $selected->setDependsOnScopeId($scope['scope_id']);
125
+ $optionClass = 'dependency-check-failed';
126
+ if($helper->validateDependency($selected,false))
127
+ {
128
+ $optionClass = 'dependency-loop';
129
+ if(Mage::helper('dependency/config')->doesYieldNoLoop($selected))
130
+ {
131
+ $optionClass = 'dependency-ok';
132
+ }
133
+ }
134
+ $html .= '<option value="' . $this->escapeHtml($_value) . '" url="' . $_option['url'] . '" ' . ($_option['selected'] ? 'selected="selected"' : '') . ' class="' . $optionClass . '" ' . ' style="' . $_option['style'] . '">';
135
+ $html .= $this->escapeHtml($_option['label']) . '</option>';
136
+ }
137
+ $html .= '</select>';
138
+ return $html;
139
+ }
140
+
141
+ /**
142
+ * Taken from Mage_Adminhtml_Block_System_Config_Switcher
143
+ */
144
+ private function getStoreSelectOptions($curStore,$curWebsite)
145
+ {
146
+ $section = $this->params['section'];
147
+
148
+ $storeModel = Mage::getSingleton('adminhtml/system_store');
149
+ /* @var $storeModel Mage_Adminhtml_Model_System_Store */
150
+
151
+ $url = Mage::getModel('adminhtml/url');
152
+
153
+ $options = array();
154
+ $options['default'] = array(
155
+ 'label' => Mage::helper('dependency')->__('No dependency'),
156
+ 'url' => $url->getUrl('*/*/*', array('section'=>$section)),
157
+ 'selected' => !$curWebsite && !$curStore,
158
+ 'style' => 'background:#ccc; font-weight:bold;',
159
+ );
160
+
161
+ foreach ($storeModel->getWebsiteCollection() as $website) {
162
+ $websiteShow = false;
163
+ foreach ($storeModel->getGroupCollection() as $group) {
164
+ if ($group->getWebsiteId() != $website->getId()) {
165
+ continue;
166
+ }
167
+ $groupShow = false;
168
+ foreach ($storeModel->getStoreCollection() as $store) {
169
+ if ($store->getGroupId() != $group->getId()) {
170
+ continue;
171
+ }
172
+ if (!$websiteShow) {
173
+ $websiteShow = true;
174
+ $options['website_' . $website->getCode()] = array(
175
+ 'label' => $website->getName(),
176
+ 'url' => $url->getUrl('*/*/*', array('section'=>$section, 'website'=>$website->getCode())),
177
+ 'selected' => !$curStore && $curWebsite == $website->getCode(),
178
+ 'style' => 'padding-left:16px; background:#DDD; font-weight:bold;',
179
+ );
180
+ }
181
+ if (!$groupShow) {
182
+ $groupShow = true;
183
+ $options['group_' . $group->getId() . '_open'] = array(
184
+ 'is_group' => true,
185
+ 'is_close' => false,
186
+ 'label' => $group->getName(),
187
+ 'style' => 'padding-left:32px;'
188
+ );
189
+ }
190
+ $options['store_' . $store->getCode()] = array(
191
+ 'label' => $store->getName(),
192
+ 'url' => $url->getUrl('*/*/*', array('section'=>$section, 'website'=>$website->getCode(), 'store'=>$store->getCode())),
193
+ 'selected' => $curStore == $store->getCode(),
194
+ 'style' => '',
195
+ );
196
+ }
197
+ if ($groupShow) {
198
+ $options['group_' . $group->getId() . '_close'] = array(
199
+ 'is_group' => true,
200
+ 'is_close' => true,
201
+ );
202
+ }
203
+ }
204
+ }
205
+
206
+ return $options;
207
+ }
208
+
209
+ private function getUpdateJsString()
210
+ {
211
+ $loopError = Mage::helper('dependency')->__("Can not depend on this store view. Loop detected.");
212
+ $dependencyCheckError = Mage::helper('dependency')->__("A website cannot depend on a store view.");
213
+
214
+ return 'updateDependencySelect(this,\'' . $this->htmlId .'\',false,\'' . $loopError . '\',\'' . $dependencyCheckError . '\')';
215
+ }
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+ }
app/code/local/Customweb/Dependency/Model/Category.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependency
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Model_Category extends Mage_Core_Model_Abstract
10
+ {
11
+ protected function _construct()
12
+ {
13
+ $this->_init('dependency/category');
14
+ }
15
+
16
+ }
app/code/local/Customweb/Dependency/Model/Config.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ ::[Header]::
5
+ * @category Local
6
+ * @package Customweb_Dependency
7
+ * @link http://www.customweb.ch
8
+ */
9
+
10
+ class Customweb_Dependency_Model_Config extends Mage_Core_Model_Abstract
11
+ {
12
+ protected function _construct()
13
+ {
14
+ $this->_init('dependency/config');
15
+ }
16
+
17
+ }
app/code/local/Customweb/Dependency/Model/ConfigObserver.php ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependency
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Model_ConfigObserver
10
+ {
11
+ /**
12
+ * The method is registered to the event 'model_config_data_save_before'. It updates
13
+ * the dependency graph.
14
+ *
15
+ * @param Varien_Event_Observer $observer
16
+ */
17
+ public function configSaveBefore(Varien_Event_Observer $observer)
18
+ {
19
+ $event = $observer->getEvent();
20
+ $config = $event->getObject();
21
+
22
+ $section = $config->getSection();
23
+ $website = $config->getWebsite();
24
+ $store = $config->getStore();
25
+ $groups = $config->getGroups();
26
+ $scope = $config->getScope();
27
+ $scopeId = $config->getScopeId();
28
+ $this->handleConfigs = array();
29
+
30
+ $write = Mage::getSingleton('core/resource')->getConnection('core_write');
31
+ $write->beginTransaction();
32
+
33
+
34
+ try
35
+ {
36
+ foreach ($groups as $group => $groupData)
37
+ {
38
+ foreach($groupData['fields'] as $name => $data)
39
+ {
40
+ if(isset($data['dependency']))
41
+ {
42
+ $path = $this->getHelper()->createPath($section, $group, $name);
43
+ $dependency = $this->getHelper()->getConfigDependency($path,$scope,$scopeId);
44
+ $source = 'default';
45
+
46
+ if(isset($data['source']))
47
+ {
48
+ $source = $this->getFirstElementIfArray($data['source']);
49
+ }
50
+
51
+ if(isset($data['inherit']) || $source == 'default')
52
+ {
53
+ $dependency->delete();
54
+
55
+ // Config values that are inherited have to be rememered, for later processing
56
+ $this->handleConfigs[] = array('path' => $path, 'scope' => $scope, 'scopeId' => $scopeId);
57
+
58
+ }
59
+ else
60
+ {
61
+ // Create dependency
62
+ $scopeInfo = $this->getHelper()->getScope($source);
63
+ $dependency->setDependsOnScope($scopeInfo['scope']);
64
+ $dependency->setDependsOnScopeId($scopeInfo['scope_id']);
65
+ $this->getHelper()->validateDependency($dependency);
66
+ $dependency->save();
67
+
68
+
69
+ // Save a config value
70
+ //$configModel = new Mage_Core_Model_Config();
71
+ //$configModel ->saveConfig('general/country/default', "US", $scope, $scopeId);
72
+ }
73
+ }
74
+ }
75
+ }
76
+ $write->commit();
77
+ }
78
+ catch(Exception $e)
79
+ {
80
+ while($write->getTransactionLevel() > 0)
81
+ {
82
+ $write->rollback();
83
+ }
84
+ throw $e;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * This method is registered to the event 'core_config_data_delete_after'. All dependencies
90
+ * are resolved after deleting and inherited values are updated.
91
+ *
92
+ * @param Varien_Event_Observer $observer
93
+ */
94
+ public function configDeleteAfter(Varien_Event_Observer $observer)
95
+ {
96
+ $this->configSaveAfter($observer);
97
+ }
98
+
99
+ /**
100
+ * This method is registered to the event 'core_config_data_save_after'. All dependencies
101
+ * are resolved after saving and inherited values are updated.
102
+ *
103
+ * @param Varien_Event_Observer $observer
104
+ */
105
+ public function configSaveAfter(Varien_Event_Observer $observer)
106
+ {
107
+ // We keep track of wheter we are already in the dependency updating process
108
+ static $configUpdateInProgress = false;
109
+
110
+ if(!$configUpdateInProgress)
111
+ {
112
+ $configUpdateInProgress = true;
113
+ $configData = $observer->getEvent()->getConfigData();
114
+
115
+ $path = $configData->getPath();
116
+ $scope = $configData->getScope();
117
+ $scopeId = $configData->getScopeId();
118
+
119
+ $this->handleConfigs[] = array('path' => $path, 'scope' => $scope, 'scopeId' => $scopeId);
120
+ $this->saveUpdateConfig($this->handleConfigs);
121
+
122
+ $configUpdateInProgress = false;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * This method listens to the event 'core_model_config_save_before'.
128
+ * This is a CUSTOM EVENT that is introduced in local/Mage/Core/Model/Config.php to
129
+ * handle changes in config values from code and not the UI.
130
+ * The dependency for the changed config value is removed if one exists and dependent values
131
+ * are updateted.
132
+ *
133
+ * @param Varien_Event_Observer $observer
134
+ */
135
+ public function coreConfigSaveAfter(Varien_Event_Observer $observer)
136
+ {
137
+ $path = $observer->getPath();
138
+ $scope = $observer->getScope();
139
+ $scopeId = $observer->getScopeId();
140
+
141
+ $write = Mage::getSingleton('core/resource')->getConnection('core_write');
142
+ $write->beginTransaction();
143
+
144
+ try
145
+ {
146
+ $this->getHelper()->deleteDependenyOf($path,$scope,$scopeId);
147
+ $this->saveUpdateConfig(array('path' => $path, 'scope' => $scope, 'scopeId' => $scopeId));
148
+ }
149
+ catch(Exception $e)
150
+ {
151
+ while($write->getTransactionLevel() > 0)
152
+ {
153
+ $write->rollback();
154
+ }
155
+ throw $e;
156
+ }
157
+
158
+ if($write->getTransactionLevel() >= 1)
159
+ {
160
+ $write->commit();
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Handles all the config values we need to update.
166
+ * @param array $configs
167
+ */
168
+ protected function saveUpdateConfig($configs)
169
+ {
170
+ foreach($configs as $config)
171
+ {
172
+ $path = $config['path'];
173
+ $scope = $config['scope'];
174
+ $scopeId = $config['scopeId'];
175
+ $allConfigData = $this->getAllConfigs($path);
176
+
177
+ if($scope == 'default' || preg_match('/website/i',$scope) || !isset($allConfigData[$scope . '_' . $scopeId]))
178
+ {
179
+ foreach($allConfigData as $entity)
180
+ {
181
+ $this->updateAllChildren($path, $entity, $allConfigData);
182
+ }
183
+ }
184
+ else
185
+ {
186
+ $entity = $allConfigData[$scope . '_' . $scopeId];
187
+ $this->updateAllChildren($path, $entity, $allConfigData);
188
+ }
189
+
190
+ $this->saveAllConfigData($allConfigData);
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Updates all children of $possibleChild in the dependency graph.
196
+ *
197
+ * @param string $path
198
+ * @param Mage_Core_Config_Data $possibleChild
199
+ * @param array $allConfigData
200
+ */
201
+ protected function updateAllChildren($path, $possibleChild, $allConfigData)
202
+ {
203
+ $edgesToDependent = $this->getHelper()->getDependentConfigEdges($path);
204
+ $edgesFromDependent = $this->getHelper()->getDependeeConfigEdges($path);
205
+ $start = $possibleChild->getScope() . "_" . $possibleChild->getScopeId();
206
+ $updateRoot = false;
207
+ $value = $possibleChild->getValue();
208
+
209
+ // If current node has a parent in the dependency graph
210
+ if(isset($edgesFromDependent[$start]))
211
+ {
212
+ $parent = $edgesFromDependent[$start];
213
+ $value = $this->getParentValue($parent,$allConfigData,$path);
214
+ $updateRoot = true;
215
+ }
216
+
217
+ $this->dfs($start, $allConfigData, $edgesToDependent, $value ,$updateRoot);
218
+ }
219
+
220
+ private function dfs($node, $allNodes, $edges, $value, $update)
221
+ {
222
+ static $visited = array();
223
+ if(array_key_exists($node,$visited) && $visited[$node] == 1)
224
+ {
225
+ throw new Exception(Mage::helper('dependency')->__("Dependency loop detected."));
226
+ }
227
+ else
228
+ {
229
+ $visited[$node] = 1;
230
+ if($update)
231
+ {
232
+ $s = $allNodes[$node];
233
+ if($s->getValue() != $value)
234
+ {
235
+ $s->setValue($value);
236
+ }
237
+ }
238
+
239
+ if(isset($edges[$node]))
240
+ {
241
+ foreach($edges[$node] as $nextNode)
242
+ {
243
+ $this->dfs($nextNode, $allNodes, $edges, $value, true);
244
+ }
245
+ }
246
+ }
247
+
248
+ $visited[$node] = 0;
249
+ }
250
+
251
+ /**
252
+ * Returns the value of the $parent node. This is a bit tricky as config values
253
+ * that use default values do no longer exist in the database.
254
+ *
255
+ * @param string $parent
256
+ * @param array $allConfigData
257
+ * @param string $path
258
+ * @return mixed
259
+ */
260
+ private function getParentValue($parent, $allConfigData, $path)
261
+ {
262
+ // If the parent uses default no config value exists.
263
+ if(!isset($allConfigData[$parent]))
264
+ {
265
+ $scope = $this->getHelper()->splitScopeString($parent);
266
+
267
+ if(preg_match("/store/i", $scope['scope']))
268
+ {
269
+ $websiteId = $this->storeToWebsite($scope['scope_id']);
270
+
271
+ // If the website config does not exist, back up to the default value.
272
+ if(!isset($allConfigData['websites_' . $websiteId]))
273
+ {
274
+ // If there is no default value in the db, backup to the confg xml
275
+ if(!isset($allConfigData['default_0']))
276
+ {
277
+ $value = Mage::getStoreConfig($path);
278
+ }
279
+ else
280
+ {
281
+ $value = $allConfigData['default_0']->getValue();
282
+ }
283
+ }
284
+ else
285
+ {
286
+ $value = $allConfigData['websites_' . $websiteId]->getValue();
287
+ }
288
+ }
289
+ else
290
+ {
291
+ $value = $allConfigData['default_0']->getValue();
292
+ }
293
+ }
294
+ else
295
+ {
296
+ $value = $allConfigData[$parent]->getValue();
297
+ }
298
+ return $value;
299
+ }
300
+
301
+ private function getFirstElementIfArray($possibleArray)
302
+ {
303
+ return is_array($possibleArray) ? $possibleArray[0] : $possibleArray;
304
+ }
305
+
306
+ /**
307
+ * Returns an array of all the stored config values for a given path
308
+ * @param string $path
309
+ * @return array
310
+ */
311
+ private function getAllConfigs($path)
312
+ {
313
+ $allConfigs = array();
314
+ $configDataCollection = Mage::getModel('core/config_data')->getCollection()
315
+ ->addFieldToFilter('path', array('like' => "%" . $path . '%'));
316
+
317
+ foreach ($configDataCollection as $data) {
318
+ $allConfigs[$data->getScope() . '_' . $data->getScopeId()] = $data;
319
+ }
320
+
321
+ return $allConfigs;
322
+ }
323
+
324
+ /**
325
+ * Returns the website id for a given store id;
326
+ * @param int $id
327
+ */
328
+ private function storeToWebsite($id)
329
+ {
330
+ if($this->storeToWebsiteMap == null)
331
+ {
332
+ $this->storeToWebsiteMap = array();
333
+ $storeModel = Mage::getSingleton('adminhtml/system_store');
334
+ foreach ($storeModel->getStoreCollection() as $store) {
335
+ $this->storeToWebsiteMap[$store->getId()] = $store->getWebsiteId();
336
+ }
337
+ }
338
+ return $this->storeToWebsiteMap[$id];
339
+ }
340
+
341
+ /**
342
+ * Stores all the configuration data to the database.
343
+ * @param array $allConfigData
344
+ */
345
+ private function saveAllConfigData($allConfigData)
346
+ {
347
+ foreach($allConfigData as $data){
348
+ $data->save();
349
+ }
350
+ }
351
+
352
+ private function getHelper()
353
+ {
354
+ if($this->helper == null)
355
+ {
356
+ $this->helper = Mage::helper('dependency/config');
357
+ }
358
+ return $this->helper;
359
+ }
360
+
361
+ private $helper = null;
362
+ private $handleConfigs = array();
363
+ private $storeToWebsiteMap = null;
364
+ }
app/code/local/Customweb/Dependency/Model/Mysql4/Category.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependency
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Model_Mysql4_Category extends Mage_Core_Model_Mysql4_Abstract{
10
+ protected function _construct()
11
+ {
12
+ $this->_init('dependency/category', 'dependency_id');
13
+ }
14
+ }
app/code/local/Customweb/Dependency/Model/Mysql4/Category/Collection.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependency
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Model_Mysql4_Category_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
10
+ protected function _construct()
11
+ {
12
+ $this->_init('dependency/category');
13
+ }
14
+ }
app/code/local/Customweb/Dependency/Model/Mysql4/Config.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ ::[Header]::
5
+ * @category Local
6
+ * @package Customweb_Dependency
7
+ * @link http://www.customweb.ch
8
+ */
9
+
10
+ class Customweb_Dependency_Model_Mysql4_Config extends Mage_Core_Model_Mysql4_Abstract{
11
+ protected function _construct()
12
+ {
13
+ $this->_init('dependency/config', 'dependency_id');
14
+ }
15
+ }
app/code/local/Customweb/Dependency/Model/Mysql4/Config/Collection.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependency
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Model_Mysql4_Config_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
10
+ protected function _construct()
11
+ {
12
+ $this->_init('dependency/config');
13
+ }
14
+ }
app/code/local/Customweb/Dependency/Model/Mysql4/Product.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ ::[Header]::
5
+ * @category Local
6
+ * @package Customweb_Dependency
7
+ * @link http://www.customweb.ch
8
+ */
9
+
10
+ class Customweb_Dependency_Model_Mysql4_Product extends Mage_Core_Model_Mysql4_Abstract{
11
+ protected function _construct()
12
+ {
13
+ $this->_init('dependency/product', 'dependency_id');
14
+ }
15
+ }
app/code/local/Customweb/Dependency/Model/Mysql4/Product/Collection.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ ::[Header]::
5
+ * @category Local
6
+ * @package Customweb_Dependency
7
+ * @link http://www.customweb.ch
8
+ */
9
+
10
+ class Customweb_Dependency_Model_Mysql4_Product_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
11
+ protected function _construct()
12
+ {
13
+ $this->_init('dependency/product');
14
+ }
15
+ }
app/code/local/Customweb/Dependency/Model/Product.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ ::[Header]::
5
+ * @category Local
6
+ * @package Customweb_Dependency
7
+ * @link http://www.customweb.ch
8
+ */
9
+
10
+ class Customweb_Dependency_Model_Product extends Mage_Core_Model_Abstract
11
+ {
12
+ protected function _construct()
13
+ {
14
+ $this->_init('dependency/product');
15
+ }
16
+
17
+ }
app/code/local/Customweb/Dependency/Model/Resource/Setup.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ ::[Header]::
4
+ * @category Local
5
+ * @package Customweb_Dependencies
6
+ * @link http://www.customweb.ch
7
+ */
8
+
9
+ class Customweb_Dependency_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
10
+ {
11
+
12
+ }
app/code/local/Customweb/Dependency/controllers/TestController.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Customweb_Dependency_TestController extends Mage_Core_Controller_Front_Action
4
+ {
5
+ public function indexAction(){
6
+ $model = new Mage_Core_Model_Config();
7
+ //$model->saveConfig('esr/account_information/deposit_for', "Geänadert auf website level", 'websites', 2);
8
+ //$model->saveConfig('esr/account_information/deposit_for', "geändert auf store level", 'stores', 2);
9
+ $model->saveConfig('esr/account_information/deposit_for', "default 88");
10
+ die("fertig");
11
+ }
12
+ }
app/code/local/Customweb/Dependency/etc/config.xml ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <modules>
5
+ <Customweb_Dependency>
6
+ <version>1.0.0</version>
7
+ </Customweb_Dependency>
8
+ </modules>
9
+
10
+ <global>
11
+ <models>
12
+ <dependency>
13
+ <class>Customweb_Dependency_Model</class>
14
+ <resourceModel>dependency_mysql4</resourceModel>
15
+ </dependency>
16
+ <dependency_mysql4>
17
+ <class>Customweb_Dependency_Model_Mysql4</class>
18
+ <entities>
19
+ <product>
20
+ <table>customweb_product_dependency</table>
21
+ </product>
22
+ <category>
23
+ <table>customweb_category_dependency</table>
24
+ </category>
25
+ <config>
26
+ <table>customweb_config_dependency</table>
27
+ </config>
28
+ </entities>
29
+ </dependency_mysql4>
30
+ </models>
31
+ <helpers>
32
+ <dependency>
33
+ <class>Customweb_Dependency_Helper</class>
34
+ </dependency>
35
+ </helpers>
36
+ <resources>
37
+ <dependency_write>
38
+ <connection>
39
+ <use>core_write</use>
40
+ </connection>
41
+ </dependency_write>
42
+ <dependency_read>
43
+ <connection>
44
+ <use>core_read</use>
45
+ </connection>
46
+ </dependency_read>
47
+ <dependency_setup>
48
+ <setup>
49
+ <module>Customweb_Dependency</module>
50
+ <class>Customweb_Dependency_Model_Resource_Setup</class>
51
+ </setup>
52
+ </dependency_setup>
53
+ </resources>
54
+ <events>
55
+ <core_model_config_save_after>
56
+ <observers>
57
+ <dependency_core_config_save_after>
58
+ <type>singleton</type>
59
+ <class>Customweb_Dependency_Model_ConfigObserver</class>
60
+ <method>coreConfigSaveAfter</method>
61
+ </dependency_core_config_save_after>
62
+ </observers>
63
+ </core_model_config_save_after>
64
+ <model_config_data_save_before>
65
+ <observers>
66
+ <dependency_config_save_before>
67
+ <type>singleton</type>
68
+ <class>Customweb_Dependency_Model_ConfigObserver</class>
69
+ <method>configSaveBefore</method>
70
+ </dependency_config_save_before>
71
+ </observers>
72
+ </model_config_data_save_before>
73
+ <core_config_data_save_after>
74
+ <observers>
75
+ <dependency_config_save_after>
76
+ <type>singleton</type>
77
+ <class>Customweb_Dependency_Model_ConfigObserver</class>
78
+ <method>configSaveAfter</method>
79
+ </dependency_config_save_after>
80
+ </observers>
81
+ </core_config_data_save_after>
82
+ <core_config_data_delete_after>
83
+ <observers>
84
+ <dependency_config_delete_after>
85
+ <type>singleton</type>
86
+ <class>Customweb_Dependency_Model_ConfigObserver</class>
87
+ <method>configDeleteAfter</method>
88
+ </dependency_config_delete_after>
89
+ </observers>
90
+ </core_config_data_delete_after>
91
+
92
+
93
+
94
+ </events>
95
+ </global>
96
+
97
+ <adminhtml>
98
+ <layout>
99
+ <updates>
100
+ <dependency>
101
+ <file>dependency.xml</file>
102
+ </dependency>
103
+ </updates>
104
+ </layout>
105
+ </adminhtml>
106
+
107
+
108
+ </config>
app/code/local/Customweb/Dependency/sql/dependency_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ ::[Header]::
5
+ * @category Local
6
+ * @package Customweb_Dependency
7
+ * @link http://www.customweb.ch
8
+ */
9
+
10
+ $installer = $this;
11
+ $installer->startSetup();
12
+ $installer->run("CREATE TABLE `customweb_product_dependency` (
13
+ `dependency_id` INT NOT NULL AUTO_INCREMENT,
14
+ `attribute_id` INT NOT NULL ,
15
+ `store_id` INT NOT NULL ,
16
+ `entity_id` INT NOT NULL ,
17
+ `depends_on_store_id` INT NOT NULL ,
18
+ PRIMARY KEY ( `dependency_id` )
19
+ ) ENGINE = InnoDB DEFAULT CHARSET=utf8;
20
+ ");
21
+
22
+ $installer->run("CREATE TABLE `customweb_category_dependency` (
23
+ `dependency_id` INT NOT NULL AUTO_INCREMENT,
24
+ `attribute_id` INT NOT NULL ,
25
+ `store_id` INT NOT NULL ,
26
+ `entity_id` INT NOT NULL ,
27
+ `depends_on_store_id` INT NOT NULL ,
28
+ PRIMARY KEY ( `dependency_id` )
29
+ ) ENGINE = InnoDB DEFAULT CHARSET=utf8;
30
+ ");
31
+
32
+ $installer->run("CREATE TABLE `customweb_config_dependency` (
33
+ `dependency_id` INT NOT NULL AUTO_INCREMENT,
34
+ `path` VARCHAR(255) NOT NULL ,
35
+ `scope` VARCHAR(8) NOT NULL ,
36
+ `scope_id` INT NOT NULL ,
37
+ `depends_on_scope` VARCHAR(8) NOT NULL ,
38
+ `depends_on_scope_id` INT NOT NULL ,
39
+ PRIMARY KEY ( `dependency_id` )
40
+ ) ENGINE = InnoDB DEFAULT CHARSET=utf8;
41
+ ");
42
+
43
+ $installer->endSetup();
44
+
45
+
app/code/local/Mage/Core/Model/Config.php ADDED
@@ -0,0 +1,1625 @@