Reflektion_Individualization_Extension - Version 1.0.0

Version Notes

This is the first public release of the Reflektion Catalogexport Module
This extension contains following feature
-> Generate and transfer your magento catalog product CSV to Reflektion SFTP.
-> Website level export.
-> Select Product Attributes to transfer at your website level.

Easy to handle and configure.

Download this release

Release Info

Developer Amar
Extension Reflektion_Individualization_Extension
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

Files changed (46) hide show
  1. app/code/community/Reflektion/.DS_Store +0 -0
  2. app/code/community/Reflektion/Catalogexport/.DS_Store +0 -0
  3. app/code/community/Reflektion/Catalogexport/Block/.DS_Store +0 -0
  4. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/.DS_Store +0 -0
  5. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export.php +35 -0
  6. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/.DS_Store +0 -0
  7. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid.php +112 -0
  8. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid/.DS_Store +0 -0
  9. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid/Renderer/Action.php +21 -0
  10. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Job.php +27 -0
  11. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Job/Grid.php +131 -0
  12. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/.DS_Store +0 -0
  13. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/Config/.DS_Store +0 -0
  14. app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/Config/CommentText.php +18 -0
  15. app/code/community/Reflektion/Catalogexport/Helper/.DS_Store +0 -0
  16. app/code/community/Reflektion/Catalogexport/Helper/Csvfile.php +140 -0
  17. app/code/community/Reflektion/Catalogexport/Helper/Data.php +105 -0
  18. app/code/community/Reflektion/Catalogexport/Helper/SftpConnection.php +204 -0
  19. app/code/community/Reflektion/Catalogexport/Model/.DS_Store +0 -0
  20. app/code/community/Reflektion/Catalogexport/Model/Feed/.DS_Store +0 -0
  21. app/code/community/Reflektion/Catalogexport/Model/Feed/Base.php +174 -0
  22. app/code/community/Reflektion/Catalogexport/Model/Feed/Product.php +152 -0
  23. app/code/community/Reflektion/Catalogexport/Model/Generatefeeds.php +56 -0
  24. app/code/community/Reflektion/Catalogexport/Model/Job.php +223 -0
  25. app/code/community/Reflektion/Catalogexport/Model/Layout.php +25 -0
  26. app/code/community/Reflektion/Catalogexport/Model/Mysql4/.DS_Store +0 -0
  27. app/code/community/Reflektion/Catalogexport/Model/Mysql4/Job.php +17 -0
  28. app/code/community/Reflektion/Catalogexport/Model/Mysql4/Job/Collection.php +17 -0
  29. app/code/community/Reflektion/Catalogexport/Model/Observer.php +91 -0
  30. app/code/community/Reflektion/Catalogexport/Model/System/.DS_Store +0 -0
  31. app/code/community/Reflektion/Catalogexport/Model/System/Config/Cron.php +46 -0
  32. app/code/community/Reflektion/Catalogexport/Model/System/Config/EnableToggle.php +20 -0
  33. app/code/community/Reflektion/Catalogexport/Model/System/Config/ProductAttributes.php +32 -0
  34. app/code/community/Reflektion/Catalogexport/Model/System/Validate/ProductAttributes.php +32 -0
  35. app/code/community/Reflektion/Catalogexport/Model/Transferfeeds.php +140 -0
  36. app/code/community/Reflektion/Catalogexport/controllers/.DS_Store +0 -0
  37. app/code/community/Reflektion/Catalogexport/controllers/Adminhtml/ExportController.php +78 -0
  38. app/code/community/Reflektion/Catalogexport/controllers/Adminhtml/JobController.php +105 -0
  39. app/code/community/Reflektion/Catalogexport/etc/adminhtml.xml +69 -0
  40. app/code/community/Reflektion/Catalogexport/etc/config.xml +126 -0
  41. app/code/community/Reflektion/Catalogexport/etc/system.xml +173 -0
  42. app/code/community/Reflektion/Catalogexport/sql/.DS_Store +0 -0
  43. app/code/community/Reflektion/Catalogexport/sql/reflektion_setup/mysql4-install-1.0.0.php +36 -0
  44. app/design/adminhtml/default/default/layout/reflektion.xml +24 -0
  45. app/etc/modules/Reflektion_Catalogexport.xml +10 -0
  46. package.xml +27 -0
app/code/community/Reflektion/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Block/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Admin export grid layout load
10
+ */
11
+ class Reflektion_Catalogexport_Block_Adminhtml_Export extends Mage_Adminhtml_Block_Widget_Grid_Container {
12
+
13
+ public function __construct() {
14
+
15
+ $this->_controller = "adminhtml_export";
16
+ $this->_blockGroup = "reflektion";
17
+ $this->_headerText = Mage::helper("reflektion")->__("Generate Data Feeds");
18
+ parent::__construct();
19
+ }
20
+
21
+ protected function _prepareLayout() {
22
+ // Remove add button
23
+ $this->_removeButton('add');
24
+
25
+ // Export all button
26
+ $this->_addButton('exportall', array(
27
+ 'label' => 'Export Feeds For All Sites',
28
+ 'onclick' => 'setLocation(\'' . $this->getUrl('*/*/exportall') . '\')',
29
+ 'class' => 'exportall',
30
+ ));
31
+
32
+ return parent::_prepareLayout();
33
+ }
34
+
35
+ }
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Prepare collection and select columns
10
+ */
11
+ class Reflektion_Catalogexport_Block_Adminhtml_Export_Grid extends Mage_Adminhtml_Block_Widget_Grid {
12
+
13
+ public function __construct() {
14
+ parent::__construct();
15
+ $this->setId("exportGrid");
16
+ $this->setDefaultDir("ASC");
17
+ $this->setSaveParametersInSession(true);
18
+ }
19
+
20
+ protected function _prepareCollection() {
21
+ // Collection for each data feed for each website
22
+ $collection = new Varien_Data_Collection();
23
+
24
+ // All websites
25
+ $websites = Mage::app()->getWebsites(false, true);
26
+ foreach ($websites as $website) {
27
+ $websiteId = $website->getId();
28
+
29
+ if (Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/general/allfeedsenabled') == 'enabled') {
30
+
31
+ $feedTypes = '';
32
+ foreach (Reflektion_Catalogexport_Model_Generatefeeds::getFeedTypes() as $curFeedType) {
33
+ if (Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/feedsenabled/' . $curFeedType) == 'enabled') {
34
+ if (strlen($feedTypes) > 0) {
35
+ $feedTypes .= ', ';
36
+ }
37
+ $feedTypes .= $curFeedType;
38
+ }
39
+ }
40
+ $sftpUser = Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/connect/username');
41
+ $sftpDestination = Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/connect/hostname');
42
+
43
+ // Grid item
44
+ $newItem = $collection->getNewEmptyItem();
45
+ $newItem->setData(array(
46
+ 'id' => $website->getId(),
47
+ 'website_name' => $website->getName(),
48
+ 'website_code' => $website->getCode(),
49
+ 'feeds' => $feedTypes,
50
+ 'sftp_destination' => $sftpDestination,
51
+ 'sftp_user' => $sftpUser,
52
+ ));
53
+ $collection->addItem($newItem);
54
+ }
55
+ }
56
+
57
+ $this->setCollection($collection);
58
+ return $this;
59
+ }
60
+
61
+ protected function _prepareColumns() {
62
+ $this->addColumn('id', array(
63
+ 'header' => Mage::helper('reflektion')->__('Website ID'),
64
+ 'width' => '50px',
65
+ 'index' => 'id'
66
+ ));
67
+
68
+ $this->addColumn('website_name', array(
69
+ 'header' => Mage::helper('reflektion')->__('Website Name'),
70
+ 'width' => '110px',
71
+ 'index' => 'website_name'
72
+ ));
73
+
74
+ $this->addColumn('website_code', array(
75
+ 'header' => Mage::helper('reflektion')->__('Website Code'),
76
+ 'width' => '100px',
77
+ 'index' => 'website_code'
78
+ ));
79
+
80
+ $this->addColumn('feeds', array(
81
+ 'header' => Mage::helper('reflektion')->__('Feeds to Send'),
82
+ 'width' => '320px',
83
+ 'index' => 'feeds'
84
+ ));
85
+
86
+ $this->addColumn('sftp_destination', array(
87
+ 'header' => Mage::helper('reflektion')->__('SFTP Destination'),
88
+ 'width' => '140px',
89
+ 'index' => 'sftp_destination'
90
+ ));
91
+
92
+ $this->addColumn('sftp_user', array(
93
+ 'header' => Mage::helper('reflektion')->__('SFTP User'),
94
+ 'width' => '100px',
95
+ 'index' => 'sftp_user'
96
+ ));
97
+
98
+ $this->addColumn('action', array(
99
+ 'header' => Mage::helper('reflektion')->__('Action'),
100
+ 'filter' => false,
101
+ 'sortable' => false,
102
+ 'renderer' => 'reflektion/adminhtml_export_grid_renderer_action'
103
+ ));
104
+
105
+ return parent::_prepareColumns();
106
+ }
107
+
108
+ public function getRowUrl($row) {
109
+ return $this->getUrl("*/*/exportone", array("id" => $row->getId()));
110
+ }
111
+
112
+ }
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid/Renderer/Action.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Render action to generate data feed queue
10
+ */
11
+ class Reflektion_Catalogexport_Block_Adminhtml_Export_Grid_Renderer_Action extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Action {
12
+
13
+ public function render(Varien_Object $row) {
14
+ $this->getColumn()->setActions(array(array(
15
+ 'url' => $this->getUrl('*/*/exportone', array('id' => $row->getId())),
16
+ 'caption' => Mage::helper('reflektion')->__('Export Feed For ' . $row->getWebsiteName()),
17
+ )));
18
+ return parent::render($row);
19
+ }
20
+
21
+ }
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Job.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Admin jobs queue grid layout load
10
+ */
11
+ class Reflektion_Catalogexport_Block_Adminhtml_Job extends Mage_Adminhtml_Block_Widget_Grid_Container {
12
+
13
+ public function __construct() {
14
+
15
+ $this->_controller = "adminhtml_job";
16
+ $this->_blockGroup = "reflektion";
17
+ $this->_headerText = Mage::helper("reflektion")->__("Data Feeds Job Queue");
18
+ parent::__construct();
19
+ }
20
+
21
+ protected function _prepareLayout() {
22
+ // Remove add button
23
+ $this->_removeButton('add');
24
+ return parent::_prepareLayout();
25
+ }
26
+
27
+ }
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Job/Grid.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Prepare collection and select columns
10
+ */
11
+ class Reflektion_Catalogexport_Block_Adminhtml_Job_Grid extends Mage_Adminhtml_Block_Widget_Grid {
12
+
13
+ public function __construct() {
14
+ parent::__construct();
15
+ $this->setId("jobGrid");
16
+ $this->setDefaultSort('job_id');
17
+ $this->setDefaultDir("DESC");
18
+ $this->setSaveParametersInSession(true);
19
+ if (Mage::registry('preparedFilter')) {
20
+ $this->setDefaultFilter(Mage::registry('preparedFilter'));
21
+ }
22
+ }
23
+
24
+ protected function _addColumnFilterToCollection($column) {
25
+ $filterArr = Mage::registry('preparedFilter');
26
+ if (($column->getId() === 'store_id' || $column->getId() === 'status') && $column->getFilter()->getValue() && strpos($column->getFilter()->getValue(), ',')) {
27
+ $_inNin = explode(',', $column->getFilter()->getValue());
28
+ $inNin = array();
29
+ foreach ($_inNin as $k => $v) {
30
+ if (is_string($v) && strlen(trim($v))) {
31
+ $inNin[] = trim($v);
32
+ }
33
+ }
34
+ if (count($inNin) > 1 && in_array($inNin[0], array('in', 'nin'))) {
35
+ $in = $inNin[0];
36
+ $values = array_slice($inNin, 1);
37
+ $this->getCollection()->addFieldToFilter($column->getId(), array($in => $values));
38
+ } else {
39
+ parent::_addColumnFilterToCollection($column);
40
+ }
41
+ } elseif (is_array($filterArr) && array_key_exists($column->getId(), $filterArr) && isset($filterArr[$column->getId()])) {
42
+ $this->getCollection()->addFieldToFilter($column->getId(), $filterArr[$column->getId()]);
43
+ } else {
44
+ parent::_addColumnFilterToCollection($column);
45
+ }
46
+ return $this;
47
+ }
48
+
49
+ protected function _prepareCollection() {
50
+ $collection = Mage::getResourceModel('reflektion/job_collection');
51
+ $this->setCollection($collection);
52
+ return parent::_prepareCollection();
53
+ }
54
+
55
+ protected function _prepareColumns() {
56
+ $this->addColumn('job_id', array(
57
+ 'header' => Mage::helper('reflektion')->__('Job ID'),
58
+ 'index' => 'job_id'
59
+ ));
60
+
61
+ $this->addColumn('website_id', array(
62
+ 'header' => Mage::helper('reflektion')->__('Website ID'),
63
+ 'index' => 'website_id'
64
+ ));
65
+
66
+ $this->addColumn('type', array(
67
+ 'header' => Mage::helper('reflektion')->__('Job Type'),
68
+ 'index' => 'type',
69
+ 'type' => 'options',
70
+ 'options' => array(
71
+ Reflektion_Catalogexport_Model_Job::TYPE_GENERATE_BASELINE => Mage::helper('reflektion')->__('Manual Feed'),
72
+ Reflektion_Catalogexport_Model_Job::TYPE_GENERATE_DAILY => Mage::helper('reflektion')->__('Daily Feed'),
73
+ Reflektion_Catalogexport_Model_Job::TYPE_TRANSFER => Mage::helper('reflektion')->__('Transfer File'),
74
+ Reflektion_Catalogexport_Model_Job::TYPE_TRANSFER_MANUAL => Mage::helper('reflektion')->__('Transfer File Manual'),
75
+ ),
76
+ ));
77
+
78
+ $this->addColumn('feed_type', array(
79
+ 'header' => Mage::helper('reflektion')->__('Feed Type'),
80
+ 'index' => 'feed_type'
81
+ ));
82
+
83
+ $this->addColumn('scheduled_at', array(
84
+ 'header' => Mage::helper('reflektion')->__('Scheduled'),
85
+ 'type' => 'datetime',
86
+ 'index' => 'scheduled_at'
87
+ ));
88
+
89
+ $this->addColumn('ended_at', array(
90
+ 'header' => Mage::helper('reflektion')->__('Completed'),
91
+ 'type' => 'datetime',
92
+ 'width' => '160px',
93
+ 'index' => 'ended_at'
94
+ ));
95
+
96
+ $this->addColumn('status', array(
97
+ 'header' => Mage::helper('reflektion')->__('Status'),
98
+ 'width' => '100px',
99
+ 'index' => 'status',
100
+ 'type' => 'options',
101
+ 'options' => array(
102
+ Reflektion_Catalogexport_Model_Job::STATUS_SCHEDULED => Mage::helper('reflektion')->__('Scheduled'),
103
+ Reflektion_Catalogexport_Model_Job::STATUS_RUNNING => Mage::helper('reflektion')->__('Running'),
104
+ Reflektion_Catalogexport_Model_Job::STATUS_COMPLETED => Mage::helper('reflektion')->__('Completed'),
105
+ Reflektion_Catalogexport_Model_Job::STATUS_ERROR => Mage::helper('reflektion')->__('Error'),
106
+ Reflektion_Catalogexport_Model_Job::STATUS_MANUAL => Mage::helper('reflektion')->__('Manual'),
107
+ ),
108
+ ));
109
+ return parent::_prepareColumns();
110
+ }
111
+
112
+ protected function _prepareMassaction() {
113
+ $this->setMassactionIdField('job_id');
114
+ $this->getMassactionBlock()->setFormFieldName('job_id');
115
+
116
+ $this->getMassactionBlock()->addItem('delete', array(
117
+ 'label' => Mage::helper('reflektion')->__('Delete'),
118
+ 'url' => $this->getUrl('*/*/massDelete'),
119
+ 'confirm' => Mage::helper('reflektion')->__('Delete selected job(s)?')
120
+ ));
121
+
122
+ $this->getMassactionBlock()->addItem('execute', array(
123
+ 'label' => Mage::helper('reflektion')->__('Run Job'),
124
+ 'url' => $this->getUrl('*/*/massRun'),
125
+ 'confirm' => Mage::helper('reflektion')->__('Run selected job(s)? Note that running multiple and/or jobs may impact site performance.')
126
+ ));
127
+
128
+ return $this;
129
+ }
130
+
131
+ }
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/Config/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/Config/CommentText.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @category Reflektion
4
+ * @package Reflektion_Catalogexport
5
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
6
+ * @createdOn 02 Mar 2016
7
+ * @license https://opensource.org/licenses/OSL-3.0
8
+ * @description To add comment in system config fields
9
+ */
10
+
11
+ class Reflektion_Catalogexport_Block_Adminhtml_System_Config_CommentText extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
12
+
13
+ {
14
+ public function render(Varien_Data_Form_Element_Abstract $element)
15
+ {
16
+ return $element->getComment();
17
+ }
18
+ }
app/code/community/Reflektion/Catalogexport/Helper/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Helper/Csvfile.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description CSV files operations - create, open, reopen, close and write
10
+ */
11
+ class Reflektion_Catalogexport_Helper_Csvfile extends Mage_Core_Helper_Abstract {
12
+
13
+ private $_filename;
14
+ private $_handle;
15
+ private $_path;
16
+ private $_errorMessage;
17
+ private $_columnHeaders;
18
+
19
+ public function __construct() {
20
+ $this->_filename = null;
21
+ $this->_handle = null;
22
+ $this->_path = null;
23
+ $this->_errorMessage = null;
24
+ }
25
+
26
+ /**
27
+ * Open file
28
+ * @param array $columnHeaders An array of column header names, one for each column
29
+ * @param string $filename fully qualified filename + path. (directory must be writable)
30
+ * @return boolean
31
+ */
32
+ public function open($filename, array $columnHeaders) {
33
+ $this->_columnHeaders = $columnHeaders;
34
+ $this->_filename = $filename;
35
+
36
+ try {
37
+ // Open file
38
+ $this->_handle = fopen($this->_filename, 'w');
39
+ // Build header row string
40
+ $rowString = implode(",", $this->encodeFields($columnHeaders)) . "\r\n";
41
+ // Write row to file
42
+ $result = fwrite($this->_handle, $rowString);
43
+ } catch (Exception $e) {
44
+ Mage::logException($e);
45
+ return false;
46
+ }
47
+
48
+ return true;
49
+ }
50
+
51
+ /**
52
+ * Re Open existing file
53
+ * @param string $filename fully qualified filename + path. (directory must be writable)
54
+ * @return boolean
55
+ */
56
+ public function reopen($filename, array $columnHeaders) {
57
+ $this->_columnHeaders = $columnHeaders;
58
+ $this->_filename = $filename;
59
+
60
+ try {
61
+ // Reopen file
62
+ $this->_handle = fopen($this->_filename, 'a');
63
+ } catch (Exception $e) {
64
+ Mage::logException($e);
65
+ return false;
66
+ }
67
+
68
+ return true;
69
+ }
70
+
71
+ /**
72
+ * Close file
73
+ */
74
+ public function close() {
75
+ try {
76
+ fclose($this->_handle);
77
+ } catch (Exception $e) {
78
+ Mage::logException($e);
79
+ return false;
80
+ }
81
+
82
+ return true;
83
+ }
84
+
85
+ /**
86
+ * Write row to file
87
+ *
88
+ * @param array $rowValues An associative array of columns => values, cells for columns not included in this row are left empty
89
+ * @return boolean
90
+ */
91
+ public function writeRow(array $rowValues) {
92
+ try {
93
+ // Filter
94
+ $selectedRowValues = array();
95
+ foreach ($this->_columnHeaders as $columnHeader) {
96
+ if (array_key_exists($columnHeader, $rowValues)) {
97
+ $selectedRowValues[] = $rowValues[$columnHeader];
98
+ } else {
99
+ $selectedRowValues[] = "";
100
+ }
101
+ }
102
+ // Convert to utf8
103
+ $convertedRowValues = $this->encodeFields($selectedRowValues);
104
+ // Build row string
105
+ $rowString = implode(",", $convertedRowValues) . "\r\n";
106
+ // Write row to file
107
+ $result = fwrite($this->_handle, $rowString);
108
+ // Check result
109
+ if ($result != strlen($rowString)) {
110
+ return false;
111
+ }
112
+ } catch (Exception $e) {
113
+ Mage::logException($e);
114
+ return false;
115
+ }
116
+
117
+ return true;
118
+ }
119
+
120
+ /**
121
+ * Convert strings in array to Utf8 and encode for CSV file usage
122
+ * @param array $values
123
+ * @return array $converted
124
+ */
125
+ private function encodeFields(array $values) {
126
+ $converted = array();
127
+ foreach ($values as $value) {
128
+ // Encode in utf8
129
+ $newVal = utf8_encode($value);
130
+ $newVal = str_replace('"', '""', $newVal);
131
+ // Delimiter
132
+ $newVal = '"' . $newVal . '"';
133
+ // Converted array
134
+ array_push($converted, $newVal);
135
+ }
136
+
137
+ return $converted;
138
+ }
139
+
140
+ }
app/code/community/Reflektion/Catalogexport/Helper/Data.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ *
10
+ */
11
+ class Reflektion_Catalogexport_Helper_Data extends Mage_Core_Helper_Abstract {
12
+
13
+ const LOG_FILE = 'reflektion.log';
14
+
15
+ /*
16
+ * Example of how logging should be done in this extension :
17
+ * Mage::helper('reflektion')->log($message, Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
18
+ */
19
+
20
+ public function log($message, $level = null, $file = null, $force = false) {
21
+ $force = $force ||
22
+ (Mage::getStoreConfig('reflektion_datafeeds/advanced/force_logging') !== "disabled");
23
+ Mage::log($message, $level, $file, $force);
24
+ }
25
+
26
+ /**
27
+ * Validate feed configuration settings for one website or all websites
28
+ */
29
+ public function validateFeedConfiguration($websiteId = null) {
30
+ $websites = array();
31
+ if ($websiteId) {
32
+ $websites[] = $websiteId;
33
+ } else {
34
+ $websiteModels = Mage::app()->getWebsites(false, true);
35
+ foreach ($websiteModels as $curWebsite) {
36
+ $websites[] = $curWebsite->getId();
37
+ }
38
+ }
39
+
40
+ //Track if feeds enabled for any website
41
+ $bFeedsEnabled = false;
42
+ foreach ($websites as $curWebsiteId) {
43
+ // If config is enabled
44
+ if (Mage::app()->getWebsite($curWebsiteId)->getConfig('reflektion_datafeeds/general/allfeedsenabled') == 'enabled') {
45
+ $bFeedsEnabled = true;
46
+
47
+ try {
48
+ // Get hostname, port & credentials
49
+ $sftpHost = Mage::app()->getWebsite($curWebsiteId)->getConfig('reflektion_datafeeds/connect/hostname');
50
+ $sftpPort = Mage::app()->getWebsite($curWebsiteId)->getConfig('reflektion_datafeeds/connect/port');
51
+ $sftpUser = Mage::app()->getWebsite($curWebsiteId)->getConfig('reflektion_datafeeds/connect/username');
52
+ $sftpPassword = Mage::app()->getWebsite($curWebsiteId)->getConfig('reflektion_datafeeds/connect/password');
53
+ } catch (Exception $e) {
54
+ Mage::logException($e);
55
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
56
+ Mage::throwException('Error looking up feed transfer connectivity parameters for website id: ' . $curWebsiteId);
57
+ }
58
+ // Check SFTP credentials
59
+ if (strlen($sftpHost) <= 0) {
60
+ Mage::throwException('SFTP host (' . $sftpHost . ') is invalid for website id: ' . $curWebsiteId);
61
+ }
62
+ if (strlen($sftpPort) <= 0 || $sftpPort < 1 || $sftpPort > 65535) {
63
+ Mage::throwException('SFTP port (' . $sftpPort . ') is invalid for website id: ' . $curWebsiteId);
64
+ }
65
+ if (strlen($sftpUser) <= 0) {
66
+ Mage::throwException('SFTP user (' . $sftpUser . ') is invalid for website id: ' . $curWebsiteId);
67
+ }
68
+ if (strlen($sftpPassword) <= 0) {
69
+ Mage::throwException('SFTP password is invalid for website id: ' . $curWebsiteId);
70
+ }
71
+ }
72
+ }
73
+
74
+ // Send error message
75
+ if (!$bFeedsEnabled) {
76
+ Mage::throwException('Data feeds not enabled');
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Description To get the Categories list with breadcrum
82
+ */
83
+ function getTreeCategories($parentId) {
84
+
85
+ $allCats = Mage::getModel('catalog/category')->getCollection()
86
+ ->addAttributeToSelect('*')
87
+ ->addAttributeToFilter('is_active', '1')
88
+ ->addAttributeToFilter('include_in_menu', '1')
89
+ ->addAttributeToFilter('parent_id', array('eq' => $parentId));
90
+
91
+ foreach ($allCats as $category) {
92
+ $this->str .= $category->getName();
93
+ $this->allCat[$category->getId()] = $this->str;
94
+ $subcats = $category->getChildren();
95
+ if ($subcats != '') {
96
+ $this->str .= " > ";
97
+ $this->getTreeCategories($category->getId());
98
+ } else {
99
+ $this->str = '';
100
+ }
101
+ }
102
+ return $this->allCat;
103
+ }
104
+
105
+ }
app/code/community/Reflektion/Catalogexport/Helper/SftpConnection.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description SFTP connect, transfer and close functions
10
+ * - Using magento library phpseclib
11
+ */
12
+ require_once('phpseclib/Net/SFTP.php');
13
+
14
+ class Reflektion_Catalogexport_Helper_SftpConnection extends Mage_Core_Helper_Abstract {
15
+
16
+ const SFTP_TIMEOUT = 20;
17
+
18
+ private $_oConnection = null;
19
+
20
+ /**
21
+ * Connect
22
+ * @return boolean
23
+ */
24
+ public function connect($host, $port, $user, $pw) {
25
+
26
+ try {
27
+ if (isset($this->_oConnection)) {
28
+ $this->close();
29
+ }
30
+
31
+ // Config values
32
+ $sServer = $host;
33
+ $sServer = ($sServer ? trim($sServer) : '');
34
+ $sPort = $port;
35
+ $sPort = ($sPort ? trim($sPort) : '');
36
+ $sUsername = $user;
37
+ $sUsername = ($sUsername ? trim($sUsername) : '');
38
+ $sPassword = $pw;
39
+ $sPassword = ($sPassword ? trim($sPassword) : '');
40
+
41
+ // Check credentials
42
+ if (!strlen($sServer)) {
43
+ Mage::throwException('Invalid SFTP host: ' . $sServer);
44
+ }
45
+ if (!strlen($sPort) || !ctype_digit($sPort)) {
46
+ Mage::throwException('Invalid SFTP port: ' . $sPort);
47
+ }
48
+ if (!strlen($sUsername)) {
49
+ Mage::throwException('Invalid SFTP user: ' . $sUsername);
50
+ }
51
+ if (!strlen($sPassword)) {
52
+ Mage::throwException('Invalid SFTP password: ' . $sPassword);
53
+ }
54
+ $this->_oConnection = new Net_SFTP($sServer, $sPort, self::SFTP_TIMEOUT);
55
+ if (!$this->_oConnection->login($sUsername, $sPassword)) {
56
+ Mage::throwException(sprintf(__("Unable to open SFTP connection as %s@%s %s", $sUsername, $sServer, $sPassword)));
57
+ }
58
+
59
+ return true;
60
+ } catch (Exception $e) {
61
+ Mage::logException($e);
62
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
63
+ Mage::helper('reflektion')->log("SFTP reported error is " . $e, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
64
+ }
65
+ return false;
66
+ }
67
+
68
+ /**
69
+ * Close
70
+ * @return boolean
71
+ */
72
+ public function close() {
73
+ try {
74
+ // Close connection
75
+ if (isset($this->_oConnection)) {
76
+ $bRes = $this->_oConnection->disconnect();
77
+ unset($this->_oConnection);
78
+ return $bRes;
79
+ } else {
80
+ Mage::throwException('Connection not open!');
81
+ }
82
+ } catch (Exception $e) {
83
+ Mage::logException($e);
84
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
85
+ }
86
+
87
+ return false;
88
+ }
89
+
90
+ /**
91
+ * Is connected
92
+ * @return boolean
93
+ */
94
+ public function isConnected() {
95
+ return (isset($this->_oConnection));
96
+ }
97
+
98
+ /**
99
+ * Change directory
100
+ * @param string directory
101
+ * @return boolean
102
+ */
103
+ public function changeDir($sDir) {
104
+ try {
105
+ if (!$this->isConnected()) {
106
+ return false;
107
+ }
108
+ return $this->_oConnection->chdir($sDir);
109
+ } catch (Exception $e) {
110
+ Mage::logException($e);
111
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
112
+ }
113
+
114
+ return false;
115
+ }
116
+
117
+ /**
118
+ * Make directory
119
+ * @param string directory
120
+ * @return boolean
121
+ */
122
+ public function makeDir($sDir) {
123
+ try {
124
+ // Close connection
125
+ if (!$this->isConnected()) {
126
+ return false;
127
+ }
128
+ return $this->_oConnection->mkdir($sDir);
129
+ } catch (Exception $e) {
130
+ Mage::logException($e);
131
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
132
+ }
133
+
134
+ return false;
135
+ }
136
+
137
+ /**
138
+ * List files
139
+ * @param string directory
140
+ * @return array
141
+ */
142
+ public function listFiles($sDir = '.') {
143
+ try {
144
+ // Close connection
145
+ if (!$this->isConnected()) {
146
+ return false;
147
+ }
148
+ return $this->_oConnection->nlist($sDir);
149
+ } catch (Exception $e) {
150
+ Mage::logException($e);
151
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
152
+ }
153
+
154
+ return false;
155
+ }
156
+
157
+ /**
158
+ * Transfer file
159
+ * @param string Local file path
160
+ * @return boolean
161
+ */
162
+ public function putFile($sLocalFilePath) {
163
+ try {
164
+ // Close connection
165
+ if (!$this->isConnected()) {
166
+ return false;
167
+ }
168
+ $sFilename = basename($sLocalFilePath); // Get filename
169
+ // Transfer
170
+ $bSuccess = $this->_oConnection->put($sFilename, $sLocalFilePath, NET_SFTP_LOCAL_FILE);
171
+ if (!$bSuccess) {
172
+ Mage::helper('reflektion')->log('SFTP Error: ' . $this->_oConnection->getLastSFTPError(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
173
+ }
174
+ return $bSuccess;
175
+ } catch (Exception $e) {
176
+ Mage::logException($e);
177
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
178
+ }
179
+
180
+ return false;
181
+ }
182
+
183
+ /**
184
+ * Transfer file and delete when successful as one atomic operation
185
+ * @param string Local file path
186
+ * @return boolean
187
+ */
188
+ public function putAndDeleteFile($sLocalFilePath) {
189
+ try {
190
+ $bSuccess = $this->putFile($sLocalFilePath);
191
+ if ($bSuccess) {
192
+ $oIo = new Varien_Io_File();
193
+ $oIo->rm($sLocalFilePath);
194
+ }
195
+ return $bSuccess;
196
+ } catch (Exception $e) {
197
+ Mage::logException($e);
198
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
199
+ }
200
+
201
+ return false;
202
+ }
203
+
204
+ }
app/code/community/Reflektion/Catalogexport/Model/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Model/Feed/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Model/Feed/Base.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Base file to manage attributes while exporting
10
+ */
11
+ class Reflektion_Catalogexport_Model_Feed_Base extends Mage_Core_Model_Abstract {
12
+
13
+ protected $_optionValueMap = array();
14
+ protected $_attrSetIdToName = array();
15
+
16
+ protected function _initAttributeSets($storeId = 0) {
17
+ $optionValueTable = Mage::getSingleton('core/resource')->getTableName('eav/attribute_option_value');
18
+ $sql = "select option_id, value from $optionValueTable where store_id=$storeId";
19
+ $attributeValues = Mage::getSingleton('core/resource')
20
+ ->getConnection('default_read')
21
+ ->fetchAll($sql);
22
+
23
+ //create an array
24
+ foreach ($attributeValues as $values) {
25
+ $this->_attrSetIdToName[$values['option_id']] = $values['value'];
26
+ }
27
+
28
+ return $this;
29
+ }
30
+
31
+ /**
32
+ * Add custom attributes selected by magento admin to query
33
+ *
34
+ * @param $collection Collection of data which will be spit out as feed
35
+ * @param $customAttribs Comma separated list of attribute codes
36
+ * @param $fieldMap Reference to fieldmap where attribute codes should also be added
37
+ */
38
+ protected function addCustomAttributes($collection, $customAttribs, &$fieldMap) {
39
+ Mage::helper('reflektion')->log("Adding custom attributes include in query: {$customAttribs}", Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
40
+ //Check if we have any custom attributes
41
+ if (strlen(trim($customAttribs)) > 0) {
42
+ foreach (explode(',', $customAttribs) as $curAttrib) {
43
+ $curAttrib = trim($curAttrib);
44
+
45
+ $_attribute = $collection->getAttribute($curAttrib);
46
+ if ($_attribute === false) {
47
+ Mage::throwException("Attribte not found: {$curAttrib}");
48
+ }
49
+ Mage::helper('reflektion')->log("Adding attribute to query: {$curAttrib}", Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
50
+
51
+ if ($_attribute->getFrontendInput() == "select" || $_attribute->getFrontendInput() == "multiselect") {
52
+ Mage::helper('reflektion')->log("Note - Attribute needs translation", Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
53
+ $this->_optionValueMap['custom_' . $curAttrib] = true;
54
+ }
55
+ // Attribute to select
56
+ $collection
57
+ ->addExpressionAttributeToSelect('custom_' . $curAttrib, "{{" . $curAttrib . "}}", $curAttrib)
58
+ ->addAttributeToSelect($curAttrib);
59
+ // Attribute to map
60
+ $fieldMap['custom_' . $curAttrib] = 'custom_' . $curAttrib;
61
+ }
62
+ }
63
+
64
+ return $collection;
65
+ }
66
+
67
+ /**
68
+ * Generate one feed for this website and store feed file at the specified path
69
+ *
70
+ * @param $websiteId Id of the website for which to generate data feed file
71
+ * @param $exportPath Path to the folder where data feed files should be stored
72
+ * @param $bBaselineFile Should this file be a baseline file or an automated daily file
73
+ * @param $minEntityId Number representing minimum value for entity Id to export - This acts as a placeholder for where the feed export left off
74
+ * @param $bDone Indicates when the feed generation is done
75
+ */
76
+ public function generate($websiteId, $exportPath, $bBaselineFile, &$minEntityId, &$bDone) {
77
+ Mage::helper('reflektion')->log('Generating ' . $this->getFileNameKey() . ' data feed for website with Id: ' . $websiteId, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
78
+ Mage::helper('reflektion')->log("Export path: {$exportPath}", Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
79
+ Mage::helper('reflektion')->log("Baseline feed: {$bBaselineFile}", Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
80
+ Mage::helper('reflektion')->log("Min entity_id: {$minEntityId}", Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
81
+
82
+ $bDone = false;
83
+
84
+ $websitecode = Mage::app()->getWebsite($websiteId)->getCode();
85
+
86
+ $incrementalDate = date("Y-m-d-H-m-s", time());
87
+
88
+ $websiteName = parse_url(Mage::app()->getWebsite($websiteId)->getDefaultStore()->getBaseUrl(), PHP_URL_HOST);
89
+
90
+ // file generate
91
+ $filename = $exportPath . DS . $websiteName . '_' . $websiteId . '_product_feed.csv';
92
+
93
+ Mage::helper('reflektion')->log("Output Filename: {$filename}", Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
94
+
95
+ $collection = $this->getFeedCollection($websiteId);
96
+
97
+
98
+ if (!$bBaselineFile) {
99
+ $collection = $this->addIncrementalFilter($collection, $incrementalDate);
100
+ }
101
+ $headerColumns = array_values($this->getFieldMap());
102
+ // Create output file
103
+ $file = Mage::helper('reflektion/csvfile');
104
+ // New file with headers
105
+ $bSuccess = $file->open($filename, $headerColumns);
106
+
107
+ if (!$bSuccess) {
108
+ Mage::helper('reflektion')->log('Failed to open data feed file:' . $filename, Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
109
+ return false;
110
+ }
111
+ //get all the website attribute
112
+ Mage::helper('reflektion')->log('Initializing attribute values', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
113
+ $this->_initAttributeSets();
114
+ $rootCatId = Mage::app()->getWebsite($websiteId)->getDefaultStore()->getRootCategoryId();
115
+ $catlistHtml = Mage::helper('reflektion')->getTreeCategories($rootCatId);
116
+ foreach ($collection as $curRow) {
117
+ $curRowData = $curRow->getData();
118
+ $rowValues = array();
119
+
120
+ foreach ($this->getFieldMap() as $mapKey => $mapValue) {
121
+ // If the attribute is a select or multiselect then we need to translate the
122
+ // option id value into the display value
123
+ if (array_key_exists($mapKey, $this->_optionValueMap)) {
124
+ $items = explode(",", $curRowData[$mapKey]);
125
+ $attrList = array();
126
+ foreach ($items as $item) {
127
+ if (array_key_exists($item, $this->_attrSetIdToName)) {
128
+ $attrList[] = $this->_attrSetIdToName[$item];
129
+ } else {
130
+ $attrList[] = "";
131
+ }
132
+ }
133
+ $rowValues[$mapValue] = implode(",", $attrList);
134
+ } else {
135
+ if ($mapKey == "category_ids") {
136
+ $arrayTempCat = array();
137
+ $arrayCats = explode(" | ", $curRowData[$mapKey]);
138
+ foreach ($arrayCats as $arrayCat) {
139
+
140
+ $arrayTempCat[] = $catlistHtml[$arrayCat];
141
+ }
142
+ $curRowData[$mapKey] = implode(" | ", $arrayTempCat);
143
+ }
144
+ if (array_key_exists($mapKey, $curRowData)) {
145
+ $rowValues[$mapValue] = $curRowData[$mapKey];
146
+ } else {
147
+ $rowValues[$mapValue] = "";
148
+ }
149
+ }
150
+ }
151
+
152
+ $bSuccess = $file->writeRow($rowValues);
153
+ if (!$bSuccess) {
154
+ Mage::helper('reflektion')->log('Failed to write to data feed file: ' . $filename, Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
155
+ $file->close();
156
+ return false;
157
+ }
158
+
159
+ // Collect last entity Id and generate new minEntityId param
160
+ $minEntityId = $curRow->getEntityId() + 1;
161
+ }
162
+ // Check if export is done
163
+ if (count($collection) > 0) {
164
+ $bDone = true;
165
+ }
166
+
167
+ $bSuccess = $file->close();
168
+ if (!$bSuccess) {
169
+ Mage::helper('reflektion')->log('Failed to close data feed file: ' . $filename, Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
170
+ return false;
171
+ }
172
+ }
173
+
174
+ }
app/code/community/Reflektion/Catalogexport/Model/Feed/Product.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Product attributes operations
10
+ */
11
+ class Reflektion_Catalogexport_Model_Feed_Product extends Reflektion_Catalogexport_Model_Feed_Base {
12
+
13
+ // Magento product fields to Reflektion Product Feed
14
+
15
+ private $fieldMap = array(
16
+ 'sku' => 'id',
17
+ 'name' => 'name',
18
+ 'description' => 'description',
19
+ 'product_url' => 'product_url',
20
+ 'image_url' => 'image_url',
21
+ 'thumbnail' => 'thumbnail',
22
+ 'small_image' => 'small_image',
23
+ 'category_ids' => 'breadcrumbs - Category IDs',
24
+ 'price' => 'price',
25
+ 'final_price' => 'special_price',
26
+ 'status' => 'status',
27
+ 'adj_qty' => 'Inventory Quantity',
28
+ 'is_in_stock' => 'Inventory Status',
29
+ 'type_id' => 'Product Type',
30
+ );
31
+
32
+ public function getFieldMap() {
33
+ return $this->fieldMap;
34
+ }
35
+
36
+ // File name key
37
+ public function getFileNameKey() {
38
+ return 'product';
39
+ }
40
+
41
+ /**
42
+ * Build collection to do query
43
+ *
44
+ * @param $websiteId Which website to query for collection
45
+ */
46
+ public function getFeedCollection($websiteId) {
47
+
48
+ $collection = Mage::getResourceModel('catalog/product_collection');
49
+
50
+ $collection
51
+ ->addAttributeToSelect('name');
52
+
53
+ $collection
54
+ ->addAttributeToSelect('description');
55
+
56
+ // Filter feed for given website
57
+ $collection
58
+ ->addWebsiteFilter($websiteId);
59
+
60
+ $collection
61
+ ->addPriceData(null, $websiteId); //Have to use this version so you can set the website id
62
+ // Add stock level fields
63
+ $collection->joinTable(
64
+ array('at_qty' => 'cataloginventory/stock_item'), 'product_id=entity_id', array('qty' => 'qty', 'is_in_stock' => 'is_in_stock'), '{{table}}.stock_id=1', 'left');
65
+
66
+ $prodCatTable = $collection->getTable('catalog/category_product');
67
+ $collection->getSelect()
68
+ ->columns(array(
69
+ 'category_ids' =>
70
+ ' (select ' .
71
+ " group_concat(distinct "
72
+ . "pc.category_id"
73
+ . " separator ' | ') " .
74
+ ' from ' . $prodCatTable . ' pc ' .
75
+ ' where ' .
76
+ ' pc.product_id = e.entity_id) '
77
+ ,));
78
+
79
+ // Add full product page URL
80
+ $baseUrl = Mage::app()->getWebsite($websiteId)->getDefaultStore()->getBaseUrl();
81
+ $coreRewriteTable = $collection->getTable('core/url_rewrite');
82
+ $collection->getSelect()
83
+ ->columns(array(
84
+ 'product_url' =>
85
+ " (select " .
86
+ " concat('{$baseUrl}', url.request_path) " .
87
+ " from " .
88
+ " {$coreRewriteTable} url " .
89
+ " where " .
90
+ " id_path = concat('product/', e.entity_id) " .
91
+ " limit 1) "
92
+ ,));
93
+
94
+ // Add product image URL
95
+ $imageBaseURL = Mage::app()->getWebsite($websiteId)->getDefaultStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . "catalog/product";
96
+ $collection
97
+ ->addExpressionAttributeToSelect(
98
+ 'image_url', "if({{image}} <> 'no_selection', " .
99
+ " concat('{$imageBaseURL}', {{image}}), " .
100
+ " '')", 'image'
101
+ );
102
+
103
+ $collection
104
+ ->addExpressionAttributeToSelect(
105
+ 'small_image', "if({{small_image}} <> 'no_selection', " .
106
+ " concat('{$imageBaseURL}', {{small_image}}), " .
107
+ " '')", 'small_image'
108
+ );
109
+
110
+ $collection
111
+ ->addExpressionAttributeToSelect(
112
+ 'thumbnail', "if({{thumbnail}} <> 'no_selection', " .
113
+ " concat('{$imageBaseURL}', {{thumbnail}}), " .
114
+ " '')", 'thumbnail'
115
+ );
116
+
117
+ // Check Status, visibility and is_in_stock
118
+ $collection
119
+ ->addExpressionAttributeToSelect('cur_status', "{{status}}", 'status');
120
+
121
+ $collection
122
+ ->addExpressionAttributeToSelect(
123
+ 'adj_qty', "if({{type_id}} = 'simple', " .
124
+ "at_qty.qty, " .
125
+ "if (at_qty.is_in_stock=1, " .
126
+ "if (at_qty.qty>0, " .
127
+ "at_qty.qty, at_qty.is_in_stock)," .
128
+ "at_qty.is_in_stock))", 'type_id'
129
+ );
130
+
131
+ // Custom attributes to feed
132
+ $customAttribs = Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/feedsenabled/product_attributes');
133
+ $collection = $this->addCustomAttributes($collection, $customAttribs, $this->fieldMap);
134
+
135
+ return $collection;
136
+ }
137
+
138
+ /**
139
+ * Add filter to collection to make it only include records necessary for automatic daily feed (instead of one-time baseline feed).
140
+ *
141
+ * @param Varien_Data_Collection_Db $collection Collection of data which will be spit out as feed
142
+ */
143
+ protected function addIncrementalFilter($collection, $incrementalDate = NULL) {
144
+ Mage::helper('reflektion')->log('Adding incremental filters to product feed', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
145
+ // Stock items Filter
146
+ $collection->
147
+ addAttributeToFilter('is_in_stock', 1);
148
+
149
+ return $collection;
150
+ }
151
+
152
+ }
app/code/community/Reflektion/Catalogexport/Model/Generatefeeds.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Generate catalog product feeds output(CSV) in queue
10
+ */
11
+ class Reflektion_Catalogexport_Model_Generatefeeds {
12
+
13
+ const REFLEKTION_FEED_PATH = 'reflektion/feeds';
14
+
15
+ protected static $feedTypes = array(
16
+ 'product'
17
+ );
18
+
19
+ protected function _construct() {
20
+
21
+ }
22
+
23
+ /**
24
+ * Return a list of possible feed types
25
+ *
26
+ * @returns array Array of all known feeds types
27
+ */
28
+ public static function getFeedTypes() {
29
+ return self::$feedTypes;
30
+ }
31
+
32
+ /**
33
+ * Generate data feeds for this specific website
34
+ *
35
+ * @param $websiteId Id of the website for which to generate data feeds
36
+ * @param $bBaselineFile Should this file be a baseline file or an automated daily file
37
+ * @param $feedType Type of feed to generate, null = generate all feeds
38
+ * @param $minEntityId Number representing minimum value for entity Id to export - This acts as a placeholder for where the feed export left off
39
+ */
40
+ public function generateForWebsite($websiteId, $bBaselineFile, $feedType, &$minEntityId, &$bDone) {
41
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
42
+
43
+ if (Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/general/allfeedsenabled') != 'enabled' ||
44
+ Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/feedsenabled/' . $feedType) != 'enabled') {
45
+ Mage::throwException('Data feeds or feedtype ' . $feedType . ' not enabled for website: ' . $websiteId);
46
+ }
47
+
48
+ $feedExportPath = Mage::getConfig()->getVarDir() . DS . Reflektion_Catalogexport_Model_Generatefeeds::REFLEKTION_FEED_PATH;
49
+ $oIo = new Varien_Io_File();
50
+ $oIo->checkAndCreateFolder($feedExportPath);
51
+
52
+ $modelFeed = Mage::getModel('reflektion/feed_' . $feedType);
53
+ $modelFeed->generate($websiteId, $feedExportPath, $bBaselineFile, $minEntityId, $bDone);
54
+ }
55
+
56
+ }
app/code/community/Reflektion/Catalogexport/Model/Job.php ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Generate Jobs in queue - manual or cron jobs
10
+ */
11
+ class Reflektion_Catalogexport_Model_Job extends Mage_Core_Model_Abstract {
12
+
13
+ /**
14
+ * Job Types
15
+ */
16
+ const TYPE_GENERATE_BASELINE = 1;
17
+ const TYPE_GENERATE_DAILY = 2;
18
+ const TYPE_TRANSFER = 3;
19
+ const TYPE_TRANSFER_MANUAL = 4;
20
+
21
+ /**
22
+ * Statuses
23
+ */
24
+ const STATUS_SCHEDULED = 1;
25
+ const STATUS_RUNNING = 2;
26
+ const STATUS_COMPLETED = 3;
27
+ const STATUS_ERROR = 4;
28
+ const STATUS_MANUAL = 5;
29
+
30
+ public function _construct() {
31
+ parent::_construct();
32
+ $this->_init('reflektion/job');
33
+ }
34
+
35
+ /**
36
+ * Pull the next job to run from the queue and set status to running
37
+ */
38
+ public static function getNextJobFromQueue() {
39
+ Mage::helper('reflektion')->log('Getting next job from the queue.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
40
+ $collection = Mage::getResourceModel('reflektion/job_collection');
41
+
42
+ $table = $collection->getTable('reflektion/job');
43
+
44
+ $collection->getSelect()
45
+ ->where('status = ' . Reflektion_Catalogexport_Model_Job::STATUS_SCHEDULED . ' or status = ' . Reflektion_Catalogexport_Model_Job::STATUS_RUNNING)
46
+ ->where(Reflektion_Catalogexport_Model_Job::STATUS_SCHEDULED . " not in (select status from {$table} mbj2 where mbj2.job_id = main_table.dependent_on_job_id) ")
47
+ ->order('job_id')
48
+ ->limit(1);
49
+
50
+ foreach ($collection as $job) {
51
+ Mage::helper('reflektion')->log('Found job id: ' . $job->getJobId(), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
52
+ $job->setStatus(Reflektion_Catalogexport_Model_Job::STATUS_RUNNING);
53
+ $job->setStartedAt(Mage::getSingleton('core/date')->gmtDate());
54
+ $job->save();
55
+ return $job;
56
+ }
57
+ Mage::helper('reflektion')->log('No jobs found.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
58
+ return false;
59
+ }
60
+
61
+ /**
62
+ * Create a new job object
63
+ */
64
+ public static function createJob($dependentOnJobId, $websiteId, $type, $feedType, $isBaseTran = 0) {
65
+ if (Reflektion_Catalogexport_Model_Job::TYPE_GENERATE_BASELINE == $type) {
66
+ $status = Reflektion_Catalogexport_Model_Job::STATUS_MANUAL;
67
+ } elseif ($isBaseTran == 1) {
68
+ $status = Reflektion_Catalogexport_Model_Job::STATUS_MANUAL;
69
+ $type = Reflektion_Catalogexport_Model_Job::TYPE_TRANSFER_MANUAL;
70
+ } else {
71
+ $status = Reflektion_Catalogexport_Model_Job::STATUS_SCHEDULED;
72
+ }
73
+ Mage::helper('reflektion')->log('Scheduling new job.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
74
+ $newJob = Mage::getModel('reflektion/job');
75
+ $newJob->setDependentOnJobId($dependentOnJobId);
76
+ $newJob->setMinEntityId(0);
77
+ $newJob->setWebsiteId($websiteId);
78
+ $newJob->setType($type);
79
+ $newJob->setFeedType($feedType);
80
+ $newJob->setScheduledAt(Mage::getSingleton('core/date')->gmtDate());
81
+ $newJob->setStatus($status);
82
+ $newJob->save();
83
+ return $newJob;
84
+ }
85
+
86
+ /**
87
+ * Schedule all the necessary daily jobs for today
88
+ */
89
+ public static function scheduleAllDailyJobs() {
90
+ $websites = Mage::app()->getWebsites(false, true);
91
+ foreach ($websites as $website) {
92
+ Reflektion_Catalogexport_Model_Job::scheduleJobs($website->getId(), false);
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Schedule all daily or baseline jobs for all websites to run immediately
98
+ */
99
+ public static function scheduleJobsAllWebsites($bBaselineFile) {
100
+ $websites = Mage::app()->getWebsites(false, true);
101
+ foreach ($websites as $website) {
102
+ $websiteId = $website->getId();
103
+ Reflektion_Catalogexport_Model_Job::scheduleJobs($websiteId, $bBaselineFile);
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Schedule baseline or incremental daily jobs to run immediately
109
+ */
110
+ public static function scheduleJobs($websiteId, $bBaselineFile) {
111
+ Mage::helper('reflektion')->log('Scheduling jobs for website: ' . $websiteId, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
112
+ Mage::helper('reflektion')->log('All feeds for website set to: ' . Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/general/allfeedsenabled'), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
113
+ $lastJobId = null;
114
+ if (Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/general/allfeedsenabled') != 'enabled') {
115
+ return;
116
+ }
117
+ // Generate jobs - enabled feeds
118
+ foreach (Reflektion_Catalogexport_Model_Generatefeeds::getFeedTypes() as $curType) {
119
+ // Create feed job
120
+ if (Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/feedsenabled/' . $curType) == 'enabled') {
121
+ // Check manual or daily
122
+ $jobType = 0;
123
+ if ($bBaselineFile) {
124
+ $jobType = Reflektion_Catalogexport_Model_Job::TYPE_GENERATE_BASELINE;
125
+ $isBaseTran = 1;
126
+ } else {
127
+ $jobType = Reflektion_Catalogexport_Model_Job::TYPE_GENERATE_DAILY;
128
+ $isBaseTran = 0;
129
+ }
130
+
131
+ $job = Reflektion_Catalogexport_Model_Job::createJob($lastJobId, $websiteId, $jobType, $curType);
132
+ $job->save();
133
+ $lastJobId = $job->getJobId();
134
+ }
135
+ }
136
+
137
+ // Transfer feeds job
138
+ $job = Reflektion_Catalogexport_Model_Job::createJob($lastJobId, $websiteId, Reflektion_Catalogexport_Model_Job::TYPE_TRANSFER, NULL, $isBaseTran);
139
+ $job->save();
140
+ }
141
+
142
+ /**
143
+ * Run job
144
+ */
145
+ public function run() {
146
+ try {
147
+ Mage::helper('reflektion')->log('Running job: ' . $this->getJobId(), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
148
+ Mage::helper('reflektion')->log('Website Id: ' . $this->getWebsiteId(), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
149
+ Mage::helper('reflektion')->log('Dependent On Job Id: ' . $this->getDependentOnJobId(), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
150
+ Mage::helper('reflektion')->log('Min Entity Id: ' . $this->getMinEntityId(), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
151
+ Mage::helper('reflektion')->log('Type: ' . $this->getType(), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
152
+ Mage::helper('reflektion')->log('Feed Type: ' . $this->getFeedType(), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
153
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
154
+
155
+ // Execute the job
156
+ $this->executeJob();
157
+
158
+ Mage::helper('reflektion')->log('Job completed successfully.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
159
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
160
+ } catch (Exception $e) {
161
+ // Fail this job
162
+ $this->setStatus(Reflektion_Catalogexport_Model_Job::STATUS_ERROR);
163
+ $this->setEndedAt(Mage::getSingleton('core/date')->gmtDate());
164
+ $this->setErrorMessage($e->getMessage());
165
+ $this->save();
166
+ // Log exception
167
+ Mage::logException($e);
168
+ Mage::helper('reflektion')->log('Job failed with error:', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
169
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
170
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
171
+ }
172
+
173
+ return $this;
174
+ }
175
+
176
+ /**
177
+ * Execute this job
178
+ */
179
+ protected function executeJob() {
180
+ if (Mage::app()->getWebsite($this->getWebsiteId())->getConfig('reflektion_datafeeds/general/allfeedsenabled') != 'enabled') {
181
+ Mage::throwException('Data feeds not enabled for website: ' . $this->getWebsiteId());
182
+ }
183
+ $bDone = false;
184
+
185
+ // Switch on job type
186
+ switch ($this->getType()) {
187
+ case Reflektion_Catalogexport_Model_Job::TYPE_GENERATE_BASELINE:
188
+ // Call - Reflektion_Catalogexport_Model_Generatefeeds
189
+ $genModel = Mage::getModel('reflektion/generatefeeds');
190
+ $minEntityId = $this->getMinEntityId();
191
+ $genModel->generateForWebsite($this->getWebsiteId(), true, $this->getFeedType(), $minEntityId, $bDone);
192
+ $this->setMinEntityId($minEntityId);
193
+ break;
194
+ case Reflektion_Catalogexport_Model_Job::TYPE_GENERATE_DAILY:
195
+ // Call - Reflektion_Catalogexport_Model_Generatefeeds
196
+ $genModel = Mage::getModel('reflektion/generatefeeds');
197
+ $minEntityId = $this->getMinEntityId();
198
+ $genModel->generateForWebsite($this->getWebsiteId(), false, $this->getFeedType(), $minEntityId, $bDone);
199
+ $this->setMinEntityId($minEntityId);
200
+ break;
201
+ case Reflektion_Catalogexport_Model_Job::TYPE_TRANSFER:
202
+ // Call - Reflektion_Catalogexport_Model_Transferfeeds
203
+ $tranModel = Mage::getModel('reflektion/transferfeeds');
204
+ $tranModel->transfer($this->getWebsiteId());
205
+ $bDone = true;
206
+ break;
207
+ case Reflektion_Catalogexport_Model_Job::TYPE_TRANSFER_MANUAL:
208
+ // Call - Reflektion_Catalogexport_Model_Transferfeeds
209
+ $tranModel = Mage::getModel('reflektion/transferfeeds');
210
+ $tranModel->transfer($this->getWebsiteId());
211
+ $bDone = true;
212
+ break;
213
+ }
214
+
215
+ // Job as succeeded
216
+ if ($bDone) {
217
+ $this->setStatus(Reflektion_Catalogexport_Model_Job::STATUS_COMPLETED);
218
+ $this->setEndedAt(Mage::getSingleton('core/date')->gmtDate());
219
+ }
220
+ $this->save();
221
+ }
222
+
223
+ }
app/code/community/Reflektion/Catalogexport/Model/Layout.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ *
10
+ */
11
+ class Reflektion_Catalogexport_Model_Layout extends Mage_Core_Model_Layout {
12
+
13
+ /**
14
+ * Add block object to layout based on xml node data
15
+ *
16
+ * @param Varien_Simplexml_Element $node
17
+ * @param Varien_Simplexml_Element $parent
18
+ * @return Mage_Core_Model_Layout
19
+ */
20
+ protected function _generateBlock($node, $parent) {
21
+
22
+ parent:: _generateBlock($node, $parent);
23
+ }
24
+
25
+ }
app/code/community/Reflektion/Catalogexport/Model/Mysql4/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Model/Mysql4/Job.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ *
10
+ */
11
+ class Reflektion_Catalogexport_Model_Mysql4_Job extends Mage_Core_Model_Mysql4_Abstract {
12
+
13
+ public function _construct() {
14
+ $this->_init('reflektion/job', 'job_id');
15
+ }
16
+
17
+ }
app/code/community/Reflektion/Catalogexport/Model/Mysql4/Job/Collection.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ *
10
+ */
11
+ class Reflektion_Catalogexport_Model_Mysql4_Job_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
12
+
13
+ public function _construct() {
14
+ $this->_init('reflektion/job');
15
+ }
16
+
17
+ }
app/code/community/Reflektion/Catalogexport/Model/Observer.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ *
10
+ */
11
+ class Reflektion_Catalogexport_Model_Observer {
12
+
13
+ /**
14
+ * Generate and send new datafeed files
15
+ *
16
+ * @param Mage_Cron_Model_Schedule $schedule
17
+ * @return Reflektion_Catalogexport_Model_Observer
18
+ */
19
+ public function processDailyFeeds($schedule) {
20
+
21
+ try {
22
+ Mage::helper('reflektion')->log('**********************************************************', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
23
+ Mage::helper('reflektion')->log('Data feeds cron process started...', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
24
+ Mage::helper('reflektion')->log('Is Single Store Mode: ' . Mage::app()->isSingleStoreMode(), Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
25
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
26
+ Mage::helper('reflektion')->log('**********************************************************', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
27
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
28
+
29
+ // schedule daily feed jobs for all websites
30
+ $this->scheduleJobs();
31
+
32
+ // Log mem usage
33
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
34
+ $collectionJobs = Mage::getModel('reflektion/job')
35
+ ->getCollection()->addFieldToFilter('status', array('eq' => Reflektion_Catalogexport_Model_Job::STATUS_SCHEDULED));
36
+ $countScheduled = $collectionJobs->count();
37
+
38
+ for ($k = 0; $k < $countScheduled; $k++) {
39
+ $this->runJob(); //products
40
+ $this->runJob(); //file transfer
41
+ }
42
+ Mage::helper('reflektion')->log('**********************************************************', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
43
+ Mage::helper('reflektion')->log('Daily feeds cron process completed successfully.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
44
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
45
+ Mage::helper('reflektion')->log('**********************************************************', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
46
+ } catch (Exception $e) {
47
+ Mage::logException($e);
48
+ Mage::helper('reflektion')->log('**********************************************************', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
49
+ Mage::helper('reflektion')->log('Data feeds cron process failed with error:', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
50
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
51
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
52
+ Mage::helper('reflektion')->log('**********************************************************', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
53
+ }
54
+
55
+ return $this;
56
+ }
57
+
58
+ /**
59
+ * Schedule any daily feed jobs which are necessary when we hit the daily trigger time
60
+ *
61
+ *
62
+ */
63
+ protected function scheduleJobs() {
64
+ try {
65
+ Reflektion_Catalogexport_Model_Job::scheduleAllDailyJobs();
66
+ } catch (Exception $e) {
67
+ Mage::logException($e);
68
+ Mage::helper('reflektion')->log('Failed to schedule daily jobs, error:', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
69
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
70
+ throw $e;
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Grab the next job and run it, if it exists
76
+ */
77
+ protected function runJob() {
78
+ try {
79
+ $job = Reflektion_Catalogexport_Model_Job::getNextJobFromQueue();
80
+ if ($job !== false) {
81
+ $job->run();
82
+ }
83
+ } catch (Exception $e) {
84
+ Mage::logException($e);
85
+ Mage::helper('reflektion')->log('Failed to run job, error:', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
86
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
87
+ throw $e;
88
+ }
89
+ }
90
+
91
+ }
app/code/community/Reflektion/Catalogexport/Model/System/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/Model/System/Config/Cron.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Validate and save cron job frequency
10
+ */
11
+ class Reflektion_Catalogexport_Model_System_Config_Cron extends Mage_Core_Model_Config_Data {
12
+
13
+ const CRON_STRING_PATH = 'crontab/jobs/reflektion_processdailyfeeds/schedule/cron_expr';
14
+
15
+ protected function _afterSave() {
16
+ $time = $this->getData('groups/configurable_cron/fields/frequency/value');
17
+ $time = explode(" ", $time);
18
+ try {
19
+ if (count($time) == 5) {
20
+ foreach ($time as $val)
21
+ if (preg_match('/[^*,\/0-9]/i', $val)) {
22
+ throw new Exception();
23
+ }
24
+ } else {
25
+ throw new Exception();
26
+ }
27
+ $cronExprArray = array(
28
+ $time[0], # Minute
29
+ $time[1], # Hour
30
+ $time[2], # Day of the Month
31
+ $time[3], # Month of the Year
32
+ $time[4], # Day of the Week
33
+ );
34
+ $cronExprString = join(' ', $cronExprArray);
35
+
36
+ Mage::getModel('core/config_data')
37
+ ->load(self::CRON_STRING_PATH, 'path')
38
+ ->setValue($cronExprString)
39
+ ->setPath(self::CRON_STRING_PATH)
40
+ ->save();
41
+ } catch (Exception $e) {
42
+ throw new Exception(Mage::helper('cron')->__('Unable to save the cron expression.'));
43
+ }
44
+ }
45
+
46
+ }
app/code/community/Reflektion/Catalogexport/Model/System/Config/EnableToggle.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description To enable or disable module and feed generation
10
+ */
11
+ class Reflektion_Catalogexport_Model_System_Config_EnableToggle {
12
+
13
+ public function toOptionArray() {
14
+ return array(
15
+ array('value' => 'enabled', 'label' => Mage::helper('adminhtml')->__('Enabled')),
16
+ array('value' => 'disabled', 'label' => Mage::helper('adminhtml')->__('Disabled')),
17
+ );
18
+ }
19
+
20
+ }
app/code/community/Reflektion/Catalogexport/Model/System/Config/ProductAttributes.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description To fetch all user defined attributes
10
+ */
11
+ class Reflektion_Catalogexport_Model_System_Config_ProductAttributes {
12
+
13
+ public function toOptionArray() {
14
+
15
+ $attributes = Mage::getResourceModel('catalog/product_attribute_collection')
16
+ ->addVisibleFilter()
17
+ ->addStoreLabel(Mage::app()->getStore()->getId())
18
+ ->setOrder('main_table.attribute_id', 'asc')
19
+ ->load();
20
+ $result = array();
21
+ foreach ($attributes as $_attribute) {
22
+ if ($_attribute->getIsUserDefined()) {
23
+ $result[] = array(
24
+ 'value' => $_attribute["attribute_code"],
25
+ 'label' => $_attribute["frontend_label"]
26
+ );
27
+ }
28
+ }
29
+ return $result;
30
+ }
31
+
32
+ }
app/code/community/Reflektion/Catalogexport/Model/System/Validate/ProductAttributes.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @category Reflektion
4
+ * @package Reflektion_Catalogexport
5
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
6
+ * @createdOn 02 Mar 2016
7
+ * @license https://opensource.org/licenses/OSL-3.0
8
+ * @description Validate product attributes to export while saving from admin panel
9
+ */
10
+ class Reflektion_Catalogexport_Model_System_Validate_ProductAttributes extends Mage_Core_Model_Config_Data {
11
+
12
+ const ATTRIBUTE_LIMIT = 30;
13
+
14
+ public function save() {
15
+ $limit = Mage::app()->getWebsite()->getConfig('reflektion_datafeeds/advanced/attribute_limit');
16
+ if (!$limit) {
17
+ $limit = self::ATTRIBUTE_LIMIT;
18
+ }
19
+
20
+ $selections = $this->getValue(); //Config Value
21
+
22
+ if (sizeof($selections) > $limit) { // more than 30 items selected
23
+ Mage::getSingleton('core/session')->addWarning(
24
+ Mage::helper('reflektion')->__(
25
+ "WARNING - Too many Product Custom Attributes selected for the product data feed.<br/>Only the first %s selected attributes were saved and applied to the feed.", $limit));
26
+ }
27
+
28
+ $this->setValue(array_slice($selections, 0, $limit, true)); //only keep the first 30 items the user selected
29
+ return parent::save();
30
+ }
31
+
32
+ }
app/code/community/Reflektion/Catalogexport/Model/Transferfeeds.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Manage to transfer feed from magento to other server through SFTP
10
+ */
11
+ class Reflektion_Catalogexport_Model_Transferfeeds {
12
+
13
+ /**
14
+ * Transfer data feeds to Reflektion, triggered by cron
15
+ *
16
+ * @param $websiteId Id of the website for which to generate data feeds
17
+ */
18
+ public function transfer($websiteId) {
19
+ try {
20
+ Mage::helper('reflektion')->log('Transferring data feeds for website with Id: ' . $websiteId, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
21
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
22
+
23
+ if (Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/general/allfeedsenabled') != 'enabled') {
24
+ Mage::throwException('Data feeds not enabled for website: ' . $websiteId);
25
+ }
26
+
27
+ $fileList = $this->buildFileList($websiteId);
28
+ $bSuccess = $this->transferFileList($websiteId, $fileList);
29
+ if (!$bSuccess) {
30
+ Mage::throwException('Transfer file list failed!');
31
+ }
32
+
33
+ Mage::helper('reflektion')->log('Sucessfully transferred data feeds for website.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
34
+ } catch (Exception $e) {
35
+ Mage::helper('reflektion')->log('Failed to transfer data feeds for website.', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
36
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
37
+ throw $e;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Build list of files to transfer, based on enabled website
43
+ *
44
+ * @param $websiteId Id of the website for which to generate data feeds
45
+ * @return array List of files to transfer for this website (full path & filename specified for each)
46
+ */
47
+ protected function buildFileList($websiteId) {
48
+ $feedPath = Mage::getConfig()->getVarDir() . DS . Reflektion_Catalogexport_Model_Generatefeeds::REFLEKTION_FEED_PATH;
49
+
50
+ Mage::helper('reflektion')->log('Searching for feed files for website id: ' . $websiteId . ' here: ' . $feedPath, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
51
+
52
+ // Websiteid match string
53
+ $websiteIdMatchString = '_product_feed';
54
+
55
+ $fileList = array();
56
+
57
+ // Open directory
58
+ $dh = opendir($feedPath);
59
+ if ($dh === FALSE) {
60
+ Mage::throwException('Failed to open feed directory: ' . $feedPath);
61
+ }
62
+
63
+ // Files in directory
64
+ while (($entry = readdir($dh)) !== FALSE) {
65
+ $fullpath = $feedPath . DS . $entry;
66
+ // Check if have a file
67
+ if (is_file($fullpath)) {
68
+ // Check if our file is for the correct websiteId
69
+ if (strpos($fullpath, $websiteIdMatchString) !== FALSE) {
70
+ $fileList[] = $fullpath;
71
+ }
72
+ }
73
+ }
74
+ closedir($dh);
75
+ Mage::helper('reflektion')->log('Found ' . count($fileList) . ' feed files for website id: ' . $websiteId, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
76
+
77
+ return $fileList;
78
+ }
79
+
80
+ /**
81
+ * Transfer this list of files to the SFTP site for Reflektion
82
+ *
83
+ * @param $websiteId Id of the website for which to generate data feeds
84
+ * @param $fileList List of file names (full path) to transfer
85
+ * @return bool Indicates if files successfully transfered or not
86
+ */
87
+ protected function transferFileList($websiteId, array $fileList) {
88
+ Mage::helper('reflektion')->log('Transferring ' . count($fileList) . ' files for website id: ' . $websiteId, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
89
+
90
+ try {
91
+ // Get hostname, port & credentials
92
+ $sftpHost = Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/connect/hostname');
93
+ $sftpPort = Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/connect/port');
94
+ $sftpUser = Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/connect/username');
95
+ $sftpPassword = Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/connect/password');
96
+ } catch (Exception $e) {
97
+ Mage::logException($e);
98
+ Mage::helper('reflektion')->log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
99
+ return false;
100
+ }
101
+
102
+ // Connect to server
103
+ $connection = Mage::helper('reflektion/sftpConnection');
104
+ $bSuccess = $connection->connect($sftpHost, $sftpPort, $sftpUser, $sftpPassword);
105
+ if (!$bSuccess) {
106
+ Mage::helper('reflektion')->log('Failed to connect to Reflektion!', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
107
+ return false;
108
+ }
109
+ $sftpFolder = Mage::app()->getWebsite($websiteId)->getConfig('reflektion_datafeeds/connect/path');
110
+ $bSuccess = $connection->changeDir($sftpFolder);
111
+ if (!$bSuccess) {
112
+ Mage::helper('reflektion')->log('Failed to change folders to: ' . $sftpFolder, Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
113
+ return false;
114
+ }
115
+
116
+ //Iterate file list and put each file
117
+ $bTransferSucceeded = true;
118
+ foreach ($fileList as $curFile) {
119
+ Mage::helper('reflektion')->log('Transferring file: ' . $curFile, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
120
+ Mage::helper('reflektion')->log('Memory usage: ' . memory_get_usage(), Zend_Log::DEBUG, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
121
+ $bSuccess = $connection->putAndDeleteFile($curFile);
122
+ if (!$bSuccess) {
123
+ Mage::helper('reflektion')->log('Failed to transfer and delete file: ' . $curFile, Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
124
+ $bTransferSucceeded = false;
125
+ }
126
+ }
127
+
128
+ $connection->close();
129
+
130
+ // Check results
131
+ if (!$bTransferSucceeded) {
132
+ Mage::helper('reflektion')->log('Some file transfers failed!', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
133
+ return false;
134
+ } else {
135
+ Mage::helper('reflektion')->log('Successfully transferred all files.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
136
+ return true;
137
+ }
138
+ }
139
+
140
+ }
app/code/community/Reflektion/Catalogexport/controllers/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/controllers/Adminhtml/ExportController.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Actions to generate jobs in queue
10
+ */
11
+ class Reflektion_Catalogexport_Adminhtml_ExportController extends Mage_Adminhtml_Controller_Action {
12
+
13
+ public function indexAction() {
14
+ $this->loadLayout()->_setActiveMenu("reflektion/export");
15
+ $this->renderLayout();
16
+ }
17
+
18
+ /**
19
+ * Export baseline data feed
20
+ */
21
+ public function exportoneAction() {
22
+ try {
23
+ $id = $this->getRequest()->getParam('id');
24
+ Mage::helper('reflektion')->validateFeedConfiguration($id);
25
+ } catch (Exception $e) {
26
+ $this->_getSession()->addError($this->__($e->getMessage()));
27
+ // Redirect
28
+ $this->_redirect('*/*/index');
29
+
30
+ return;
31
+ }
32
+
33
+ try {
34
+ $id = $this->getRequest()->getParam('id');
35
+ Mage::log('Scheduling immediate baseline data feeds for website Id: ' . $id, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
36
+
37
+ // Schedule all feeds for site
38
+ Reflektion_Catalogexport_Model_Job::scheduleJobs($id, true);
39
+ Mage::log('Successfully scheduled feeds.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
40
+ } catch (Exception $e) {
41
+ Mage::logException($e);
42
+ Mage::log('Failed to schedule feeds.', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
43
+ Mage::log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
44
+ }
45
+ $this->_getSession()->addSuccess($this->__('Feed generation and transfer has been scheduled for website ID ' . $id . '.'));
46
+ $this->_redirect('*/*/index');
47
+ }
48
+
49
+ /**
50
+ * Export all baseline data feeds
51
+ */
52
+ public function exportallAction() {
53
+ try {
54
+ Mage::helper('reflektion')->validateFeedConfiguration();
55
+ } catch (Exception $e) {
56
+ $this->_getSession()->addError($this->__($e->getMessage()));
57
+ $this->_redirect('*/*/index');
58
+
59
+ return;
60
+ }
61
+
62
+ try {
63
+ $id = $this->getRequest()->getParam('id');
64
+ Mage::log('Scheduling immediate baseline data feeds for all websites.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
65
+
66
+ // Schedule all feeds for site
67
+ Reflektion_Catalogexport_Model_Job::scheduleJobsAllWebsites(true);
68
+ Mage::log('Successfully scheduled feeds.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
69
+ } catch (Exception $e) {
70
+ Mage::logException($e);
71
+ Mage::log('Failed to schedule feeds.', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
72
+ Mage::log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
73
+ }
74
+ $this->_getSession()->addSuccess($this->__('Feed generation and transfer has been scheduled all websites.'));
75
+ $this->_redirect('*/*/index');
76
+ }
77
+
78
+ }
app/code/community/Reflektion/Catalogexport/controllers/Adminhtml/JobController.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Actions to process jobs in queue
10
+ */
11
+ class Reflektion_Catalogexport_Adminhtml_JobController extends Mage_Adminhtml_Controller_Action {
12
+
13
+ public function indexAction() {
14
+ $this->loadLayout()->_setActiveMenu("reflektion/job");
15
+ $this->renderLayout();
16
+ }
17
+
18
+ /**
19
+ * Export all baseline data feeds
20
+ */
21
+ public function exportallAction() {
22
+ try {
23
+ Mage::helper('reflektion')->validateFeedConfiguration();
24
+ } catch (Exception $e) {
25
+ $this->_getSession()->addError($this->__($e->getMessage()));
26
+ $this->_redirect('*/*/index');
27
+
28
+ return;
29
+ }
30
+
31
+ try {
32
+ Mage::log('Scheduling immediate baseline data feeds for all websites.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
33
+ // Schedule all feeds for site
34
+ Reflektion_Catalogexport_Model_Job::scheduleJobsAllWebsites(true);
35
+ Mage::log('Successfully scheduled feeds.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
36
+ } catch (Exception $e) {
37
+ Mage::logException($e);
38
+ Mage::log('Failed to schedule feeds.', Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
39
+ Mage::log($e->getMessage(), Zend_Log::ERR, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
40
+ }
41
+ $this->_getSession()->addSuccess($this->__('Feed generation and transfer has been scheduled all websites.'));
42
+ $this->_redirect('*/*/index');
43
+ }
44
+
45
+ public function massDeleteAction() { {
46
+ $jobIds = $this->getRequest()->getParam('job_id');
47
+ if (!is_array($jobIds)) {
48
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('reflektion')->__('Please select jobs(s) to delete.'));
49
+ } else {
50
+ try {
51
+ $jobModel = Mage::getModel('reflektion/job');
52
+ foreach ($jobIds as $jobId) {
53
+ Mage::log('Mass delete - Deleting job id ' . $jobId, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
54
+ $jobModel->load($jobId)->delete();
55
+ }
56
+ } catch (Exception $e) {
57
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
58
+ }
59
+ }
60
+
61
+ Mage::getSingleton('adminhtml/session')->addSuccess(
62
+ Mage::helper('reflektion')->__(
63
+ 'Total of %d record(s) were deleted.', count($jobIds)
64
+ )
65
+ );
66
+
67
+ Mage::log('Mass delete - ' . count($jobIds) . ' jobs deleted.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
68
+
69
+ $this->_redirect('*/*/index');
70
+ }
71
+ }
72
+
73
+ public function massRunAction() {
74
+ $jobIds = $this->getRequest()->getParam('job_id');
75
+ if (!is_array($jobIds)) {
76
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('reflektion')->__('Please select jobs(s) to execute.'));
77
+ } else {
78
+ try {
79
+ $jobModel = Mage::getModel('reflektion/job');
80
+ asort($jobIds);
81
+ foreach ($jobIds as $jobId) {
82
+ Mage::log('Mass execute - Execute job id ' . $jobId, Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
83
+
84
+ $jobModel->load($jobId)
85
+ ->setStartedAt(Mage::getSingleton('core/date')->gmtDate())
86
+ ->save()
87
+ ->run();
88
+ }
89
+ } catch (Exception $e) {
90
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
91
+ }
92
+ }
93
+
94
+ Mage::getSingleton('adminhtml/session')->addSuccess(
95
+ Mage::helper('reflektion')->__(
96
+ 'Total of %d jobs(s) were executed', count($jobIds)
97
+ )
98
+ );
99
+
100
+ Mage::log('Mass execute - ' . count($jobIds) . ' jobs executed.', Zend_Log::INFO, Reflektion_Catalogexport_Helper_Data::LOG_FILE);
101
+
102
+ $this->_redirect('*/*/index');
103
+ }
104
+
105
+ }
app/code/community/Reflektion/Catalogexport/etc/adminhtml.xml ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Admin ACL and menu configurations
10
+ */
11
+ -->
12
+ <config>
13
+ <menu>
14
+ <reflektion module="reflektion">
15
+ <title>Reflektion</title>
16
+ <sort_order>87</sort_order>
17
+ <children>
18
+ <export module="reflektion">
19
+ <title>Generate Feeds</title>
20
+ <sort_order>0</sort_order>
21
+ <action>reflektion/adminhtml_export</action>
22
+ </export>
23
+ <job module="reflektion">
24
+ <title>Feeds in Queue</title>
25
+ <sort_order>0</sort_order>
26
+ <action>reflektion/adminhtml_job</action>
27
+ </job>
28
+ </children>
29
+ </reflektion>
30
+ </menu>
31
+ <acl>
32
+ <resources>
33
+ <admin>
34
+ <children>
35
+ <system>
36
+ <children>
37
+ <config>
38
+ <children>
39
+ <reflektion_datafeeds translate="title" module="reflektion">
40
+ <title>Reflektion Data Feeds Configuration Section</title>
41
+ <sort_order>1</sort_order>
42
+ </reflektion_datafeeds>
43
+ </children>
44
+ </config>
45
+ </children>
46
+ </system>
47
+ </children>
48
+ </admin>
49
+ </resources>
50
+ </acl>
51
+
52
+ <acl>
53
+ <resources>
54
+ <admin>
55
+ <children>
56
+ <reflektion translate="title" module="reflektion">
57
+ <title>Reflektion</title>
58
+ <sort_order>1000</sort_order>
59
+ <children>
60
+ <export translate="title">
61
+ <title>Reflektion</title>
62
+ </export>
63
+ </children>
64
+ </reflektion>
65
+ </children>
66
+ </admin>
67
+ </resources>
68
+ </acl>
69
+ </config>
app/code/community/Reflektion/Catalogexport/etc/config.xml ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ *
10
+ */
11
+ -->
12
+ <config>
13
+
14
+ <modules>
15
+ <Reflektion_Catalogexport>
16
+ <version>1.0.0</version>
17
+ </Reflektion_Catalogexport>
18
+ </modules>
19
+
20
+ <global>
21
+ <helpers>
22
+ <reflektion>
23
+ <class>Reflektion_Catalogexport_Helper</class>
24
+ </reflektion>
25
+ </helpers>
26
+
27
+ <blocks>
28
+ <reflektion>
29
+ <class>Reflektion_Catalogexport_Block</class>
30
+ </reflektion>
31
+ </blocks>
32
+ <models>
33
+ <reflektion>
34
+ <class>Reflektion_Catalogexport_Model</class>
35
+ <resourceModel>reflektion_mysql4</resourceModel>
36
+ </reflektion>
37
+ <core>
38
+ <rewrite>
39
+ <layout>Reflektion_Catalogexport_Model_Layout</layout>
40
+ </rewrite>
41
+ </core>
42
+ <reflektion_mysql4>
43
+ <class>Reflektion_Catalogexport_Model_Mysql4</class>
44
+ <entities>
45
+ <job>
46
+ <table>reflektion_job</table>
47
+ </job>
48
+ </entities>
49
+ </reflektion_mysql4>
50
+ </models>
51
+ <resources>
52
+ <reflektion_setup>
53
+ <setup>
54
+ <module>Reflektion_Catalogexport</module>
55
+ <class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
56
+ </setup>
57
+ <connection>
58
+ <use>core_setup</use>
59
+ </connection>
60
+ </reflektion_setup>
61
+ <reflektion_write>
62
+ <connection>
63
+ <use>core_write</use>
64
+ </connection>
65
+ </reflektion_write>
66
+ <reflektion_read>
67
+ <connection>
68
+ <use>core_read</use>
69
+ </connection>
70
+ </reflektion_read>
71
+ </resources>
72
+ </global>
73
+
74
+ <admin>
75
+ <routers>
76
+ <reflektion>
77
+ <use>admin</use>
78
+ <args>
79
+ <module>Reflektion_Catalogexport</module>
80
+ <frontName>reflektion</frontName>
81
+ </args>
82
+ </reflektion>
83
+ </routers>
84
+ </admin>
85
+ <adminhtml>
86
+ <layout>
87
+ <updates>
88
+ <reflektion>
89
+ <file>reflektion.xml</file>
90
+ </reflektion>
91
+ </updates>
92
+ </layout>
93
+ </adminhtml>
94
+
95
+ <crontab>
96
+ <jobs>
97
+ <reflektion_processdailyfeeds>
98
+ <run>
99
+ <model>reflektion/observer::processDailyFeeds</model>
100
+ </run>
101
+ </reflektion_processdailyfeeds>
102
+ </jobs>
103
+ </crontab>
104
+
105
+ <default>
106
+ <reflektion_datafeeds>
107
+ <general>
108
+ <allfeedsenabled>disabled</allfeedsenabled>
109
+ </general>
110
+ <connect>
111
+ <hostname></hostname>
112
+ <port></port>
113
+ <username></username>
114
+ <password></password>
115
+ </connect>
116
+ <feedsenabled>
117
+ <product>enabled</product>
118
+ <product_attributes></product_attributes>
119
+ </feedsenabled>
120
+ <advanced>
121
+ <!-- 30+ can cause problem -->
122
+ <attribute_limit>30</attribute_limit>
123
+ </advanced>
124
+ </reflektion_datafeeds>
125
+ </default>
126
+ </config>
app/code/community/Reflektion/Catalogexport/etc/system.xml ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description System configurations
10
+ */
11
+ -->
12
+ <config>
13
+ <tabs>
14
+ <reflektion translate="label" module="reflektion">
15
+ <label><![CDATA[<div style="text-transform:none;padding-left:0px;">Reflektion</div>]]></label>
16
+ <sort_order>150</sort_order>
17
+ </reflektion>
18
+ </tabs>
19
+
20
+ <sections>
21
+ <reflektion_datafeeds translate="label" module="reflektion">
22
+ <label>Data Feeds Configuration</label>
23
+ <tab>reflektion</tab>
24
+ <frontend_type>text</frontend_type>
25
+ <sort_order>3310</sort_order>
26
+ <show_in_default>1</show_in_default>
27
+ <show_in_website>1</show_in_website>
28
+ <show_in_store>1</show_in_store>
29
+ <groups>
30
+ <general translate="label">
31
+ <label>General</label>
32
+ <frontend_type>text</frontend_type>
33
+ <sort_order>0</sort_order>
34
+ <show_in_default>1</show_in_default>
35
+ <show_in_website>1</show_in_website>
36
+ <show_in_store>1</show_in_store>
37
+ <fields>
38
+ <allfeedsenabled translate="label">
39
+ <label>Data Feeds Enabled</label>
40
+ <frontend_type>select</frontend_type>
41
+ <source_model>reflektion/system_config_enableToggle</source_model>
42
+ <sort_order>1</sort_order>
43
+ <show_in_default>1</show_in_default>
44
+ <show_in_website>1</show_in_website>
45
+ <show_in_store>1</show_in_store>
46
+ <comment>Enable/disable all data feeds</comment>
47
+ </allfeedsenabled>
48
+ </fields>
49
+ </general>
50
+ <configurable_cron translate="label">
51
+ <label>Cron Schedule</label>
52
+ <sort_order>1</sort_order>
53
+ <show_in_default>1</show_in_default>
54
+ <show_in_website>0</show_in_website>
55
+ <show_in_store>0</show_in_store>
56
+ <fields>
57
+ <frequency translate="label">
58
+ <label>Frequency(Server Time)</label>
59
+ <frontend_type>text</frontend_type>
60
+ <backend_model>reflektion/system_config_cron</backend_model>
61
+ <sort_order>20</sort_order>
62
+ <show_in_default>1</show_in_default>
63
+ <show_in_website>0</show_in_website>
64
+ <show_in_store>0</show_in_store>
65
+ <comment>Set cron job for all websites</comment>
66
+ </frequency>
67
+ </fields>
68
+ </configurable_cron>
69
+ <connect translate="label">
70
+ <label>SFTP Connectivity</label>
71
+ <frontend_type>text</frontend_type>
72
+ <sort_order>2</sort_order>
73
+ <show_in_default>1</show_in_default>
74
+ <show_in_website>1</show_in_website>
75
+ <show_in_store>1</show_in_store>
76
+ <fields>
77
+ <hostname translate="label">
78
+ <label>Hostname</label>
79
+ <frontend_type>text</frontend_type>
80
+ <sort_order>1</sort_order>
81
+ <show_in_default>0</show_in_default>
82
+ <show_in_website>1</show_in_website>
83
+ <show_in_store>0</show_in_store>
84
+ <comment>Enter Hostname provided by Reflektion</comment>
85
+ </hostname>
86
+ <port translate="label">
87
+ <label>Port Number</label>
88
+ <frontend_type>text</frontend_type>
89
+ <sort_order>2</sort_order>
90
+ <show_in_default>0</show_in_default>
91
+ <show_in_website>1</show_in_website>
92
+ <show_in_store>0</show_in_store>
93
+ <validate>validate-number</validate>
94
+ <comment>Enter the port number provided by Reflektion</comment>
95
+ </port>
96
+ <path translate="label">
97
+ <label>Path</label>
98
+ <frontend_type>text</frontend_type>
99
+ <sort_order>3</sort_order>
100
+ <show_in_default>0</show_in_default>
101
+ <show_in_website>1</show_in_website>
102
+ <show_in_store>0</show_in_store>
103
+ <comment>Enter Path provided by Reflektion</comment>
104
+ </path>
105
+ <username translate="label">
106
+ <label>Username</label>
107
+ <frontend_type>text</frontend_type>
108
+ <sort_order>4</sort_order>
109
+ <show_in_default>0</show_in_default>
110
+ <show_in_website>1</show_in_website>
111
+ <show_in_store>0</show_in_store>
112
+ <comment>Enter SFTP username provided by Reflektion</comment>
113
+ </username>
114
+ <password translate="label">
115
+ <label>Password</label>
116
+ <frontend_type>password</frontend_type>
117
+ <!--backend_model>adminhtml/system_config_backend_encrypted</backend_model-->
118
+ <sort_order>5</sort_order>
119
+ <show_in_default>0</show_in_default>
120
+ <show_in_website>1</show_in_website>
121
+ <show_in_store>0</show_in_store>
122
+ <comment>Enter SFTP account password provided by Reflektion</comment>
123
+ </password>
124
+ </fields>
125
+ </connect>
126
+
127
+ <feedsenabled translate="label">
128
+ <label>Data Feeds</label>
129
+ <frontend_type>text</frontend_type>
130
+ <sort_order>5</sort_order>
131
+ <show_in_default>1</show_in_default>
132
+ <show_in_website>1</show_in_website>
133
+ <show_in_store>1</show_in_store>
134
+ <fields>
135
+
136
+ <notice translate="label">
137
+ <frontend_type>Text</frontend_type>
138
+ <frontend_model>reflektion/adminhtml_system_config_commentText</frontend_model> <!-- render comment as text -->
139
+ <comment><![CDATA[
140
+ To configure <b>Data Feeds</b>, please select a <b>website</b> scope from the <i>Current Configuration Scope</i> dropdown
141
+ ]]>
142
+ </comment>
143
+ <sort_order>0</sort_order>
144
+ <show_in_default>1</show_in_default>
145
+ <show_in_website>0</show_in_website>
146
+ <show_in_store>1</show_in_store>
147
+ </notice>
148
+ <product translate="label">
149
+ <label>Product Feed</label>
150
+ <frontend_type>select</frontend_type>
151
+ <source_model>reflektion/system_config_enableToggle</source_model>
152
+ <sort_order>2</sort_order>
153
+ <show_in_default>0</show_in_default>
154
+ <show_in_website>1</show_in_website>
155
+ <show_in_store>0</show_in_store>
156
+ </product>
157
+ <product_attributes translate="label">
158
+ <label>Product Custom Attributes</label>
159
+ <frontend_type>multiselect</frontend_type>
160
+ <source_model>reflektion/system_config_productAttributes</source_model>
161
+ <backend_model>reflektion/system_validate_productAttributes</backend_model>
162
+ <sort_order>3</sort_order>
163
+ <show_in_default>0</show_in_default>
164
+ <show_in_website>1</show_in_website>
165
+ <show_in_store>0</show_in_store>
166
+ </product_attributes>
167
+
168
+ </fields>
169
+ </feedsenabled>
170
+ </groups>
171
+ </reflektion_datafeeds>
172
+ </sections>
173
+ </config>
app/code/community/Reflektion/Catalogexport/sql/.DS_Store ADDED
Binary file
app/code/community/Reflektion/Catalogexport/sql/reflektion_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ * @description Creating table to record job queue
10
+ */
11
+ $installer = $this;
12
+ $installer->startSetup();
13
+
14
+ $installer->run("
15
+ DROP TABLE IF EXISTS `reflektion_job`;
16
+
17
+ CREATE TABLE `reflektion_job` (
18
+ `job_id` int unsigned NOT NULL AUTO_INCREMENT,
19
+ `website_id` smallint(5) unsigned NOT NULL,
20
+ `dependent_on_job_id` int unsigned,
21
+ `min_entity_id` int unsigned,
22
+ `type` varchar(40) NOT NULL,
23
+ `feed_type` varchar(40) NOT NULL,
24
+ `status` int(11) NOT NULL,
25
+ `scheduled_at` datetime DEFAULT NULL,
26
+ `started_at` datetime DEFAULT NULL,
27
+ `ended_at` datetime DEFAULT NULL,
28
+ `error_message` varchar(64) NOT NULL,
29
+ PRIMARY KEY (`job_id`),
30
+ INDEX `indx_export_type` (`type`),
31
+ INDEX `indx_export_entity` (`feed_type`),
32
+ INDEX `indx_export_status` (`status`)
33
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
34
+ ");
35
+
36
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/reflektion.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Reflektion
5
+ * @package Reflektion_Catalogexport
6
+ * @website http://www.reflektion.com/ <http://www.reflektion.com/>
7
+ * @createdOn 02 Mar 2016
8
+ * @license https://opensource.org/licenses/OSL-3.0
9
+ *
10
+ */
11
+ -->
12
+ <layout version="0.1.0">
13
+ <reflektion_adminhtml_export_index>
14
+ <reference name="content">
15
+ <block type="reflektion/adminhtml_export" name="export" />
16
+ </reference>
17
+ </reflektion_adminhtml_export_index>
18
+
19
+ <reflektion_adminhtml_job_index>
20
+ <reference name="content">
21
+ <block type="reflektion/adminhtml_job" name="export" />
22
+ </reference>
23
+ </reflektion_adminhtml_job_index>
24
+ </layout>
app/etc/modules/Reflektion_Catalogexport.xml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Reflektion_Catalogexport>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ <version>1.0.0</version>
8
+ </Reflektion_Catalogexport>
9
+ </modules>
10
+ </config>
package.xml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Reflektion_Individualization_Extension</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="https://opensource.org/licenses/osl-3.0.php">Open Software License</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Reflektion Individualization Extension</summary>
10
+ <description>Reflektion Catalogexport &#xD;
11
+ -&gt; Generate and transfer your magento catalog product CSV to Reflektion SFTP. &#xD;
12
+ -&gt; Website level export.&#xD;
13
+ -&gt; Select Product Attributes to transfer at your website level.</description>
14
+ <notes>This is the first public release of the Reflektion Catalogexport Module&#xD;
15
+ This extension contains following feature&#xD;
16
+ -&gt; Generate and transfer your magento catalog product CSV to Reflektion SFTP. &#xD;
17
+ -&gt; Website level export.&#xD;
18
+ -&gt; Select Product Attributes to transfer at your website level.&#xD;
19
+ &#xD;
20
+ Easy to handle and configure. </notes>
21
+ <authors><author><name>Amar</name><user>Reflektion</user><email>amar.chokhawala@reflektion.com</email></author></authors>
22
+ <date>2016-03-24</date>
23
+ <time>14:55:59</time>
24
+ <contents><target name="magecommunity"><dir name="Reflektion"><dir name="Catalogexport"><dir name="Block"><dir name="Adminhtml"><dir name="Export"><dir name="Grid"><dir name="Renderer"><file name="Action.php" hash="b3b9199977244654a6fda64b6ff63258"/></dir><file name=".DS_Store" hash="f5e5eb9d8f2bd07a4f0a291eaaf961e1"/></dir><file name="Grid.php" hash="cd365e0068b3e7334a9e1202f7bad93b"/><file name=".DS_Store" hash="85c0eee10740cff52e6ed937e88a6a47"/></dir><file name="Export.php" hash="41bbb64df606d65b19a02ce7b64ce747"/><dir name="Job"><file name="Grid.php" hash="97d23b5f9f99d94bb2f872d692eb82fd"/></dir><file name="Job.php" hash="092d92f6205fca2d9f19546de3ac52be"/><dir name="System"><dir name="Config"><file name="CommentText.php" hash="c9d005c2fbbf475d0c300cf09e0bba93"/><file name=".DS_Store" hash="194577a7e20bdcc7afbb718f502c134c"/></dir><file name=".DS_Store" hash="ecc285cdf6cd604b73665019d3cc59d9"/></dir><file name=".DS_Store" hash="a7747cd360c14d7cd70dd0a58487e5e3"/></dir><file name=".DS_Store" hash="391e9dc787419a8e50faa38a500fc901"/></dir><dir name="Helper"><file name="Csvfile.php" hash="31cc46cb9d9d6cffdc02e8810e476890"/><file name="Data.php" hash="9f394a3f9b522ac293863d16c6051ca4"/><file name="SftpConnection.php" hash="11ccf7e1bf17e6349f77796c18ebe4ff"/><file name=".DS_Store" hash="4b7b4bd8d1321e13694bee3f8ab310b7"/></dir><dir name="Model"><dir name="Feed"><file name="Base.php" hash="4ea3b61176fee497140efd0ba7a48490"/><file name="Product.php" hash="6821cf58dc0d44e0e20735abf54574cb"/><file name=".DS_Store" hash="4562d2af77da971301bd80a89876ca5d"/></dir><file name="Generatefeeds.php" hash="bd4f075f2df599235d19e9474a23c968"/><file name="Job.php" hash="31357f187786d954bf49c096c6640d63"/><file name="Layout.php" hash="ce5d1aff535ce7e915c58d4c0a49bf44"/><dir name="Mysql4"><dir name="Job"><file name="Collection.php" hash="6d11119cc6977eb048f8684124b5d11f"/></dir><file name="Job.php" hash="470e008a894919f3750d76b84bbc723a"/><file name=".DS_Store" hash="d02ffe64c6894d5852d5194f1a99f570"/></dir><file name="Observer.php" hash="f7afc3f2204e6021ae8d72ee7e569326"/><dir name="System"><dir name="Config"><file name="Cron.php" hash="541d079c8c895c2d8c1804221067c9ff"/><file name="EnableToggle.php" hash="f634245689001ab6355e759677e4b542"/><file name="ProductAttributes.php" hash="da97bd3ee4cdf145b208b5773f6aad32"/></dir><dir name="Validate"><file name="ProductAttributes.php" hash="87ee014d30083d235670ab259d0b303d"/></dir><file name=".DS_Store" hash="1c045337730e5065ba09ce6640066142"/></dir><file name="Transferfeeds.php" hash="069a934c3e9c9d524e58edffad9ec97e"/><file name=".DS_Store" hash="6eb6caae94dd0ea8150e5f9f45bed6b3"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="ExportController.php" hash="a5b29d83b11782b5b69ba71cf0f8d0f3"/><file name="JobController.php" hash="245ef2bbb904f6334c3f2f3b5a447d24"/></dir><file name=".DS_Store" hash="34aac0486e4893257aa1d865f97615f2"/></dir><dir name="etc"><file name="adminhtml.xml" hash="0ee309ab4300a8c218c62edc4203dffe"/><file name="config.xml" hash="211f0d74fa851703ae1fb652ad62e250"/><file name="system.xml" hash="e17bd23e6e1175b8737b7cb8b6b8dcbc"/></dir><dir name="sql"><dir name="reflektion_setup"><file name="mysql4-install-1.0.0.php" hash="41d35e6b847202cf6c8adddafc413a56"/></dir><file name=".DS_Store" hash="12354d0e1f8f17f4a540f0f987f96491"/></dir><file name=".DS_Store" hash="a693bdb537706fea3365ceb2117c6082"/></dir><file name=".DS_Store" hash="323da3616e354a9acd210829171524f4"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="reflektion.xml" hash="8e111b6a81750b38bf7b75cc4f9172ec"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Reflektion_Catalogexport.xml" hash="c8558ad019d72517eef1516801828b37"/></dir></target></contents>
25
+ <compatible/>
26
+ <dependencies><required><php><min>5.4.0</min><max>5.6.18</max></php></required></dependencies>
27
+ </package>