Intelligent_Reach - Version 1.0.36

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.36
Comparing to
See all releases


Code changes from version 1.0.35 to 1.0.36

intelligentreach_integration.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- /** Version 1.0.35 Last updated by Kire on 03/02/2016 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  include_once 'app/Mage.php';
@@ -15,20 +15,19 @@ class IntelligentReach
15
  private $_splitby = 100;
16
  private $_amountOfProductsPerPage = 100;
17
  private $_lastPageNumber = 0;
18
- private $_versionDisplay = "Version 1.0.35 <br />Last updated on 03/02/2016";
19
 
20
  public function run()
21
  {
22
- $prodcoll = $this->getProducts(1);
23
- $this->_lastPageNumber = $prodcoll->getLastPageNumber();
24
- if (isset($_GET["splitby"]))
25
- $this->_splitby = $_GET["splitby"];
26
- if (isset($_GET["amountofproducts"]))
27
- $this->_amountOfProductsPerPage = $_GET["amountofproducts"];
28
-
29
  // If a store id was provided then print the products to the output.
30
  if ($this->storeIsSelected())
31
  {
 
 
 
 
 
 
32
  if ((isset($_GET["startingpage"]) && isset($_GET["endpage"])) || isset($_GET["getall"]))
33
  {
34
  header("Content-Type: text/xml; charset=UTF-8");
@@ -74,7 +73,7 @@ class IntelligentReach
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
  {
@@ -133,11 +132,20 @@ class IntelligentReach
133
  if(isset($_GET["storeid"]))
134
  Mage::app()->setCurrentStore($_GET["storeid"]);
135
 
136
- $products = Mage::getModel('catalog/product')->getCollection()->addStoreFilter($_GET["storeid"]);
137
- $products->setPage($page, $this->_amountOfProductsPerPage);
138
- $products->addAttributeToSelect('*');
 
 
139
  return $products;
140
  }
 
 
 
 
 
 
 
141
 
142
  // Run the task
143
  public function runTheTask($startPage, $endPage)
@@ -146,11 +154,12 @@ class IntelligentReach
146
  {
147
  $products = $this->getProducts($startPage);
148
  if ($products->count() == 0)
149
- $this->_log('There are no products to export', true);
150
  else
151
  {
152
- Mage::getSingleton('core/resource_iterator')
153
- ->walk($products->getSelect(), array(array($this, 'printProducts')));
 
154
  }
155
  $startPage = $startPage + 1;
156
  unset($products);
@@ -158,12 +167,11 @@ class IntelligentReach
158
  }
159
  }
160
 
161
- public function printProducts($args)
162
  {
163
  $parentIds = null;
164
  $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
165
-
166
- $product = Mage::getModel('catalog/product')->load($args['row']['entity_id']);
167
  if ($product->getTypeId() == 'simple')
168
  {
169
  $parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
@@ -209,6 +217,20 @@ class IntelligentReach
209
  if((isset($parentProduct)) && ($parentProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED))
210
  $value = "Disabled";
211
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
  if(is_array($value))
214
  {
@@ -231,9 +253,9 @@ class IntelligentReach
231
  $value = "<![CDATA[$value]]>";
232
 
233
  $key = str_replace('"', '', $key);
234
- if(is_numeric($key[0]) && isset($_GET["convertNumberToWord"]))
235
  $key = $this->convertNumberToWord($key[0]).substr($key, 1);
236
- echo '<' . $key . '>' . $value . '</' . $key . '>';
237
  }
238
  }
239
 
@@ -332,8 +354,6 @@ class IntelligentReach
332
  echo '<ir_longest_category_path><![CDATA['.$path.']]></ir_longest_category_path>';
333
  /** End of New longest Category Path code **/
334
 
335
-
336
-
337
  echo '</product>';
338
  if (is_object($parentIds))
339
  unset($parentIds);
@@ -378,7 +398,7 @@ class IntelligentReach
378
  $value = "<![CDATA[$value]]>";
379
 
380
  $key = str_replace('"', '', $key);
381
- if(is_numeric($key[0]) && isset($_GET["convertNumberToWord"]))
382
  $key = $this->convertNumberToWord($key[0]).substr($key, 1);
383
  echo '<ir_parent_' . $key . '>' . $value . '</ir_parent_' . $key . '>';
384
 
@@ -394,6 +414,8 @@ class IntelligentReach
394
 
395
  public function convertNumberToWord($number)
396
  {
 
 
397
  $dictionary = array( 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine');
398
  return $dictionary[$number];
399
  }
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';
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");
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
  {
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)
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);
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());
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
  {
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
 
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);
398
  $value = "<![CDATA[$value]]>";
399
 
400
  $key = str_replace('"', '', $key);
401
+ if(is_numeric($key[0]))
402
  $key = $this->convertNumberToWord($key[0]).substr($key, 1);
403
  echo '<ir_parent_' . $key . '>' . $value . '</ir_parent_' . $key . '>';
404
 
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
  }
intelligentreach_integration_qty.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- /** Version 1.0.35 Last updated by Kire on 24/09/2015 **/
4
  ini_set('display_errors', 1);
5
  ini_set('max_execution_time', 1800);
6
  include_once 'app/Mage.php';
@@ -16,20 +16,19 @@ class IntelligentReach
16
  private $_splitby = 100;
17
  private $_amountOfProductsPerPage = 100;
18
  private $_lastPageNumber = 0;
19
- private $_versionDisplay = "Version 1.0.35 <br />Last updated on 24/09/2015";
20
 
21
  public function run()
22
  {
23
- $prodcoll = $this->getProducts(1);
24
- $this->_lastPageNumber = $prodcoll->getLastPageNumber();
25
- if (isset($_GET["splitby"]))
26
- $this->_splitby = $_GET["splitby"];
27
- if (isset($_GET["amountofproducts"]))
28
- $this->_amountOfProductsPerPage = $_GET["amountofproducts"];
29
-
30
  // If a store id was provided then print the products to the output.
31
  if ($this->storeIsSelected())
32
  {
 
 
 
 
 
 
33
  if ((isset($_GET["startingpage"]) && isset($_GET["endpage"])) || isset($_GET["getall"]))
34
  {
35
  header("Content-Type: text/xml; charset=UTF-8");
@@ -123,13 +122,29 @@ class IntelligentReach
123
  {
124
  if(isset($_GET["storeid"]))
125
  Mage::app()->setCurrentStore($_GET["storeid"]);
126
-
127
- $products = Mage::getModel('catalog/product')->getCollection()->addStoreFilter($_GET["storeid"]);
128
- $products->setPage($page, $this->_amountOfProductsPerPage);
129
- $products->addAttributeToSelect('*');
130
- $products->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED));
 
 
 
 
 
 
 
131
  return $products;
132
  }
 
 
 
 
 
 
 
 
 
133
 
134
  // Run the task
135
  public function runTheTask($startPage, $endPage)
@@ -138,13 +153,13 @@ class IntelligentReach
138
  {
139
  $products = $this->getProducts($startPage);
140
  if ($products->count() == 0)
141
- $this->_log('There are no products to export', true);
142
  else
143
  {
144
  Mage::getSingleton('core/resource_iterator')
145
  ->walk($products->getSelect(), array(array($this, 'printProducts')));
146
  }
147
- $startPage = $startPage + 1;
148
  unset($products);
149
  flush();
150
  }
@@ -152,15 +167,24 @@ class IntelligentReach
152
 
153
  public function printProducts($args)
154
  {
155
- $product = Mage::getModel('catalog/product')->load($args['row']['entity_id']);
156
-
157
- $inventoryProduct = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
158
- echo'<product>';
159
- echo '<entity_id><![CDATA['.$inventoryProduct->getProductId().']]></entity_id>';
160
- echo '<qty><![CDATA['.(int)$inventoryProduct->getQty().']]></qty>';
161
- echo '<is_in_stock><![CDATA['.(int)$inventoryProduct->getIsInStock().']]></is_in_stock>';
 
 
 
 
 
 
 
 
 
 
 
162
  echo '</product>';
163
-
164
- $product->clearInstance();
165
  }
166
  }
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';
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");
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)
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
  }
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
  }
ircronscripts/intelligentreach_integration_cron.php ADDED
@@ -0,0 +1,503 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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');
7
+ include_once '../app/Mage.php';
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.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";
59
+ }
60
+ else
61
+ $this->printStores();
62
+ }
63
+
64
+ // Check if a storeid parameter has been set, returns a boolean.
65
+ public function storeIsSelected()
66
+ {
67
+ if (isset($_GET["storeid"]))
68
+ return true;
69
+ else
70
+ return false;
71
+ }
72
+
73
+ // Gets all the stores on all websites,
74
+ // returns a table containing Store Ids and Store Names.
75
+ public function getStores()
76
+ {
77
+ $websiteStores = Mage::app()->getStores();
78
+ echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
79
+ echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
80
+ foreach ($websiteStores as $store)
81
+ echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "'>" . $store->getName() . "</a></td></tr>";
82
+ echo "</table>";
83
+ }
84
+
85
+ public function printStores()
86
+ {
87
+ echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
88
+ $this->getStores();
89
+ echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
90
+ echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
91
+ echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
92
+ echo "<h3>Other options</h3>";
93
+ echo "<p>To enable the stripping of invalid XML characters add the <strong>'stripInvalidChars'</strong> parameter</p>";
94
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>stripInvalidChars=1</strong></p>";
95
+ 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>";
96
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>convertNumberToWord=1</strong></p>";
97
+ echo "<p>To return all the parent product fields, use the <strong>'includeAllParentFields'</strong> parameter.</p>";
98
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>includeAllParentFields=1</strong></p>";
99
+ echo "<h5>".$this->_versionDisplay."</h5></div>";
100
+ }
101
+
102
+ /**
103
+ * @param $page
104
+ * @param $storeId
105
+ * @return Mage_Catalog_Model_Resource_Product_Collection
106
+ */
107
+ public function getProducts($page,$storeId)
108
+ {
109
+ if($storeId) {
110
+ Mage::app()->setCurrentStore($storeId);
111
+ }
112
+
113
+ $products = $this->getProductCollection($storeId);
114
+
115
+ // use limit otherwise resource iterator will ignore the page unless we load the collection first.
116
+ // previously this was loaded when count was called.
117
+ $products->getSelect()
118
+ ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage);
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)
165
+ {
166
+ $parentIds = null;
167
+ $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
168
+ $feedData = "";
169
+
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)
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
+ $feedData .= " <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
+ $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
+ }
244
+
245
+ if(version_compare(PHP_VERSION, '5.4.0', '>='))
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>';
267
+ $feedData .= '<ir_parent_sku><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getSku()).']]></ir_parent_sku>';
268
+ $feedData .= '<ir_parent_url><![CDATA[' . $this->stripInvalidXMLCharacters(trim(str_replace('/intelligentreach_integration.php', '', $parentProduct->getProductUrl()))) . ']]></ir_parent_url>';
269
+ $feedData .= '<ir_parent_image><![CDATA['.$this->stripInvalidXMLCharacters($baseUrl . 'media/catalog/product' . $parentProduct->getImage()).']]></ir_parent_image>';
270
+ }
271
+ $gallery = $parentProduct->getMediaGallery();
272
+ if(count($gallery['images']) != 0)
273
+ {
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
+
298
+ $lastPageNumber = $categories->getLastPageNumber();
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) != "")
367
+ {
368
+ if(preg_match('/('.$this->getIntelligentReachCategoryExclusions($storeId).')/i', $catPath) != true)
369
+ array_push($validCategoryPaths, $catPath);
370
+ }
371
+ else
372
+ array_push($validCategoryPaths, $catPath);
373
+ }
374
+ }
375
+
376
+ if(count($validCategoryPaths) != 0)
377
+ {
378
+ if(count($validCategoryPaths) > 1)
379
+ usort($validCategoryPaths, function ($a, $b) { return (strlen($a) < strlen($b)); });
380
+ $feedData .= "<ir_longest_category_path><![CDATA[".$validCategoryPaths[0]."]]></ir_longest_category_path>";
381
+ }
382
+ else if($output != "")
383
+ $feedData .= '<ir_longest_category_path><![CDATA['.$output.']]></ir_longest_category_path>';
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
+ {
404
+ $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
405
+ $parentFeedData = "";
406
+ foreach ($parentProduct->getData() as $key => $value)
407
+ {
408
+ if ($parentProduct->getResource()->getAttribute($key) != null)
409
+ $value = $parentProduct->getResource()->getAttribute($key)->getFrontend()->getValue($parentProduct);
410
+
411
+ if (($key == 'url_path') || ($key == 'url_key'))
412
+ $value = trim(str_replace('/intelligentreach_integration.php', '', $parentProduct->getProductUrl()));
413
+
414
+ if ($key == 'image')
415
+ $value = $baseUrl . "media/catalog/product" . $value;
416
+
417
+ if ($key == 'thumbnail')
418
+ $value = $baseUrl . "media/catalog/product" . $value;
419
+
420
+ if(is_array($value))
421
+ {
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
+ }
431
+ if(version_compare(PHP_VERSION, '5.4.0', '>='))
432
+ $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
433
+ else
434
+ $value = htmlentities($value, ENT_COMPAT, "UTF-8");
435
+ $value = $this->stripInvalidXMLCharacters($value);
436
+
437
+ $value = "<![CDATA[$value]]>";
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);
445
+ }
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
+
ircronscripts/intelligentreach_integration_cron_pre.php ADDED
@@ -0,0 +1,502 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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');
7
+ include_once '../app/Mage.php';
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.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";
59
+ }
60
+ else
61
+ $this->printStores();
62
+ }
63
+
64
+ // Check if a storeid parameter has been set, returns a boolean.
65
+ public function storeIsSelected()
66
+ {
67
+ if (isset($_GET["storeid"]))
68
+ return true;
69
+ else
70
+ return false;
71
+ }
72
+
73
+ // Gets all the stores on all websites,
74
+ // returns a table containing Store Ids and Store Names.
75
+ public function getStores()
76
+ {
77
+ $websiteStores = Mage::app()->getStores();
78
+ echo "<table cellspacing='2px;' border='1px;' cellpadding='8px;'>";
79
+ echo "<tr><th>Store Id</th><th>Store Name</th></tr>";
80
+ foreach ($websiteStores as $store)
81
+ echo "<tr><td>" . $store->getId() . "</td><td><a href='?storeid=" . $store->getId() . "'>" . $store->getName() . "</a></td></tr>";
82
+ echo "</table>";
83
+ }
84
+
85
+ public function printStores()
86
+ {
87
+ echo "<p>Sorry a Store Id was not provided, please choose a store from the options below.</p>";
88
+ $this->getStores();
89
+ echo "<p>If you want to skip this step in the future, you can manually enter the Store Id in the URL.<br />";
90
+ echo "e.g. http://www.exampledomain.com/intelligentreach_integration.php?storeid=1</p>";
91
+ echo "<p><strong>NB:</strong> The Store Id parameter name is case sensitive. Only use \"storeid=\" not another variation.</p>";
92
+ echo "<h3>Other options</h3>";
93
+ echo "<p>To enable the stripping of invalid XML characters add the <strong>'stripInvalidChars'</strong> parameter</p>";
94
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>stripInvalidChars=1</strong></p>";
95
+ 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>";
96
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>convertNumberToWord=1</strong></p>";
97
+ echo "<p>To return all the parent product fields, use the <strong>'includeAllParentFields'</strong> parameter.</p>";
98
+ echo "<strong>e.g.</strong> http://www.exampledomain.com/intelligentreach_integration.php?storeid=1&<strong>includeAllParentFields=1</strong></p>";
99
+ echo "<h5>".$this->_versionDisplay."</h5></div>";
100
+ }
101
+
102
+ /**
103
+ * @param $page
104
+ * @param $storeId
105
+ * @return Mage_Catalog_Model_Resource_Product_Collection
106
+ */
107
+ public function getProducts($page,$storeId)
108
+ {
109
+ if($storeId) {
110
+ Mage::app()->setCurrentStore($storeId);
111
+ }
112
+
113
+ $products = $this->getProductCollection($storeId);
114
+
115
+ // use limit otherwise resource iterator will ignore the page unless we load the collection first.
116
+ // previously this was loaded when count was called.
117
+ $products->getSelect()
118
+ ->limit($this->_amountOfProductsPerPage,($page - 1) * $this->_amountOfProductsPerPage);
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)
164
+ {
165
+ $parentIds = null;
166
+ $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
167
+ $feedData = "";
168
+
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)
182
+ {
183
+ if ($key !== 'stock_item')
184
+ {
185
+ if ($product->getResource()->getAttribute($key) != null)
186
+ $value = $product->getResource()->getAttribute($key)->getFrontend()->getValue($product);
187
+
188
+ if (($key == 'url_path') || ($key == 'url_key'))
189
+ $value = trim(str_replace('/intelligentreach_integration.php', '', $product->getProductUrl()));
190
+
191
+ if ($key == 'image')
192
+ $value = $baseUrl . "media/catalog/product" . $value;
193
+
194
+ if ($key == 'thumbnail')
195
+ $value = $baseUrl . "media/catalog/product" . $value;
196
+
197
+ if (($value == '') && (isset($parentProduct)))
198
+ {
199
+ $attr = $parentProduct->getResource()->getAttribute($key);
200
+ if (!is_object($attr))
201
+ continue;
202
+ $value = $attr->getFrontend()->getValue($parentProduct);
203
+ }
204
+
205
+ // Print out all media gallery images.
206
+ if($key == 'media_gallery')
207
+ {
208
+ for($i = 0; $i < count($value['images']); $i++)
209
+ $feedData .= " <image_".($i + 1)."><![CDATA[". $baseUrl . "media/catalog/product" . $value['images'][$i]['file']."]]></image_".($i + 1).">";
210
+ continue;
211
+ }
212
+ if($key == 'status')
213
+ {
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
+ }
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
+ $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>';
266
+ $feedData .= '<ir_parent_sku><![CDATA['.$this->stripInvalidXMLCharacters($parentProduct->getSku()).']]></ir_parent_sku>';
267
+ $feedData .= '<ir_parent_url><![CDATA[' . $this->stripInvalidXMLCharacters(trim(str_replace('/intelligentreach_integration.php', '', $parentProduct->getProductUrl()))) . ']]></ir_parent_url>';
268
+ $feedData .= '<ir_parent_image><![CDATA['.$this->stripInvalidXMLCharacters($baseUrl . 'media/catalog/product' . $parentProduct->getImage()).']]></ir_parent_image>';
269
+ }
270
+ $gallery = $parentProduct->getMediaGallery();
271
+ if(count($gallery['images']) != 0)
272
+ {
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
+
297
+ $lastPageNumber = $categories->getLastPageNumber();
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) != "")
366
+ {
367
+ if(preg_match('/('.$this->getIntelligentReachCategoryExclusions($storeId).')/i', $catPath) != true)
368
+ array_push($validCategoryPaths, $catPath);
369
+ }
370
+ else
371
+ array_push($validCategoryPaths, $catPath);
372
+ }
373
+ }
374
+
375
+ if(count($validCategoryPaths) != 0)
376
+ {
377
+ if(count($validCategoryPaths) > 1)
378
+ usort($validCategoryPaths, function ($a, $b) { return (strlen($a) < strlen($b)); });
379
+ $feedData .= "<ir_longest_category_path><![CDATA[".$validCategoryPaths[0]."]]></ir_longest_category_path>";
380
+ }
381
+ else if($output != "")
382
+ $feedData .= '<ir_longest_category_path><![CDATA['.$output.']]></ir_longest_category_path>';
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
+ {
403
+ $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
404
+ $parentFeedData = "";
405
+ foreach ($parentProduct->getData() as $key => $value)
406
+ {
407
+ if ($parentProduct->getResource()->getAttribute($key) != null)
408
+ $value = $parentProduct->getResource()->getAttribute($key)->getFrontend()->getValue($parentProduct);
409
+
410
+ if (($key == 'url_path') || ($key == 'url_key'))
411
+ $value = trim(str_replace('/intelligentreach_integration.php', '', $parentProduct->getProductUrl()));
412
+
413
+ if ($key == 'image')
414
+ $value = $baseUrl . "media/catalog/product" . $value;
415
+
416
+ if ($key == 'thumbnail')
417
+ $value = $baseUrl . "media/catalog/product" . $value;
418
+
419
+ if(is_array($value))
420
+ {
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
+ }
430
+ if(version_compare(PHP_VERSION, '5.4.0', '>='))
431
+ $value = htmlentities($value, ENT_COMPAT | ENT_SUBSTITUTE, "UTF-8");
432
+ else
433
+ $value = htmlentities($value, ENT_COMPAT, "UTF-8");
434
+ $value = $this->stripInvalidXMLCharacters($value);
435
+
436
+ $value = "<![CDATA[$value]]>";
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);
444
+ }
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
+
ircronscripts/intelligentreach_integration_cron_qty_price.php ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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');
7
+ 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
+ }
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Intelligent_Reach</name>
4
- <version>1.0.35</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-02-03</date>
21
- <time>13:23:47</time>
22
- <contents><target name="mage"><dir name="."><file name="intelligentreach_integration.php" hash="885942f573091021a3ca96fe3821990d"/><file name="intelligentreach_integration_qty.php" hash="be91c9662955f12636ae78736dad78fe"/></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></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.36</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-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>