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.
|
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.
|
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 =
|
137 |
-
|
138 |
-
$products->
|
|
|
|
|
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 |
-
|
150 |
else
|
151 |
{
|
152 |
-
|
153 |
-
|
|
|
154 |
}
|
155 |
$startPage = $startPage + 1;
|
156 |
unset($products);
|
@@ -158,12 +167,11 @@ class IntelligentReach
|
|
158 |
}
|
159 |
}
|
160 |
|
161 |
-
public function printProducts($
|
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])
|
235 |
$key = $this->convertNumberToWord($key[0]).substr($key, 1);
|
236 |
-
|
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])
|
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.
|
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.
|
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 =
|
128 |
-
|
129 |
-
|
130 |
-
$products
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
142 |
else
|
143 |
{
|
144 |
Mage::getSingleton('core/resource_iterator')
|
145 |
->walk($products->getSelect(), array(array($this, 'printProducts')));
|
146 |
}
|
147 |
-
$startPage
|
148 |
unset($products);
|
149 |
flush();
|
150 |
}
|
@@ -152,15 +167,24 @@ class IntelligentReach
|
|
152 |
|
153 |
public function printProducts($args)
|
154 |
{
|
155 |
-
|
156 |
-
|
157 |
-
$
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
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-
|
21 |
-
<time>
|
22 |
-
<contents><target name="mage"><dir name="."><file name="intelligentreach_integration.php" hash="
|
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>
|