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
- app/code/community/Reflektion/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Block/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export.php +35 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid.php +112 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Export/Grid/Renderer/Action.php +21 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Job.php +27 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/Job/Grid.php +131 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/Config/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Block/Adminhtml/System/Config/CommentText.php +18 -0
- app/code/community/Reflektion/Catalogexport/Helper/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Helper/Csvfile.php +140 -0
- app/code/community/Reflektion/Catalogexport/Helper/Data.php +105 -0
- app/code/community/Reflektion/Catalogexport/Helper/SftpConnection.php +204 -0
- app/code/community/Reflektion/Catalogexport/Model/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Model/Feed/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Model/Feed/Base.php +174 -0
- app/code/community/Reflektion/Catalogexport/Model/Feed/Product.php +152 -0
- app/code/community/Reflektion/Catalogexport/Model/Generatefeeds.php +56 -0
- app/code/community/Reflektion/Catalogexport/Model/Job.php +223 -0
- app/code/community/Reflektion/Catalogexport/Model/Layout.php +25 -0
- app/code/community/Reflektion/Catalogexport/Model/Mysql4/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Model/Mysql4/Job.php +17 -0
- app/code/community/Reflektion/Catalogexport/Model/Mysql4/Job/Collection.php +17 -0
- app/code/community/Reflektion/Catalogexport/Model/Observer.php +91 -0
- app/code/community/Reflektion/Catalogexport/Model/System/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/Model/System/Config/Cron.php +46 -0
- app/code/community/Reflektion/Catalogexport/Model/System/Config/EnableToggle.php +20 -0
- app/code/community/Reflektion/Catalogexport/Model/System/Config/ProductAttributes.php +32 -0
- app/code/community/Reflektion/Catalogexport/Model/System/Validate/ProductAttributes.php +32 -0
- app/code/community/Reflektion/Catalogexport/Model/Transferfeeds.php +140 -0
- app/code/community/Reflektion/Catalogexport/controllers/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/controllers/Adminhtml/ExportController.php +78 -0
- app/code/community/Reflektion/Catalogexport/controllers/Adminhtml/JobController.php +105 -0
- app/code/community/Reflektion/Catalogexport/etc/adminhtml.xml +69 -0
- app/code/community/Reflektion/Catalogexport/etc/config.xml +126 -0
- app/code/community/Reflektion/Catalogexport/etc/system.xml +173 -0
- app/code/community/Reflektion/Catalogexport/sql/.DS_Store +0 -0
- app/code/community/Reflektion/Catalogexport/sql/reflektion_setup/mysql4-install-1.0.0.php +36 -0
- app/design/adminhtml/default/default/layout/reflektion.xml +24 -0
- app/etc/modules/Reflektion_Catalogexport.xml +10 -0
- 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 
|
11 |
+
-> Generate and transfer your magento catalog product CSV to Reflektion SFTP. 
|
12 |
+
-> Website level export.
|
13 |
+
-> Select Product Attributes to transfer at your website level.</description>
|
14 |
+
<notes>This is the first public release of the Reflektion Catalogexport Module
|
15 |
+
This extension contains following feature
|
16 |
+
-> Generate and transfer your magento catalog product CSV to Reflektion SFTP. 
|
17 |
+
-> Website level export.
|
18 |
+
-> Select Product Attributes to transfer at your website level.
|
19 |
+

|
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>
|