Fontis_Australia - Version 2.2.4

Version Notes

Currently active are modules for BPAY, direct deposit, Australia Post, the addition of regions and postcodes, and the addition of ABN and phone number to the general configuration values (although currently not in use).

Download this release

Release Info

Developer Chris Norton
Extension Fontis_Australia
Version 2.2.4
Comparing to
See all releases


Code changes from version 2.0.7 to 2.2.4

Files changed (43) hide show
  1. app/code/community/Fontis/Australia/Block/Autocomplete.php +29 -20
  2. app/code/community/Fontis/Australia/Block/Getprice.php +87 -0
  3. app/code/community/Fontis/Australia/Block/Googleproducts.php +88 -0
  4. app/code/community/Fontis/Australia/Block/Myshopping.php +10 -6
  5. app/code/community/Fontis/Australia/Block/Shopbot.php +8 -4
  6. app/code/community/Fontis/Australia/Block/Shoppingdotcom.php +86 -0
  7. app/code/community/Fontis/Australia/Model/Child.php +100 -0
  8. app/code/community/Fontis/Australia/Model/Config/Condition.php +13 -0
  9. app/code/community/Fontis/Australia/Model/FeedCronBase.php +281 -0
  10. app/code/community/Fontis/Australia/Model/Getprice.php +69 -0
  11. app/code/community/Fontis/Australia/Model/Getprice/Cron.php +69 -175
  12. app/code/community/Fontis/Australia/Model/Googleproducts.php +61 -0
  13. app/code/community/Fontis/Australia/Model/Googleproducts/Cron.php +180 -0
  14. app/code/community/Fontis/Australia/Model/Myshopping.php +57 -0
  15. app/code/community/Fontis/Australia/Model/Myshopping/Cron.php +52 -138
  16. app/code/community/Fontis/Australia/Model/Mysql4/Shipping/Carrier/Eparcel.php +53 -6
  17. app/code/community/Fontis/Australia/Model/Payment/Directdeposit.php +7 -4
  18. app/code/community/Fontis/Australia/Model/Shipping/Carrier/Australiapost.php +259 -287
  19. app/code/community/Fontis/Australia/Model/Shipping/Carrier/Eparcel.php +55 -1
  20. app/code/community/Fontis/Australia/Model/Shipping/Carrier/Eparcel/Export/Abstract.php +164 -0
  21. app/code/community/Fontis/Australia/Model/Shipping/Carrier/Eparcel/Export/Csv.php +303 -0
  22. app/code/community/Fontis/Australia/Model/Shipping/Carrier/Eparcel/Export/Exception.php +7 -0
  23. app/{design/frontend/default/default/template/fontis/australia/payment/bpay/form.phtml → code/community/Fontis/Australia/Model/Shipping/Config/Shippingmethods.php} +20 -12
  24. app/{design/frontend/default/default/template/fontis/australia/payment/bpay/info.phtml → code/community/Fontis/Australia/Model/Shopbot.php} +19 -7
  25. app/code/community/Fontis/Australia/Model/Shopbot/Cron.php +44 -149
  26. app/code/community/Fontis/Australia/Model/Shoppingdotcom.php +104 -0
  27. app/code/community/Fontis/Australia/Model/Shoppingdotcom/Cron.php +89 -0
  28. app/code/community/Fontis/Australia/controllers/EparcelController.php +42 -0
  29. app/code/community/Fontis/Australia/etc/config.xml +159 -120
  30. app/code/community/Fontis/Australia/etc/system.xml +350 -10
  31. app/code/community/Fontis/Australia/sql/australia_setup/mysql4-install-0.7.0.php +10 -1
  32. app/code/community/Fontis/Australia/sql/australia_setup/mysql4-install-2.2.0.php +131 -0
  33. app/code/community/Fontis/Australia/sql/australia_setup/mysql4-install-2.2.2.php +140 -0
  34. app/{design/frontend/default/default/template/fontis/australia/payment/directdeposit/info.phtml → code/community/Fontis/Australia/sql/australia_setup/mysql4-upgrade-2.1.0-2.2.0.php} +8 -9
  35. app/code/community/Fontis/Australia/sql/australia_setup/mysql4-upgrade-2.2.1-2.2.2.php +31 -0
  36. app/code/community/Fontis/Australia/sql/australia_setup/postcodes.csv +16933 -0
  37. app/design/frontend/default/default/layout/fontis_australia.xml +0 -45
  38. app/design/frontend/default/default/template/fontis/australia/payment/bpay/success.phtml +0 -40
  39. app/design/frontend/default/default/template/fontis/australia/payment/directdeposit/form.phtml +0 -41
  40. app/design/frontend/default/default/template/fontis/australia/payment/directdeposit/success.phtml +0 -38
  41. app/design/frontend/default/default/template/fontis/australia/postcode-checkout.phtml +0 -84
  42. app/design/frontend/default/default/template/fontis/australia/postcode.phtml +0 -55
  43. package.xml +7 -7
app/code/community/Fontis/Australia/Block/Autocomplete.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Fontis Australia Extension
4
  *
@@ -24,34 +25,42 @@
24
  */
25
  class Fontis_Australia_Block_Autocomplete extends Mage_Core_Block_Abstract
26
  {
 
27
  protected function _toHtml()
28
  {
29
  $html = '';
30
 
31
- if (!$this->_beforeToHtml()) {
32
- return $html;
33
- }
34
-
35
- // Get the text that the customer has entered as a query.
36
- $query = $this->helper('australia')->getQueryText();
37
- $country = $this->helper('australia')->getQueryCountry();
38
- if($country != "AU") return $html;
39
-
40
- $conn = Mage::getModel('Core/Mysql4_Config')->getReadConnection();
41
- $resultArray = $conn->fetchAll('SELECT au.*, dcr.region_id FROM au_postcode AS au
42
- INNER JOIN directory_country_region AS dcr ON au.region_code = dcr.code
43
- WHERE city LIKE \'%' . $query . '%\' ORDER BY city, region_code');
44
-
45
- $html = '<ul>';
46
- $counter = 0;
47
- foreach ($resultArray as $item) {
48
- $html .= '<li class="'.((++$counter)%2?'odd':'even').'" id="region-' . $item['region_id'] . '-postcode-' . $item['postcode'] . '">';
 
 
 
 
 
 
49
  $html .= $item['city'] . '<span class="informal"> ' . $item['region_code'] . ', ' . $item['postcode'] . '</span>';
50
  $html .= '</li>';
51
- }
52
 
53
- $html.= '</ul>';
54
 
55
  return $html;
56
  }
 
57
  }
1
  <?php
2
+
3
  /**
4
  * Fontis Australia Extension
5
  *
25
  */
26
  class Fontis_Australia_Block_Autocomplete extends Mage_Core_Block_Abstract
27
  {
28
+
29
  protected function _toHtml()
30
  {
31
  $html = '';
32
 
33
+ if (!$this->_beforeToHtml()) {
34
+ return $html;
35
+ }
36
+
37
+ // Get the text that the customer has entered as a query.
38
+ $query = $this->helper('australia')->getQueryText();
39
+ $country = $this->helper('australia')->getQueryCountry();
40
+ if ($country != "AU") {
41
+ return $html;
42
+ }
43
+
44
+ /* @var $conn Varien_Db_Adapter_Pdo_Mysql */
45
+ $conn = Mage::getSingleton('core/resource')->getConnection('australia_read');
46
+ $resultArray = $conn->fetchAll(
47
+ 'SELECT au.*, dcr.region_id FROM ' . Mage::getSingleton('core/resource')->getTableName('australia_postcode') . ' AS au
48
+ INNER JOIN ' . Mage::getSingleton('core/resource')->getTableName('directory_country_region') . ' AS dcr ON au.region_code = dcr.code
49
+ WHERE city LIKE :city ORDER BY city, region_code',
50
+ array('city' => $query)
51
+ );
52
+
53
+ $html = '<ul>';
54
+ $counter = 0;
55
+ foreach ($resultArray as $item) {
56
+ $html .= '<li class="' . ((++$counter) % 2 ? 'odd' : 'even') . '" id="region-' . $item['region_id'] . '-postcode-' . $item['postcode'] . '">';
57
  $html .= $item['city'] . '<span class="informal"> ' . $item['region_code'] . ', ' . $item['postcode'] . '</span>';
58
  $html .= '</li>';
59
+ }
60
 
61
+ $html.= '</ul>';
62
 
63
  return $html;
64
  }
65
+
66
  }
app/code/community/Fontis/Australia/Block/Getprice.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis Australia Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com and you will be sent a copy immediately.
14
+ *
15
+ * @category Fontis
16
+ * @package Fontis_Australia
17
+ * @author Tom Greenaway
18
+ * @copyright Copyright (c) 2008 Fontis Pty. Ltd. (http://www.fontis.com.au)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+ class Fontis_Australia_Block_Getprice extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
22
+ {
23
+ protected $magentoOptions = array('final_price' => 'final_price', 'product_num' => 'product_num', "link" => "link", "category" => "category", "image_url" => "image_url", "currency" => "currency");
24
+
25
+ public function __construct()
26
+ {
27
+ $this->addColumn('magento', array(
28
+ 'label' => Mage::helper('adminhtml')->__('Magento product attribute'),
29
+ 'size' => 28,
30
+ ));
31
+ $this->addColumn('xmlfeed', array(
32
+ 'label' => Mage::helper('adminhtml')->__('Getprice feed tag'),
33
+ 'size' => 28
34
+ ));
35
+ $this->_addAfter = false;
36
+ $this->_addButtonLabel = Mage::helper('adminhtml')->__('Add linked attribute');
37
+
38
+ parent::__construct();
39
+ $this->setTemplate('fontis/australia/system/config/form/field/array_dropdown.phtml');
40
+
41
+ // product options
42
+ $eav_config_model = Mage::getModel('eav/config');
43
+ $attributes = $eav_config_model->getEntityAttributeCodes('catalog_product');
44
+
45
+ foreach($attributes as $att_code)
46
+ {
47
+ $attribute = $eav_config_model->getAttribute('catalog_product', $att_code);
48
+ Mage::log($attribute);
49
+
50
+ if ($att_code != '')
51
+ {
52
+ $this->magentoOptions[$att_code] = $att_code;
53
+ }
54
+ }
55
+ asort($this->magentoOptions);
56
+ }
57
+
58
+ protected function _renderCellTemplate($columnName)
59
+ {
60
+ if (empty($this->_columns[$columnName])) {
61
+ throw new Exception('Wrong column name specified.');
62
+ }
63
+ $column = $this->_columns[$columnName];
64
+ $inputName = $this->getElement()->getName() . '[#{_id}][' . $columnName . ']';
65
+
66
+ if($columnName == 'magento')
67
+ {
68
+ $rendered = '<select name="'.$inputName.'">';
69
+ foreach($this->magentoOptions as $att => $name)
70
+ {
71
+ $rendered .= '<option value="'.$att.'">'.$name.'</option>';
72
+ }
73
+ $rendered .= '</select>';
74
+ }
75
+ else
76
+ {
77
+ $rendered = '<select name="' . $inputName . '">';
78
+ $model = Mage::getModel('australia/getprice');
79
+ foreach ($model->available_fields as $field) {
80
+ $rendered .= '<option value="'.$field.'">'.str_replace("_", " ", $field)."</option>";
81
+ }
82
+ $rendered .= '</select>';
83
+ }
84
+
85
+ return $rendered;
86
+ }
87
+ }
app/code/community/Fontis/Australia/Block/Googleproducts.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis Australia Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com and you will be sent a copy immediately.
14
+ *
15
+ * @category Fontis
16
+ * @package Fontis_Australia
17
+ * @author Peter Spiller
18
+ * @copyright Copyright (c) 2008 Fontis Pty. Ltd. (http://www.fontis.com.au)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+ class Fontis_Australia_Block_Googleproducts extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
22
+ {
23
+ // Map in some of the values not normally visible
24
+ protected $magentoOptions = array('is_salable' => 'is_saleable', 'manufacturer_name' => 'manufacturer_name', 'final_price' => 'final_price');
25
+
26
+ public function __construct()
27
+ {
28
+ $this->addColumn('magento', array(
29
+ 'label' => Mage::helper('adminhtml')->__('Magento product attribute'),
30
+ 'size' => 28,
31
+ ));
32
+ $this->addColumn('xmlfeed', array(
33
+ 'label' => Mage::helper('adminhtml')->__('Google Products feed tag'),
34
+ 'size' => 28
35
+ ));
36
+ $this->_addAfter = false;
37
+ $this->_addButtonLabel = Mage::helper('adminhtml')->__('Add linked attribute');
38
+
39
+ parent::__construct();
40
+ $this->setTemplate('fontis/australia/system/config/form/field/array_dropdown.phtml');
41
+
42
+ // product options
43
+ $eav_config_model = Mage::getModel('eav/config');
44
+ $attributes = $eav_config_model->getEntityAttributeCodes('catalog_product');
45
+
46
+ foreach($attributes as $att_code)
47
+ {
48
+ $attribute = $eav_config_model->getAttribute('catalog_product', $att_code);
49
+ if ($att_code != '')
50
+ {
51
+ $this->magentoOptions[$att_code] = $att_code;
52
+ }
53
+ }
54
+ asort($this->magentoOptions);
55
+ }
56
+
57
+ protected function _renderCellTemplate($columnName)
58
+ {
59
+ if (empty($this->_columns[$columnName])) {
60
+ throw new Exception('Wrong column name specified.');
61
+ }
62
+ $column = $this->_columns[$columnName];
63
+ $inputName = $this->getElement()->getName() . '[#{_id}][' . $columnName . ']';
64
+
65
+ if($columnName == 'magento')
66
+ {
67
+ $rendered = '<select name="'.$inputName.'">';
68
+ foreach($this->magentoOptions as $att => $name)
69
+ {
70
+ $rendered .= '<option value="'.$att.'">'.$name.'</option>';
71
+ }
72
+ $rendered .= '</select>';
73
+ }
74
+ else
75
+ {
76
+ $rendered = '<select name="' . $inputName . '">';
77
+ $model = Mage::getModel('australia/googleproducts');
78
+ foreach ($model->available_fields as $field) {
79
+ $rendered .= '<option value="'.$field.'">'.str_replace("_", " ", $field)."</option>";
80
+ }
81
+ $rendered .= '</select>';
82
+ }
83
+
84
+ return $rendered;
85
+ }
86
+
87
+
88
+ }
app/code/community/Fontis/Australia/Block/Myshopping.php CHANGED
@@ -20,7 +20,7 @@
20
  */
21
  class Fontis_Australia_Block_Myshopping extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
22
  {
23
- protected $magentoOptions;
24
 
25
  public function __construct()
26
  {
@@ -29,7 +29,7 @@ class Fontis_Australia_Block_Myshopping extends Mage_Adminhtml_Block_System_Conf
29
  'size' => 28,
30
  ));
31
  $this->addColumn('xmlfeed', array(
32
- 'label' => Mage::helper('adminhtml')->__('Shopbot feed tag'),
33
  'size' => 28
34
  ));
35
  $this->_addAfter = false;
@@ -47,8 +47,7 @@ class Fontis_Australia_Block_Myshopping extends Mage_Adminhtml_Block_System_Conf
47
  $attribute = $eav_config_model->getAttribute('catalog_product', $att_code);
48
  Mage::log($attribute);
49
 
50
- if ($att_code != ''
51
- )
52
  {
53
  $this->magentoOptions[$att_code] = $att_code;
54
  }
@@ -75,9 +74,14 @@ class Fontis_Australia_Block_Myshopping extends Mage_Adminhtml_Block_System_Conf
75
  }
76
  else
77
  {
78
- return '<input type="text" name="' . $inputName . '" value="#{' . $columnName . '}" ' . ($column['size'] ? 'size="' . $column['size'] . '"' : '') . '/>';
 
 
 
 
 
79
  }
80
-
81
  return $rendered;
82
  }
83
  }
20
  */
21
  class Fontis_Australia_Block_Myshopping extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
22
  {
23
+ protected $magentoOptions = array('instock' => 'instock', 'brand' => 'brand', 'final_price' => 'final_price', 'product_id' => 'product_id', "category" => "category", "link" => "link", "image_url" => "image_url");
24
 
25
  public function __construct()
26
  {
29
  'size' => 28,
30
  ));
31
  $this->addColumn('xmlfeed', array(
32
+ 'label' => Mage::helper('adminhtml')->__('Myshopping feed tag'),
33
  'size' => 28
34
  ));
35
  $this->_addAfter = false;
47
  $attribute = $eav_config_model->getAttribute('catalog_product', $att_code);
48
  Mage::log($attribute);
49
 
50
+ if ($att_code != '')
 
51
  {
52
  $this->magentoOptions[$att_code] = $att_code;
53
  }
74
  }
75
  else
76
  {
77
+ $rendered = '<select name="' . $inputName . '">';
78
+ $model = Mage::getModel('australia/myshopping');
79
+ foreach ($model->available_fields as $field) {
80
+ $rendered .= '<option value="'.$field.'">'.str_replace("_", " ", $field)."</option>";
81
+ }
82
+ $rendered .= '</select>';
83
  }
84
+
85
  return $rendered;
86
  }
87
  }
app/code/community/Fontis/Australia/Block/Shopbot.php CHANGED
@@ -20,7 +20,7 @@
20
  */
21
  class Fontis_Australia_Block_Shopbot extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
22
  {
23
- protected $magentoOptions;
24
 
25
  public function __construct()
26
  {
@@ -52,8 +52,7 @@ class Fontis_Australia_Block_Shopbot extends Mage_Adminhtml_Block_System_Config_
52
  $attribute = $eav_config_model->getAttribute('catalog_product', $att_code);
53
  Mage::log($attribute);
54
 
55
- if ($att_code != ''
56
- )
57
  {
58
  $this->magentoOptions[$att_code] = $att_code;
59
  }
@@ -80,7 +79,12 @@ class Fontis_Australia_Block_Shopbot extends Mage_Adminhtml_Block_System_Config_
80
  }
81
  else
82
  {
83
- return '<input type="text" name="' . $inputName . '" value="#{' . $columnName . '}" ' . ($column['size'] ? 'size="' . $column['size'] . '"' : '') . '/>';
 
 
 
 
 
84
  }
85
 
86
  return $rendered;
20
  */
21
  class Fontis_Australia_Block_Shopbot extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
22
  {
23
+ protected $magentoOptions = array("final_price" => "final_price", "link" => "link", "availability" => "availability", "price" => "price");
24
 
25
  public function __construct()
26
  {
52
  $attribute = $eav_config_model->getAttribute('catalog_product', $att_code);
53
  Mage::log($attribute);
54
 
55
+ if ($att_code != '')
 
56
  {
57
  $this->magentoOptions[$att_code] = $att_code;
58
  }
79
  }
80
  else
81
  {
82
+ $rendered = '<select name="' . $inputName . '">';
83
+ $model = Mage::getModel('australia/shopbot');
84
+ foreach ($model->available_fields as $field) {
85
+ $rendered .= '<option value="'.$field.'">'.str_replace("_", " ", $field)."</option>";
86
+ }
87
+ $rendered .= '</select>';
88
  }
89
 
90
  return $rendered;
app/code/community/Fontis/Australia/Block/Shoppingdotcom.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis Australia Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com and you will be sent a copy immediately.
14
+ *
15
+ * @category Fontis
16
+ * @package Fontis_Australia
17
+ * @author Peter Spiller
18
+ * @copyright Copyright (c) 2008 Fontis Pty. Ltd. (http://www.fontis.com.au)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+ class Fontis_Australia_Block_Shoppingdotcom extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
22
+ {
23
+ // Map in some of the values not normally visible
24
+ protected $magentoOptions = array('is_salable' => 'is_saleable', 'manufacturer_name' => 'manufacturer_name', 'final_price' => 'final_price');
25
+
26
+ public function __construct()
27
+ {
28
+ $this->addColumn('magento', array(
29
+ 'label' => Mage::helper('adminhtml')->__('Magento product attribute'),
30
+ 'size' => 28,
31
+ ));
32
+ $this->addColumn('xmlfeed', array(
33
+ 'label' => Mage::helper('adminhtml')->__('Shopping.com feed tag'),
34
+ 'size' => 28
35
+ ));
36
+ $this->_addAfter = false;
37
+ $this->_addButtonLabel = Mage::helper('adminhtml')->__('Add linked attribute');
38
+
39
+ parent::__construct();
40
+ $this->setTemplate('fontis/australia/system/config/form/field/array_dropdown.phtml');
41
+
42
+ // product options
43
+ $eav_config_model = Mage::getModel('eav/config');
44
+ $attributes = $eav_config_model->getEntityAttributeCodes('catalog_product');
45
+
46
+ foreach($attributes as $att_code)
47
+ {
48
+ $attribute = $eav_config_model->getAttribute('catalog_product', $att_code);
49
+ if ($att_code != '')
50
+ {
51
+ $this->magentoOptions[$att_code] = $att_code;
52
+ }
53
+ }
54
+ asort($this->magentoOptions);
55
+ }
56
+
57
+ protected function _renderCellTemplate($columnName)
58
+ {
59
+ if (empty($this->_columns[$columnName])) {
60
+ throw new Exception('Wrong column name specified.');
61
+ }
62
+ $column = $this->_columns[$columnName];
63
+ $inputName = $this->getElement()->getName() . '[#{_id}][' . $columnName . ']';
64
+
65
+ if($columnName == 'magento')
66
+ {
67
+ $rendered = '<select name="'.$inputName.'">';
68
+ foreach($this->magentoOptions as $att => $name)
69
+ {
70
+ $rendered .= '<option value="'.$att.'">'.$name.'</option>';
71
+ }
72
+ $rendered .= '</select>';
73
+ }
74
+ else
75
+ {
76
+ $rendered = '<select name="' . $inputName . '">';
77
+ $model = Mage::getModel('australia/shoppingdotcom');
78
+ foreach ($model->available_fields as $field) {
79
+ $rendered .= '<option value="'.$field.'">'.str_replace("_", " ", $field)."</option>";
80
+ }
81
+ $rendered .= '</select>';
82
+ }
83
+
84
+ return $rendered;
85
+ }
86
+ }
app/code/community/Fontis/Australia/Model/Child.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis Australia Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com and you will be sent a copy immediately.
14
+ *
15
+ * @category Fontis
16
+ * @package Fontis_Australia
17
+ * @author Peter Spiller
18
+ * @copyright Copyright (c) 2008 Fontis Pty. Ltd. (http://www.fontis.com.au)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+
22
+ $input = "";
23
+ do {
24
+ $input .= fgets(STDIN);
25
+ } while (!feof(STDIN));
26
+
27
+ $config = json_decode($input);
28
+
29
+ errlog("Child got: ".$input);
30
+
31
+ // Start-up Magento stack
32
+ require_once $config->magento_path . '/app/Mage.php';
33
+ // Copied from the original - apparently it fixes problems on some flavours of hosting...
34
+ // TODO: Explain why/what?
35
+ $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'] = $config->magento_path . "/app/code/community/Fontis/Australia/Model/Child.php";
36
+
37
+ $store_id = $config->store_id;
38
+ Mage::app($store_id);
39
+
40
+
41
+ $products = array();
42
+ foreach($config->entity_ids as $entity_id) {
43
+ errlog("Processing $entity_id");
44
+ // Load product, tax helper and generate final price information
45
+ $product = Mage::getModel('catalog/product')->load($entity_id);
46
+
47
+ //Collect basic attributes
48
+ $product_data = $product->getData();
49
+
50
+ // Add generated attributes
51
+ $tax = Mage::helper('tax');
52
+ $final_price = $tax->getPrice($product, $product->getFinalPrice(), true);
53
+ $product_data['final_price'] = $final_price;
54
+ $product_data['manufacturer_name'] = $product->getResource()->getAttribute('manufacturer')->getFrontend()->getValue($product);
55
+ $product_data['link'] = str_replace("Child.php/", "", $product->getProductUrl());
56
+ $product_data['sku'] = $product->getSku();
57
+ $product_data['image_url'] = (string)Mage::helper('catalog/image')->init($product, 'image');
58
+ $product_data['instock'] = $product->isSaleable() ? "Y" : "N"; // myshopping
59
+ $product_data['availability'] = $product->isSaleable() ? "yes" : "no"; // shopbot
60
+ $product_data['product_id'] = $product->getId();
61
+ $product_data['product_num'] = $product->getEntityId();
62
+ $product_data['brand'] = $product_data['manufacturer_name'] == "No" ? "Generic" : $product_data['manufacturer_name']; // myshopping
63
+ $product_data['currency'] = Mage::getStoreConfig('fontis_feeds/'. $config->config_path .'/currency');
64
+
65
+ if (Mage::getStoreConfig('fontis_feeds/'. $config->config_path .'/manufacturer')) {
66
+ if ($product_data['manufacturer_name'] != "No") {
67
+ $product_data['manufacturer'] = $product_data['manufacturer_name']; // getprice
68
+ }
69
+ }
70
+
71
+ if ($config->generate_categories) {
72
+ $category_found = false;
73
+ foreach($product->getCategoryCollection() as $c) {
74
+ $children = $c->getData('children_count');
75
+ if ($children <= 0) {
76
+ $product_data['category'] = utf8_encode($c->getName());
77
+
78
+ $loaded_categories = Mage::getModel('catalog/category')
79
+ ->getCollection()
80
+ ->addIdFilter(array($c->getId()))
81
+ ->addAttributeToSelect(array('name'), 'inner')->load();
82
+
83
+ foreach($loaded_categories as $loaded_category) {
84
+ $product_data['category'] = utf8_encode($loaded_category->getName());
85
+ }
86
+ $category_found = true;
87
+ }
88
+ }
89
+ if (!$category_found) {
90
+ $product_data['category'] = utf8_encode(Mage::getStoreConfig('fontis_feeds/'. $config->config_path .'/defaultcategory'));
91
+ }
92
+ }
93
+
94
+ $products[] = $product_data;
95
+ }
96
+ fwrite (STDOUT, json_encode($products));
97
+
98
+ function errlog($mesg) {
99
+ fwrite (STDERR, "Child: ".$mesg."\n");
100
+ }
app/code/community/Fontis/Australia/Model/Config/Condition.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Fontis_Australia_Model_Config_Condition
4
+ {
5
+ public function toOptionArray()
6
+ {
7
+ return array(
8
+ array('value' => 'new', 'label' => 'New'),
9
+ array('value' => 'used', 'label' => 'Used'),
10
+ array('value' => 'refurbished', 'label' => 'Refurbished'),
11
+ );
12
+ }
13
+ }
app/code/community/Fontis/Australia/Model/FeedCronBase.php ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis Australia Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com and you will be sent a copy immediately.
14
+ *
15
+ * @category Fontis
16
+ * @package Fontis_Australia
17
+ * @author Peter Spiller
18
+ * @copyright Copyright (c) 2008 Fontis Pty. Ltd. (http://www.fontis.com.au)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+
22
+ abstract class Fontis_Australia_Model_FeedCronBase {
23
+ protected $BATCH_SIZE = 100;
24
+ protected $accumulator;
25
+ protected $product_category_accumulator;
26
+ protected $store;
27
+ protected $required_fields = array();
28
+ protected $generate_product_category = false;
29
+
30
+ protected function getPath() {
31
+ $path = "";
32
+ $output_path = Mage::getStoreConfig('fontis_feeds/'.$this->config_path.'/output');
33
+
34
+ if (substr($output_path, 0, 1) == "/") {
35
+ $path = $output_path . '/';
36
+ } else {
37
+ $path = $this->info("base_dir") . '/' . $output_path . '/';
38
+ }
39
+
40
+ return str_replace('//', '/', $path);
41
+ }
42
+
43
+ public function generateFeed() {
44
+ $this->log('Entering update function');
45
+ if (!Mage::getStoreConfig('fontis_feeds/'.$this->config_path.'/active')) {
46
+ $this->log('Module disabled');
47
+ } else {
48
+ $this->setupAppData();
49
+
50
+ $stores = Mage::app()->getStores();
51
+ $this->log("Found " . count($stores) . " stores - starting to process.");
52
+ foreach($stores as $this->store) {
53
+ $this->log('Processing store: ' . $this->store->getName());
54
+ if ($this->generate_product_category) {
55
+ // Create the entire products xml file
56
+ $this->batchProcessStore();
57
+ // Create for each leaf category, their products xml file
58
+ $categories = $this->getCategoriesXml();
59
+ foreach($categories['link_ids'] as $category_id) {
60
+ $this->log('Generating Product Category XML File: ' . $category_id);
61
+ $this->batchProcessStore($category_id);
62
+ }
63
+ } else {
64
+ $this->batchProcessStore();
65
+ }
66
+ }
67
+ $this->finaliseAppData();
68
+ }
69
+ $this->log('Finished update function');
70
+ }
71
+
72
+ private function batchProcessStore($cat_id = null) {
73
+ $this->setupStoreData();
74
+
75
+ $product_class = Mage::getModel('catalog/product');
76
+ $product_collection = $product_class->getCollection();
77
+ $product_collection->setStoreId($this->store);
78
+ $product_collection->addStoreFilter();
79
+ $product_collection->addAttributeToSelect('*');
80
+ $product_collection->addAttributeToFilter('status', 1);
81
+ $product_collection->addAttributeToFilter('visibility', 4);
82
+
83
+ if ($cat_id != -1 && $cat_id) {
84
+ $product_collection->getSelect()->where("e.entity_id IN (
85
+ SELECT product_id FROM catalog_category_product WHERE category_id = ". $cat_id ."
86
+ )");
87
+ $product_collection->getSelect()->order('product_id');
88
+ }
89
+
90
+ $skip_query = false;
91
+ $include_all = Mage::getStoreConfig('fontis_feeds/'.$this->config_path.'/include_all_products');
92
+ $override_attribute_code = Mage::getStoreConfig('fontis_feeds/'.$this->config_path.'/custom_filter_attribute');
93
+ if ($override_attribute_code != '0') {
94
+ // TODO: Find out why 'no' was originally included in these filters...
95
+ if ($include_all) {
96
+ // Include all with exceptions - test for exclusion by requiring a 'null' value
97
+ $this->log("Include all products, but exclude where $override_attribute_code = true");
98
+ $product_collection->addAttributeToFilter($override_attribute_code, array('in' => array(0, '0', '', false, 'no')));
99
+ } else {
100
+ // Exclude all with exceptions - test for inclusion by requiring something other than a 'null' value
101
+ $this->log("Exclude all products, but include where $override_attribute_code = true");
102
+ $product_collection->addAttributeToFilter($override_attribute_code, array('nin' => array(0, '0', '', false, 'no')));
103
+ }
104
+ } else {
105
+ if ($include_all) {
106
+ // Include all with no exceptions - the simple case
107
+ $this->log("Include all products");
108
+ } else {
109
+ // Exclude all with no exceptions - no results
110
+ $this->log("Exclude all products");
111
+ $skip_query = true;
112
+ }
113
+ }
114
+
115
+ if (!$skip_query) {
116
+ //$this->log("Iterating using SQL:\n" . $product_collection->getSelect());
117
+ Mage::getSingleton('core/resource_iterator')->walk($product_collection->getSelect(), array(array($this, "productBatchCallback")));
118
+ $this->log('Iterating: ' . $product_collection->getSize() . ' products...');
119
+ // Finish off anything left in the array (if we didn't process a multiple of BATCH_SIZE)
120
+ $this->collectDataForAccumulatedEntities();
121
+ }
122
+
123
+ $this->finaliseStoreData($cat_id);
124
+ }
125
+
126
+ public function productBatchCallback ($args) {
127
+ $this->accumulator[] = $args['row']['entity_id'];
128
+ if(count($this->accumulator) >= $this->BATCH_SIZE) {
129
+ $this->collectDataForAccumulatedEntities();
130
+ }
131
+ }
132
+
133
+ private function collectDataForAccumulatedEntities() {
134
+ $total = count($this->accumulator);
135
+ // $this->log("Submitting ".$total." entity ids: ". join(array_slice($this->accumulator, 0, 8), ", "). "... ". $this->accumulator[$total-1]);
136
+
137
+ // Build file descriptor list for talking to sub process
138
+ $descriptorspec = array(
139
+ 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
140
+ 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
141
+ 2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
142
+ );
143
+ $pipes = array();
144
+
145
+ // Build child path from current file location and Magento path delimiter
146
+ $exec_path = escapeshellarg(dirname(__FILE__) . DS . "Child.php");
147
+
148
+ // Open child process with proc_open
149
+ //$this->log("Opening child: ".$exec_path);
150
+ $process = proc_open('php '.$exec_path, $descriptorspec, &$pipes);
151
+
152
+ if (!is_resource($process)) {
153
+ $this->log("Error opening child");
154
+ fclose($pipes[0]);
155
+ } else {
156
+ // Write entity id/attribute info to pipe
157
+ $data = array(
158
+ "magento_path" => $this->info("base_dir"),
159
+ "store_id" => $this->info("store_id"),
160
+ "entity_ids" => $this->accumulator,
161
+ "attributes" => array(),
162
+ "generate_categories" => $this->generate_categories,
163
+ "config_path" => $this->config_path
164
+ );
165
+ $this->accumulator = array();
166
+
167
+ fwrite($pipes[0], json_encode($data));
168
+ fclose($pipes[0]);
169
+
170
+ // Read child's output until it finishes or child is no longer running
171
+ // TODO: Set time limit (in case child never finishes)
172
+ // TODO: Add stream blocking using stream_select
173
+ $result = "";
174
+ do {
175
+ $result .= fgets($pipes[1]);
176
+ $state = proc_get_status($process);
177
+ } while (!feof($pipes[1]) && $state['running']);
178
+
179
+ // read JSON-encoded data from child process
180
+ $batch_data = json_decode($result, true);
181
+
182
+ if(is_array($batch_data)) {
183
+ $this->populateFeedWithBatchData($batch_data);
184
+ } else {
185
+ $this->log("Could not unserialize to array:");
186
+ $this->log($result);
187
+ $this->log($batch_data);
188
+ }
189
+
190
+ // Close child process with proc_close (should already be finished, but just in case)
191
+ $exit_status = proc_close($process);
192
+ //self::log("Child exit value: ".$exit_status);
193
+ }
194
+
195
+ // close remaining file handles
196
+ @fclose($pipes[1]);
197
+ }
198
+
199
+ protected function collectLinkedAttributes () {
200
+ $result = @unserialize(Mage::getStoreConfig('fontis_feeds/'.$this->config_path.'/m_to_xml_attributes', $this->info('store_id')));
201
+ if (is_array($result)) {
202
+ //$this->log("Found mapping: " . Mage::getStoreConfig('fontis_feeds/'.$this->config_path.'/m_to_xml_attributes', $this->store->getId()));
203
+ return $result;
204
+ } else {
205
+ return array();
206
+ }
207
+ }
208
+
209
+ protected function collectAttributeMapping() {
210
+ $fields = $this->required_fields;
211
+ $flipped = array_flip($fields);
212
+ foreach ($this->collectLinkedAttributes() as $id => $field_data) {
213
+ $attr = $field_data['magento'];
214
+ $feed_tag = $field_data['xmlfeed'];
215
+ //$this->log("Comparing $attr, $feed_tag with:\n" . var_dump($flipped));
216
+ // Remapping default fields: If the feed tag exists in the required fields we remove it and replace it with the user-configured one.
217
+ if (array_key_exists($feed_tag, $flipped)) {
218
+ $existing_key = $flipped[$feed_tag];
219
+ //$this->log("Found $existing_key => $feed_tag - deleting");
220
+ unset($fields[$existing_key]);
221
+ }
222
+ $fields[$attr] = $feed_tag;
223
+ }
224
+ //$this->log("Final mapping: ". var_dump($fields));
225
+
226
+ return $fields;
227
+ }
228
+
229
+ // NOTE: Subclasses can use any or all of the methods below to do setup/teardown, and to process
230
+ // generated data at the batch, store or application level.
231
+ protected function setupAppData() {
232
+ // For feeds generating a single file, set it up here
233
+ }
234
+ protected function setupStoreData() {
235
+ // For feeds generating a single file, set it up here
236
+ }
237
+ protected function populateFeedWithBatchData($batch_data) {
238
+ // Process returned data at the batch level
239
+ }
240
+ protected function finaliseStoreData() {
241
+ // Process returned data at the store level
242
+ }
243
+ protected function finaliseAppData() {
244
+ // Process returned data at the application level
245
+ }
246
+
247
+ protected function info($info_to_get) {
248
+ $store = $this->store;
249
+ $core_date = Mage::getModel('core/date')->timestamp(time());
250
+
251
+ switch($info_to_get) {
252
+ case "store_id":
253
+ $info = $store->getId();
254
+ break;
255
+ case "store_url":
256
+ $info = $store->getBaseUrl();
257
+ break;
258
+ case "shop_name":
259
+ $info = $store->getName();
260
+ break;
261
+ case "date":
262
+ $info = date("d-m-Y", $core_date);
263
+ break;
264
+ case "time":
265
+ $info = date("h:i:s", $core_date);
266
+ break;
267
+ case "clean_store_name":
268
+ $info = str_replace('+', '-', strtolower(urlencode($store->getName())));
269
+ break;
270
+ case "base_dir":
271
+ $info = Mage::getBaseDir();
272
+ break;
273
+ }
274
+ return $info;
275
+ }
276
+
277
+ public function log($mesg) {
278
+ //print $mesg."\n";
279
+ Mage::log(get_class($this).": ".$mesg);
280
+ }
281
+ }
app/code/community/Fontis/Australia/Model/Getprice.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis Australia Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Fontis
16
+ * @package Fontis_Australia
17
+ * @author Peter Spiller
18
+ * @copyright Copyright (c) 2008 Fontis Pty. Ltd. (http://www.fontis.com.au)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+
22
+ /**
23
+ * GetPrice model
24
+ *
25
+ * @category Fontis
26
+ * @package Fontis_Australia
27
+ */
28
+ class Fontis_Australia_Model_GetPrice {
29
+
30
+ public $available_fields = array(
31
+ "product_num",
32
+ "upc",
33
+ "product_name",
34
+ "attribute1",
35
+ "description",
36
+ "category_name",
37
+ "manufacturer",
38
+ "model",
39
+ "product_url",
40
+ "image",
41
+ "shipment_cost",
42
+ "shipping_times",
43
+ "price",
44
+ "sale_price",
45
+ "currency",
46
+ "mpn",
47
+ "availability",
48
+ "color",
49
+ "feature",
50
+ "id",
51
+ "link",
52
+ "model_number",
53
+ "product_type",
54
+ "quantity",
55
+ "shipping_time",
56
+ "size",
57
+ "author",
58
+ "isbn",
59
+ "artist",
60
+ "rating",
61
+ "age",
62
+ "colour",
63
+ "carats",
64
+ "wine Varietal",
65
+ "vintage",
66
+ "platform"
67
+ );
68
+
69
+ }
app/code/community/Fontis/Australia/Model/Getprice/Cron.php CHANGED
@@ -19,138 +19,57 @@
19
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
  */
21
 
22
- // Callback used by the Magento resource iterator walk() method. Adds a
23
- // product ID to a static array and calls addProductXmlgetPrice() to
24
- // generate XML when the array reaches the batch size.
25
- function addProductXmlCallbackGetPrice($args) {
26
- Fontis_Australia_Model_GetPrice_Cron::$accumulator[] = $args['row']['entity_id'];
27
-
28
- $length = count(Fontis_Australia_Model_GetPrice_Cron::$accumulator);
29
- if($length >= Fontis_Australia_Model_GetPrice_Cron::BATCH_SIZE) {
30
- addProductXmlGetPrice();
31
- }
32
- }
33
-
34
- // Runs a subprocesss to create feed XML for the product IDs in the static
35
- // array, then empties the array.
36
- function addProductXmlGetPrice() {
37
- $length = count(Fontis_Australia_Model_GetPrice_Cron::$accumulator);
38
- if($length > 0) {
39
- Mage::log("Fontis/Australia_Model_Getprice_Cron: Processing product IDs " . Fontis_Australia_Model_GetPrice_Cron::$accumulator[0] .
40
- " to " . Fontis_Australia_Model_GetPrice_Cron::$accumulator[$length - 1]);
41
- $store_id = Fontis_Australia_Model_GetPrice_Cron::$store->getId();
42
-
43
- $data = shell_exec("php " . Mage::getBaseDir() . "/app/code/community/Fontis/Australia/Model/Getprice/Child.php " .
44
- Mage::getBaseDir() . " '" . serialize(Fontis_Australia_Model_GetPrice_Cron::$accumulator) .
45
- "' " . $store_id);
46
- Fontis_Australia_Model_GetPrice_Cron::$accumulator = array();
47
-
48
- $array = json_decode($data, true);
49
-
50
- if(is_array($array)) {
51
- $codes = array();
52
- foreach($array as $prod) {
53
- Fontis_Australia_Model_GetPrice_Cron::$debugCount += 1;
54
- $product_node = Fontis_Australia_Model_GetPrice_Cron::$root_node->addChild('product');
55
- foreach($prod as $key => $val) {
56
- if($key == 'Code') {
57
- $codes[] = $val;
58
- }
59
- $product_node->addChild($key, htmlspecialchars($val));
60
- }
61
- }
62
- if(!empty($codes)) {
63
- Mage::log("Fontis/Australia_Model_Getprice_Cron: Codes: ".implode(",", $codes));
64
- }
65
- } else {
66
- Mage::log("Fontis/Australia_Model_Getprice_Cron: Could not unserialize to array:");
67
- Mage::log($data);
68
- Mage::log($array);
69
- }
70
-
71
- Mage::log('Fontis/Australia_Model_Getprice_Cron: ' . strlen($data) . ' characters returned');
72
- }
73
- }
74
-
75
- class Fontis_Australia_Model_GetPrice_Cron {
76
- const BATCH_SIZE = 100;
77
 
78
- public static $doc;
79
- public static $root_node;
80
- public static $store;
81
- public static $accumulator;
82
- public static $debugCount = 0;
83
-
84
- protected function _construct() {
85
- self::$accumulator = array();
86
- }
87
-
88
- protected function getPath() {
89
- $path = "";
90
- $config_path = Mage::getStoreConfig('fontis_feeds/getpricefeed/output');
91
-
92
- if (substr($config_path, 0, 1) == "/") {
93
- $path = $config_path . '/';
94
- } else {
95
- $path = Mage::getBaseDir() . '/' . $config_path . '/';
96
- }
97
-
98
- return str_replace('//', '/', $path);
99
  }
100
 
101
- public function nonstatic() {
102
- self::update();
103
  }
104
 
105
- public static function update() {
106
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Entered update function');
107
-
108
- if (Mage::getStoreConfig('fontis_feeds/getpricefeed/active')) {
109
- $io = new Varien_Io_File();
110
- $io->setAllowCreateFolders(true);
111
-
112
- $io->open(array('path' => self::getPath()));
113
-
114
- // Loop through all stores:
115
- foreach(Mage::app()->getStores() as $store) {
116
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Processing store: ' . $store->getName());
117
- $clean_store_name = str_replace('+', '-', strtolower(urlencode($store->getName())));
118
-
119
- // Write the entire products xml file:
120
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Generating All Products XML File');
121
- $products_result = self::getProductsXml($store);
122
- $io->write($clean_store_name . '-products.xml', $products_result['xml']);
123
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Wrote to file: ' . $clean_store_name . '-products.xml', $products_result['xml']);
124
-
125
- // Write the leaf categories xml file:
126
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Generating Categories XML File');
127
- $categories_result = self::getCategoriesXml($store);
128
- $io->write($clean_store_name . '-categories.xml', $categories_result['xml']);
129
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Wrote to file: ' . $clean_store_name . '-categories.xml', $categories_result['xml']);
130
-
131
- // Write for each leaf category, their products xml file:
132
- foreach($categories_result['link_ids'] as $link_id) {
133
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Generating Product Category XML File: ' . $link_id);
134
- $subcategory_products_result = self::getProductsXml($store, $link_id);
135
- $io->write($clean_store_name . '-products-'.$link_id.'.xml', $subcategory_products_result['xml']);
136
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Wrote to file: ' . $clean_store_name . '-products-'.$link_id.'.xml', $subcategory_products_result['xml']);
137
- }
138
  }
139
-
140
- $io->close();
141
- } else {
142
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Disabled');
143
  }
144
  }
145
 
146
- public function getCategoriesXml($store) {
147
- $clean_store_name = str_replace('+', '-', strtolower(urlencode($store->getName())));
148
-
149
  $result = array();
150
  $categories = Mage::getModel('catalog/category')->getCollection()
151
- ->setStoreId($store->getId())
152
  ->addAttributeToFilter('is_active', 1);
153
-
154
  $categories->load()->getItems();
155
 
156
  $full_categories = array();
@@ -165,77 +84,52 @@ class Fontis_Australia_Model_GetPrice_Cron {
165
  }
166
  }
167
 
168
- $storeUrl = $store->getBaseUrl();
169
- $shopName = $store->getName();
170
- $date = date("d-m-Y", Mage::getModel('core/date')->timestamp(time()));
171
- $time = date("h:i:s", Mage::getModel('core/date')->timestamp(time()));
172
-
173
- $doc = new SimpleXMLElement('<store url="' . $storeUrl. '" date="'.$date.'" time="'.$time.'" name="' . $shopName . '"></store>');
174
 
175
  foreach($full_categories as $category) {
176
- $category_node = $doc->addChild('cat');
177
 
178
  $title_node = $category_node->addChild('name');
179
  $title_node[0] = htmlspecialchars($category->getName());
180
 
181
  $link_node = $category_node->addChild('link');
182
- $link_node[0] = Mage::getStoreConfig('web/unsecure/base_url') .
183
- Mage::getStoreConfig('fontis_feeds/getpricefeed/output') . "/$clean_store_name-products-" . $category->getId() . '.xml';
184
 
185
  $result['link_ids'][] = $category->getId();
186
- }
187
-
188
- $result['xml'] = self::formatSimpleXML($doc);
 
 
 
189
  return $result;
190
  }
191
 
192
- public function getProductsXml($store, $cat_id = -1) {
193
- Fontis_Australia_Model_GetPrice_Cron::$store = $store;
194
- $result = array();
195
-
196
- $product = Mage::getModel('catalog/product');
197
- $products = $product->getCollection();
198
- $products->setStoreId($store);
199
- $products->addStoreFilter();
200
- $products->addAttributeToSelect('*');
201
- $products->addAttributeToSelect(array('name', 'price', 'image', 'status', 'manufacturer'), 'left');
202
- $products->addAttributeToFilter('status', 1);
203
- $products->addAttributeToFilter('visibility', 4);
204
-
205
- if ($cat_id != -1) {
206
- $products->getSelect()->where("e.entity_id IN (
207
- SELECT product_id FROM catalog_category_product WHERE category_id = ".$cat_id."
208
- )");
209
- }
210
-
211
- $products->getSelect()->order('product_id');
212
-
213
- $storeUrl = $store->getBaseUrl();
214
- $shopName = $store->getName();
215
- $date = date("d-m-Y", Mage::getModel('core/date')->timestamp(time()));
216
- $time = date("h:i:s", Mage::getModel('core/date')->timestamp(time()));
217
-
218
- self::$doc = new SimpleXMLElement('<store url="' . $storeUrl. '" date="'.$date.'" time="'.$time.'" name="' . $shopName . '"></store>');
219
- self::$root_node = self::$doc->addChild('products');
220
-
221
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Iterating: ' . $products->getSize() . ' products...');
222
- Mage::getSingleton('core/resource_iterator')->walk($products->getSelect(), array('addProductXmlCallbackGetPrice'), array('product' => $product));
223
-
224
- // call XML generation function one last time to process remaining batch
225
- addProductXmlGetPrice();
226
- Mage::log('Fontis/Australia_Model_Getprice_Cron: Iteration complete');
227
-
228
- $result['xml'] = self::formatSimpleXML(self::$doc);
229
- return $result;
230
- }
231
-
232
- public static function formatSimpleXML($doc) {
233
  $dom = new DOMDocument('1.0');
234
  $dom->preserveWhiteSpace = false;
235
  $dom->formatOutput = true;
236
- $dom_sxml = dom_import_simplexml($doc);
237
  $dom_sxml = $dom->importNode($dom_sxml, true);
238
  $dom->appendChild($dom_sxml);
239
- return $dom->saveXML();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  }
241
  }
19
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
  */
21
 
22
+ class Fontis_Australia_Model_GetPrice_Cron extends Fontis_Australia_Model_FeedCronBase {
23
+
24
+ public $config_path = 'getpricefeed';
25
+ public $generate_categories = true;
26
+ protected $generate_product_category = true;
27
+ protected $product_doc;
28
+ protected $category_doc;
29
+ protected $root_node;
30
+ protected $required_fields = array(
31
+ "product_num" => "product_num",
32
+ "sku" => "upc",
33
+ "name" => "attribute1",
34
+ "description" => "description",
35
+ "category" => "category_name",
36
+ "image_url" => "image",
37
+ "final_price" => "price",
38
+ "currency" => "currency",
39
+ "link" => "product_url"
40
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ public static function update() {
43
+ // Static launcher fopr Magento's cron logic
44
+ $obj = new self();
45
+ $obj->generateFeed();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
 
48
+ protected function setupStoreData() {
49
+ $this->product_doc = new SimpleXMLElement('<store url="' . $this->info("store_url") . '" date="'. $this->info("date") .'" time="'. $this->info("time") .'" name="' . $this->info("shop_name") . '"></store>');
50
  }
51
 
52
+ protected function populateFeedWithBatchData($batch_data) {
53
+ $fields = $this->collectAttributeMapping();
54
+ $this->root_node = $this->product_doc->addChild('products');
55
+ foreach($batch_data as $product) {
56
+ $product_node = $this->root_node->addChild('product');
57
+ foreach($fields as $key => $feed_tag) {
58
+ // remove carriage return/HTML tags
59
+ $safe_string = strip_tags($product[$key]);
60
+ $safe_string = preg_replace("/\s*\n\s*/", " ", $safe_string);
61
+ // ...we also need to make it XML safe
62
+ $safe_string = htmlspecialchars($safe_string);
63
+ $product_node->addChild($feed_tag, $safe_string);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  }
 
 
 
 
65
  }
66
  }
67
 
68
+ protected function getCategoriesXml() {
 
 
69
  $result = array();
70
  $categories = Mage::getModel('catalog/category')->getCollection()
71
+ ->setStoreId($this->store)
72
  ->addAttributeToFilter('is_active', 1);
 
73
  $categories->load()->getItems();
74
 
75
  $full_categories = array();
84
  }
85
  }
86
 
87
+ $this->category_doc = new SimpleXMLElement('<store url="' . $this->info("store_url") . '" date="' . $this->info("date") . '" time="' . $this->info("time") . '" name="' . $this->info("shop_name") . '"></store>');
 
 
 
 
 
88
 
89
  foreach($full_categories as $category) {
90
+ $category_node = $this->category_doc->addChild('cat');
91
 
92
  $title_node = $category_node->addChild('name');
93
  $title_node[0] = htmlspecialchars($category->getName());
94
 
95
  $link_node = $category_node->addChild('link');
96
+ $link_node[0] = Mage::getStoreConfig('web/unsecure/base_url', $this->store) .
97
+ Mage::getStoreConfig('fontis_feeds/'. $this->config_path . '/output', $this->store) . $this->info('clean_store_name') ."-products-" . $category->getId() . '.xml';
98
 
99
  $result['link_ids'][] = $category->getId();
100
+ }
101
+ // create categories XML feed
102
+ $this->createXml(array(
103
+ 'name' => "categories",
104
+ 'doc' => $this->category_doc
105
+ ));
106
  return $result;
107
  }
108
 
109
+ protected function createXml($data = array()) {
110
+ // Use DOM to nicely format XML
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  $dom = new DOMDocument('1.0');
112
  $dom->preserveWhiteSpace = false;
113
  $dom->formatOutput = true;
114
+ $dom_sxml = dom_import_simplexml($data['doc']);
115
  $dom_sxml = $dom->importNode($dom_sxml, true);
116
  $dom->appendChild($dom_sxml);
117
+ // $this->log("Generated XML:\n".$dom->saveXML());
118
+
119
+ // Write dom to file
120
+ $filename = $this->info("clean_store_name") . '-' . $data['name'] . '.xml';
121
+ $io = new Varien_Io_File();
122
+ $io->setAllowCreateFolders(true);
123
+ $io->open(array('path' => $this->getPath()));
124
+ $io->write($filename, $dom->saveXML());
125
+ $io->close();
126
+
127
+ }
128
+
129
+ protected function finaliseStoreData($cat_id = null) {
130
+ $this->createXml(array(
131
+ 'name' => $cat_id ? "products-".$cat_id : "products",
132
+ 'doc' => $this->product_doc
133
+ ));
134
  }
135
  }
app/code/community/Fontis/Australia/Model/Googleproducts.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fontis Australia Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Fontis
16
+ * @package Fontis_Australia
17
+ * @author Jeremy Champion
18
+ * @copyright Copyright (c) 2011 Fontis Pty. Ltd. (http://www.fontis.com.au)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+
22
+ /**
23
+ * Shopping.com data model
24
+ *
25
+ * @category Fontis
26
+ * @package Fontis_Australia
27
+ */
28
+ class Fontis_Australia_Model_Googleproducts {
29
+
30
+ public $available_fields = array(
31
+ 'g:id',
32
+ 'title',
33
+ 'link',
34
+ 'g:price',
35
+ 'description',
36
+ 'g:condition',
37
+ 'g:gtin',
38
+ 'g:brand',
39
+ 'g:mpn',
40
+ 'g:image_link',
41
+ 'g:product_type',
42
+ 'g:quantity',
43
+ 'g:availability',
44
+ //'g:shipping', // TODO: I need to be handled!
45
+ 'g:feature',
46
+ 'g:online_only',
47
+ 'g:manufacturer',
48
+ 'g:expiration_date',
49
+ 'g:shipping_weight',
50
+ 'g:product_review_average',
51
+ 'g:product_review_count',
52
+ 'g:genre',
53
+ 'g:featured_product',
54
+ 'g:color',
55
+ 'g:size',
56
+ 'g:year',
57
+ 'g:author',
58
+ 'g:edition',
59
+ );
60
+
61
+ }
app/code/community/Fontis/Australia/Model/Googleproducts/Cron.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Fontis_Australia_Model_Googleproducts_Cron extends Fontis_Australia_Model_FeedCronBase {
4
+ public $config_path = 'googleproductsfeed';
5
+
6
+ protected $doc;
7
+ protected $required_fields = array(
8
+ "sku" => "g:id",
9
+ "name" => "title",
10
+ "link" => "g:link",
11
+ "final_price" => "g:price",
12
+ "description" => "description",
13
+ "image" => "g:image_link",
14
+ );
15
+
16
+ public static function update() {
17
+ // Static launcher for Magento's cron logic
18
+ $obj = new self();
19
+ $obj->generateFeed();
20
+ }
21
+
22
+ protected function getConfig($key)
23
+ {
24
+ return Mage::getStoreConfig('fontis_feeds/' . $this->config_path . '/' . $key);
25
+ }
26
+
27
+ /*
28
+ * Instantiate the XML object
29
+ */
30
+ protected function setupStoreData() {
31
+ // have to use XMLWriter, because SimpleXML destroys the g: of a bunch of the attribute names
32
+ $this->doc = new XMLWriter();
33
+ $this->doc->openMemory();
34
+ $this->doc->setIndent(true);
35
+ $this->doc->setIndentString(' ');
36
+ $this->doc->startDocument('1.0', 'UTF-8');
37
+ $this->doc->startElement('feed');
38
+ $this->doc->writeAttribute('xmlns', 'http://www.w3.org/2005/Atom');
39
+ $this->doc->writeAttribute('xmlns:g', 'http://base.google.com/ns/1.0');
40
+
41
+ $this->doc->writeElement('title', $this->getConfig('title'));
42
+
43
+ $this->doc->startElement('link');
44
+ $this->doc->writeAttribute('rel', 'self');
45
+ $this->doc->writeAttribute('href', $this->store->getBaseUrl());
46
+ $this->doc->endElement();
47
+
48
+ $date = new Zend_Date();
49
+ $this->doc->writeElement('updated', $date->get(Zend_Date::ATOM));
50
+
51
+ $this->doc->startElement('author');
52
+ $this->doc->writeElement('name', $this->getConfig('author'));
53
+ $this->doc->endElement();
54
+
55
+ $url = $this->store->getBaseUrl();
56
+ $day = $date->toString('yyyy-MM-dd');
57
+ $path = Mage::getStoreConfig('fontis_feeds/'.$this->config_path.'/output');
58
+ $filename = $path . '/' . str_replace('+', '-', strtolower(urlencode($this->store->getName()))) . '-products.xml';
59
+
60
+ $this->doc->writeElement('id', 'tag:' . $url . ',' . $day . ':' . $filename);
61
+ }
62
+
63
+ /*
64
+ * Add generated data to the feed element
65
+ */
66
+ protected function populateFeedWithBatchData($batch_data) {
67
+ $fields = $this->collectAttributeMapping();
68
+ $defaultCondition = $this->getConfig('default_condition');
69
+
70
+ foreach($batch_data as $product) {
71
+ $this->doc->startElement('entry');
72
+
73
+ foreach($fields as $key => $tag) {
74
+ if(!is_array($tag)) {
75
+ $feed_tags = array($tag);
76
+ } else {
77
+ $feed_tags = $tag;
78
+ }
79
+ foreach($feed_tags as $feed_tag) {
80
+ switch ($feed_tag) {
81
+ case 'g:price':
82
+ // Prices require two decimal places.
83
+ $safe_string = sprintf('%.2f', $product[$key]);
84
+ $this->doc->writeElement($feed_tag, $safe_string);
85
+ break;
86
+
87
+ case 'g:link':
88
+ // Links must be written as an attribute
89
+ $this->doc->startElement($feed_tag);
90
+ $this->doc->writeAttribute('href', $product[$key]);
91
+ $this->doc->endElement();
92
+ break;
93
+
94
+ case 'g:condition':
95
+ // allow condition override
96
+ if(isset($product[$key]) && $product[$key] != 0) {
97
+ $this->doc->writeElement($feed_tag, $product[$key]);
98
+ } else {
99
+ $this->doc->writeElement($feed_tag, $defaultCondition);
100
+ }
101
+ break;
102
+
103
+ case 'g:image_link':
104
+ $safe_string = $product[$key];
105
+ // check if the link is a full URL
106
+ if(substr($product[$key], 0, 5) != 'http:') {
107
+ $safe_string = $this->store->getBaseUrl('media') . 'catalog/product' . $product[$key];
108
+ }
109
+
110
+ $this->doc->writeElement($feed_tag, $safe_string);
111
+ break;
112
+
113
+ default:
114
+ // Google doesn't like HTML tags in the feed
115
+ $safe_string = strip_tags($product[$key]);
116
+
117
+ $this->doc->writeElement($feed_tag, $safe_string);
118
+ break;
119
+ }
120
+ }
121
+ }
122
+
123
+ $this->doc->endElement();
124
+ }
125
+ }
126
+
127
+ protected function finaliseStoreData() {
128
+ // Write the end of the xml document
129
+ $this->doc->endElement();
130
+ $this->doc->endDocument();
131
+
132
+ // Write dom to file
133
+ $clean_store_name = str_replace('+', '-', strtolower(urlencode($this->store->getName())));
134
+ $filename = $clean_store_name . '-products.xml';
135
+ $io = new Varien_Io_File();
136
+ $io->setAllowCreateFolders(true);
137
+ $io->open(array('path' => $this->getPath()));
138
+ $io->write($filename, $this->doc->outputMemory());
139
+ $io->close();
140
+ }
141
+
142
+ protected function collectAttributeMapping() {
143
+ $fields = $this->required_fields;
144
+ $flipped = array_flip($fields);
145
+ foreach ($this->collectLinkedAttributes() as $id => $field_data) {
146
+ $attr = $field_data['magento'];
147
+ $feed_tag = $field_data['xmlfeed'];
148
+ //$this->log("Comparing $attr, $feed_tag with:\n" . var_dump($flipped));
149
+ // Remapping default fields: If the feed tag exists in the required fields we remove it and replace it with the user-configured one.
150
+ if (array_key_exists($feed_tag, $flipped)) {
151
+ $existing_key = $flipped[$feed_tag];
152
+ //$this->log("Found $existing_key => $feed_tag - deleting");
153
+ unset($fields[$existing_key]);
154
+ }
155
+
156
+ // If the attribute already exists in the mapping list (not the
157
+ // required list) then add the tag as an array. This supports
158
+ // things like the g:image_link tag which allows for multiple
159
+ // entities in each entry.
160
+ if(isset($fields[$attr])) {
161
+ if(is_array($fields[$attr])) {
162
+ $fields[$attr][] = $feed_tag;
163
+ } else {
164
+ $cur = $fields[$attr];
165
+ $fields[$attr] = array($cur, $feed_tag);
166
+ }
167
+ } else {
168
+ $fields[$attr] = $feed_tag;
169
+ }
170
+ }
171
+ //$this->log("Final mapping: ". var_dump($fields));
172
+
173
+ if(!in_array('g:condition', array_values($fields)))
174
+ {
175
+ $fields['UNSET_CONDITION'] = 'g:condition';
176
+ }
177
+
178
+ return $fields;
179
+ }
180
+ }
app/code/community/Fontis/Australia/Model/Myshopping.php ADDED
@@ -0,0 +1,57 @@