Intelligent_Reach - Version 1.0.37

Version Notes

Stable release. Compatible with older versions. Feed creation has been optimized to handle larger loads. The option to choose the store is now available. Can retrieve associated products for grouped types.Bug fixes.Has support for PHP V5.2. Quantity script has now been added. Flat Catalog support has been added,

Download this release

Release Info

Developer Intelligent Reach
Extension Intelligent_Reach
Version 1.0.37
Comparing to
See all releases


Code changes from version 1.0.36 to 1.0.37

app/code/local/IntelligentReach/AmazonPayment/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_AmazonPayment>
5
- <version>1.0.35</version>
6
  </IntelligentReach_AmazonPayment>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_AmazonPayment>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_AmazonPayment>
7
  </modules>
8
  <global>
app/code/local/IntelligentReach/DebenhamsPayment/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_DebenhamsPayment>
5
- <version>1.0.35</version>
6
  </IntelligentReach_DebenhamsPayment>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_DebenhamsPayment>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_DebenhamsPayment>
7
  </modules>
8
  <global>
app/code/local/IntelligentReach/EbayPayment/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_EbayPayment>
5
- <version>1.0.35</version>
6
  </IntelligentReach_EbayPayment>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_EbayPayment>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_EbayPayment>
7
  </modules>
8
  <global>
app/code/local/IntelligentReach/IRShipping/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_IRShipping>
5
- <version>1.0.35</version>
6
  </IntelligentReach_IRShipping>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_IRShipping>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_IRShipping>
7
  </modules>
8
  <global>
app/code/local/IntelligentReach/Integration/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_Integration>
5
- <version>1.0.35</version>
6
  </IntelligentReach_Integration>
7
  </modules>
8
  <frontend>
2
  <config>
3
  <modules>
4
  <IntelligentReach_Integration>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_Integration>
7
  </modules>
8
  <frontend>
app/code/local/IntelligentReach/LazadaPayment/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_LazadaPayment>
5
- <version>1.0.35</version>
6
  </IntelligentReach_LazadaPayment>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_LazadaPayment>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_LazadaPayment>
7
  </modules>
8
  <global>
app/code/local/IntelligentReach/PlayPayment/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_PlayPayment>
5
- <version>1.0.35</version>
6
  </IntelligentReach_PlayPayment>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_PlayPayment>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_PlayPayment>
7
  </modules>
8
  <global>
app/code/local/IntelligentReach/RakutenPayment/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_RakutenPayment>
5
- <version>1.0.35</version>
6
  </IntelligentReach_RakutenPayment>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_RakutenPayment>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_RakutenPayment>
7
  </modules>
8
  <global>
app/code/local/IntelligentReach/TradeMePayment/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_TradeMePayment>
5
- <version>1.0.35</version>
6
  </IntelligentReach_TradeMePayment>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_TradeMePayment>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_TradeMePayment>
7
  </modules>
8
  <global>
app/code/local/IntelligentReach/WestfieldPayment/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <IntelligentReach_WestfieldPayment>
5
- <version>1.0.35</version>
6
  </IntelligentReach_WestfieldPayment>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <IntelligentReach_WestfieldPayment>
5
+ <version>1.0.37</version>
6
  </IntelligentReach_WestfieldPayment>
7
  </modules>
8
  <global>
intelligentreach_integration.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- /** Version 1.0.36 Last updated by Kire on 27/04/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  include_once 'app/Mage.php';
@@ -12,68 +12,68 @@ $ir->run();
12
 
13
  class IntelligentReach
14
  {
15
- private $_splitby = 100;
16
- private $_amountOfProductsPerPage = 100;
17
- private $_lastPageNumber = 0;
18
- private $_versionDisplay = "Version 1.0.36 <br />Last updated on 27/04/2016";
19
-
20
- public function run()
21
- {
22
- // If a store id was provided then print the products to the output.
23
- if ($this->storeIsSelected())
24
- {
25
- if (isset($_GET["splitby"]))
26
- $this->_splitby = $_GET["splitby"];
27
- if (isset($_GET["amountofproducts"]))
28
- $this->_amountOfProductsPerPage = $_GET["amountofproducts"];
29
- $this->_lastPageNumber = ceil($this->getProductCollection()->getSize() / $this->_amountOfProductsPerPage);
30
-
31
- if ((isset($_GET["startingpage"]) && isset($_GET["endpage"])) || isset($_GET["getall"]))
32
- {
33
- header("Content-Type: text/xml; charset=UTF-8");
34
- header("Cache-Control: no-cache, must-revalidate");
35
- echo '<?xml version="1.0" encoding="utf-8"?>
36
- <products>';
37
- $this->runTheTask(isset($_GET["getall"]) ? 1 : $_GET["startingpage"], isset($_GET["getall"]) ? $this->_lastPageNumber : $_GET["endpage"]);
38
- echo '</products>';
39
- }
40
- else
41
- $this->printSections();
42
- }
43
- else
44
- $this->printStores();
45
- }
46
-
47
- // Check if a storeid parameter has been set, returns a boolean.
48
- public function storeIsSelected()
49
- {
50
- if (isset($_GET["storeid"]))
51
- return true;
52
- else
53
- return false;
54
- }
55
-
56
- // Gets all the stores on all websites,
57
- // returns a table containing Store Ids and Store Names.
58
- public function getStores()
59
- {
60
- $websiteStores = Mage::app()->getStores();
61
- echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
62
- echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
63
- foreach ($websiteStores as $store)
64
- echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "&splitby=100&amountofproducts=100'>" . $store->getName() . "</a></td></tr>";
65
- echo "</table>";
66
- }
67
-
68
- public function printStores()
69
- {
70
- echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
71
- $this->getStores();
72
- echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
73
- echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
74
- echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
75
- echo "<h5>".$this->_versionDisplay."</h5></div>";
76
- }
77
 
78
  public function getSections($sections)
79
  {
@@ -83,186 +83,183 @@ class IntelligentReach
83
  $pages = $this->_lastPageNumber;
84
  echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
85
  echo "<tr><th>Section</th><th>Pages</th></tr>";
86
- for ($i = $sections; $i > 0; $i--)
87
- {
88
- $startingPage = $pages - $this->_splitby + 1;
89
- if ($startingPage < 1)
90
- $startingPage = 1;
91
-
92
- echo "<tr><td><a href='?storeid=" . $_GET["storeid"] . "&startingpage=" . $startingPage . "&endpage=" . $pages . "&splitby=".$this->_splitby ."&amountofproducts=".$this->_amountOfProductsPerPage.$convertNumberToWord.$stripInvalidChars.$includeAllParentFields."'>" . $i . "</a></td><td>" . $startingPage . "-" . $pages . "</td></tr>";
93
- $pages = $startingPage - 1;
94
- }
95
- echo "</table>";
96
- }
97
-
98
- public function printSections()
99
- {
100
- $sections = ceil($this->_lastPageNumber / $this->_splitby);
101
- echo "<h2>Please select a section to return the products.</h2>";
102
- echo "<div class='sections' style='float:left; padding-left:50px;'>";
103
- $this->getSections($sections);
104
- echo "</div>";
105
- echo "<div class='instructions' style='float:left; padding-left:50px;'>";
106
- echo "<h3>Instructions</h3>";
107
- echo "<p>The parameter <strong>'splitby'</strong> in the URL splits pages into sections, each page contains (unless specified otherwise) the default amount of 100 products.</p>";
108
- echo "<p>So setting <strong>'splitby'</strong> to equal 100 will bring back 1,000 products per page and 10,000 products per section, if there are 40,000 products in the store then this will return 4 sections. </p>";
109
- echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>splitby=100</strong></p>";
110
- echo "<p>You can also set the value of the number of products per page that is returned, by setting the parameter <strong>'amountofproducts'</strong> in the URL</p>";
111
- echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&splitby=100&<strong>amountofproducts=100</strong></p>";
112
- echo "<p><strong>NB:</strong> The default value for <strong>'splitby'</strong> is 100 and for <strong>'amountofproducts'</strong> is 100.</p>";
113
  echo "<h3>Other options</h3>";
114
- echo "<p>You can retrieve all products by using the <strong>'getall'</strong> parameter</p>";
115
- echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>getall=1</strong></p>";
116
  echo "<p>To enable the stripping of invalid XML characters add the <strong>'stripInvalidChars'</strong> parameter</p>";
117
  echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>stripInvalidChars=1</strong></p>";
118
  echo "<p>To enable the converting of the first character in the XML tag from a number to a word, use the <strong>'convertNumberToWord'</strong> parameter.</p>";
119
  echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>convertNumberToWord=1</strong></p>";
120
  echo "<p>To return all the parent product fields, use the <strong>'includeAllParentFields'</strong> parameter.</p>";
121
  echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>includeAllParentFields=1</strong></p>";
122
- echo "</div>";
123
  echo "<div style='float:left; padding-left:50px;'><h5>";
124
  echo $this->_versionDisplay;
125
  echo "</h5></div>";
126
- }
127
 
128
- // Gets all the products in the catalog in the specific store view,
129
- // returns an array of products and their details.
130
- public function getProducts($page)
131
- {
132
  if(isset($_GET["storeid"]))
133
  Mage::app()->setCurrentStore($_GET["storeid"]);
134
-
135
- $products = $this->getProductCollection();
136
-
137
- $products->getSelect()
138
- ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage);
139
-
140
- return $products;
141
- }
142
-
143
- public function getProductCollection()
144
- {
145
- return Mage::getModel('catalog/product')->getCollection()
146
- ->addStoreFilter($_GET["storeid"])
147
- ->addAttributeToSelect('*');
148
- }
149
-
150
- // Run the task
151
- public function runTheTask($startPage, $endPage)
152
- {
153
- while ($startPage <= $endPage)
154
- {
155
- $products = $this->getProducts($startPage);
156
- if ($products->count() == 0)
157
- Mage::log('File: intelligentreach_integration.php, Error: There are no products to export at page '.$startPage.' when the amount of products per page is '. $this->_amountOfProductsPerPage);
158
- else
159
- {
160
- foreach($products as $product){
161
  $this->printProducts($product);
162
- }
163
- }
164
- $startPage = $startPage + 1;
165
- unset($products);
166
- flush();
167
- }
168
- }
169
 
170
- public function printProducts($product)
171
- {
172
  $parentIds = null;
173
- $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
174
-
175
- if ($product->getTypeId() == 'simple')
176
- {
177
- $parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
178
- if (!$parentIds)
179
- $parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
180
- if (isset($parentIds[0]))
181
- $parentProduct = Mage::getModel('catalog/product')->load($parentIds[0]);
182
- }
183
- echo'<product>';
184
- foreach ($product->getData() as $key => $value)
185
- {
186
- if ($key !== 'stock_item')
187
- {
188
- if ($product->getResource()->getAttribute($key) != null)
189
- $value = $product->getResource()->getAttribute($key)->getFrontend()->getValue($product);
190
-
191
- if (($key == 'url_path') || ($key == 'url_key'))
192
- $value = trim(str_replace('/intelligentreach_integration.php', '', $product->getProductUrl()));
193
-
194
- if ($key == 'image')
195
- $value = $baseUrl . "media/catalog/product" . $value;
196
-
197
- if ($key == 'thumbnail')
198
- $value = $baseUrl . "media/catalog/product" . $value;
199
-
200
- if (($value == '') && (isset($parentProduct)))
201
- {
202
- $attr = $parentProduct->getResource()->getAttribute($key);
203
- if (!is_object($attr))
204
- continue;
205
- $value = $attr->getFrontend()->getValue($parentProduct);
206
- }
207
-
208
- // Print out all media gallery images.
209
- if($key == 'media_gallery')
210
- {
211
- for($i = 0; $i < count($value['images']); $i++)
212
- echo " <image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $value['images'][$i]['file']."]]></image_".($i + 1).">";
213
- continue;
214
- }
215
  if($key == 'status')
216
  {
217
  if((isset($parentProduct)) && ($parentProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED))
218
  $value = "Disabled";
219
  }
220
-
221
- if($key == 'special_price')
222
- {
223
- $specialPriceEnabledValue = is_null($value) ? 0 : 1;
224
- $fromDate = $product->getResource()->getAttribute('special_from_date')->getFrontend()->getValue($product);
225
- $toDate = $product->getResource()->getAttribute('special_to_date')->getFrontend()->getValue($product);
226
-
227
- if($fromDate != null)
228
- $specialPriceEnabledValue = (strtotime($fromDate) <= strtotime(date('Y-m-d'))) ? 1 : 0;
229
- if($toDate != null)
230
- $specialPriceEnabledValue = (strtotime(date('Y-m-d')) <= strtotime($toDate)) ? 1 : 0;
231
-
232
- echo "<special_price_enabled><![CDATA[".$specialPriceEnabledValue."]]></special_price_enabled>";
233
- }
234
 
 
 
 
235
  if(is_array($value))
236
  {
237
  foreach($value as $vkey => $vvalue)
238
- {
239
  foreach($vvalue as $pkey => $pvalue)
240
- {
241
  echo "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
242
- }
243
  }
244
  continue;
245
  }
246
-
247
  if(version_compare(PHP_VERSION, '5.4.0', '>='))
248
  $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
249
  else
250
  $value = htmlentities($value, ENT_COMPAT, "UTF-8");
251
  $value = $this->stripInvalidXMLCharacters($value);
252
 
253
- $value = "<![CDATA[$value]]>";
254
 
255
- $key = str_replace('"', '', $key);
256
  if(is_numeric($key[0]))
257
  $key = $this->convertNumberToWord($key[0]).substr($key, 1);
258
  echo '<' . $key . '>' . $value . '</' . $key . '>';
259
- }
260
- }
261
-
262
  if(isset($parentProduct))
263
  {
264
- if(isset($_GET["includeAllParentFields"]))
265
- $this->printAllParentFields($parentProduct);
266
  else
267
  {
268
  echo '<ir_parent_entity_id><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getId()).']]></ir_parent_entity_id>';
@@ -278,34 +275,33 @@ class IntelligentReach
278
  }
279
  }
280
 
281
- $categories = $product->getCategoryIds();
282
  if((count($categories) == 0) && isset($parentProduct))
283
  $categories = $parentProduct->getCategoryIds();
284
  if(count($categories) == 0)
285
  {
286
- echo '</product>';
287
  if (is_object($parentIds))
288
  unset($parentIds);
289
-
290
  unset($product);
291
  return;
292
  }
293
  $category = Mage::getModel('catalog/category')->setStoreId($_GET["storeid"])->load($categories[0]);
294
-
295
  /** Old Category Path code: will be deleted in the future. **/
296
- $cat_parentCategories = array_reverse($category->getParentCategories(), true);
297
- $output = "";
298
-
299
- foreach ($cat_parentCategories as $parent)
300
- {
301
- $output .= $parent->getName();
302
- if ($parent !== end($cat_parentCategories))
303
- $output .= ' > ';
304
- }
305
- if($output != "")
306
- echo '<category_path><![CDATA['.$output.']]></category_path>';
307
  /** End of Old Category path code **/
308
-
309
  /** New Category Path code **/
310
  $pathIds = array_reverse(explode(",", $category->getPathInStore()), true);
311
  $path = "";
@@ -321,7 +317,7 @@ class IntelligentReach
321
 
322
  /** New longest Category Path code **/
323
  $validCategoryPaths = array();
324
- $intelligent_reach_category_exclusions = Mage::getModel('core/variable')->setStoreId($_GET["storeid"])->loadByCode('intelligent_reach_category_exclusions')->getValue();
325
  foreach($categories as $cat)
326
  {
327
  $category = Mage::getModel('catalog/category')->setStoreId($_GET["storeid"])->load($cat);
@@ -334,14 +330,14 @@ class IntelligentReach
334
  $catpath .= ' > ';
335
  }
336
  if($catpath != "")
337
- {
338
- if($intelligent_reach_category_exclusions != "")
339
- {
340
- if(preg_match('/('.$intelligent_reach_category_exclusions.')/i', $catpath) != true)
 
 
 
341
  array_push($validCategoryPaths, $catpath);
342
- }
343
- else
344
- array_push($validCategoryPaths, $catpath);
345
  }
346
  }
347
  if(count($validCategoryPaths) != 0)
@@ -353,39 +349,36 @@ class IntelligentReach
353
  else if($path != "")
354
  echo '<ir_longest_category_path><![CDATA['.$path.']]></ir_longest_category_path>';
355
  /** End of New longest Category Path code **/
356
-
357
- echo '</product>';
358
- if (is_object($parentIds))
359
- unset($parentIds);
360
-
361
- unset($product);
362
- }
363
-
364
  public function printAllParentFields($parentProduct)
365
  {
366
- $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
367
  foreach ($parentProduct->getData() as $key => $value)
368
- {
369
  if ($parentProduct->getResource()->getAttribute($key) != null)
370
  $value = $parentProduct->getResource()->getAttribute($key)->getFrontend()->getValue($parentProduct);
371
 
372
  if (($key == 'url_path') || ($key == 'url_key'))
373
  $value = trim(str_replace('/intelligentreach_integration.php', '', $parentProduct->getProductUrl()));
374
-
375
  if ($key == 'image')
376
  $value = $baseUrl . "media/catalog/product" . $value;
377
 
378
  if ($key == 'thumbnail')
379
  $value = $baseUrl . "media/catalog/product" . $value;
380
-
381
  if(is_array($value))
382
  {
383
  foreach($value as $vkey => $vvalue)
384
- {
385
  foreach($vvalue as $pkey => $pvalue)
386
- {
387
  echo "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
388
- }
389
  }
390
  continue;
391
  }
@@ -405,19 +398,19 @@ class IntelligentReach
405
  }
406
  }
407
 
408
- public function stripInvalidXMLCharacters($value)
409
- {
410
- if(!isset($_GET["stripInvalidChars"]))
411
- return $value;
412
- return preg_replace("/[^A-Za-z0-9\d\!\"\$%^&*:;?'@~#{}|`()\\/.,_+=\-<>\s]/u", '', $value);
413
- }
414
 
415
- public function convertNumberToWord($number)
416
- {
417
- if(!isset($_GET["convertNumberToWord"]))
418
- return $number;
419
- $dictionary = array( 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine');
420
- return $dictionary[$number];
421
- }
422
  }
423
 
1
  <?php
2
 
3
+ /** Version 1.0.37 Last updated by Kire on 18/05/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  include_once 'app/Mage.php';
12
 
13
  class IntelligentReach
14
  {
15
+ private $_splitby = 100;
16
+ private $_amountOfProductsPerPage = 100;
17
+ private $_lastPageNumber = 0;
18
+ private $_versionDisplay = "Version 1.0.37 <br />Last updated on 18/05/2016";
19
+
20
+ public function run()
21
+ {
22
+ // If a store id was provided then print the products to the output.
23
+ if ($this->storeIsSelected())
24
+ {
25
+ if (isset($_GET["splitby"]))
26
+ $this->_splitby = $_GET["splitby"];
27
+ if (isset($_GET["amountofproducts"]))
28
+ $this->_amountOfProductsPerPage = $_GET["amountofproducts"];
29
+ $this->_lastPageNumber = ceil($this->getProductCollection()->getSize() / $this->_amountOfProductsPerPage);
30
+
31
+ if ((isset($_GET["startingpage"]) && isset($_GET["endpage"])) || isset($_GET["getall"]))
32
+ {
33
+ header("Content-Type: text/xml; charset=UTF-8");
34
+ header("Cache-Control: no-cache, must-revalidate");
35
+ echo '<?xml version="1.0" encoding="utf-8"?>
36
+ <products version="1.0.37" type="web">';
37
+ $this->runTheTask(isset($_GET["getall"]) ? 1 : $_GET["startingpage"], isset($_GET["getall"]) ? $this->_lastPageNumber : $_GET["endpage"]);
38
+ echo '</products>';
39
+ }
40
+ else
41
+ $this->printSections();
42
+ }
43
+ else
44
+ $this->printStores();
45
+ }
46
+
47
+ // Check if a storeid parameter has been set, returns a boolean.
48
+ public function storeIsSelected()
49
+ {
50
+ if (isset($_GET["storeid"]))
51
+ return true;
52
+ else
53
+ return false;
54
+ }
55
+
56
+ // Gets all the stores on all websites,
57
+ // returns a table containing Store Ids and Store Names.
58
+ public function getStores()
59
+ {
60
+ $websiteStores = Mage::app()->getStores();
61
+ echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
62
+ echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
63
+ foreach ($websiteStores as $store)
64
+ echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "&splitby=100&amountofproducts=100'>" . $store->getName() . "</a></td></tr>";
65
+ echo "</table>";
66
+ }
67
+
68
+ public function printStores()
69
+ {
70
+ echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
71
+ $this->getStores();
72
+ echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
73
+ echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
74
+ echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
75
+ echo "<h5>".$this->_versionDisplay."</h5></div>";
76
+ }
77
 
78
  public function getSections($sections)
79
  {
83
  $pages = $this->_lastPageNumber;
84
  echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
85
  echo "<tr><th>Section</th><th>Pages</th></tr>";
86
+ for ($i = $sections; $i > 0; $i--)
87
+ {
88
+ $startingPage = $pages - $this->_splitby + 1;
89
+ if ($startingPage < 1)
90
+ $startingPage = 1;
91
+
92
+ echo "<tr><td><a href='?storeid=" . $_GET["storeid"] . "&startingpage=" . $startingPage . "&endpage=" . $pages . "&splitby=".$this->_splitby ."&amountofproducts=".$this->_amountOfProductsPerPage.$convertNumberToWord.$stripInvalidChars.$includeAllParentFields."'>" . $i . "</a></td><td>" . $startingPage . "-" . $pages . "</td></tr>";
93
+ $pages = $startingPage - 1;
94
+ }
95
+ echo "</table>";
96
+ }
97
+
98
+ public function printSections()
99
+ {
100
+ $sections = ceil($this->_lastPageNumber / $this->_splitby);
101
+ echo "<h2>Please select a section to return the products.</h2>";
102
+ echo "<div class='sections' style='float:left; padding-left:50px;'>";
103
+ $this->getSections($sections);
104
+ echo "</div>";
105
+ echo "<div class='instructions' style='float:left; padding-left:50px;'>";
106
+ echo "<h3>Instructions</h3>";
107
+ echo "<p>The parameter <strong>'splitby'</strong> in the URL splits pages into sections, each page contains (unless specified otherwise) the default amount of 100 products.</p>";
108
+ echo "<p>So setting <strong>'splitby'</strong> to equal 100 will bring back 1,000 products per page and 10,000 products per section, if there are 40,000 products in the store then this will return 4 sections. </p>";
109
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>splitby=100</strong></p>";
110
+ echo "<p>You can also set the value of the number of products per page that is returned, by setting the parameter <strong>'amountofproducts'</strong> in the URL</p>";
111
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&splitby=100&<strong>amountofproducts=100</strong></p>";
112
+ echo "<p><strong>NB:</strong> The default value for <strong>'splitby'</strong> is 100 and for <strong>'amountofproducts'</strong> is 100.</p>";
113
  echo "<h3>Other options</h3>";
114
+ echo "<p>You can retrieve all products by using the <strong>'getall'</strong> parameter</p>";
115
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>getall=1</strong></p>";
116
  echo "<p>To enable the stripping of invalid XML characters add the <strong>'stripInvalidChars'</strong> parameter</p>";
117
  echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>stripInvalidChars=1</strong></p>";
118
  echo "<p>To enable the converting of the first character in the XML tag from a number to a word, use the <strong>'convertNumberToWord'</strong> parameter.</p>";
119
  echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>convertNumberToWord=1</strong></p>";
120
  echo "<p>To return all the parent product fields, use the <strong>'includeAllParentFields'</strong> parameter.</p>";
121
  echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>includeAllParentFields=1</strong></p>";
122
+ echo "</div>";
123
  echo "<div style='float:left; padding-left:50px;'><h5>";
124
  echo $this->_versionDisplay;
125
  echo "</h5></div>";
126
+ }
127
 
128
+ // Gets all the products in the catalog in the specific store view,
129
+ // returns an array of products and their details.
130
+ public function getProducts($page)
131
+ {
132
  if(isset($_GET["storeid"]))
133
  Mage::app()->setCurrentStore($_GET["storeid"]);
134
+
135
+ $products = $this->getProductCollection();
136
+
137
+ $products->getSelect()
138
+ ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage);
139
+
140
+ return $products;
141
+ }
142
+
143
+ public function getProductCollection()
144
+ {
145
+ return Mage::getModel('catalog/product')->getCollection()
146
+ ->addStoreFilter($_GET["storeid"])
147
+ ->addAttributeToSelect('*');
148
+ }
149
+
150
+ // Run the task
151
+ public function runTheTask($startPage, $endPage)
152
+ {
153
+ while ($startPage <= $endPage)
154
+ {
155
+ $products = $this->getProducts($startPage);
156
+ if ($products->count() == 0)
157
+ Mage::log('File: intelligentreach_integration.php, Error: There are no products to export at page '.$startPage.' when the amount of products per page is '. $this->_amountOfProductsPerPage);
158
+ else
159
+ {
160
+ foreach($products as $product)
161
  $this->printProducts($product);
162
+ }
163
+ $startPage = $startPage + 1;
164
+ unset($products);
165
+ flush();
166
+ }
167
+ }
 
168
 
169
+ public function printProducts($product)
170
+ {
171
  $parentIds = null;
172
+ $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
173
+
174
+ if($product->getTypeId() == 'simple')
175
+ {
176
+ $parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
177
+ if(!$parentIds)
178
+ $parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
179
+ if(isset($parentIds[0]))
180
+ $parentProduct = Mage::getModel('catalog/product')->load($parentIds[0]);
181
+ }
182
+ echo'<product>';
183
+ foreach ($product->getData() as $key => $value)
184
+ {
185
+ if ($key !== 'stock_item')
186
+ {
187
+ if ($product->getResource()->getAttribute($key) != null)
188
+ $value = $product->getResource()->getAttribute($key)->getFrontend()->getValue($product);
189
+
190
+ if (($key == 'url_path') || ($key == 'url_key'))
191
+ $value = trim(str_replace('/intelligentreach_integration.php', '', $product->getProductUrl()));
192
+
193
+ if ($key == 'image')
194
+ $value = $baseUrl . "media/catalog/product" . $value;
195
+
196
+ if ($key == 'thumbnail')
197
+ $value = $baseUrl . "media/catalog/product" . $value;
198
+
199
+ if (($value == '') && (isset($parentProduct)))
200
+ {
201
+ $attr = $parentProduct->getResource()->getAttribute($key);
202
+ if (!is_object($attr))
203
+ continue;
204
+ $value = $attr->getFrontend()->getValue($parentProduct);
205
+ }
206
+
207
+ // Print out all media gallery images.
208
+ if($key == 'media_gallery')
209
+ {
210
+ for($i = 0; $i < count($value['images']); $i++)
211
+ echo " <image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $value['images'][$i]['file']."]]></image_".($i + 1).">";
212
+ continue;
213
+ }
214
  if($key == 'status')
215
  {
216
  if((isset($parentProduct)) && ($parentProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED))
217
  $value = "Disabled";
218
  }
219
+
220
+ if($key == 'special_price')
221
+ {
222
+ $specialPriceEnabledValue = is_null($value) ? 0 : 1;
223
+ $fromDate = $product->getResource()->getAttribute('special_from_date')->getFrontend()->getValue($product);
224
+ $toDate = $product->getResource()->getAttribute('special_to_date')->getFrontend()->getValue($product);
225
+
226
+ if($fromDate != null)
227
+ $specialPriceEnabledValue = (strtotime($fromDate) <= strtotime(date('Y-m-d'))) ? 1 : 0;
228
+ if($toDate != null)
229
+ $specialPriceEnabledValue = (strtotime(date('Y-m-d')) <= strtotime($toDate)) ? 1 : 0;
 
 
 
230
 
231
+ echo "<special_price_enabled><![CDATA[".$specialPriceEnabledValue."]]></special_price_enabled>";
232
+ }
233
+
234
  if(is_array($value))
235
  {
236
  foreach($value as $vkey => $vvalue)
237
+ {
238
  foreach($vvalue as $pkey => $pvalue)
 
239
  echo "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
 
240
  }
241
  continue;
242
  }
243
+
244
  if(version_compare(PHP_VERSION, '5.4.0', '>='))
245
  $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
246
  else
247
  $value = htmlentities($value, ENT_COMPAT, "UTF-8");
248
  $value = $this->stripInvalidXMLCharacters($value);
249
 
250
+ $value = "<![CDATA[$value]]>";
251
 
252
+ $key = str_replace('"', '', $key);
253
  if(is_numeric($key[0]))
254
  $key = $this->convertNumberToWord($key[0]).substr($key, 1);
255
  echo '<' . $key . '>' . $value . '</' . $key . '>';
256
+ }
257
+ }
258
+
259
  if(isset($parentProduct))
260
  {
261
+ if(isset($_GET["includeAllParentFields"]))
262
+ $this->printAllParentFields($parentProduct);
263
  else
264
  {
265
  echo '<ir_parent_entity_id><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getId()).']]></ir_parent_entity_id>';
275
  }
276
  }
277
 
278
+ $categories = $product->getCategoryIds();
279
  if((count($categories) == 0) && isset($parentProduct))
280
  $categories = $parentProduct->getCategoryIds();
281
  if(count($categories) == 0)
282
  {
283
+ echo '</product>';
284
  if (is_object($parentIds))
285
  unset($parentIds);
 
286
  unset($product);
287
  return;
288
  }
289
  $category = Mage::getModel('catalog/category')->setStoreId($_GET["storeid"])->load($categories[0]);
290
+
291
  /** Old Category Path code: will be deleted in the future. **/
292
+ $cat_parentCategories = array_reverse($category->getParentCategories(), true);
293
+ $output = "";
294
+
295
+ foreach ($cat_parentCategories as $parent)
296
+ {
297
+ $output .= $parent->getName();
298
+ if ($parent !== end($cat_parentCategories))
299
+ $output .= ' > ';
300
+ }
301
+ if($output != "")
302
+ echo '<category_path><![CDATA['.$output.']]></category_path>';
303
  /** End of Old Category path code **/
304
+
305
  /** New Category Path code **/
306
  $pathIds = array_reverse(explode(",", $category->getPathInStore()), true);
307
  $path = "";
317
 
318
  /** New longest Category Path code **/
319
  $validCategoryPaths = array();
320
+ $intelligent_reach_category_exclusions = Mage::getModel('core/variable')->setStoreId($_GET["storeid"])->loadByCode('intelligent_reach_category_exclusions')->getValue();
321
  foreach($categories as $cat)
322
  {
323
  $category = Mage::getModel('catalog/category')->setStoreId($_GET["storeid"])->load($cat);
330
  $catpath .= ' > ';
331
  }
332
  if($catpath != "")
333
+ {
334
+ if($intelligent_reach_category_exclusions != "")
335
+ {
336
+ if(preg_match('/('.$intelligent_reach_category_exclusions.')/i', $catpath) != true)
337
+ array_push($validCategoryPaths, $catpath);
338
+ }
339
+ else
340
  array_push($validCategoryPaths, $catpath);
 
 
 
341
  }
342
  }
343
  if(count($validCategoryPaths) != 0)
349
  else if($path != "")
350
  echo '<ir_longest_category_path><![CDATA['.$path.']]></ir_longest_category_path>';
351
  /** End of New longest Category Path code **/
352
+
353
+ echo '</product>';
354
+ if (is_object($parentIds))
355
+ unset($parentIds);
356
+ unset($product);
357
+ }
358
+
 
359
  public function printAllParentFields($parentProduct)
360
  {
361
+ $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
362
  foreach ($parentProduct->getData() as $key => $value)
363
+ {
364
  if ($parentProduct->getResource()->getAttribute($key) != null)
365
  $value = $parentProduct->getResource()->getAttribute($key)->getFrontend()->getValue($parentProduct);
366
 
367
  if (($key == 'url_path') || ($key == 'url_key'))
368
  $value = trim(str_replace('/intelligentreach_integration.php', '', $parentProduct->getProductUrl()));
369
+
370
  if ($key == 'image')
371
  $value = $baseUrl . "media/catalog/product" . $value;
372
 
373
  if ($key == 'thumbnail')
374
  $value = $baseUrl . "media/catalog/product" . $value;
375
+
376
  if(is_array($value))
377
  {
378
  foreach($value as $vkey => $vvalue)
379
+ {
380
  foreach($vvalue as $pkey => $pvalue)
 
381
  echo "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
 
382
  }
383
  continue;
384
  }
398
  }
399
  }
400
 
401
+ public function stripInvalidXMLCharacters($value)
402
+ {
403
+ if(!isset($_GET["stripInvalidChars"]))
404
+ return $value;
405
+ return preg_replace("/[^A-Za-z0-9\d\!\"\$%^&*:;?'@~#{}|`()\\/.,_+=\-<>\s]/u", '', $value);
406
+ }
407
 
408
+ public function convertNumberToWord($number)
409
+ {
410
+ if(!isset($_GET["convertNumberToWord"]))
411
+ return $number;
412
+ $dictionary = array( 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine');
413
+ return $dictionary[$number];
414
+ }
415
  }
416
 
intelligentreach_integration_pre.php ADDED
@@ -0,0 +1,415 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /** Version 1.0.37 Last updated by Kire on 18/05/2016 **/
4
+ ini_set('display_errors', 1);
5
+ ini_set('max_execution_time', 1800);
6
+ include_once 'app/Mage.php';
7
+ umask(0);
8
+ Mage::app();
9
+
10
+ $ir = new IntelligentReach();
11
+ $ir->run();
12
+
13
+ class IntelligentReach
14
+ {
15
+ private $_splitby = 100;
16
+ private $_amountOfProductsPerPage = 100;
17
+ private $_lastPageNumber = 0;
18
+ private $_versionDisplay = "Version 1.0.37 <br />Last updated on 18/05/2016";
19
+
20
+ public function run()
21
+ {
22
+ // If a store id was provided then print the products to the output.
23
+ if ($this->storeIsSelected())
24
+ {
25
+ if (isset($_GET["splitby"]))
26
+ $this->_splitby = $_GET["splitby"];
27
+ if (isset($_GET["amountofproducts"]))
28
+ $this->_amountOfProductsPerPage = $_GET["amountofproducts"];
29
+ $this->_lastPageNumber = ceil($this->getProductCollection()->getSize() / $this->_amountOfProductsPerPage);
30
+
31
+ if ((isset($_GET["startingpage"]) && isset($_GET["endpage"])) || isset($_GET["getall"]))
32
+ {
33
+ header("Content-Type: text/xml; charset=UTF-8");
34
+ header("Cache-Control: no-cache, must-revalidate");
35
+ echo '<?xml version="1.0" encoding="utf-8"?>
36
+ <products version="1.0.37" type="web_pre">';
37
+ $this->runTheTask(isset($_GET["getall"]) ? 1 : $_GET["startingpage"], isset($_GET["getall"]) ? $this->_lastPageNumber : $_GET["endpage"]);
38
+ echo '</products>';
39
+ }
40
+ else
41
+ $this->printSections();
42
+ }
43
+ else
44
+ $this->printStores();
45
+ }
46
+
47
+ // Check if a storeid parameter has been set, returns a boolean.
48
+ public function storeIsSelected()
49
+ {
50
+ if (isset($_GET["storeid"]))
51
+ return true;
52
+ else
53
+ return false;
54
+ }
55
+
56
+ // Gets all the stores on all websites,
57
+ // returns a table containing Store Ids and Store Names.
58
+ public function getStores()
59
+ {
60
+ $websiteStores = Mage::app()->getStores();
61
+ echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
62
+ echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
63
+ foreach ($websiteStores as $store)
64
+ echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "&splitby=100&amountofproducts=100'>" . $store->getName() . "</a></td></tr>";
65
+ echo "</table>";
66
+ }
67
+
68
+ public function printStores()
69
+ {
70
+ echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
71
+ $this->getStores();
72
+ echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
73
+ echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
74
+ echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
75
+ echo "<h5>".$this->_versionDisplay."</h5></div>";
76
+ }
77
+
78
+ public function getSections($sections)
79
+ {
80
+ $convertNumberToWord = (isset($_GET["convertNumberToWord"])) ? "&convertNumberToWord=1" : "";
81
+ $stripInvalidChars = (isset($_GET["stripInvalidChars"])) ? "&stripInvalidChars=1" : "";
82
+ $includeAllParentFields = (isset($_GET["includeAllParentFields"])) ? "&includeAllParentFields=1" : "";
83
+ $pages = $this->_lastPageNumber;
84
+ echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
85
+ echo "<tr><th>Section</th><th>Pages</th></tr>";
86
+ for ($i = $sections; $i > 0; $i--)
87
+ {
88
+ $startingPage = $pages - $this->_splitby + 1;
89
+ if ($startingPage < 1)
90
+ $startingPage = 1;
91
+
92
+ echo "<tr><td><a href='?storeid=" . $_GET["storeid"] . "&startingpage=" . $startingPage . "&endpage=" . $pages . "&splitby=".$this->_splitby ."&amountofproducts=".$this->_amountOfProductsPerPage.$convertNumberToWord.$stripInvalidChars.$includeAllParentFields."'>" . $i . "</a></td><td>" . $startingPage . "-" . $pages . "</td></tr>";
93
+ $pages = $startingPage - 1;
94
+ }
95
+ echo "</table>";
96
+ }
97
+
98
+ public function printSections()
99
+ {
100
+ $sections = ceil($this->_lastPageNumber / $this->_splitby);
101
+ echo "<h2>Please select a section to return the products.</h2>";
102
+ echo "<div class='sections' style='float:left; padding-left:50px;'>";
103
+ $this->getSections($sections);
104
+ echo "</div>";
105
+ echo "<div class='instructions' style='float:left; padding-left:50px;'>";
106
+ echo "<h3>Instructions</h3>";
107
+ echo "<p>The parameter <strong>'splitby'</strong> in the URL splits pages into sections, each page contains (unless specified otherwise) the default amount of 100 products.</p>";
108
+ echo "<p>So setting <strong>'splitby'</strong> to equal 100 will bring back 1,000 products per page and 10,000 products per section, if there are 40,000 products in the store then this will return 4 sections. </p>";
109
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>splitby=100</strong></p>";
110
+ echo "<p>You can also set the value of the number of products per page that is returned, by setting the parameter <strong>'amountofproducts'</strong> in the URL</p>";
111
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&splitby=100&<strong>amountofproducts=100</strong></p>";
112
+ echo "<p><strong>NB:</strong> The default value for <strong>'splitby'</strong> is 100 and for <strong>'amountofproducts'</strong> is 100.</p>";
113
+ echo "<h3>Other options</h3>";
114
+ echo "<p>You can retrieve all products by using the <strong>'getall'</strong> parameter</p>";
115
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>getall=1</strong></p>";
116
+ echo "<p>To enable the stripping of invalid XML characters add the <strong>'stripInvalidChars'</strong> parameter</p>";
117
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>stripInvalidChars=1</strong></p>";
118
+ echo "<p>To enable the converting of the first character in the XML tag from a number to a word, use the <strong>'convertNumberToWord'</strong> parameter.</p>";
119
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>convertNumberToWord=1</strong></p>";
120
+ echo "<p>To return all the parent product fields, use the <strong>'includeAllParentFields'</strong> parameter.</p>";
121
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>includeAllParentFields=1</strong></p>";
122
+ echo "</div>";
123
+ echo "<div style='float:left; padding-left:50px;'><h5>";
124
+ echo $this->_versionDisplay;
125
+ echo "</h5></div>";
126
+ }
127
+
128
+ // Gets all the products in the catalog in the specific store view,
129
+ // returns an array of products and their details.
130
+ public function getProducts($page)
131
+ {
132
+ if(isset($_GET["storeid"]))
133
+ Mage::app()->setCurrentStore($_GET["storeid"]);
134
+
135
+ $products = $this->getProductCollection();
136
+
137
+ $products->getSelect()
138
+ ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage);
139
+
140
+ return $products;
141
+ }
142
+
143
+ public function getProductCollection()
144
+ {
145
+ return Mage::getModel('catalog/product')->getCollection()
146
+ ->addStoreFilter($_GET["storeid"]);
147
+ }
148
+
149
+ // Run the task
150
+ public function runTheTask($startPage, $endPage)
151
+ {
152
+ while ($startPage <= $endPage)
153
+ {
154
+ $products = $this->getProducts($startPage);
155
+ if ($products->count() == 0)
156
+ Mage::log('File: intelligentreach_integration.php, Error: There are no products to export at page '.$startPage.' when the amount of products per page is '. $this->_amountOfProductsPerPage);
157
+ else
158
+ {
159
+ Mage::getSingleton('core/resource_iterator')
160
+ ->walk($products->getSelect(), array(array($this, 'printProducts')),array('store_id' => $_GET["storeid"]));
161
+ }
162
+ $startPage = $startPage + 1;
163
+ unset($products);
164
+ flush();
165
+ }
166
+ }
167
+
168
+ public function printProducts($args)
169
+ {
170
+ $parentIds = null;
171
+ $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
172
+ $product = Mage::getModel('catalog/product')->load($args['row']['entity_id']);
173
+ if($product->getTypeId() == 'simple')
174
+ {
175
+ $parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
176
+ if(!$parentIds)
177
+ $parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
178
+ if(isset($parentIds[0]))
179
+ $parentProduct = Mage::getModel('catalog/product')->load($parentIds[0]);
180
+ }
181
+ echo'<product>';
182
+ foreach ($product->getData() as $key => $value)
183
+ {
184
+ if ($key !== 'stock_item')
185
+ {
186
+ if ($product->getResource()->getAttribute($key) != null)
187
+ $value = $product->getResource()->getAttribute($key)->getFrontend()->getValue($product);
188
+
189
+ if (($key == 'url_path') || ($key == 'url_key'))
190
+ $value = trim(str_replace('/intelligentreach_integration.php', '', $product->getProductUrl()));
191
+
192
+ if ($key == 'image')
193
+ $value = $baseUrl . "media/catalog/product" . $value;
194
+
195
+ if ($key == 'thumbnail')
196
+ $value = $baseUrl . "media/catalog/product" . $value;
197
+
198
+ if (($value == '') && (isset($parentProduct)))
199
+ {
200
+ $attr = $parentProduct->getResource()->getAttribute($key);
201
+ if (!is_object($attr))
202
+ continue;
203
+ $value = $attr->getFrontend()->getValue($parentProduct);
204
+ }
205
+
206
+ // Print out all media gallery images.
207
+ if($key == 'media_gallery')
208
+ {
209
+ for($i = 0; $i < count($value['images']); $i++)
210
+ echo " <image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $value['images'][$i]['file']."]]></image_".($i + 1).">";
211
+ continue;
212
+ }
213
+ if($key == 'status')
214
+ {
215
+ if((isset($parentProduct)) && ($parentProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED))
216
+ $value = "Disabled";
217
+ }
218
+
219
+ if($key == 'special_price')
220
+ {
221
+ $specialPriceEnabledValue = is_null($value) ? 0 : 1;
222
+ $fromDate = $product->getResource()->getAttribute('special_from_date')->getFrontend()->getValue($product);
223
+ $toDate = $product->getResource()->getAttribute('special_to_date')->getFrontend()->getValue($product);
224
+
225
+ if($fromDate != null)
226
+ $specialPriceEnabledValue = (strtotime($fromDate) <= strtotime(date('Y-m-d'))) ? 1 : 0;
227
+ if($toDate != null)
228
+ $specialPriceEnabledValue = (strtotime(date('Y-m-d')) <= strtotime($toDate)) ? 1 : 0;
229
+
230
+ echo "<special_price_enabled><![CDATA[".$specialPriceEnabledValue."]]></special_price_enabled>";
231
+ }
232
+
233
+ if(is_array($value))
234
+ {
235
+ foreach($value as $vkey => $vvalue)
236
+ {
237
+ foreach($vvalue as $pkey => $pvalue)
238
+ echo "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
239
+ }
240
+ continue;
241
+ }
242
+
243
+ if(version_compare(PHP_VERSION, '5.4.0', '>='))
244
+ $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
245
+ else
246
+ $value = htmlentities($value, ENT_COMPAT, "UTF-8");
247
+ $value = $this->stripInvalidXMLCharacters($value);
248
+
249
+ $value = "<![CDATA[$value]]>";
250
+
251
+ $key = str_replace('"', '', $key);
252
+ if(is_numeric($key[0]))
253
+ $key = $this->convertNumberToWord($key[0]).substr($key, 1);
254
+ echo '<' . $key . '>' . $value . '</' . $key . '>';
255
+ }
256
+ }
257
+
258
+ if(isset($parentProduct))
259
+ {
260
+ if(isset($_GET["includeAllParentFields"]))
261
+ $this->printAllParentFields($parentProduct);
262
+ else
263
+ {
264
+ echo '<ir_parent_entity_id><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getId()).']]></ir_parent_entity_id>';
265
+ echo '<ir_parent_sku><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getSku()).']]></ir_parent_sku>';
266
+ echo '<ir_parent_url><![CDATA[' . $this->stripInvalidXMLCharacters(trim(str_replace('/intelligentreach_integration.php', '', $parentProduct->getProductUrl()))) . ']]></ir_parent_url>';
267
+ echo '<ir_parent_image><![CDATA['.$this->stripInvalidXMLCharacters($baseUrl . 'media/catalog/product' . $parentProduct->getImage()).']]></ir_parent_image>';
268
+ }
269
+ $gallery = $parentProduct->getMediaGallery();
270
+ if(count($gallery['images']) != 0)
271
+ {
272
+ for($i = 0; $i < count($gallery['images']); $i++)
273
+ echo " <ir_parent_image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $gallery['images'][$i]['file']."]]></ir_parent_image_".($i + 1).">";
274
+ }
275
+ }
276
+
277
+ $categories = $product->getCategoryIds();
278
+ if((count($categories) == 0) && isset($parentProduct))
279
+ $categories = $parentProduct->getCategoryIds();
280
+ if(count($categories) == 0)
281
+ {
282
+ echo '</product>';
283
+ if (is_object($parentIds))
284
+ unset($parentIds);
285
+ unset($product);
286
+ return;
287
+ }
288
+ $category = Mage::getModel('catalog/category')->setStoreId($_GET["storeid"])->load($categories[0]);
289
+
290
+ /** Old Category Path code: will be deleted in the future. **/
291
+ $cat_parentCategories = array_reverse($category->getParentCategories(), true);
292
+ $output = "";
293
+
294
+ foreach ($cat_parentCategories as $parent)
295
+ {
296
+ $output .= $parent->getName();
297
+ if ($parent !== end($cat_parentCategories))
298
+ $output .= ' > ';
299
+ }
300
+ if($output != "")
301
+ echo '<category_path><![CDATA['.$output.']]></category_path>';
302
+ /** End of Old Category path code **/
303
+
304
+ /** New Category Path code **/
305
+ $pathIds = array_reverse(explode(",", $category->getPathInStore()), true);
306
+ $path = "";
307
+ foreach($pathIds as $pathId)
308
+ {
309
+ $path .= Mage::getModel('catalog/category')->setStoreId($_GET["storeid"])->load($pathId)->getName();
310
+ if($pathId != end($pathIds))
311
+ $path .= ' > ';
312
+ }
313
+ if($path != "")
314
+ echo '<ir_category_path><![CDATA['.$path.']]></ir_category_path>';
315
+ /** End of New Category Path code **/
316
+
317
+ /** New longest Category Path code **/
318
+ $validCategoryPaths = array();
319
+ $intelligent_reach_category_exclusions = Mage::getModel('core/variable')->setStoreId($_GET["storeid"])->loadByCode('intelligent_reach_category_exclusions')->getValue();
320
+ foreach($categories as $cat)
321
+ {
322
+ $category = Mage::getModel('catalog/category')->setStoreId($_GET["storeid"])->load($cat);
323
+ $pathIds = array_reverse(explode(",", $category->getPathInStore()), true);
324
+ $catpath = "";
325
+ foreach($pathIds as $pathId)
326
+ {
327
+ $catpath .= Mage::getModel('catalog/category')->setStoreId($_GET["storeid"])->load($pathId)->getName();
328
+ if($pathId != end($pathIds))
329
+ $catpath .= ' > ';
330
+ }
331
+ if($catpath != "")
332
+ {
333
+ if($intelligent_reach_category_exclusions != "")
334
+ {
335
+ if(preg_match('/('.$intelligent_reach_category_exclusions.')/i', $catpath) != true)
336
+ array_push($validCategoryPaths, $catpath);
337
+ }
338
+ else
339
+ array_push($validCategoryPaths, $catpath);
340
+ }
341
+ }
342
+ if(count($validCategoryPaths) != 0)
343
+ {
344
+ if(count($validCategoryPaths) > 1)
345
+ usort($validCategoryPaths, function ($a, $b) { return (strlen($a) < strlen($b)); });
346
+ echo "<ir_longest_category_path><![CDATA[".$validCategoryPaths[0]."]]></ir_longest_category_path>";
347
+ }
348
+ else if($path != "")
349
+ echo '<ir_longest_category_path><![CDATA['.$path.']]></ir_longest_category_path>';
350
+ /** End of New longest Category Path code **/
351
+
352
+ echo '</product>';
353
+ if (is_object($parentIds))
354
+ unset($parentIds);
355
+ unset($product);
356
+ }
357
+
358
+ public function printAllParentFields($parentProduct)
359
+ {
360
+ $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
361
+ foreach ($parentProduct->getData() as $key => $value)
362
+ {
363
+ if ($parentProduct->getResource()->getAttribute($key) != null)
364
+ $value = $parentProduct->getResource()->getAttribute($key)->getFrontend()->getValue($parentProduct);
365
+
366
+ if (($key == 'url_path') || ($key == 'url_key'))
367
+ $value = trim(str_replace('/intelligentreach_integration.php', '', $parentProduct->getProductUrl()));
368
+
369
+ if ($key == 'image')
370
+ $value = $baseUrl . "media/catalog/product" . $value;
371
+
372
+ if ($key == 'thumbnail')
373
+ $value = $baseUrl . "media/catalog/product" . $value;
374
+
375
+ if(is_array($value))
376
+ {
377
+ foreach($value as $vkey => $vvalue)
378
+ {
379
+ foreach($vvalue as $pkey => $pvalue)
380
+ echo "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
381
+ }
382
+ continue;
383
+ }
384
+ if(version_compare(PHP_VERSION, '5.4.0', '>='))
385
+ $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
386
+ else
387
+ $value = htmlentities($value, ENT_COMPAT, "UTF-8");
388
+ $value = $this->stripInvalidXMLCharacters($value);
389
+
390
+ $value = "<![CDATA[$value]]>";
391
+
392
+ $key = str_replace('"', '', $key);
393
+ if(is_numeric($key[0]))
394
+ $key = $this->convertNumberToWord($key[0]).substr($key, 1);
395
+ echo '<ir_parent_' . $key . '>' . $value . '</ir_parent_' . $key . '>';
396
+
397
+ }
398
+ }
399
+
400
+ public function stripInvalidXMLCharacters($value)
401
+ {
402
+ if(!isset($_GET["stripInvalidChars"]))
403
+ return $value;
404
+ return preg_replace("/[^A-Za-z0-9\d\!\"\$%^&*:;?'@~#{}|`()\\/.,_+=\-<>\s]/u", '', $value);
405
+ }
406
+
407
+ public function convertNumberToWord($number)
408
+ {
409
+ if(!isset($_GET["convertNumberToWord"]))
410
+ return $number;
411
+ $dictionary = array( 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine');
412
+ return $dictionary[$number];
413
+ }
414
+ }
415
+
intelligentreach_integration_qty.php CHANGED
@@ -1,190 +1,186 @@
1
  <?php
2
 
3
- /** Version 1.0.36 Last updated by Kire on 27/04/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  include_once 'app/Mage.php';
7
  umask(0);
8
  Mage::app();
9
 
10
-
11
  $ir = new IntelligentReach();
12
  $ir->run();
13
 
14
  class IntelligentReach
15
  {
16
- private $_splitby = 100;
17
  private $_amountOfProductsPerPage = 100;
18
- private $_lastPageNumber = 0;
19
- private $_versionDisplay = "Version 1.0.36 <br />Last updated on 27/04/2016";
20
-
21
- public function run()
22
- {
23
- // If a store id was provided then print the products to the output.
24
- if ($this->storeIsSelected())
25
- {
26
- if (isset($_GET["splitby"]))
27
- $this->_splitby = $_GET["splitby"];
28
- if (isset($_GET["amountofproducts"]))
29
- $this->_amountOfProductsPerPage = $_GET["amountofproducts"];
30
- $this->_lastPageNumber = ceil($this->getProductCollection()->getSize() / $this->_amountOfProductsPerPage);
31
-
32
- if ((isset($_GET["startingpage"]) && isset($_GET["endpage"])) || isset($_GET["getall"]))
33
- {
34
- header("Content-Type: text/xml; charset=UTF-8");
35
  header("Cache-Control: no-cache, must-revalidate");
36
- echo '<?xml version="1.0" encoding="utf-8"?>
37
- <products>';
38
- $this->runTheTask(isset($_GET["getall"]) ? 1 : $_GET["startingpage"], isset($_GET["getall"]) ? $this->_lastPageNumber : $_GET["endpage"]);
39
- echo '</products>';
40
- }
41
- else
42
- $this->printSections();
43
- }
44
- else
45
- $this->printStores();
46
- }
47
-
48
- // Check if a storeid parameter has been set, returns a boolean.
49
- public function storeIsSelected()
50
- {
51
- if (isset($_GET["storeid"]))
52
- return true;
53
- else
54
- return false;
55
- }
56
-
57
- // Gets all the stores on the current website,
58
- // returns a table containing Store Ids and Store Names.
59
- public function getStores()
60
- {
61
- $websiteStores = Mage::app()->getStores();
62
- echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
63
- echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
64
- foreach ($websiteStores as $store)
65
- echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "&splitby=100&amountofproducts=100'>" . $store->getName() . "</a></td></tr>";
66
- echo "</table>";
67
- }
68
-
69
- public function printStores()
70
- {
71
- echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
72
- $this->getStores();
73
- echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
74
- echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
75
- echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
76
  echo "<h5>".$this->_versionDisplay."</h5></div>";
77
- }
78
-
79
- public function getSections($sections)
80
- {
81
- $pages = $this->_lastPageNumber;
82
- echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
83
- echo "<tr><th>Section</th><th>Pages</th></tr>";
84
- for ($i = $sections; $i > 0; $i--)
85
- {
86
- $startingPage = $pages - $this->_splitby + 1;
87
- if ($startingPage < 1)
88
- $startingPage = 1;
89
-
90
- echo "<tr><td><a href='?storeid=" . $_GET["storeid"] . "&startingpage=" . $startingPage . "&endpage=" . $pages . "&splitby=".$this->_splitby ."&amountofproducts=".$this->_amountOfProductsPerPage."'>" . $i . "</a></td><td>" . $startingPage . "-" . $pages . "</td></tr>";
91
- $pages = $startingPage - 1;
92
- }
93
- echo "</table>";
94
- }
95
-
96
- public function printSections()
97
- {
98
- $sections = ceil($this->_lastPageNumber / $this->_splitby);
99
- echo "<h2>Please select a section to return the product quantities.</h2>";
100
- echo "<div class='sections' style='float:left;'>";
101
- $this->getSections($sections);
102
- echo "</div>";
103
- echo "<div class='instructions' style='float:left; padding-left:100px;'>";
104
- echo "<h3>Instructions</h3>";
105
- echo "<p>The parameter <strong>'splitby'</strong> in the URL splits pages into sections, each page contains (unless specified otherwise) the default amount of 100 products.</p>";
106
- echo "<p>So setting <strong>'splitby'</strong> to equal 100 will bring back 1,000 products per page and 10,000 products per section, if there are 40,000 products in the store then this will return 4 sections. </p>";
107
- echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>splitby=100</strong></p>";
108
- echo "<p>You can also set the value of the number of products per page that is returned, by setting the parameter <strong>'amountofproducts'</strong> in the URL</p>";
109
- echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&splitby=100&<strong>amountofproducts=100</strong></p>";
110
- echo "<p><strong>NB:</strong> The default value for <strong>'splitby'</strong> is 100 and for <strong>'amountofproducts'</strong> is 100.</p>";
111
- echo "<p>You can also retrieve all product quantities but using the 'getall' parameter</p>";
112
- echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>getall=1</strong></p>";
113
- echo "</div>";
114
  echo "<div style='float:left; padding-left:50px;'><h5>";
115
  echo $this->_versionDisplay;
116
  echo "</h5></div>";
117
- }
118
 
119
- // Gets all the products in the catalog in the specific store view,
120
- // returns an array of products and their details.
121
- public function getProducts($page)
122
- {
123
  if(isset($_GET["storeid"]))
124
  Mage::app()->setCurrentStore($_GET["storeid"]);
125
-
126
- $products = $this->getProductCollection();
127
-
128
- // join stock item, saves having to load the stock item model.
129
- $products
130
- ->getSelect()
131
- ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage)
132
- ->joinLeft(array('si'=>'cataloginventory_stock_item'),'e.entity_id = si.product_id',
133
- array('use_config_manage_stock','manage_stock','qty','is_in_stock'))
134
- ->group('e.entity_id') // sometimes there can be duplicate stock items.
135
- ->order('e.entity_id');
136
-
137
- return $products;
138
- }
139
-
140
- public function getProductCollection()
141
- {
142
- return Mage::getModel('catalog/product')
143
- ->getCollection()
144
- ->addStoreFilter($_GET["storeid"])
145
- ->addAttributeToSelect('price', 'left')
146
- ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED));
147
- }
148
-
149
- // Run the task
150
- public function runTheTask($startPage, $endPage)
151
- {
152
- while ($startPage <= $endPage)
153
- {
154
- $products = $this->getProducts($startPage);
155
- if ($products->count() == 0)
156
- Mage::log('File: intelligentreach_integration_qty.php, Error: There are no products to export at page '.$startPage.' when the amount of products per page is '. $this->_amountOfProductsPerPage);
157
- else
158
- {
159
- Mage::getSingleton('core/resource_iterator')
160
- ->walk($products->getSelect(), array(array($this, 'printProducts')));
161
- }
162
- $startPage++;
163
- unset($products);
164
- flush();
165
- }
166
- }
167
-
168
- public function printProducts($args)
169
- {
170
- // We check for manage stock. This is implemented in the catalog inventory stock item model however we don't want to load the model.
171
- $manageStock = $args['row']['manage_stock'];
172
- $configManageStock = $args['row']['use_config_manage_stock'];
173
- $isInStock = $args['row']['is_in_stock'];
174
-
175
- if($configManageStock){
176
- $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
177
- }
178
-
179
- if(!$manageStock){
180
- $isInStock = true; // if we don't manage, "is in stock" is always true.
181
- }
182
-
183
- echo '<product>';
184
- echo '<entity_id><![CDATA['. $args['row']['entity_id'].']]></entity_id>';
185
- echo '<qty><![CDATA['.(int)$args['row']['qty'].']]></qty>';
186
- echo '<is_in_stock><![CDATA['.(int)$isInStock.']]></is_in_stock>';
187
- echo '<price><![CDATA['.$args['row']['price'].']]></price>';
188
- echo '</product>';
189
- }
190
  }
1
  <?php
2
 
3
+ /** Version 1.0.37 Last updated by Kire on 18/05/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  include_once 'app/Mage.php';
7
  umask(0);
8
  Mage::app();
9
 
 
10
  $ir = new IntelligentReach();
11
  $ir->run();
12
 
13
  class IntelligentReach
14
  {
15
+ private $_splitby = 100;
16
  private $_amountOfProductsPerPage = 100;
17
+ private $_lastPageNumber = 0;
18
+ private $_versionDisplay = "Version 1.0.37 <br />Last updated on 18/05/2016";
19
+
20
+ public function run()
21
+ {
22
+ // If a store id was provided then print the products to the output.
23
+ if ($this->storeIsSelected())
24
+ {
25
+ if (isset($_GET["splitby"]))
26
+ $this->_splitby = $_GET["splitby"];
27
+ if (isset($_GET["amountofproducts"]))
28
+ $this->_amountOfProductsPerPage = $_GET["amountofproducts"];
29
+ $this->_lastPageNumber = ceil($this->getProductCollection()->getSize() / $this->_amountOfProductsPerPage);
30
+
31
+ if ((isset($_GET["startingpage"]) && isset($_GET["endpage"])) || isset($_GET["getall"]))
32
+ {
33
+ header("Content-Type: text/xml; charset=UTF-8");
34
  header("Cache-Control: no-cache, must-revalidate");
35
+ echo '<?xml version="1.0" encoding="utf-8"?>
36
+ <products version="1.0.37" type="web">';
37
+ $this->runTheTask(isset($_GET["getall"]) ? 1 : $_GET["startingpage"], isset($_GET["getall"]) ? $this->_lastPageNumber : $_GET["endpage"]);
38
+ echo '</products>';
39
+ }
40
+ else
41
+ $this->printSections();
42
+ }
43
+ else
44
+ $this->printStores();
45
+ }
46
+
47
+ // Check if a storeid parameter has been set, returns a boolean.
48
+ public function storeIsSelected()
49
+ {
50
+ if (isset($_GET["storeid"]))
51
+ return true;
52
+ else
53
+ return false;
54
+ }
55
+
56
+ // Gets all the stores on the current website,
57
+ // returns a table containing Store Ids and Store Names.
58
+ public function getStores()
59
+ {
60
+ $websiteStores = Mage::app()->getStores();
61
+ echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
62
+ echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
63
+ foreach ($websiteStores as $store)
64
+ echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "&splitby=100&amountofproducts=100'>" . $store->getName() . "</a></td></tr>";
65
+ echo "</table>";
66
+ }
67
+
68
+ public function printStores()
69
+ {
70
+ echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
71
+ $this->getStores();
72
+ echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
73
+ echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
74
+ echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
75
  echo "<h5>".$this->_versionDisplay."</h5></div>";
76
+ }
77
+
78
+ public function getSections($sections)
79
+ {
80
+ $pages = $this->_lastPageNumber;
81
+ echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
82
+ echo "<tr><th>Section</th><th>Pages</th></tr>";
83
+ for ($i = $sections; $i > 0; $i--)
84
+ {
85
+ $startingPage = $pages - $this->_splitby + 1;
86
+ if ($startingPage < 1)
87
+ $startingPage = 1;
88
+ echo "<tr><td><a href='?storeid=" . $_GET["storeid"] . "&startingpage=" . $startingPage . "&endpage=" . $pages . "&splitby=".$this->_splitby ."&amountofproducts=".$this->_amountOfProductsPerPage."'>" . $i . "</a></td><td>" . $startingPage . "-" . $pages . "</td></tr>";
89
+ $pages = $startingPage - 1;
90
+ }
91
+ echo "</table>";
92
+ }
93
+
94
+ public function printSections()
95
+ {
96
+ $sections = ceil($this->_lastPageNumber / $this->_splitby);
97
+ echo "<h2>Please select a section to return the product quantities.</h2>";
98
+ echo "<div class='sections' style='float:left;'>";
99
+ $this->getSections($sections);
100
+ echo "</div>";
101
+ echo "<div class='instructions' style='float:left; padding-left:100px;'>";
102
+ echo "<h3>Instructions</h3>";
103
+ echo "<p>The parameter <strong>'splitby'</strong> in the URL splits pages into sections, each page contains (unless specified otherwise) the default amount of 100 products.</p>";
104
+ echo "<p>So setting <strong>'splitby'</strong> to equal 100 will bring back 1,000 products per page and 10,000 products per section, if there are 40,000 products in the store then this will return 4 sections. </p>";
105
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>splitby=100</strong></p>";
106
+ echo "<p>You can also set the value of the number of products per page that is returned, by setting the parameter <strong>'amountofproducts'</strong> in the URL</p>";
107
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&splitby=100&<strong>amountofproducts=100</strong></p>";
108
+ echo "<p><strong>NB:</strong> The default value for <strong>'splitby'</strong> is 100 and for <strong>'amountofproducts'</strong> is 100.</p>";
109
+ echo "<p>You can also retrieve all product quantities but using the 'getall' parameter</p>";
110
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>getall=1</strong></p>";
111
+ echo "</div>";
 
112
  echo "<div style='float:left; padding-left:50px;'><h5>";
113
  echo $this->_versionDisplay;
114
  echo "</h5></div>";
115
+ }
116
 
117
+ // Gets all the products in the catalog in the specific store view,
118
+ // returns an array of products and their details.
119
+ public function getProducts($page)
120
+ {
121
  if(isset($_GET["storeid"]))
122
  Mage::app()->setCurrentStore($_GET["storeid"]);
123
+
124
+ $products = $this->getProductCollection();
125
+
126
+ // join stock item, saves having to load the stock item model.
127
+ $products
128
+ ->getSelect()
129
+ ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage)
130
+ ->joinLeft(array('si'=>'cataloginventory_stock_item'),'e.entity_id = si.product_id',
131
+ array('use_config_manage_stock','manage_stock','qty','is_in_stock'))
132
+ ->group('e.entity_id') // sometimes there can be duplicate stock items.
133
+ ->order('e.entity_id');
134
+
135
+ return $products;
136
+ }
137
+
138
+ public function getProductCollection()
139
+ {
140
+ return Mage::getModel('catalog/product')
141
+ ->getCollection()
142
+ ->addStoreFilter($_GET["storeid"])
143
+ ->addAttributeToSelect('price', 'left')
144
+ ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED));
145
+ }
146
+
147
+ // Run the task
148
+ public function runTheTask($startPage, $endPage)
149
+ {
150
+ while ($startPage <= $endPage)
151
+ {
152
+ $products = $this->getProducts($startPage);
153
+ if ($products->count() == 0)
154
+ Mage::log('File: intelligentreach_integration_qty.php, Error: There are no products to export at page '.$startPage.' when the amount of products per page is '. $this->_amountOfProductsPerPage);
155
+ else
156
+ {
157
+ Mage::getSingleton('core/resource_iterator')
158
+ ->walk($products->getSelect(), array(array($this, 'printProducts')));
159
+ }
160
+ $startPage++;
161
+ unset($products);
162
+ flush();
163
+ }
164
+ }
165
+
166
+ public function printProducts($args)
167
+ {
168
+ // We check for manage stock. This is implemented in the catalog inventory stock item model however we don't want to load the model.
169
+ $manageStock = $args['row']['manage_stock'];
170
+ $configManageStock = $args['row']['use_config_manage_stock'];
171
+ $isInStock = $args['row']['is_in_stock'];
172
+
173
+ if($configManageStock)
174
+ $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
175
+
176
+ if(!$manageStock)
177
+ $isInStock = true; // if we don't manage, "is in stock" is always true.
178
+
179
+ echo '<product>';
180
+ echo '<entity_id><![CDATA['. $args['row']['entity_id'].']]></entity_id>';
181
+ echo '<qty><![CDATA['.(int)$args['row']['qty'].']]></qty>';
182
+ echo '<is_in_stock><![CDATA['.(int)$isInStock.']]></is_in_stock>';
183
+ echo '<price><![CDATA['.$args['row']['price'].']]></price>';
184
+ echo '</product>';
185
+ }
 
 
186
  }
ircronscripts/intelligentreach_integration_cron.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- /** Version 1.0.36 Last updated by Kire on 27/04/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  ini_set('memory_limit', '2G');
@@ -13,46 +13,45 @@ $ir->run();
13
 
14
  class IntelligentReach
15
  {
16
- private $_versionDisplay = "Version 1.0.36 <br />Last updated on 27/04/2016";
17
- private $_outputDirectory = "output";
18
  private $_fileName = "Feed";
19
  private $_fileNameTemp = "";
20
  private $_amountOfProductsPerPage = 1000;
21
  private $_categories = null;
22
  private $_intelligentReachCategoryExclusions = null;
23
- private $_gzipFile = true;
24
- private $_parentProducts = array();
25
-
26
- private $_includeAllParentFields = false;
27
  private $_stripInvalidChars = false;
28
  private $_convertNumberToWord = false;
29
 
30
- public function run()
31
  {
32
  $storeId = (isset($_GET["storeid"]))? $_GET["storeid"] : false;
33
 
34
  // If a store id was provided then print the products to the output.
35
  if ($this->storeIsSelected())
36
  {
37
- $this->_fileName = $this->_outputDirectory."/".$this->_fileName."_".$storeId.".xml"; // added store id to feed file name for multi store support.
38
  $this->_fileNameTemp = tempnam("", $this->_fileName);
39
  echo "Temp File created: ". $this->_fileNameTemp."<br />";
40
  $time = microtime(true);
41
  file_put_contents($this->_fileNameTemp, '<?xml version="1.0" encoding="utf-8"?>
42
- <products>', LOCK_EX);
43
  $this->runTheTask($storeId);
44
  file_put_contents($this->_fileNameTemp, '</products>', FILE_APPEND | LOCK_EX);
45
-
46
- if (!file_exists($this->_outputDirectory))
47
- mkdir($this->_outputDirectory);
48
-
49
  file_put_contents($this->_fileName, file_get_contents($this->_fileNameTemp), LOCK_EX);
50
  unlink($this->_fileNameTemp);
51
  echo "Finished Generating Feed file: '".$this->_fileName."'";
52
 
53
- if($this->_gzipFile){
54
- $this->gzCompressFile($this->_fileName);
55
- }
56
 
57
  echo "<br />".((microtime(true) - $time))." secs";
58
  echo "<br />".(memory_get_usage(true))." bytes";
@@ -106,9 +105,8 @@ class IntelligentReach
106
  */
107
  public function getProducts($page,$storeId)
108
  {
109
- if($storeId) {
110
  Mage::app()->setCurrentStore($storeId);
111
- }
112
 
113
  $products = $this->getProductCollection($storeId);
114
 
@@ -119,46 +117,45 @@ class IntelligentReach
119
 
120
  return $products;
121
  }
122
-
123
- public function getProductCollection($storeId)
124
- {
125
- return Mage::getModel('catalog/product')
126
- ->getCollection()
127
- ->addStoreFilter($storeId)
128
- ->addAttributeToSelect('*');
129
- }
130
 
131
  // Run the task
132
  public function runTheTask($storeId)
133
  {
134
- // build category map
135
- $this->_buildCategoryMap();
136
  $currentPage = 1;
137
- $lastPage = ceil($this->getProducts($currentPage,$storeId)->getSize() / $this->_amountOfProductsPerPage);
138
 
139
- echo $lastPage. " pages <br />";
140
  do{
141
- $products = $this->getProducts($currentPage,$storeId);
142
 
143
- echo "Starting page $currentPage of $lastPage ..";
144
- Mage::getSingleton('core/resource_iterator')
145
- ->walk($products->getSelect(), array(array($this, 'printProducts')),array('store_id' => $storeId));
146
- $currentPage++;
147
 
148
- $products->clear();
149
- unset($products);
150
 
151
- foreach($this->_parentProducts as $parentProduct){
152
- $parentProduct->clearInstance();
153
- }
154
 
155
- $this->_parentProducts = array(); // clear parent products
156
- ob_flush();
157
- flush();
158
- echo " ".(memory_get_usage(true))." bytes ";
159
- echo ".. Finished (ok) <br />";
160
 
161
- }while($currentPage <= $lastPage);
162
  }
163
 
164
  public function printProducts($args)
@@ -170,13 +167,12 @@ class IntelligentReach
170
  $product = Mage::getModel('catalog/product')->setData($args['row']);
171
  if ($product->getTypeId() == 'simple')
172
  {
173
- // use singleton saves re instantiating new model
174
  $parentIds = Mage::getSingleton('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
175
  if (!$parentIds)
176
  $parentIds = Mage::getSingleton('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
177
- if (isset($parentIds[0])){
178
- $parentProduct = $this->getParentProduct($parentIds[0]);// use already loaded parent if available
179
- }
180
  }
181
  $feedData .= '<product>';
182
  foreach ($product->getData() as $key => $value)
@@ -202,7 +198,6 @@ class IntelligentReach
202
  continue;
203
  $value = $attr->getFrontend()->getValue($parentProduct);
204
  }
205
-
206
  // Print out all media gallery images.
207
  if($key == 'media_gallery')
208
  {
@@ -215,29 +210,25 @@ class IntelligentReach
215
  if((isset($parentProduct)) && ($parentProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED))
216
  $value = "Disabled";
217
  }
218
-
219
- if($key == 'special_price')
220
- {
221
- $specialPriceEnabledValue = is_null($value) ? 0 : 1;
222
- $fromDate = $product->getResource()->getAttribute('special_from_date')->getFrontend()->getValue($product);
223
- $toDate = $product->getResource()->getAttribute('special_to_date')->getFrontend()->getValue($product);
224
-
225
- if($fromDate != null)
226
- $specialPriceEnabledValue = (strtotime($fromDate) <= strtotime(date('Y-m-d'))) ? 1 : 0;
227
- if($toDate != null)
228
- $specialPriceEnabledValue = (strtotime(date('Y-m-d')) <= strtotime($toDate)) ? 1 : 0;
229
-
230
- $feedData .= "<special_price_enabled><![CDATA[".$specialPriceEnabledValue."]]></special_price_enabled>";
231
- }
232
 
 
 
233
  if(is_array($value))
234
  {
235
  foreach($value as $vkey => $vvalue)
236
  {
237
  foreach($vvalue as $pkey => $pvalue)
238
- {
239
  $feedData .= "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
240
- }
241
  }
242
  continue;
243
  }
@@ -246,21 +237,25 @@ class IntelligentReach
246
  $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
247
  else
248
  $value = htmlentities($value, ENT_COMPAT, "UTF-8");
249
- $value = $this->stripInvalidXMLCharacters($value);
250
 
 
251
  $value = "<![CDATA[$value]]>";
252
 
253
  $key = str_replace('"', '', $key);
254
  if(is_numeric($key[0]))
255
- $key = $this->convertNumberToWord($key[0]).substr($key, 1);
256
  $feedData .= '<' . $key . '>' . $value . '</' . $key . '>';
257
  }
258
  }
259
 
260
  if(isset($parentProduct))
261
  {
262
- if($_includeAllParentFields)
 
 
 
263
  $this->printAllParentFields($parentProduct);
 
264
  else
265
  {
266
  $feedData .= '<ir_parent_entity_id><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getId()).']]></ir_parent_entity_id>';
@@ -274,24 +269,25 @@ class IntelligentReach
274
  for($i = 0; $i < count($gallery['images']); $i++)
275
  $feedData .= " <ir_parent_image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $gallery['images'][$i]['file']."]]></ir_parent_image_".($i + 1).">";
276
  }
277
- $feedData .= $this->getCategoryData($product,$args['store_id'],$parentProduct);
278
  }
279
 
280
  $feedData .= '</product>'.PHP_EOL;
281
  if (is_object($parentIds))
282
  unset($parentIds);
283
 
284
- $product->clearInstance(); // unset by itself doesn't clear some variables you need to let the model handle this itself
285
  unset($product);
286
  file_put_contents($this->_fileNameTemp, $feedData, FILE_APPEND | LOCK_EX);
287
  }
288
 
289
- private function _buildCategoryMap(){
 
290
  $categories = Mage::getModel('catalog/category')
291
- ->getCollection()
292
- ->addAttributeToSelect("level", "path", "entity_id")
293
- ->addNameToResult()
294
- ->addOrder("level");
295
 
296
  $categories->setPageSize(100);
297
 
@@ -299,68 +295,68 @@ class IntelligentReach
299
  $currentPage = 1;
300
  do{
301
  $categories->setCurPage($currentPage);
302
- foreach($categories as $category){
 
303
  $this->_categories[$category->getId()] =
304
- array(
305
- "name" => $category->getName(),
306
- "path_in_store" => $category->getPathInStore()
307
- );
308
- $category->getName();
309
  }
310
 
311
  $categories->clear();
312
  $currentPage++;
313
 
314
  }while($currentPage <= $lastPageNumber);
315
-
316
- return $this->_categories;
317
  }
318
 
319
  public function getCategoryData($product, $storeId, $parentProduct)
320
- {
321
- $feedData = '';
322
  $categories = $product->getCategoryIds();
323
 
324
  if((count($categories) == 0) && isset($parentProduct))
325
  $categories = $parentProduct->getCategoryIds();
326
- if(count($categories) == 0 || !isset($this->_categories[$categories[0]]))
327
  return;
328
 
329
- $categoryData = $this->_categories[$categories[0]];
330
-
331
- $parentCategories = array_reverse(explode(',',$categoryData['path_in_store']));
332
-
333
- $output = '';
334
- foreach($parentCategories as $parent){
335
- if(isset($this->_categories[$parent])){
336
- $output .= $this->_categories[$parent]['name'];
337
- if ($parent !== end($parentCategories)) {
338
- $output .= ' > ';
339
- }
340
- }
341
- }
342
-
343
- if($output != "")
344
- {
345
- /** Old Category Path code: will be deleted in the future. **/
346
- $feedData .= '<category_path><![CDATA[' . $output . ']]></category_path>';
347
- /** End of Old Category path code **/
348
- /** New Category Path code **/
349
- $feedData .= '<ir_category_path><![CDATA['.$output.']]></ir_category_path>';
350
- /** End of New Category Path code **/
351
- }
352
 
353
  /** New longest Category Path code **/
354
  $validCategoryPaths = array();
355
- $catPath = '';
356
  foreach($categories as $cat)
357
  {
358
- if(isset($this->_categories[$cat])){
359
- $catPath .= $this->_categories[$cat]['name'];
360
- if ($cat !== end($categories)) {
361
- $catPath .= ' > ';
362
- }
363
- }
364
  if($catPath != "")
365
  {
366
  if($this->getIntelligentReachCategoryExclusions($storeId) != "")
@@ -369,7 +365,7 @@ class IntelligentReach
369
  array_push($validCategoryPaths, $catPath);
370
  }
371
  else
372
- array_push($validCategoryPaths, $catPath);
373
  }
374
  }
375
 
@@ -384,20 +380,20 @@ class IntelligentReach
384
 
385
  /** End of New longest Category Path code **/
386
 
387
- return $feedData;
388
  }
389
 
390
- public function getIntelligentReachCategoryExclusions($storeId)
391
- {
392
- if($this->_intelligentReachCategoryExclusions == null)
393
- {
394
- $this->_intelligentReachCategoryExclusions = Mage::getModel('core/variable')
395
- ->setStoreId($storeId)
396
- ->loadByCode('intelligent_reach_category_exclusions')
397
- ->getValue();
398
- }
399
- return $this->_intelligentReachCategoryExclusions;
400
- }
401
 
402
  public function printAllParentFields($parentProduct)
403
  {
@@ -422,9 +418,7 @@ class IntelligentReach
422
  foreach($value as $vkey => $vvalue)
423
  {
424
  foreach($vvalue as $pkey => $pvalue)
425
- {
426
  $parentFeedData .= "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
427
- }
428
  }
429
  continue;
430
  }
@@ -438,7 +432,7 @@ class IntelligentReach
438
 
439
  $key = str_replace('"', '', $key);
440
  if(is_numeric($key[0]))
441
- $key = $this->convertNumberToWord($key[0]).substr($key, 1);
442
  $parentFeedData .= '<ir_parent_' . $key . '>' . $value . '</ir_parent_' . $key . '>';
443
  }
444
  file_put_contents($this->_fileNameTemp, $parentFeedData, FILE_APPEND | LOCK_EX);
@@ -446,58 +440,58 @@ class IntelligentReach
446
 
447
  public function stripInvalidXMLCharacters($value)
448
  {
449
- if(!$_stripInvalidChars)
450
  return $value;
451
  return preg_replace("/[^A-Za-z0-9\d\!\"\$%^&*:;?'@~#{}|`()\\/.,_+=\-<>\s]/u", '', $value);
452
  }
453
 
454
- public function getParentProduct($parentId)
455
- {
456
- if(!isset($this->_parentProducts[$parentId]))
457
- $this->_parentProducts[$parentId] = Mage::getModel('catalog/product')->load($parentId);
458
- return $this->_parentProducts[$parentId];
459
- }
460
 
461
  public function convertNumberToWord($number)
462
  {
463
- if(!$_convertNumberToWord)
464
  return $number;
465
  $dictionary = array( 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine');
466
  return $dictionary[$number];
467
  }
468
 
469
- /**
470
- * GZIPs a file on disk (appending .gz to the name)
471
- *
472
- * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
473
- * Based on function by Kioob at:
474
- * http://www.php.net/manual/en/function.gzwrite.php#34955
475
- *
476
- * @param string $source Path to file that should be compressed
477
- * @param integer $level GZIP compression level (default: 9)
478
- * @return string New filename (with .gz appended) if success, or false if operation fails
479
- */
480
- public function gzCompressFile($source, $level = 9)
481
- {
482
- $dest = $source . '.gz';
483
- $mode = 'wb' . $level;
484
- $error = false;
485
- if ($fp_out = gzopen($dest, $mode)) {
486
- if ($fp_in = fopen($source,'rb')) {
487
- while (!feof($fp_in))
488
- gzwrite($fp_out, fread($fp_in, 1024 * 512));
489
- fclose($fp_in);
490
- } else {
491
- $error = true;
492
- }
493
- gzclose($fp_out);
494
- } else {
495
- $error = true;
496
- }
497
- if ($error)
498
- return false;
499
- else
500
- return $dest;
501
- }
502
  }
503
 
1
  <?php
2
 
3
+ /** Version 1.0.37 Last updated by Kire on 18/05/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  ini_set('memory_limit', '2G');
13
 
14
  class IntelligentReach
15
  {
16
+ private $_versionDisplay = "Version 1.0.37 <br />Last updated on 18/05/2016";
17
+ private $_outputDirectory = "output";
18
  private $_fileName = "Feed";
19
  private $_fileNameTemp = "";
20
  private $_amountOfProductsPerPage = 1000;
21
  private $_categories = null;
22
  private $_intelligentReachCategoryExclusions = null;
23
+ private $_parentProducts = array();
24
+
25
+ private $_gzipFile = true;
26
+ private $_includeAllParentFields = false;
27
  private $_stripInvalidChars = false;
28
  private $_convertNumberToWord = false;
29
 
30
+ public function run()
31
  {
32
  $storeId = (isset($_GET["storeid"]))? $_GET["storeid"] : false;
33
 
34
  // If a store id was provided then print the products to the output.
35
  if ($this->storeIsSelected())
36
  {
37
+ $this->_fileName = $this->_outputDirectory."/".$this->_fileName."_".$storeId.".xml"; // added store id to feed file name for multi store support.
38
  $this->_fileNameTemp = tempnam("", $this->_fileName);
39
  echo "Temp File created: ". $this->_fileNameTemp."<br />";
40
  $time = microtime(true);
41
  file_put_contents($this->_fileNameTemp, '<?xml version="1.0" encoding="utf-8"?>
42
+ <products version="1.0.37" type="cron">', LOCK_EX);
43
  $this->runTheTask($storeId);
44
  file_put_contents($this->_fileNameTemp, '</products>', FILE_APPEND | LOCK_EX);
45
+
46
+ if (!file_exists($this->_outputDirectory))
47
+ mkdir($this->_outputDirectory);
48
+
49
  file_put_contents($this->_fileName, file_get_contents($this->_fileNameTemp), LOCK_EX);
50
  unlink($this->_fileNameTemp);
51
  echo "Finished Generating Feed file: '".$this->_fileName."'";
52
 
53
+ if($this->_gzipFile)
54
+ $this->gzCompressFile($this->_fileName);
 
55
 
56
  echo "<br />".((microtime(true) - $time))." secs";
57
  echo "<br />".(memory_get_usage(true))." bytes";
105
  */
106
  public function getProducts($page,$storeId)
107
  {
108
+ if($storeId)
109
  Mage::app()->setCurrentStore($storeId);
 
110
 
111
  $products = $this->getProductCollection($storeId);
112
 
117
 
118
  return $products;
119
  }
120
+
121
+ public function getProductCollection($storeId)
122
+ {
123
+ return Mage::getModel('catalog/product')
124
+ ->getCollection()
125
+ ->addStoreFilter($storeId)
126
+ ->addAttributeToSelect('*');
127
+ }
128
 
129
  // Run the task
130
  public function runTheTask($storeId)
131
  {
132
+ // build category map
133
+ $this->_buildCategoryMap();
134
  $currentPage = 1;
135
+ $lastPage = ceil($this->getProductCollection($storeId)->getSize() / $this->_amountOfProductsPerPage);
136
 
137
+ echo $lastPage. " pages <br />";
138
  do{
139
+ $products = $this->getProducts($currentPage,$storeId);
140
 
141
+ echo "Starting page $currentPage of $lastPage ..";
142
+ Mage::getSingleton('core/resource_iterator')
143
+ ->walk($products->getSelect(), array(array($this, 'printProducts')),array('store_id' => $storeId));
144
+ $currentPage++;
145
 
146
+ $products->clear();
147
+ unset($products);
148
 
149
+ foreach($this->_parentProducts as $parentProduct)
150
+ $parentProduct->clearInstance();
 
151
 
152
+ $this->_parentProducts = array(); // clear parent products
153
+ ob_flush();
154
+ flush();
155
+ echo " ".(memory_get_usage(true))." bytes ";
156
+ echo ".. Finished (ok) <br />";
157
 
158
+ }while($currentPage <= $lastPage);
159
  }
160
 
161
  public function printProducts($args)
167
  $product = Mage::getModel('catalog/product')->setData($args['row']);
168
  if ($product->getTypeId() == 'simple')
169
  {
170
+ // use singleton saves re instantiating new model
171
  $parentIds = Mage::getSingleton('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
172
  if (!$parentIds)
173
  $parentIds = Mage::getSingleton('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
174
+ if (isset($parentIds[0]))
175
+ $parentProduct = $this->getParentProduct($parentIds[0]);// use already loaded parent if available
 
176
  }
177
  $feedData .= '<product>';
178
  foreach ($product->getData() as $key => $value)
198
  continue;
199
  $value = $attr->getFrontend()->getValue($parentProduct);
200
  }
 
201
  // Print out all media gallery images.
202
  if($key == 'media_gallery')
203
  {
210
  if((isset($parentProduct)) && ($parentProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED))
211
  $value = "Disabled";
212
  }
213
+ if($key == 'special_price')
214
+ {
215
+ $specialPriceEnabledValue = is_null($value) ? 0 : 1;
216
+ $fromDate = $product->getResource()->getAttribute('special_from_date')->getFrontend()->getValue($product);
217
+ $toDate = $product->getResource()->getAttribute('special_to_date')->getFrontend()->getValue($product);
218
+
219
+ if($fromDate != null)
220
+ $specialPriceEnabledValue = (strtotime($fromDate) <= strtotime(date('Y-m-d'))) ? 1 : 0;
221
+ if($toDate != null)
222
+ $specialPriceEnabledValue = (strtotime(date('Y-m-d')) <= strtotime($toDate)) ? 1 : 0;
 
 
 
 
223
 
224
+ $feedData .= "<special_price_enabled><![CDATA[".$specialPriceEnabledValue."]]></special_price_enabled>";
225
+ }
226
  if(is_array($value))
227
  {
228
  foreach($value as $vkey => $vvalue)
229
  {
230
  foreach($vvalue as $pkey => $pvalue)
 
231
  $feedData .= "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
 
232
  }
233
  continue;
234
  }
237
  $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
238
  else
239
  $value = htmlentities($value, ENT_COMPAT, "UTF-8");
 
240
 
241
+ $value = $this->stripInvalidXMLCharacters($value);
242
  $value = "<![CDATA[$value]]>";
243
 
244
  $key = str_replace('"', '', $key);
245
  if(is_numeric($key[0]))
246
+ $key = $this->convertNumberToWord($key[0]).substr($key, 1);
247
  $feedData .= '<' . $key . '>' . $value . '</' . $key . '>';
248
  }
249
  }
250
 
251
  if(isset($parentProduct))
252
  {
253
+ if($this->_includeAllParentFields)
254
+ {
255
+ file_put_contents($this->_fileNameTemp, $feedData, FILE_APPEND | LOCK_EX);
256
+ $feedData = "";
257
  $this->printAllParentFields($parentProduct);
258
+ }
259
  else
260
  {
261
  $feedData .= '<ir_parent_entity_id><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getId()).']]></ir_parent_entity_id>';
269
  for($i = 0; $i < count($gallery['images']); $i++)
270
  $feedData .= " <ir_parent_image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $gallery['images'][$i]['file']."]]></ir_parent_image_".($i + 1).">";
271
  }
272
+ $feedData .= $this->getCategoryData($product,$args['store_id'],$parentProduct);
273
  }
274
 
275
  $feedData .= '</product>'.PHP_EOL;
276
  if (is_object($parentIds))
277
  unset($parentIds);
278
 
279
+ $product->clearInstance(); // unset by itself doesn't clear some variables you need to let the model handle this itself
280
  unset($product);
281
  file_put_contents($this->_fileNameTemp, $feedData, FILE_APPEND | LOCK_EX);
282
  }
283
 
284
+ private function _buildCategoryMap()
285
+ {
286
  $categories = Mage::getModel('catalog/category')
287
+ ->getCollection()
288
+ ->addAttributeToSelect("level", "path", "entity_id")
289
+ ->addNameToResult()
290
+ ->addOrder("level");
291
 
292
  $categories->setPageSize(100);
293
 
295
  $currentPage = 1;
296
  do{
297
  $categories->setCurPage($currentPage);
298
+ foreach($categories as $category)
299
+ {
300
  $this->_categories[$category->getId()] =
301
+ array(
302
+ "name" => $category->getName(),
303
+ "path_in_store" => $category->getPathInStore()
304
+ );
305
+ $category->getName();
306
  }
307
 
308
  $categories->clear();
309
  $currentPage++;
310
 
311
  }while($currentPage <= $lastPageNumber);
312
+ return $this->_categories;
 
313
  }
314
 
315
  public function getCategoryData($product, $storeId, $parentProduct)
316
+ {
317
+ $feedData = '';
318
  $categories = $product->getCategoryIds();
319
 
320
  if((count($categories) == 0) && isset($parentProduct))
321
  $categories = $parentProduct->getCategoryIds();
322
+ if((count($categories) == 0) || !isset($this->_categories[$categories[0]]))
323
  return;
324
 
325
+ $categoryData = $this->_categories[$categories[0]];
326
+ $parentCategories = array_reverse(explode(',',$categoryData['path_in_store']));
327
+
328
+ $output = '';
329
+ foreach($parentCategories as $parent)
330
+ {
331
+ if(isset($this->_categories[$parent]))
332
+ {
333
+ $output .= $this->_categories[$parent]['name'];
334
+ if($parent !== end($parentCategories))
335
+ $output .= ' > ';
336
+ }
337
+ }
338
+
339
+ if($output != "")
340
+ {
341
+ /** Old Category Path code: will be deleted in the future. **/
342
+ $feedData .= '<category_path><![CDATA[' . $output . ']]></category_path>';
343
+ /** End of Old Category path code **/
344
+ /** New Category Path code **/
345
+ $feedData .= '<ir_category_path><![CDATA['.$output.']]></ir_category_path>';
346
+ /** End of New Category Path code **/
347
+ }
348
 
349
  /** New longest Category Path code **/
350
  $validCategoryPaths = array();
351
+ $catPath = '';
352
  foreach($categories as $cat)
353
  {
354
+ if(isset($this->_categories[$cat]))
355
+ {
356
+ $catPath .= $this->_categories[$cat]['name'];
357
+ if ($cat !== end($categories))
358
+ $catPath .= ' > ';
359
+ }
360
  if($catPath != "")
361
  {
362
  if($this->getIntelligentReachCategoryExclusions($storeId) != "")
365
  array_push($validCategoryPaths, $catPath);
366
  }
367
  else
368
+ array_push($validCategoryPaths, $catPath);
369
  }
370
  }
371
 
380
 
381
  /** End of New longest Category Path code **/
382
 
383
+ return $feedData;
384
  }
385
 
386
+ public function getIntelligentReachCategoryExclusions($storeId)
387
+ {
388
+ if($this->_intelligentReachCategoryExclusions == null)
389
+ {
390
+ $this->_intelligentReachCategoryExclusions = Mage::getModel('core/variable')
391
+ ->setStoreId($storeId)
392
+ ->loadByCode('intelligent_reach_category_exclusions')
393
+ ->getValue();
394
+ }
395
+ return $this->_intelligentReachCategoryExclusions;
396
+ }
397
 
398
  public function printAllParentFields($parentProduct)
399
  {
418
  foreach($value as $vkey => $vvalue)
419
  {
420
  foreach($vvalue as $pkey => $pvalue)
 
421
  $parentFeedData .= "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
 
422
  }
423
  continue;
424
  }
432
 
433
  $key = str_replace('"', '', $key);
434
  if(is_numeric($key[0]))
435
+ $key = $this->convertNumberToWord($key[0]).substr($key, 1);
436
  $parentFeedData .= '<ir_parent_' . $key . '>' . $value . '</ir_parent_' . $key . '>';
437
  }
438
  file_put_contents($this->_fileNameTemp, $parentFeedData, FILE_APPEND | LOCK_EX);
440
 
441
  public function stripInvalidXMLCharacters($value)
442
  {
443
+ if(!$this->_stripInvalidChars)
444
  return $value;
445
  return preg_replace("/[^A-Za-z0-9\d\!\"\$%^&*:;?'@~#{}|`()\\/.,_+=\-<>\s]/u", '', $value);
446
  }
447
 
448
+ public function getParentProduct($parentId)
449
+ {
450
+ if(!isset($this->_parentProducts[$parentId]))
451
+ $this->_parentProducts[$parentId] = Mage::getModel('catalog/product')->load($parentId);
452
+ return $this->_parentProducts[$parentId];
453
+ }
454
 
455
  public function convertNumberToWord($number)
456
  {
457
+ if(!$this->_convertNumberToWord)
458
  return $number;
459
  $dictionary = array( 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine');
460
  return $dictionary[$number];
461
  }
462
 
463
+ /**
464
+ * GZIPs a file on disk (appending .gz to the name)
465
+ *
466
+ * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
467
+ * Based on function by Kioob at:
468
+ * http://www.php.net/manual/en/function.gzwrite.php#34955
469
+ *
470
+ * @param string $source Path to file that should be compressed
471
+ * @param integer $level GZIP compression level (default: 9)
472
+ * @return string New filename (with .gz appended) if success, or false if operation fails
473
+ */
474
+ public function gzCompressFile($source, $level = 9)
475
+ {
476
+ $dest = $source . '.gz';
477
+ $mode = 'wb' . $level;
478
+ $error = false;
479
+ if ($fp_out = gzopen($dest, $mode)) {
480
+ if ($fp_in = fopen($source,'rb')) {
481
+ while (!feof($fp_in))
482
+ gzwrite($fp_out, fread($fp_in, 1024 * 512));
483
+ fclose($fp_in);
484
+ } else {
485
+ $error = true;
486
+ }
487
+ gzclose($fp_out);
488
+ } else {
489
+ $error = true;
490
+ }
491
+ if ($error)
492
+ return false;
493
+ else
494
+ return $dest;
495
+ }
496
  }
497
 
ircronscripts/intelligentreach_integration_cron_pre.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- /** Version 1.0.36 Last updated by Kire on 27/04/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  ini_set('memory_limit', '2G');
@@ -13,46 +13,45 @@ $ir->run();
13
 
14
  class IntelligentReach
15
  {
16
- private $_versionDisplay = "Version 1.0.36 <br />Last updated on 27/04/2016";
17
- private $_outputDirectory = "output";
18
  private $_fileName = "Feed";
19
  private $_fileNameTemp = "";
20
  private $_amountOfProductsPerPage = 1000;
21
  private $_categories = null;
22
  private $_intelligentReachCategoryExclusions = null;
23
- private $_gzipFile = true;
24
- private $_parentProducts = array();
25
-
26
- private $_includeAllParentFields = false;
27
  private $_stripInvalidChars = false;
28
  private $_convertNumberToWord = false;
29
 
30
- public function run()
31
  {
32
  $storeId = (isset($_GET["storeid"]))? $_GET["storeid"] : false;
33
 
34
  // If a store id was provided then print the products to the output.
35
  if ($this->storeIsSelected())
36
  {
37
- $this->_fileName = $this->_outputDirectory."/".$this->_fileName."_".$storeId.".xml"; // added store id to feed file name for multi store support.
38
  $this->_fileNameTemp = tempnam("", $this->_fileName);
39
  echo "Temp File created: ". $this->_fileNameTemp."<br />";
40
  $time = microtime(true);
41
  file_put_contents($this->_fileNameTemp, '<?xml version="1.0" encoding="utf-8"?>
42
- <products>', LOCK_EX);
43
  $this->runTheTask($storeId);
44
  file_put_contents($this->_fileNameTemp, '</products>', FILE_APPEND | LOCK_EX);
45
-
46
- if (!file_exists($this->_outputDirectory))
47
- mkdir($this->_outputDirectory);
48
-
49
  file_put_contents($this->_fileName, file_get_contents($this->_fileNameTemp), LOCK_EX);
50
  unlink($this->_fileNameTemp);
51
  echo "Finished Generating Feed file: '".$this->_fileName."'";
52
 
53
- if($this->_gzipFile){
54
- $this->gzCompressFile($this->_fileName);
55
- }
56
 
57
  echo "<br />".((microtime(true) - $time))." secs";
58
  echo "<br />".(memory_get_usage(true))." bytes";
@@ -106,9 +105,8 @@ class IntelligentReach
106
  */
107
  public function getProducts($page,$storeId)
108
  {
109
- if($storeId) {
110
  Mage::app()->setCurrentStore($storeId);
111
- }
112
 
113
  $products = $this->getProductCollection($storeId);
114
 
@@ -119,45 +117,44 @@ class IntelligentReach
119
 
120
  return $products;
121
  }
122
-
123
- public function getProductCollection($storeId)
124
- {
125
- return Mage::getModel('catalog/product')
126
- ->getCollection()
127
- ->addStoreFilter($storeId);
128
- }
129
 
130
  // Run the task
131
  public function runTheTask($storeId)
132
  {
133
- // build category map
134
- $this->_buildCategoryMap();
135
  $currentPage = 1;
136
  $lastPage = ceil($this->getProductCollection($storeId)->getSize() / $this->_amountOfProductsPerPage);
137
 
138
- echo $lastPage. " pages <br />";
139
  do{
140
- $products = $this->getProducts($currentPage,$storeId);
141
 
142
- echo "Starting page $currentPage of $lastPage ..";
143
- Mage::getSingleton('core/resource_iterator')
144
- ->walk($products->getSelect(), array(array($this, 'printProducts')),array('store_id' => $storeId));
145
- $currentPage++;
146
 
147
- $products->clear();
148
- unset($products);
149
 
150
- foreach($this->_parentProducts as $parentProduct){
151
- $parentProduct->clearInstance();
152
- }
153
 
154
- $this->_parentProducts = array(); // clear parent products
155
- ob_flush();
156
- flush();
157
- echo " ".(memory_get_usage(true))." bytes ";
158
- echo ".. Finished (ok) <br />";
159
 
160
- }while($currentPage <= $lastPage);
161
  }
162
 
163
  public function printProducts($args)
@@ -169,13 +166,12 @@ class IntelligentReach
169
  $product = Mage::getModel('catalog/product')->load($args['row']['entity_id']);
170
  if ($product->getTypeId() == 'simple')
171
  {
172
- // use singleton saves re instantiating new model
173
  $parentIds = Mage::getSingleton('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
174
  if (!$parentIds)
175
  $parentIds = Mage::getSingleton('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
176
- if (isset($parentIds[0])){
177
- $parentProduct = $this->getParentProduct($parentIds[0]);// use already loaded parent if available
178
- }
179
  }
180
  $feedData .= '<product>';
181
  foreach ($product->getData() as $key => $value)
@@ -201,7 +197,6 @@ class IntelligentReach
201
  continue;
202
  $value = $attr->getFrontend()->getValue($parentProduct);
203
  }
204
-
205
  // Print out all media gallery images.
206
  if($key == 'media_gallery')
207
  {
@@ -214,29 +209,25 @@ class IntelligentReach
214
  if((isset($parentProduct)) && ($parentProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED))
215
  $value = "Disabled";
216
  }
217
-
218
- if($key == 'special_price')
219
- {
220
- $specialPriceEnabledValue = is_null($value) ? 0 : 1;
221
- $fromDate = $product->getResource()->getAttribute('special_from_date')->getFrontend()->getValue($product);
222
- $toDate = $product->getResource()->getAttribute('special_to_date')->getFrontend()->getValue($product);
223
-
224
- if($fromDate != null)
225
- $specialPriceEnabledValue = (strtotime($fromDate) <= strtotime(date('Y-m-d'))) ? 1 : 0;
226
- if($toDate != null)
227
- $specialPriceEnabledValue = (strtotime(date('Y-m-d')) <= strtotime($toDate)) ? 1 : 0;
228
-
229
- $feedData .= "<special_price_enabled><![CDATA[".$specialPriceEnabledValue."]]></special_price_enabled>";
230
- }
231
 
 
 
232
  if(is_array($value))
233
  {
234
  foreach($value as $vkey => $vvalue)
235
  {
236
  foreach($vvalue as $pkey => $pvalue)
237
- {
238
  $feedData .= "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
239
- }
240
  }
241
  continue;
242
  }
@@ -245,21 +236,25 @@ class IntelligentReach
245
  $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
246
  else
247
  $value = htmlentities($value, ENT_COMPAT, "UTF-8");
248
- $value = $this->stripInvalidXMLCharacters($value);
249
 
 
250
  $value = "<![CDATA[$value]]>";
251
 
252
  $key = str_replace('"', '', $key);
253
  if(is_numeric($key[0]))
254
- $key = $this->convertNumberToWord($key[0]).substr($key, 1);
255
  $feedData .= '<' . $key . '>' . $value . '</' . $key . '>';
256
  }
257
  }
258
 
259
  if(isset($parentProduct))
260
  {
261
- if($_includeAllParentFields)
 
 
 
262
  $this->printAllParentFields($parentProduct);
 
263
  else
264
  {
265
  $feedData .= '<ir_parent_entity_id><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getId()).']]></ir_parent_entity_id>';
@@ -273,24 +268,25 @@ class IntelligentReach
273
  for($i = 0; $i < count($gallery['images']); $i++)
274
  $feedData .= " <ir_parent_image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $gallery['images'][$i]['file']."]]></ir_parent_image_".($i + 1).">";
275
  }
276
- $feedData .= $this->getCategoryData($product,$args['store_id'],$parentProduct);
277
  }
278
 
279
  $feedData .= '</product>'.PHP_EOL;
280
  if (is_object($parentIds))
281
  unset($parentIds);
282
 
283
- $product->clearInstance(); // unset by itself doesn't clear some variables you need to let the model handle this itself
284
  unset($product);
285
  file_put_contents($this->_fileNameTemp, $feedData, FILE_APPEND | LOCK_EX);
286
  }
287
 
288
- private function _buildCategoryMap(){
 
289
  $categories = Mage::getModel('catalog/category')
290
- ->getCollection()
291
- ->addAttributeToSelect("level", "path", "entity_id")
292
- ->addNameToResult()
293
- ->addOrder("level");
294
 
295
  $categories->setPageSize(100);
296
 
@@ -298,68 +294,68 @@ class IntelligentReach
298
  $currentPage = 1;
299
  do{
300
  $categories->setCurPage($currentPage);
301
- foreach($categories as $category){
 
302
  $this->_categories[$category->getId()] =
303
- array(
304
- "name" => $category->getName(),
305
- "path_in_store" => $category->getPathInStore()
306
- );
307
- $category->getName();
308
  }
309
 
310
  $categories->clear();
311
  $currentPage++;
312
 
313
  }while($currentPage <= $lastPageNumber);
314
-
315
- return $this->_categories;
316
  }
317
 
318
  public function getCategoryData($product, $storeId, $parentProduct)
319
- {
320
- $feedData = '';
321
  $categories = $product->getCategoryIds();
322
 
323
  if((count($categories) == 0) && isset($parentProduct))
324
  $categories = $parentProduct->getCategoryIds();
325
- if(count($categories) == 0 || !isset($this->_categories[$categories[0]]))
326
  return;
327
 
328
- $categoryData = $this->_categories[$categories[0]];
329
-
330
- $parentCategories = array_reverse(explode(',',$categoryData['path_in_store']));
331
-
332
- $output = '';
333
- foreach($parentCategories as $parent){
334
- if(isset($this->_categories[$parent])){
335
- $output .= $this->_categories[$parent]['name'];
336
- if ($parent !== end($parentCategories)) {
337
- $output .= ' > ';
338
- }
339
- }
340
- }
341
-
342
- if($output != "")
343
- {
344
- /** Old Category Path code: will be deleted in the future. **/
345
- $feedData .= '<category_path><![CDATA[' . $output . ']]></category_path>';
346
- /** End of Old Category path code **/
347
- /** New Category Path code **/
348
- $feedData .= '<ir_category_path><![CDATA['.$output.']]></ir_category_path>';
349
- /** End of New Category Path code **/
350
- }
351
 
352
  /** New longest Category Path code **/
353
  $validCategoryPaths = array();
354
- $catPath = '';
355
  foreach($categories as $cat)
356
  {
357
- if(isset($this->_categories[$cat])){
358
- $catPath .= $this->_categories[$cat]['name'];
359
- if ($cat !== end($categories)) {
360
- $catPath .= ' > ';
361
- }
362
- }
363
  if($catPath != "")
364
  {
365
  if($this->getIntelligentReachCategoryExclusions($storeId) != "")
@@ -368,7 +364,7 @@ class IntelligentReach
368
  array_push($validCategoryPaths, $catPath);
369
  }
370
  else
371
- array_push($validCategoryPaths, $catPath);
372
  }
373
  }
374
 
@@ -383,20 +379,20 @@ class IntelligentReach
383
 
384
  /** End of New longest Category Path code **/
385
 
386
- return $feedData;
387
  }
388
 
389
- public function getIntelligentReachCategoryExclusions($storeId)
390
- {
391
- if($this->_intelligentReachCategoryExclusions == null)
392
- {
393
- $this->_intelligentReachCategoryExclusions = Mage::getModel('core/variable')
394
- ->setStoreId($storeId)
395
- ->loadByCode('intelligent_reach_category_exclusions')
396
- ->getValue();
397
- }
398
- return $this->_intelligentReachCategoryExclusions;
399
- }
400
 
401
  public function printAllParentFields($parentProduct)
402
  {
@@ -421,9 +417,7 @@ class IntelligentReach
421
  foreach($value as $vkey => $vvalue)
422
  {
423
  foreach($vvalue as $pkey => $pvalue)
424
- {
425
  $parentFeedData .= "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
426
- }
427
  }
428
  continue;
429
  }
@@ -437,7 +431,7 @@ class IntelligentReach
437
 
438
  $key = str_replace('"', '', $key);
439
  if(is_numeric($key[0]))
440
- $key = $this->convertNumberToWord($key[0]).substr($key, 1);
441
  $parentFeedData .= '<ir_parent_' . $key . '>' . $value . '</ir_parent_' . $key . '>';
442
  }
443
  file_put_contents($this->_fileNameTemp, $parentFeedData, FILE_APPEND | LOCK_EX);
@@ -445,58 +439,58 @@ class IntelligentReach
445
 
446
  public function stripInvalidXMLCharacters($value)
447
  {
448
- if(!$_stripInvalidChars)
449
  return $value;
450
  return preg_replace("/[^A-Za-z0-9\d\!\"\$%^&*:;?'@~#{}|`()\\/.,_+=\-<>\s]/u", '', $value);
451
  }
452
 
453
- public function getParentProduct($parentId)
454
- {
455
- if(!isset($this->_parentProducts[$parentId]))
456
- $this->_parentProducts[$parentId] = Mage::getModel('catalog/product')->load($parentId);
457
- return $this->_parentProducts[$parentId];
458
- }
459
 
460
  public function convertNumberToWord($number)
461
  {
462
- if(!$_convertNumberToWord)
463
  return $number;
464
  $dictionary = array( 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine');
465
  return $dictionary[$number];
466
  }
467
 
468
- /**
469
- * GZIPs a file on disk (appending .gz to the name)
470
- *
471
- * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
472
- * Based on function by Kioob at:
473
- * http://www.php.net/manual/en/function.gzwrite.php#34955
474
- *
475
- * @param string $source Path to file that should be compressed
476
- * @param integer $level GZIP compression level (default: 9)
477
- * @return string New filename (with .gz appended) if success, or false if operation fails
478
- */
479
- public function gzCompressFile($source, $level = 9)
480
- {
481
- $dest = $source . '.gz';
482
- $mode = 'wb' . $level;
483
- $error = false;
484
- if ($fp_out = gzopen($dest, $mode)) {
485
- if ($fp_in = fopen($source,'rb')) {
486
- while (!feof($fp_in))
487
- gzwrite($fp_out, fread($fp_in, 1024 * 512));
488
- fclose($fp_in);
489
- } else {
490
- $error = true;
491
- }
492
- gzclose($fp_out);
493
- } else {
494
- $error = true;
495
- }
496
- if ($error)
497
- return false;
498
- else
499
- return $dest;
500
- }
501
  }
502
 
1
  <?php
2
 
3
+ /** Version 1.0.37 Last updated by Kire on 18/05/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  ini_set('memory_limit', '2G');
13
 
14
  class IntelligentReach
15
  {
16
+ private $_versionDisplay = "Version 1.0.37 <br />Last updated on 18/05/2016";
17
+ private $_outputDirectory = "output";
18
  private $_fileName = "Feed";
19
  private $_fileNameTemp = "";
20
  private $_amountOfProductsPerPage = 1000;
21
  private $_categories = null;
22
  private $_intelligentReachCategoryExclusions = null;
23
+ private $_parentProducts = array();
24
+
25
+ private $_gzipFile = true;
26
+ private $_includeAllParentFields = false;
27
  private $_stripInvalidChars = false;
28
  private $_convertNumberToWord = false;
29
 
30
+ public function run()
31
  {
32
  $storeId = (isset($_GET["storeid"]))? $_GET["storeid"] : false;
33
 
34
  // If a store id was provided then print the products to the output.
35
  if ($this->storeIsSelected())
36
  {
37
+ $this->_fileName = $this->_outputDirectory."/".$this->_fileName."_".$storeId.".xml"; // added store id to feed file name for multi store support.
38
  $this->_fileNameTemp = tempnam("", $this->_fileName);
39
  echo "Temp File created: ". $this->_fileNameTemp."<br />";
40
  $time = microtime(true);
41
  file_put_contents($this->_fileNameTemp, '<?xml version="1.0" encoding="utf-8"?>
42
+ <products version="1.0.37" type="cron_pre">', LOCK_EX);
43
  $this->runTheTask($storeId);
44
  file_put_contents($this->_fileNameTemp, '</products>', FILE_APPEND | LOCK_EX);
45
+
46
+ if (!file_exists($this->_outputDirectory))
47
+ mkdir($this->_outputDirectory);
48
+
49
  file_put_contents($this->_fileName, file_get_contents($this->_fileNameTemp), LOCK_EX);
50
  unlink($this->_fileNameTemp);
51
  echo "Finished Generating Feed file: '".$this->_fileName."'";
52
 
53
+ if($this->_gzipFile)
54
+ $this->gzCompressFile($this->_fileName);
 
55
 
56
  echo "<br />".((microtime(true) - $time))." secs";
57
  echo "<br />".(memory_get_usage(true))." bytes";
105
  */
106
  public function getProducts($page,$storeId)
107
  {
108
+ if($storeId)
109
  Mage::app()->setCurrentStore($storeId);
 
110
 
111
  $products = $this->getProductCollection($storeId);
112
 
117
 
118
  return $products;
119
  }
120
+
121
+ public function getProductCollection($storeId)
122
+ {
123
+ return Mage::getModel('catalog/product')
124
+ ->getCollection()
125
+ ->addStoreFilter($storeId);
126
+ }
127
 
128
  // Run the task
129
  public function runTheTask($storeId)
130
  {
131
+ // build category map
132
+ $this->_buildCategoryMap();
133
  $currentPage = 1;
134
  $lastPage = ceil($this->getProductCollection($storeId)->getSize() / $this->_amountOfProductsPerPage);
135
 
136
+ echo $lastPage. " pages <br />";
137
  do{
138
+ $products = $this->getProducts($currentPage,$storeId);
139
 
140
+ echo "Starting page $currentPage of $lastPage ..";
141
+ Mage::getSingleton('core/resource_iterator')
142
+ ->walk($products->getSelect(), array(array($this, 'printProducts')),array('store_id' => $storeId));
143
+ $currentPage++;
144
 
145
+ $products->clear();
146
+ unset($products);
147
 
148
+ foreach($this->_parentProducts as $parentProduct)
149
+ $parentProduct->clearInstance();
 
150
 
151
+ $this->_parentProducts = array(); // clear parent products
152
+ ob_flush();
153
+ flush();
154
+ echo " ".(memory_get_usage(true))." bytes ";
155
+ echo ".. Finished (ok) <br />";
156
 
157
+ }while($currentPage <= $lastPage);
158
  }
159
 
160
  public function printProducts($args)
166
  $product = Mage::getModel('catalog/product')->load($args['row']['entity_id']);
167
  if ($product->getTypeId() == 'simple')
168
  {
169
+ // use singleton saves re instantiating new model
170
  $parentIds = Mage::getSingleton('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
171
  if (!$parentIds)
172
  $parentIds = Mage::getSingleton('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
173
+ if (isset($parentIds[0]))
174
+ $parentProduct = $this->getParentProduct($parentIds[0]);// use already loaded parent if available
 
175
  }
176
  $feedData .= '<product>';
177
  foreach ($product->getData() as $key => $value)
197
  continue;
198
  $value = $attr->getFrontend()->getValue($parentProduct);
199
  }
 
200
  // Print out all media gallery images.
201
  if($key == 'media_gallery')
202
  {
209
  if((isset($parentProduct)) && ($parentProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED))
210
  $value = "Disabled";
211
  }
212
+ if($key == 'special_price')
213
+ {
214
+ $specialPriceEnabledValue = is_null($value) ? 0 : 1;
215
+ $fromDate = $product->getResource()->getAttribute('special_from_date')->getFrontend()->getValue($product);
216
+ $toDate = $product->getResource()->getAttribute('special_to_date')->getFrontend()->getValue($product);
217
+
218
+ if($fromDate != null)
219
+ $specialPriceEnabledValue = (strtotime($fromDate) <= strtotime(date('Y-m-d'))) ? 1 : 0;
220
+ if($toDate != null)
221
+ $specialPriceEnabledValue = (strtotime(date('Y-m-d')) <= strtotime($toDate)) ? 1 : 0;
 
 
 
 
222
 
223
+ $feedData .= "<special_price_enabled><![CDATA[".$specialPriceEnabledValue."]]></special_price_enabled>";
224
+ }
225
  if(is_array($value))
226
  {
227
  foreach($value as $vkey => $vvalue)
228
  {
229
  foreach($vvalue as $pkey => $pvalue)
 
230
  $feedData .= "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
 
231
  }
232
  continue;
233
  }
236
  $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
237
  else
238
  $value = htmlentities($value, ENT_COMPAT, "UTF-8");
 
239
 
240
+ $value = $this->stripInvalidXMLCharacters($value);
241
  $value = "<![CDATA[$value]]>";
242
 
243
  $key = str_replace('"', '', $key);
244
  if(is_numeric($key[0]))
245
+ $key = $this->convertNumberToWord($key[0]).substr($key, 1);
246
  $feedData .= '<' . $key . '>' . $value . '</' . $key . '>';
247
  }
248
  }
249
 
250
  if(isset($parentProduct))
251
  {
252
+ if($this->_includeAllParentFields)
253
+ {
254
+ file_put_contents($this->_fileNameTemp, $feedData, FILE_APPEND | LOCK_EX);
255
+ $feedData = "";
256
  $this->printAllParentFields($parentProduct);
257
+ }
258
  else
259
  {
260
  $feedData .= '<ir_parent_entity_id><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getId()).']]></ir_parent_entity_id>';
268
  for($i = 0; $i < count($gallery['images']); $i++)
269
  $feedData .= " <ir_parent_image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $gallery['images'][$i]['file']."]]></ir_parent_image_".($i + 1).">";
270
  }
271
+ $feedData .= $this->getCategoryData($product,$args['store_id'],$parentProduct);
272
  }
273
 
274
  $feedData .= '</product>'.PHP_EOL;
275
  if (is_object($parentIds))
276
  unset($parentIds);
277
 
278
+ $product->clearInstance(); // unset by itself doesn't clear some variables you need to let the model handle this itself
279
  unset($product);
280
  file_put_contents($this->_fileNameTemp, $feedData, FILE_APPEND | LOCK_EX);
281
  }
282
 
283
+ private function _buildCategoryMap()
284
+ {
285
  $categories = Mage::getModel('catalog/category')
286
+ ->getCollection()
287
+ ->addAttributeToSelect("level", "path", "entity_id")
288
+ ->addNameToResult()
289
+ ->addOrder("level");
290
 
291
  $categories->setPageSize(100);
292
 
294
  $currentPage = 1;
295
  do{
296
  $categories->setCurPage($currentPage);
297
+ foreach($categories as $category)
298
+ {
299
  $this->_categories[$category->getId()] =
300
+ array(
301
+ "name" => $category->getName(),
302
+ "path_in_store" => $category->getPathInStore()
303
+ );
304
+ $category->getName();
305
  }
306
 
307
  $categories->clear();
308
  $currentPage++;
309
 
310
  }while($currentPage <= $lastPageNumber);
311
+ return $this->_categories;
 
312
  }
313
 
314
  public function getCategoryData($product, $storeId, $parentProduct)
315
+ {
316
+ $feedData = '';
317
  $categories = $product->getCategoryIds();
318
 
319
  if((count($categories) == 0) && isset($parentProduct))
320
  $categories = $parentProduct->getCategoryIds();
321
+ if((count($categories) == 0) || !isset($this->_categories[$categories[0]]))
322
  return;
323
 
324
+ $categoryData = $this->_categories[$categories[0]];
325
+ $parentCategories = array_reverse(explode(',',$categoryData['path_in_store']));
326
+
327
+ $output = '';
328
+ foreach($parentCategories as $parent)
329
+ {
330
+ if(isset($this->_categories[$parent]))
331
+ {
332
+ $output .= $this->_categories[$parent]['name'];
333
+ if($parent !== end($parentCategories))
334
+ $output .= ' > ';
335
+ }
336
+ }
337
+
338
+ if($output != "")
339
+ {
340
+ /** Old Category Path code: will be deleted in the future. **/
341
+ $feedData .= '<category_path><![CDATA[' . $output . ']]></category_path>';
342
+ /** End of Old Category path code **/
343
+ /** New Category Path code **/
344
+ $feedData .= '<ir_category_path><![CDATA['.$output.']]></ir_category_path>';
345
+ /** End of New Category Path code **/
346
+ }
347
 
348
  /** New longest Category Path code **/
349
  $validCategoryPaths = array();
350
+ $catPath = '';
351
  foreach($categories as $cat)
352
  {
353
+ if(isset($this->_categories[$cat]))
354
+ {
355
+ $catPath .= $this->_categories[$cat]['name'];
356
+ if ($cat !== end($categories))
357
+ $catPath .= ' > ';
358
+ }
359
  if($catPath != "")
360
  {
361
  if($this->getIntelligentReachCategoryExclusions($storeId) != "")
364
  array_push($validCategoryPaths, $catPath);
365
  }
366
  else
367
+ array_push($validCategoryPaths, $catPath);
368
  }
369
  }
370
 
379
 
380
  /** End of New longest Category Path code **/
381
 
382
+ return $feedData;
383
  }
384
 
385
+ public function getIntelligentReachCategoryExclusions($storeId)
386
+ {
387
+ if($this->_intelligentReachCategoryExclusions == null)
388
+ {
389
+ $this->_intelligentReachCategoryExclusions = Mage::getModel('core/variable')
390
+ ->setStoreId($storeId)
391
+ ->loadByCode('intelligent_reach_category_exclusions')
392
+ ->getValue();
393
+ }
394
+ return $this->_intelligentReachCategoryExclusions;
395
+ }
396
 
397
  public function printAllParentFields($parentProduct)
398
  {
417
  foreach($value as $vkey => $vvalue)
418
  {
419
  foreach($vvalue as $pkey => $pvalue)
 
420
  $parentFeedData .= "<".$key."_".$vkey."_".$pkey."><![CDATA[".$pvalue."]]></".$key."_".$vkey."_".$pkey.">";
 
421
  }
422
  continue;
423
  }
431
 
432
  $key = str_replace('"', '', $key);
433
  if(is_numeric($key[0]))
434
+ $key = $this->convertNumberToWord($key[0]).substr($key, 1);
435
  $parentFeedData .= '<ir_parent_' . $key . '>' . $value . '</ir_parent_' . $key . '>';
436
  }
437
  file_put_contents($this->_fileNameTemp, $parentFeedData, FILE_APPEND | LOCK_EX);
439
 
440
  public function stripInvalidXMLCharacters($value)
441
  {
442
+ if(!$this->_stripInvalidChars)
443
  return $value;
444
  return preg_replace("/[^A-Za-z0-9\d\!\"\$%^&*:;?'@~#{}|`()\\/.,_+=\-<>\s]/u", '', $value);
445
  }
446
 
447
+ public function getParentProduct($parentId)
448
+ {
449
+ if(!isset($this->_parentProducts[$parentId]))
450
+ $this->_parentProducts[$parentId] = Mage::getModel('catalog/product')->load($parentId);
451
+ return $this->_parentProducts[$parentId];
452
+ }
453
 
454
  public function convertNumberToWord($number)
455
  {
456
+ if(!$this->_convertNumberToWord)
457
  return $number;
458
  $dictionary = array( 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine');
459
  return $dictionary[$number];
460
  }
461
 
462
+ /**
463
+ * GZIPs a file on disk (appending .gz to the name)
464
+ *
465
+ * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
466
+ * Based on function by Kioob at:
467
+ * http://www.php.net/manual/en/function.gzwrite.php#34955
468
+ *
469
+ * @param string $source Path to file that should be compressed
470
+ * @param integer $level GZIP compression level (default: 9)
471
+ * @return string New filename (with .gz appended) if success, or false if operation fails
472
+ */
473
+ public function gzCompressFile($source, $level = 9)
474
+ {
475
+ $dest = $source . '.gz';
476
+ $mode = 'wb' . $level;
477
+ $error = false;
478
+ if ($fp_out = gzopen($dest, $mode)) {
479
+ if ($fp_in = fopen($source,'rb')) {
480
+ while (!feof($fp_in))
481
+ gzwrite($fp_out, fread($fp_in, 1024 * 512));
482
+ fclose($fp_in);
483
+ } else {
484
+ $error = true;
485
+ }
486
+ gzclose($fp_out);
487
+ } else {
488
+ $error = true;
489
+ }
490
+ if ($error)
491
+ return false;
492
+ else
493
+ return $dest;
494
+ }
495
  }
496
 
ircronscripts/intelligentreach_integration_cron_qty_price.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- /** Version 1.0.36 Last updated by Kire on 27/04/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  ini_set('memory_limit', '2G');
@@ -8,188 +8,180 @@ include_once '../app/Mage.php';
8
  umask(0);
9
  Mage::app();
10
 
11
-
12
  $ir = new IntelligentReach();
13
  $ir->run();
14
 
15
  class IntelligentReach
16
  {
17
- private $_versionDisplay = "Version 1.0.36 <br />Last updated on 27/04/2016";
18
- private $_outputDirectory = "output";
19
  private $_fileName = "Feed_Quantity_And_Price";
20
- private $_fileNameTemp = "";
21
- private $_amountOfProductsPerPage = 1000;
22
- private $_gzipFile = true;
23
-
24
- public function run()
25
- {
26
- $storeId = (isset($_GET["storeid"]))? $_GET["storeid"] : false;
27
-
28
- // If a store id was provided then print the products to the output.
29
- if ($storeId !== false)
30
- {
31
- $startTime = microtime(true);
32
- $this->_fileName = $this->_outputDirectory."/".$this->_fileName."_".$storeId.".xml"; // added store id to feed file name for multi store support.
33
  $this->_fileNameTemp = tempnam("", $this->_fileName);
34
- echo "Temp File created: ". $this->_fileNameTemp."<br />";
35
-
36
- file_put_contents($this->_fileNameTemp, '<?xml version="1.0" encoding="utf-8"?><products>', LOCK_EX);
37
- $this->runTheTask($storeId);
38
- file_put_contents($this->_fileNameTemp, '</products>', FILE_APPEND | LOCK_EX);
39
-
40
- if (!file_exists($this->_outputDirectory))
41
- mkdir($this->_outputDirectory);
42
-
43
- file_put_contents($this->_fileName, file_get_contents($this->_fileNameTemp), LOCK_EX);
44
- unlink($this->_fileNameTemp);
45
- echo "Finished Generating Feed Quantity file: '".$this->_fileName."'";
46
-
47
- if($this->_gzipFile) {
48
- $this->gzCompressFile($this->_fileName); // gzip as file is very large
49
- }
50
-
51
- echo "<br />".((microtime(true) - $startTime))." secs";
52
- echo "<br />".(memory_get_usage(true))." bytes";
53
- }
54
- else {
55
- $this->printStores();
56
- }
57
- }
58
-
59
- // Gets all the stores on the current website,
60
- // returns a table containing Store Ids and Store Names.
61
- public function getStores()
62
- {
63
- $websiteStores = Mage::app()->getStores();
64
- echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
65
- echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
66
- foreach ($websiteStores as $store)
67
- echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "'>" . $store->getName() . "</a></td></tr>";
68
- echo "</table>";
69
- }
70
-
71
- public function printStores()
72
- {
73
- echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
74
- $this->getStores();
75
- echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
76
- echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
77
- echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
78
- echo "<h5>".$this->_versionDisplay."</h5></div>";
79
- }
80
-
81
- // Gets all the products in the catalog in the specific store view,
82
- // returns a collection of products and their details.
83
- public function getProducts($page,$storeId)
84
- {
85
- if($storeId) {
86
- Mage::app()->setCurrentStore($storeId);
87
- }
88
-
89
- $products = $this->getProductCollection($storeId);
90
-
91
- // join stock item, saves having to load the stock item model.
92
- $products
93
- ->getSelect()
94
- ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage)
95
- ->joinLeft(array('si'=>'cataloginventory_stock_item'),'e.entity_id = si.product_id',
96
- array('use_config_manage_stock','manage_stock','qty','is_in_stock'))
97
- ->group('e.entity_id') // sometimes there can be duplicate stock items.
98
- ->order('e.entity_id');
99
- return $products;
100
- }
101
-
102
- public function getProductCollection($storeId)
103
- {
104
- return Mage::getModel('catalog/product')
105
- ->getCollection()
106
- ->addStoreFilter($storeId)
107
  ->addAttributeToSelect('price', 'left')
108
- ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED));
109
- }
110
 
111
- // Run the task
112
- public function runTheTask($storeId)
113
- {
114
- $currentPage = 1;
115
  $lastPage = ceil($this->getProductCollection($storeId)->getSize() / $this->_amountOfProductsPerPage);
116
-
117
- do{
118
- $products = $this->getProducts($currentPage,$storeId);
119
- echo "Starting page $currentPage of $lastPage ..";
120
- Mage::getSingleton('core/resource_iterator') // seems this ignores the current page
121
- ->walk($products->getSelect(), array(array($this, 'printProducts')));
122
- $currentPage++;
123
-
124
- $products->clear();
125
- unset($products);
126
- ob_flush();
127
- flush();
128
- echo " ".(memory_get_usage(true))." bytes ";
129
- echo ".. Finished (ok) <br />";
130
- }while($currentPage <= $lastPage);
131
-
132
- }
133
-
134
- public function printProducts($args)
135
- {
136
- $feedData = "";
137
-
138
- // We check for manage stock. This is implemented in the catalog inventory stock item model however we don't want to load the model.
139
- $manageStock = $args['row']['manage_stock'];
140
- $configManageStock = $args['row']['use_config_manage_stock'];
141
- $isInStock = $args['row']['is_in_stock'];
142
-
143
- if($configManageStock){
144
- $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
145
- }
146
-
147
- if(!$manageStock){
148
- $isInStock = true; // if we don't manage, "is in stock" is always true.
149
- }
150
-
151
- $feedData .= '<product>';
152
- $feedData .= '<entity_id><![CDATA['. $args['row']['entity_id'].']]></entity_id>';
153
- $feedData .= '<qty><![CDATA['.(int)$args['row']['qty'].']]></qty>';
154
- $feedData .= '<is_in_stock><![CDATA['.(int)$isInStock.']]></is_in_stock>';
155
  $feedData .= '<price><![CDATA['.$args['row']['price'].']]></price>';
156
- $feedData .= '</product>'.PHP_EOL;
157
 
158
  file_put_contents($this->_fileNameTemp, $feedData, FILE_APPEND | LOCK_EX);
159
- }
160
-
161
- /**
162
- * GZIPs a file on disk (appending .gz to the name)
163
- *
164
- * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
165
- * Based on function by Kioob at:
166
- * http://www.php.net/manual/en/function.gzwrite.php#34955
167
- *
168
- * @param string $source Path to file that should be compressed
169
- * @param integer $level GZIP compression level (default: 9)
170
- * @return string New filename (with .gz appended) if success, or false if operation fails
171
- */
172
- public function gzCompressFile($source, $level = 9){
173
- $dest = $source . '.gz';
174
- $mode = 'wb' . $level;
175
- $error = false;
176
- if ($fp_out = gzopen($dest, $mode)) {
177
- if ($fp_in = fopen($source,'rb')) {
178
- while (!feof($fp_in))
179
- gzwrite($fp_out, fread($fp_in, 1024 * 512));
180
- fclose($fp_in);
181
- } else {
182
- $error = true;
183
- }
184
- gzclose($fp_out);
185
- } else {
186
- $error = true;
187
- }
188
- if ($error)
189
- return false;
190
- else
191
- return $dest;
192
- }
193
-
194
-
195
  }
1
  <?php
2
 
3
+ /** Version 1.0.37 Last updated by Kire on 18/05/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  ini_set('memory_limit', '2G');
8
  umask(0);
9
  Mage::app();
10
 
 
11
  $ir = new IntelligentReach();
12
  $ir->run();
13
 
14
  class IntelligentReach
15
  {
16
+ private $_versionDisplay = "Version 1.0.37 <br />Last updated on 18/05/2016";
17
+ private $_outputDirectory = "output";
18
  private $_fileName = "Feed_Quantity_And_Price";
19
+ private $_fileNameTemp = "";
20
+ private $_amountOfProductsPerPage = 1000;
21
+ private $_gzipFile = true;
22
+
23
+ public function run()
24
+ {
25
+ $storeId = (isset($_GET["storeid"]))? $_GET["storeid"] : false;
26
+
27
+ // If a store id was provided then print the products to the output.
28
+ if ($storeId !== false)
29
+ {
30
+ $startTime = microtime(true);
31
+ $this->_fileName = $this->_outputDirectory."/".$this->_fileName."_".$storeId.".xml"; // added store id to feed file name for multi store support.
32
  $this->_fileNameTemp = tempnam("", $this->_fileName);
33
+ echo "Temp File created: ". $this->_fileNameTemp."<br />";
34
+
35
+ file_put_contents($this->_fileNameTemp, '<?xml version="1.0" encoding="utf-8"?><products version="1.0.37" type="cron">', LOCK_EX);
36
+ $this->runTheTask($storeId);
37
+ file_put_contents($this->_fileNameTemp, '</products>', FILE_APPEND | LOCK_EX);
38
+
39
+ if (!file_exists($this->_outputDirectory))
40
+ mkdir($this->_outputDirectory);
41
+
42
+ file_put_contents($this->_fileName, file_get_contents($this->_fileNameTemp), LOCK_EX);
43
+ unlink($this->_fileNameTemp);
44
+ echo "Finished Generating Feed Quantity file: '".$this->_fileName."'";
45
+
46
+ if($this->_gzipFile)
47
+ $this->gzCompressFile($this->_fileName); // gzip as file is very large
48
+
49
+ echo "<br />".((microtime(true) - $startTime))." secs";
50
+ echo "<br />".(memory_get_usage(true))." bytes";
51
+ }
52
+ else
53
+ $this->printStores();
54
+ }
55
+
56
+ // Gets all the stores on the current website,
57
+ // returns a table containing Store Ids and Store Names.
58
+ public function getStores()
59
+ {
60
+ $websiteStores = Mage::app()->getStores();
61
+ echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
62
+ echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
63
+ foreach ($websiteStores as $store)
64
+ echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "'>" . $store->getName() . "</a></td></tr>";
65
+ echo "</table>";
66
+ }
67
+
68
+ public function printStores()
69
+ {
70
+ echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
71
+ $this->getStores();
72
+ echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
73
+ echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
74
+ echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
75
+ echo "<h5>".$this->_versionDisplay."</h5></div>";
76
+ }
77
+
78
+ // Gets all the products in the catalog in the specific store view,
79
+ // returns a collection of products and their details.
80
+ public function getProducts($page,$storeId)
81
+ {
82
+ if($storeId)
83
+ Mage::app()->setCurrentStore($storeId);
84
+
85
+ $products = $this->getProductCollection($storeId);
86
+
87
+ // join stock item, saves having to load the stock item model.
88
+ $products
89
+ ->getSelect()
90
+ ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage)
91
+ ->joinLeft(array('si'=>'cataloginventory_stock_item'),'e.entity_id = si.product_id',
92
+ array('use_config_manage_stock','manage_stock','qty','is_in_stock'))
93
+ ->group('e.entity_id') // sometimes there can be duplicate stock items.
94
+ ->order('e.entity_id');
95
+ return $products;
96
+ }
97
+
98
+ public function getProductCollection($storeId)
99
+ {
100
+ return Mage::getModel('catalog/product')
101
+ ->getCollection()
102
+ ->addStoreFilter($storeId)
 
 
 
103
  ->addAttributeToSelect('price', 'left')
104
+ ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED));
105
+ }
106
 
107
+ // Run the task
108
+ public function runTheTask($storeId)
109
+ {
110
+ $currentPage = 1;
111
  $lastPage = ceil($this->getProductCollection($storeId)->getSize() / $this->_amountOfProductsPerPage);
112
+
113
+ do{
114
+ $products = $this->getProducts($currentPage,$storeId);
115
+ echo "Starting page $currentPage of $lastPage ..";
116
+ Mage::getSingleton('core/resource_iterator') // seems this ignores the current page
117
+ ->walk($products->getSelect(), array(array($this, 'printProducts')));
118
+ $currentPage++;
119
+
120
+ $products->clear();
121
+ unset($products);
122
+ ob_flush();
123
+ flush();
124
+ echo " ".(memory_get_usage(true))." bytes ";
125
+ echo ".. Finished (ok) <br />";
126
+ }while($currentPage <= $lastPage);
127
+ }
128
+
129
+ public function printProducts($args)
130
+ {
131
+ $feedData = "";
132
+
133
+ // We check for manage stock. This is implemented in the catalog inventory stock item model however we don't want to load the model.
134
+ $manageStock = $args['row']['manage_stock'];
135
+ $configManageStock = $args['row']['use_config_manage_stock'];
136
+ $isInStock = $args['row']['is_in_stock'];
137
+
138
+ if($configManageStock)
139
+ $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
140
+
141
+ if(!$manageStock)
142
+ $isInStock = true; // if we don't manage, "is in stock" is always true.
143
+
144
+ $feedData .= '<product>';
145
+ $feedData .= '<entity_id><![CDATA['. $args['row']['entity_id'].']]></entity_id>';
146
+ $feedData .= '<qty><![CDATA['.(int)$args['row']['qty'].']]></qty>';
147
+ $feedData .= '<is_in_stock><![CDATA['.(int)$isInStock.']]></is_in_stock>';
 
 
 
148
  $feedData .= '<price><![CDATA['.$args['row']['price'].']]></price>';
149
+ $feedData .= '</product>'.PHP_EOL;
150
 
151
  file_put_contents($this->_fileNameTemp, $feedData, FILE_APPEND | LOCK_EX);
152
+ }
153
+
154
+ /**
155
+ * GZIPs a file on disk (appending .gz to the name)
156
+ *
157
+ * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
158
+ * Based on function by Kioob at:
159
+ * http://www.php.net/manual/en/function.gzwrite.php#34955
160
+ *
161
+ * @param string $source Path to file that should be compressed
162
+ * @param integer $level GZIP compression level (default: 9)
163
+ * @return string New filename (with .gz appended) if success, or false if operation fails
164
+ */
165
+ public function gzCompressFile($source, $level = 9)
166
+ {
167
+ $dest = $source . '.gz';
168
+ $mode = 'wb' . $level;
169
+ $error = false;
170
+ if ($fp_out = gzopen($dest, $mode)) {
171
+ if ($fp_in = fopen($source,'rb')) {
172
+ while (!feof($fp_in))
173
+ gzwrite($fp_out, fread($fp_in, 1024 * 512));
174
+ fclose($fp_in);
175
+ } else {
176
+ $error = true;
177
+ }
178
+ gzclose($fp_out);
179
+ } else {
180
+ $error = true;
181
+ }
182
+ if ($error)
183
+ return false;
184
+ else
185
+ return $dest;
186
+ }
 
187
  }
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Intelligent_Reach</name>
4
- <version>1.0.36</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/OSL-3.0">OSL</license>
7
  <channel>community</channel>
@@ -17,9 +17,9 @@ Intelligent reach also offers advanced insight and trading services; whilst ensu
17
  Contact us to arrange a free E-commerce therapy session. Get advice about e-privacy compliance, tag management, analytics or BI implementations and Data quality as well as any key pain points or challenges which are hampering your growth.</description>
18
  <notes>Stable release. Compatible with older versions. Feed creation has been optimized to handle larger loads. The option to choose the store is now available. Can retrieve associated products for grouped types.Bug fixes.Has support for PHP V5.2. Quantity script has now been added. Flat Catalog support has been added,</notes>
19
  <authors><author><name>Intelligent Reach</name><user>IR</user><email>development@intelligentreach.com</email></author></authors>
20
- <date>2016-04-27</date>
21
- <time>15:00:21</time>
22
- <contents><target name="mage"><dir name="."><file name="intelligentreach_integration.php" hash="26713469349a9952d55dcfb872775c30"/><file name="intelligentreach_integration_qty.php" hash="dc6cf227b5a27fc732f429a3a1a49584"/></dir><dir><dir name="app"><dir name="etc"><dir name="modules"><file name="IntelligentReach_Integration.xml" hash="6cdd19a11572e7073dbb3d746b6b57b6"/><file name="IntelligentReach_AmazonPayment.xml" hash="10faf651f19ea2298217be1a95707b7c"/><file name="IntelligentReach_EbayPayment.xml" hash="eb9acbd1b55da29e10b09981f0b7af8f"/><file name="IntelligentReach_DebenhamsPayment.xml" hash="649e25d5edf93ea84ce0a35240441ecb"/><file name="IntelligentReach_LazadaPayment.xml" hash="74ebd9f7bab6023049128e6de012b52c"/><file name="IntelligentReach_PlayPayment.xml" hash="c711e18f9a79c24bcddce4143ffb6fb6"/><file name="IntelligentReach_RakutenPayment.xml" hash="d70ce1efcf60b29ecc02fcea8df1f7e9"/><file name="IntelligentReach_TradeMePayment.xml" hash="367154d17430c1000c3798454be25dcb"/><file name="IntelligentReach_WestfieldPayment.xml" hash="b0ae5878bb26f86674ce88a50876496b"/><file name="IntelligentReach_IRShipping.xml" hash="f0e21aff453dc0436541117f33d58e74"/></dir></dir><dir name="code"><dir name="local"><dir name="IntelligentReach"><dir name="Integration"><dir name="etc"><file name="config.xml" hash="21facf61b669221c185f546bfa487465"/></dir></dir><dir name="AmazonPayment"><dir name="etc"><file name="config.xml" hash="963cc3755918a01ae2775c59985e960b"/><file name="system.xml" hash="7b236978b8022dc4deda628640ea8689"/></dir><dir name="Helper"><file name="Data.php" hash="2e4ef89b210d0f992cd25b8ef5f4b96e"/></dir><dir name="Model"><file name="Pay.php" hash="4f706307986b9cd0f7cb64f69402cbd5"/></dir></dir><dir name="EbayPayment"><dir name="etc"><file name="config.xml" hash="31a77057cab9c76cc99059373907e40f"/><file name="system.xml" hash="7246fbf64d238328f74bd6445cc05b29"/></dir><dir name="Helper"><file name="Data.php" hash="0e112e22a4786f3624216628dee796a0"/></dir><dir name="Model"><file name="Pay.php" hash="9195dd4e2dbdeae9170220d78efc9f7b"/></dir></dir><dir name="DebenhamsPayment"><dir name="etc"><file name="config.xml" hash="88cfaa2d55be884a8c22d99ae6db1bdc"/><file name="system.xml" hash="fab15158ef26748821326174ca9d91eb"/></dir><dir name="Helper"><file name="Data.php" hash="24e03a8fb06b27480aae4e37f2dc54d8"/></dir><dir name="Model"><file name="Pay.php" hash="45162537d76f8c9e9ccc1ec493c59691"/></dir></dir><dir name="LazadaPayment"><dir name="etc"><file name="config.xml" hash="e23f304f60d3441178617b820c8b6356"/><file name="system.xml" hash="bf34e8ec60287c727d8221163f436c9c"/></dir><dir name="Helper"><file name="Data.php" hash="7eee4edb781ab93817979b61f314787f"/></dir><dir name="Model"><file name="Pay.php" hash="d52eafb63ab3bad2a390e2f83ebfab6e"/></dir></dir><dir name="PlayPayment"><dir name="etc"><file name="config.xml" hash="3d184a7f2f6b14ffba255befcd06efb1"/><file name="system.xml" hash="4afb9b545ca22d4043b0606222d734a6"/></dir><dir name="Helper"><file name="Data.php" hash="486d43158da7188608eb07d3c9e45845"/></dir><dir name="Model"><file name="Pay.php" hash="78432762a0020455de623fbe79166045"/></dir></dir><dir name="RakutenPayment"><dir name="etc"><file name="config.xml" hash="89a2f3d238c6d73f6d09996f8ab8e819"/><file name="system.xml" hash="6c19c11b0ad20305d3dd705a0e3f71b9"/></dir><dir name="Helper"><file name="Data.php" hash="87cc7e597d4f70a26911c861358d5695"/></dir><dir name="Model"><file name="Pay.php" hash="b52e5cb4fdb78db91c23bc929e8a70eb"/></dir></dir><dir name="TradeMePayment"><dir name="etc"><file name="config.xml" hash="8e47d2ea64ae18e39ab8a2ca02d19f34"/><file name="system.xml" hash="98893010b7a44f27611421780a09cd6a"/></dir><dir name="Helper"><file name="Data.php" hash="b789a1164f2296882e81d4dced4897a0"/></dir><dir name="Model"><file name="Pay.php" hash="74ba42a1af907d6159fcd8c507d533de"/></dir></dir><dir name="WestfieldPayment"><dir name="etc"><file name="config.xml" hash="b29ff269ecffe2c43fc3ad26a79064ca"/><file name="system.xml" hash="de52dce1e16aaa20f62253a4a22f419f"/></dir><dir name="Helper"><file name="Data.php" hash="1d1fcc723fc60d73b004173094a8499e"/></dir><dir name="Model"><file name="Pay.php" hash="d398e69f34d1b7b4105d264eccf01799"/></dir></dir><dir name="IRShipping"><dir name="etc"><file name="api.xml" hash="e6a94fbe12b32f3c7ff52d1a5e0f1641"/><file name="config.xml" hash="7e99c787b32526e643a1cb6ae6d383a9"/><file name="system.xml" hash="a8557991e72769db9da9f2ac90b0b9a5"/><file name="wsdl.xml" hash="ffc7012d4eece41205102d41c8c6b953"/><file name="wsi.xml" hash="77ce37c2b3adb664c3b9f2cc4f901388"/></dir><dir name="Model"><file name="Carrier.php" hash="262539a4ab189952a4e6f914bb0855d8"/><dir name="Cart"><file name="Api.php" hash="9eac552aecc9f4de277b4e15976ea7b5"/><dir name="Api"><file name="V2.php" hash="0f02ea1b2ba3e88d166b0fdaea8444d1"/></dir><dir name="Shipping"><file name="Api.php" hash="75a01931a00a72b74890858f1fc994a9"/><dir name="Api"><file name="V2.php" hash="ca18e89a5d9846423682dedb58e72762"/></dir></dir></dir><dir name="Quote"><dir name="Address"><dir name="Total"><file name="Shipping.php" hash="5f6b34bd1fc668481580010573091e38"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="d2d25617c465d0dce4dd52b9eac7649f"/></dir></dir></dir></dir></dir><dir name="design"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="intelligentreach_integration.xml" hash="c45eb729e1e4b5025b25c20ac2723eeb"/></dir><dir name="template"><dir name="intelligentreach_integration"><file name="intelligentreach_integration.phtml" hash="cfcf6e1c2de50fa66258a820fb296775"/><dir name="product"><file name="intelligentreach_integration.phtml" hash="0d1f3ce4a57d977d8955176b01e2f87d"/></dir><dir name="basket"><file name="intelligentreach_integration.phtml" hash="983743acab4cd1c2819ea4fb6eebe0b5"/></dir><dir name="checkout"><dir name="onepage"><file name="intelligentreach_integration.phtml" hash="dfcfe625fadaf06fb3b069cb9257b4cc"/></dir><dir name="multishipping"><file name="intelligentreach_integration.phtml" hash="206d1fe72ab530829ca274fd52e90108"/></dir></dir></dir></dir></dir></dir><dir name="enterprise"><dir name="default"><dir name="layout"><file name="intelligentreach_integration.xml" hash="c45eb729e1e4b5025b25c20ac2723eeb"/></dir><dir name="template"><dir name="intelligentreach_integration"><file name="intelligentreach_integration.phtml" hash="cfcf6e1c2de50fa66258a820fb296775"/><dir name="product"><file name="intelligentreach_integration.phtml" hash="0d1f3ce4a57d977d8955176b01e2f87d"/></dir><dir name="basket"><file name="intelligentreach_integration.phtml" hash="983743acab4cd1c2819ea4fb6eebe0b5"/></dir><dir name="checkout"><dir name="onepage"><file name="intelligentreach_integration.phtml" hash="dfcfe625fadaf06fb3b069cb9257b4cc"/></dir><dir name="multishipping"><file name="intelligentreach_integration.phtml" hash="206d1fe72ab530829ca274fd52e90108"/></dir></dir></dir></dir></dir></dir><dir name="default"><dir name="default"><dir name="layout"><file name="intelligentreach_integration.xml" hash="c45eb729e1e4b5025b25c20ac2723eeb"/></dir><dir name="template"><dir name="intelligentreach_integration"><file name="intelligentreach_integration.phtml" hash="cfcf6e1c2de50fa66258a820fb296775"/><dir name="product"><file name="intelligentreach_integration.phtml" hash="0d1f3ce4a57d977d8955176b01e2f87d"/></dir><dir name="basket"><file name="intelligentreach_integration.phtml" hash="983743acab4cd1c2819ea4fb6eebe0b5"/></dir><dir name="checkout"><dir name="onepage"><file name="intelligentreach_integration.phtml" hash="dfcfe625fadaf06fb3b069cb9257b4cc"/></dir><dir name="multishipping"><file name="intelligentreach_integration.phtml" hash="206d1fe72ab530829ca274fd52e90108"/></dir></dir></dir></dir></dir></dir></dir></dir></dir><dir name="ircronscripts"><file name="intelligentreach_integration_cron.php" hash="9a90fbbdc3200c1c5f5d6147ac667e99"/><file name="intelligentreach_integration_cron_pre.php" hash="cb2c12b375256a8dd1d56b89cc29ca42"/><file name="intelligentreach_integration_cron_qty_price.php" hash="308b327c5df24ad3404c6dd8db6281f6"/></dir></dir></target></contents>
23
  <compatible/>
24
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
25
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Intelligent_Reach</name>
4
+ <version>1.0.37</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/OSL-3.0">OSL</license>
7
  <channel>community</channel>
17
  Contact us to arrange a free E-commerce therapy session. Get advice about e-privacy compliance, tag management, analytics or BI implementations and Data quality as well as any key pain points or challenges which are hampering your growth.</description>
18
  <notes>Stable release. Compatible with older versions. Feed creation has been optimized to handle larger loads. The option to choose the store is now available. Can retrieve associated products for grouped types.Bug fixes.Has support for PHP V5.2. Quantity script has now been added. Flat Catalog support has been added,</notes>
19
  <authors><author><name>Intelligent Reach</name><user>IR</user><email>development@intelligentreach.com</email></author></authors>
20
+ <date>2016-05-18</date>
21
+ <time>13:13:30</time>
22
+ <contents><target name="mage"><dir name="."><file name="intelligentreach_integration.php" hash="025b854d090a95c8e4d0cadcb2a7effe"/><file name="intelligentreach_integration_qty.php" hash="ce4c85c014496fac485785fdfa80a4b7"/><file name="intelligentreach_integration_pre.php" hash="fadaa1f5a48eb1285535ecd3a1991957"/></dir><dir><dir name="app"><dir name="etc"><dir name="modules"><file name="IntelligentReach_Integration.xml" hash="6cdd19a11572e7073dbb3d746b6b57b6"/><file name="IntelligentReach_AmazonPayment.xml" hash="10faf651f19ea2298217be1a95707b7c"/><file name="IntelligentReach_EbayPayment.xml" hash="eb9acbd1b55da29e10b09981f0b7af8f"/><file name="IntelligentReach_DebenhamsPayment.xml" hash="649e25d5edf93ea84ce0a35240441ecb"/><file name="IntelligentReach_LazadaPayment.xml" hash="74ebd9f7bab6023049128e6de012b52c"/><file name="IntelligentReach_PlayPayment.xml" hash="c711e18f9a79c24bcddce4143ffb6fb6"/><file name="IntelligentReach_RakutenPayment.xml" hash="d70ce1efcf60b29ecc02fcea8df1f7e9"/><file name="IntelligentReach_TradeMePayment.xml" hash="367154d17430c1000c3798454be25dcb"/><file name="IntelligentReach_WestfieldPayment.xml" hash="b0ae5878bb26f86674ce88a50876496b"/><file name="IntelligentReach_IRShipping.xml" hash="f0e21aff453dc0436541117f33d58e74"/></dir></dir><dir name="code"><dir name="local"><dir name="IntelligentReach"><dir name="Integration"><dir name="etc"><file name="config.xml" hash="0b784e438516a78bca82762d1e6b2519"/></dir></dir><dir name="AmazonPayment"><dir name="etc"><file name="config.xml" hash="a1cad0a484b0ca9e8493bd50904bdc45"/><file name="system.xml" hash="7b236978b8022dc4deda628640ea8689"/></dir><dir name="Helper"><file name="Data.php" hash="2e4ef89b210d0f992cd25b8ef5f4b96e"/></dir><dir name="Model"><file name="Pay.php" hash="4f706307986b9cd0f7cb64f69402cbd5"/></dir></dir><dir name="EbayPayment"><dir name="etc"><file name="config.xml" hash="b5d5c39f624080166e7df2695c92ccec"/><file name="system.xml" hash="7246fbf64d238328f74bd6445cc05b29"/></dir><dir name="Helper"><file name="Data.php" hash="0e112e22a4786f3624216628dee796a0"/></dir><dir name="Model"><file name="Pay.php" hash="9195dd4e2dbdeae9170220d78efc9f7b"/></dir></dir><dir name="DebenhamsPayment"><dir name="etc"><file name="config.xml" hash="66e05db6779d60d2d4fdb51c4de8d1b4"/><file name="system.xml" hash="fab15158ef26748821326174ca9d91eb"/></dir><dir name="Helper"><file name="Data.php" hash="24e03a8fb06b27480aae4e37f2dc54d8"/></dir><dir name="Model"><file name="Pay.php" hash="45162537d76f8c9e9ccc1ec493c59691"/></dir></dir><dir name="LazadaPayment"><dir name="etc"><file name="config.xml" hash="9b5c6dd9f7ecdeed250ecd5c0f397ba8"/><file name="system.xml" hash="bf34e8ec60287c727d8221163f436c9c"/></dir><dir name="Helper"><file name="Data.php" hash="7eee4edb781ab93817979b61f314787f"/></dir><dir name="Model"><file name="Pay.php" hash="d52eafb63ab3bad2a390e2f83ebfab6e"/></dir></dir><dir name="PlayPayment"><dir name="etc"><file name="config.xml" hash="767175910c1d6f6048e1355392a4745b"/><file name="system.xml" hash="4afb9b545ca22d4043b0606222d734a6"/></dir><dir name="Helper"><file name="Data.php" hash="486d43158da7188608eb07d3c9e45845"/></dir><dir name="Model"><file name="Pay.php" hash="78432762a0020455de623fbe79166045"/></dir></dir><dir name="RakutenPayment"><dir name="etc"><file name="config.xml" hash="1969756f962c687f720a649d62132c09"/><file name="system.xml" hash="6c19c11b0ad20305d3dd705a0e3f71b9"/></dir><dir name="Helper"><file name="Data.php" hash="87cc7e597d4f70a26911c861358d5695"/></dir><dir name="Model"><file name="Pay.php" hash="b52e5cb4fdb78db91c23bc929e8a70eb"/></dir></dir><dir name="TradeMePayment"><dir name="etc"><file name="config.xml" hash="18bd61d1932edb195bf91b16c528bafc"/><file name="system.xml" hash="98893010b7a44f27611421780a09cd6a"/></dir><dir name="Helper"><file name="Data.php" hash="b789a1164f2296882e81d4dced4897a0"/></dir><dir name="Model"><file name="Pay.php" hash="74ba42a1af907d6159fcd8c507d533de"/></dir></dir><dir name="WestfieldPayment"><dir name="etc"><file name="config.xml" hash="b2bba57c16a2b504f68e44877f96b668"/><file name="system.xml" hash="de52dce1e16aaa20f62253a4a22f419f"/></dir><dir name="Helper"><file name="Data.php" hash="1d1fcc723fc60d73b004173094a8499e"/></dir><dir name="Model"><file name="Pay.php" hash="d398e69f34d1b7b4105d264eccf01799"/></dir></dir><dir name="IRShipping"><dir name="etc"><file name="api.xml" hash="e6a94fbe12b32f3c7ff52d1a5e0f1641"/><file name="config.xml" hash="c5f1f836e4263f50d3876f2db4d2bc17"/><file name="system.xml" hash="a8557991e72769db9da9f2ac90b0b9a5"/><file name="wsdl.xml" hash="ffc7012d4eece41205102d41c8c6b953"/><file name="wsi.xml" hash="77ce37c2b3adb664c3b9f2cc4f901388"/></dir><dir name="Model"><file name="Carrier.php" hash="262539a4ab189952a4e6f914bb0855d8"/><dir name="Cart"><file name="Api.php" hash="9eac552aecc9f4de277b4e15976ea7b5"/><dir name="Api"><file name="V2.php" hash="0f02ea1b2ba3e88d166b0fdaea8444d1"/></dir><dir name="Shipping"><file name="Api.php" hash="75a01931a00a72b74890858f1fc994a9"/><dir name="Api"><file name="V2.php" hash="ca18e89a5d9846423682dedb58e72762"/></dir></dir></dir><dir name="Quote"><dir name="Address"><dir name="Total"><file name="Shipping.php" hash="5f6b34bd1fc668481580010573091e38"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="d2d25617c465d0dce4dd52b9eac7649f"/></dir></dir></dir></dir></dir><dir name="design"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="intelligentreach_integration.xml" hash="c45eb729e1e4b5025b25c20ac2723eeb"/></dir><dir name="template"><dir name="intelligentreach_integration"><file name="intelligentreach_integration.phtml" hash="cfcf6e1c2de50fa66258a820fb296775"/><dir name="product"><file name="intelligentreach_integration.phtml" hash="0d1f3ce4a57d977d8955176b01e2f87d"/></dir><dir name="basket"><file name="intelligentreach_integration.phtml" hash="983743acab4cd1c2819ea4fb6eebe0b5"/></dir><dir name="checkout"><dir name="onepage"><file name="intelligentreach_integration.phtml" hash="dfcfe625fadaf06fb3b069cb9257b4cc"/></dir><dir name="multishipping"><file name="intelligentreach_integration.phtml" hash="206d1fe72ab530829ca274fd52e90108"/></dir></dir></dir></dir></dir></dir><dir name="enterprise"><dir name="default"><dir name="layout"><file name="intelligentreach_integration.xml" hash="c45eb729e1e4b5025b25c20ac2723eeb"/></dir><dir name="template"><dir name="intelligentreach_integration"><file name="intelligentreach_integration.phtml" hash="cfcf6e1c2de50fa66258a820fb296775"/><dir name="product"><file name="intelligentreach_integration.phtml" hash="0d1f3ce4a57d977d8955176b01e2f87d"/></dir><dir name="basket"><file name="intelligentreach_integration.phtml" hash="983743acab4cd1c2819ea4fb6eebe0b5"/></dir><dir name="checkout"><dir name="onepage"><file name="intelligentreach_integration.phtml" hash="dfcfe625fadaf06fb3b069cb9257b4cc"/></dir><dir name="multishipping"><file name="intelligentreach_integration.phtml" hash="206d1fe72ab530829ca274fd52e90108"/></dir></dir></dir></dir></dir></dir><dir name="default"><dir name="default"><dir name="layout"><file name="intelligentreach_integration.xml" hash="c45eb729e1e4b5025b25c20ac2723eeb"/></dir><dir name="template"><dir name="intelligentreach_integration"><file name="intelligentreach_integration.phtml" hash="cfcf6e1c2de50fa66258a820fb296775"/><dir name="product"><file name="intelligentreach_integration.phtml" hash="0d1f3ce4a57d977d8955176b01e2f87d"/></dir><dir name="basket"><file name="intelligentreach_integration.phtml" hash="983743acab4cd1c2819ea4fb6eebe0b5"/></dir><dir name="checkout"><dir name="onepage"><file name="intelligentreach_integration.phtml" hash="dfcfe625fadaf06fb3b069cb9257b4cc"/></dir><dir name="multishipping"><file name="intelligentreach_integration.phtml" hash="206d1fe72ab530829ca274fd52e90108"/></dir></dir></dir></dir></dir></dir></dir></dir></dir><dir name="ircronscripts"><file name="intelligentreach_integration_cron.php" hash="3aceec1070ff94beca6a6612e1d188fc"/><file name="intelligentreach_integration_cron_pre.php" hash="9515401e6467f44539866946757a8563"/><file name="intelligentreach_integration_cron_qty_price.php" hash="004b62d8894e58740c62cd75c558cea4"/></dir></dir></target></contents>
23
  <compatible/>
24
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
25
  </package>