Flagbit_Factfinder - Version 4.1.11

Version Notes

Release

Download this release

Release Info

Developer FACTFinder
Extension Flagbit_Factfinder
Version 4.1.11
Comparing to
See all releases


Code changes from version 4.1.10 to 4.1.11

Files changed (50) hide show
  1. app/code/community/FACTFinder/Asn/etc/system.xml +1 -1
  2. app/code/community/FACTFinder/Campaigns/Block/Abstract.php +1 -3
  3. app/code/community/FACTFinder/Campaigns/Block/Feedback/Page.php +41 -0
  4. app/code/community/FACTFinder/Campaigns/Block/Feedback/Product.php +6 -3
  5. app/code/community/FACTFinder/Campaigns/Block/Pushed/Abstract.php +13 -12
  6. app/code/community/FACTFinder/Campaigns/Block/Pushed/Page.php +41 -0
  7. app/code/community/FACTFinder/Campaigns/Block/Pushed/Product.php +6 -3
  8. app/code/community/FACTFinder/Campaigns/Block/Pushed/Search.php +0 -18
  9. app/code/community/FACTFinder/Campaigns/Helper/Data.php +68 -0
  10. app/code/community/FACTFinder/Campaigns/Model/Handler/Abstract.php +14 -11
  11. app/code/community/FACTFinder/Campaigns/Model/Handler/Cart.php +2 -2
  12. app/code/community/FACTFinder/Campaigns/Model/Handler/Page.php +73 -0
  13. app/code/community/FACTFinder/Campaigns/Model/Handler/Product.php +2 -2
  14. app/code/community/FACTFinder/Campaigns/etc/system.xml +29 -9
  15. app/code/community/FACTFinder/Core/Block/Catalog/Product/List/Toolbar.php +7 -3
  16. app/code/community/FACTFinder/Core/Block/Catalog/Product/Pager.php +77 -2
  17. app/code/community/FACTFinder/Core/Helper/Data.php +5 -4
  18. app/code/community/FACTFinder/Core/Helper/Export.php +55 -8
  19. app/code/community/FACTFinder/Core/Model/Export/Observer.php +8 -2
  20. app/code/community/FACTFinder/Core/Model/Export/Semaphore.php +125 -0
  21. app/code/community/FACTFinder/Core/Model/Export/Type/Interface.php +44 -0
  22. app/code/community/FACTFinder/Core/Model/Export/{Price.php → Type/Price.php} +87 -16
  23. app/code/community/FACTFinder/Core/Model/Export/{Product.php → Type/Product.php} +182 -61
  24. app/code/community/FACTFinder/Core/Model/Export/{Stock.php → Type/Stock.php} +89 -19
  25. app/code/community/FACTFinder/Core/Model/File.php +181 -10
  26. app/code/community/FACTFinder/Core/Model/File/Validator/Abstract.php +168 -0
  27. app/code/community/FACTFinder/Core/Model/File/Validator/Price.php +43 -0
  28. app/code/community/FACTFinder/Core/Model/File/Validator/Product.php +43 -0
  29. app/code/community/FACTFinder/Core/Model/File/Validator/Stock.php +43 -0
  30. app/code/community/FACTFinder/Core/Model/Handler/Search.php +19 -3
  31. app/code/community/FACTFinder/Core/Model/Handler/Status.php +2 -8
  32. app/code/community/FACTFinder/Core/Model/Resource/Export.php +1 -1
  33. app/code/community/FACTFinder/Core/controllers/ExportController.php +15 -45
  34. app/code/community/FACTFinder/Core/etc/system.xml +73 -63
  35. app/code/community/FACTFinder/Recommendation/Model/Observer.php +7 -0
  36. app/code/community/FACTFinder/Suggest/Helper/Data.php +1 -1
  37. app/code/community/FACTFinder/Suggest/Model/Observer.php +6 -0
  38. app/code/community/FACTFinder/Suggest/etc/system.xml +6 -6
  39. app/code/community/FACTFinder/Tracking/Block/Recommendation.php +7 -1
  40. app/code/community/FACTFinder/Tracking/Model/Observer.php +3 -0
  41. app/code/community/FACTFinder/Tracking/Model/Processor.php +38 -3
  42. app/code/community/FACTFinder/Tracking/etc/config.xml +1 -1
  43. app/code/community/FACTFinder/Tracking/etc/system.xml +4 -4
  44. app/code/community/FACTFinder/Tracking/sql/factfinder_tracking_setup/upgrade-4.1.2-4.1.11.php +35 -0
  45. app/design/frontend/base/default/layout/factfinder/campaigns.xml +25 -0
  46. app/design/frontend/rwd/enterprise/layout/factfinder/suggest.xml +28 -0
  47. js/factfinder/suggest.js +1 -0
  48. js/factfinder/tracking.js +9 -2
  49. package.xml +6 -6
  50. shell/factfinder.php +21 -6
app/code/community/FACTFinder/Asn/etc/system.xml CHANGED
@@ -21,7 +21,7 @@
21
<label>Replace Catalog Navigation</label>
22
<frontend_type>select</frontend_type>
23
<source_model>adminhtml/system_config_source_yesno</source_model>
24
- <sort_order>15</sort_order>
25
<show_in_default>1</show_in_default>
26
<show_in_website>1</show_in_website>
27
<show_in_store>1</show_in_store>
21
<label>Replace Catalog Navigation</label>
22
<frontend_type>select</frontend_type>
23
<source_model>adminhtml/system_config_source_yesno</source_model>
24
+ <sort_order>20</sort_order>
25
<show_in_default>1</show_in_default>
26
<show_in_website>1</show_in_website>
27
<show_in_store>1</show_in_store>
app/code/community/FACTFinder/Campaigns/Block/Abstract.php CHANGED
@@ -38,9 +38,7 @@ abstract class FACTFinder_Campaigns_Block_Abstract extends Mage_Core_Block_Templ
38
*/
39
protected function _canBeShown()
40
{
41
- if (Mage::registry('current_category')
42
- && !Mage::helper('factfinder_campaigns')->isCatalogNavigationReplaced()
43
- ) {
44
return false;
45
}
46
38
*/
39
protected function _canBeShown()
40
{
41
+ if (!Mage::helper('factfinder_campaigns')->getIsResultListingPage()) {
42
return false;
43
}
44
app/code/community/FACTFinder/Campaigns/Block/Feedback/Page.php ADDED
@@ -0,0 +1,41 @@
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author tuegeb
8
+ * @copyright Copyright (c) 2016, tuegeb
9
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
10
+ */
11
+
12
+ /**
13
+ * Class FACTFinder_Campaigns_Block_Feedback_Page
14
+ *
15
+ * @category Mage
16
+ * @package FACTFinder_Campaigns
17
+ * @author tuegeb
18
+ * @copyright Copyright (c) 2016, tuegeb
19
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
20
+ */
21
+ class FACTFinder_Campaigns_Block_Feedback_Page extends FACTFinder_Campaigns_Block_Feedback_Abstract
22
+ {
23
+
24
+ protected $_handlerModel = 'factfinder_campaigns/handler_page';
25
+
26
+ /**
27
+ * Check is the campign can be shown on landing page
28
+ *
29
+ * @return bool
30
+ */
31
+ protected function _canBeShown()
32
+ {
33
+ if (!Mage::helper('factfinder_campaigns')->getIsOnLandingPage()
34
+ && !Mage::helper('factfinder_campaigns')->getIsOnStartPage()
35
+ ) {
36
+ return false;
37
+ }
38
+ return (bool) Mage::helper('factfinder')->isEnabled('campaigns');
39
+ }
40
+
41
+ }
app/code/community/FACTFinder/Campaigns/Block/Feedback/Product.php CHANGED
@@ -33,9 +33,12 @@ class FACTFinder_Campaigns_Block_Feedback_Product extends FACTFinder_Campaigns_B
33
*/
34
protected function _canBeShown()
35
{
36
- $enabledOnProduct = Mage::helper('factfinder_campaigns')->canShowCampaignsOnProduct();
37
-
38
- return parent::_canBeShown() && $enabledOnProduct;
39
}
40
41
33
*/
34
protected function _canBeShown()
35
{
36
+ if (!Mage::registry('current_product')
37
+ || !Mage::helper('factfinder_campaigns')->canShowCampaignsOnProduct())
38
+ {
39
+ return false;
40
+ }
41
+ return (bool) Mage::helper('factfinder')->isEnabled('campaigns');
42
}
43
44
app/code/community/FACTFinder/Campaigns/Block/Pushed/Abstract.php CHANGED
@@ -97,18 +97,6 @@ abstract class FACTFinder_Campaigns_Block_Pushed_Abstract extends Mage_Catalog_B
97
return $this->__('Pushed products');
98
}
99
100
-
101
- /**
102
- * Check if campaigns can be shown
103
- *
104
- * @return bool
105
- */
106
- protected function _canBeShown()
107
- {
108
- return (bool) Mage::helper('factfinder')->isEnabled('campaigns');
109
- }
110
-
111
-
112
/**
113
* Render html
114
* Return empty string if module isn't enabled
@@ -124,5 +112,18 @@ abstract class FACTFinder_Campaigns_Block_Pushed_Abstract extends Mage_Catalog_B
124
return parent::_toHtml();
125
}
126
127
128
}
97
return $this->__('Pushed products');
98
}
99
100
/**
101
* Render html
102
* Return empty string if module isn't enabled
112
return parent::_toHtml();
113
}
114
115
+ /**
116
+ * Check if campaigns can be shown
117
+ *
118
+ * @return bool
119
+ */
120
+ protected function _canBeShown()
121
+ {
122
+ if (!Mage::helper('factfinder_campaigns')->getIsResultListingPage()) {
123
+ return false;
124
+ }
125
+
126
+ return (bool) Mage::helper('factfinder')->isEnabled('campaigns');
127
+ }
128
129
}
app/code/community/FACTFinder/Campaigns/Block/Pushed/Page.php ADDED
@@ -0,0 +1,41 @@
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author tuegeb
8
+ * @copyright Copyright (c) 2016, tuegeb
9
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
10
+ */
11
+
12
+ /**
13
+ * Class FACTFinder_Campaigns_Block_Pushed_Page
14
+ *
15
+ * @category Mage
16
+ * @package FACTFinder_Campaigns
17
+ * @author tuegeb
18
+ * @copyright Copyright (c) 2016, tuegeb
19
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
20
+ */
21
+ class FACTFinder_Campaigns_Block_Pushed_Page extends FACTFinder_Campaigns_Block_Pushed_Abstract
22
+ {
23
+
24
+ protected $_handlerModel = 'factfinder_campaigns/handler_page';
25
+
26
+ /**
27
+ * Check is the campign can be shown on landing page
28
+ *
29
+ * @return bool
30
+ */
31
+ protected function _canBeShown()
32
+ {
33
+ if (!Mage::helper('factfinder_campaigns')->getIsOnLandingPage()
34
+ && !Mage::helper('factfinder_campaigns')->getIsOnStartPage()
35
+ ) {
36
+ return false;
37
+ }
38
+ return (bool) Mage::helper('factfinder')->isEnabled('campaigns');
39
+ }
40
+
41
+ }
app/code/community/FACTFinder/Campaigns/Block/Pushed/Product.php CHANGED
@@ -33,9 +33,12 @@ class FACTFinder_Campaigns_Block_Pushed_Product extends FACTFinder_Campaigns_Blo
33
*/
34
protected function _canBeShown()
35
{
36
- $enabledOnProduct = Mage::helper('factfinder_campaigns')->canShowCampaignsOnProduct();
37
-
38
- return parent::_canBeShown() && $enabledOnProduct;
39
}
40
41
33
*/
34
protected function _canBeShown()
35
{
36
+ if (!Mage::registry('current_product')
37
+ || !Mage::helper('factfinder_campaigns')->canShowCampaignsOnProduct())
38
+ {
39
+ return false;
40
+ }
41
+ return (bool) Mage::helper('factfinder')->isEnabled('campaigns');
42
}
43
44
app/code/community/FACTFinder/Campaigns/Block/Pushed/Search.php CHANGED
@@ -25,22 +25,4 @@ class FACTFinder_Campaigns_Block_Pushed_Search extends FACTFinder_Campaigns_Bloc
25
26
protected $_handlerModel = 'factfinder_campaigns/handler_search';
27
28
-
29
- /**
30
- * Check if campaigns can be shown
31
- *
32
- * @return bool
33
- */
34
- protected function _canBeShown()
35
- {
36
- if (Mage::registry('current_category')
37
- && !Mage::helper('factfinder_campaigns')->isCatalogNavigationReplaced()
38
- ) {
39
- return false;
40
- }
41
-
42
- return parent::_canBeShown();
43
- }
44
-
45
-
46
}
25
26
protected $_handlerModel = 'factfinder_campaigns/handler_search';
27
28
}
app/code/community/FACTFinder/Campaigns/Helper/Data.php CHANGED
@@ -25,6 +25,8 @@ class FACTFinder_Campaigns_Helper_Data extends Mage_Core_Helper_Abstract
25
const CATALOG_NAVIGATION_REPLACED_CONFIG_PATH = 'factfinder/modules/catalog_navigation';
26
const CAMPAIGNS_IDENTIFIER_CONFIG_PATH = 'factfinder/config/campaigns_identifier';
27
const ENABLE_CAMPAIGNS_ON_PROD_PAGE_CONFIG_PATH = 'factfinder/config/enable_campaigns_on_prod_page';
28
29
30
/**
@@ -36,6 +38,26 @@ class FACTFinder_Campaigns_Helper_Data extends Mage_Core_Helper_Abstract
36
{
37
return (bool) Mage::app()->getStore()->getConfig(self::ENABLE_CAMPAIGNS_ON_PROD_PAGE_CONFIG_PATH);
38
}
39
40
41
/**
@@ -59,5 +81,51 @@ class FACTFinder_Campaigns_Helper_Data extends Mage_Core_Helper_Abstract
59
return (bool) Mage::app()->getStore()->getConfig(self::CATALOG_NAVIGATION_REPLACED_CONFIG_PATH);
60
}
61
62
63
}
25
const CATALOG_NAVIGATION_REPLACED_CONFIG_PATH = 'factfinder/modules/catalog_navigation';
26
const CAMPAIGNS_IDENTIFIER_CONFIG_PATH = 'factfinder/config/campaigns_identifier';
27
const ENABLE_CAMPAIGNS_ON_PROD_PAGE_CONFIG_PATH = 'factfinder/config/enable_campaigns_on_prod_page';
28
+ const ENABLE_LANDING_PAGE_CAMPAIGNS_CONFIG_PATH = 'factfinder/config/enable_landing_page_campaigns';
29
+ const ENABLE_START_PAGE_CAMPAIGNS_CONFIG_PATH = 'factfinder/config/enable_start_page_campaigns';
30
31
32
/**
38
{
39
return (bool) Mage::app()->getStore()->getConfig(self::ENABLE_CAMPAIGNS_ON_PROD_PAGE_CONFIG_PATH);
40
}
41
+
42
+ /**
43
+ * Check config if showing campaigns on product page is enabled
44
+ *
45
+ * @return bool
46
+ */
47
+ public function canShowLandingPageCampaigns()
48
+ {
49
+ return (bool) Mage::app()->getStore()->getConfig(self::ENABLE_LANDING_PAGE_CAMPAIGNS_CONFIG_PATH);
50
+ }
51
+
52
+ /**
53
+ * Check config if showing campaigns on start page is enabled
54
+ *
55
+ * @return bool
56
+ */
57
+ public function canShowStartPageCampaigns()
58
+ {
59
+ return (bool) Mage::app()->getStore()->getConfig(self::ENABLE_START_PAGE_CAMPAIGNS_CONFIG_PATH);
60
+ }
61
62
63
/**
81
return (bool) Mage::app()->getStore()->getConfig(self::CATALOG_NAVIGATION_REPLACED_CONFIG_PATH);
82
}
83
84
+ /**
85
+ * Determines whether the current page is a category start page which can access page campaigns.
86
+ *
87
+ * @return bool
88
+ */
89
+ public function getIsOnLandingPage()
90
+ {
91
+ if (!Mage::registry('current_category')
92
+ || Mage::registry('current_category')->getDisplayMode() === Mage_Catalog_Model_Category::DM_PRODUCT
93
+ || !self::canShowLandingPageCampaigns())
94
+ {
95
+ return false;
96
+ }
97
+ return true;
98
+ }
99
+
100
+ /**
101
+ * Determines whether the current page is the start page which can access page campaigns.
102
+ *
103
+ * @return bool
104
+ */
105
+ public function getIsOnStartPage()
106
+ {
107
+ if (Mage::getSingleton('cms/page')->getIdentifier() !== 'home'
108
+ || !self::canShowStartPageCampaigns())
109
+ {
110
+ return false;
111
+ }
112
+ return true;
113
+ }
114
+
115
+ /**
116
+ * Determines whether the current page is including a FACT-Finder result listing.
117
+ *
118
+ * @return bool
119
+ */
120
+ public function getIsResultListingPage()
121
+ {
122
+ if (Mage::registry('current_category')
123
+ && !Mage::helper('factfinder_campaigns')->isCatalogNavigationReplaced()
124
+ || Mage::registry('current_product')
125
+ ) {
126
+ return false;
127
+ }
128
+ return true;
129
+ }
130
131
}
app/code/community/FACTFinder/Campaigns/Model/Handler/Abstract.php CHANGED
@@ -35,6 +35,14 @@ abstract class FACTFinder_Campaigns_Model_Handler_Abstract extends FACTFinder_Co
35
* @var array
36
*/
37
protected $_productIds = array();
38
39
/**
40
* Available campaigns
@@ -57,7 +65,7 @@ abstract class FACTFinder_Campaigns_Model_Handler_Abstract extends FACTFinder_Co
57
*
58
* @param array $productIds
59
*/
60
- public function __construct($productIds)
61
{
62
$this->_productIds = $productIds;
63
parent::__construct();
@@ -90,7 +98,11 @@ abstract class FACTFinder_Campaigns_Model_Handler_Abstract extends FACTFinder_Co
90
$params = array();
91
92
$params['do'] = $this->_getDoParam();
93
- $params['productNumber'] = $this->_getProductNumberParam();
94
$params['idsOnly'] = 'true';
95
if(Mage::getStoreConfigFlag('factfinder/config/personalization')) {
96
$params['sid'] = Mage::helper('factfinder_tracking')->getSessionId();
@@ -106,15 +118,6 @@ abstract class FACTFinder_Campaigns_Model_Handler_Abstract extends FACTFinder_Co
106
*/
107
abstract protected function _getDoParam();
108
109
-
110
- /**
111
- * Get array of product ids
112
- *
113
- * @return array
114
- */
115
- abstract protected function _getProductNumberParam();
116
-
117
-
118
/**
119
* Get array of guestions from advisor campaign
120
*
35
* @var array
36
*/
37
protected $_productIds = array();
38
+
39
+ /**
40
+ * Page IDs
41
+ *
42
+ * @var string
43
+ */
44
+ protected $_pageId = null;
45
+
46
47
/**
48
* Available campaigns
65
*
66
* @param array $productIds
67
*/
68
+ public function __construct($productIds = null)
69
{
70
$this->_productIds = $productIds;
71
parent::__construct();
98
$params = array();
99
100
$params['do'] = $this->_getDoParam();
101
+ if ($this instanceof FACTFinder_Campaigns_Model_Handler_Page) {
102
+ $params['pageId'] = $this->_getPageIdParam();
103
+ } else {
104
+ $params['productNumber'] = $this->_getProductNumberParam();
105
+ }
106
$params['idsOnly'] = 'true';
107
if(Mage::getStoreConfigFlag('factfinder/config/personalization')) {
108
$params['sid'] = Mage::helper('factfinder_tracking')->getSessionId();
118
*/
119
abstract protected function _getDoParam();
120
121
/**
122
* Get array of guestions from advisor campaign
123
*
app/code/community/FACTFinder/Campaigns/Model/Handler/Cart.php CHANGED
@@ -61,9 +61,9 @@ class FACTFinder_Campaigns_Model_Handler_Cart extends FACTFinder_Campaigns_Model
61
{
62
if (!empty($this->_productIds)) {
63
$this->_getFacade()->getProductCampaignAdapter()->makeShoppingCartCampaign();
64
}
65
-
66
- return parent::getCampaigns();
67
}
68
69
61
{
62
if (!empty($this->_productIds)) {
63
$this->_getFacade()->getProductCampaignAdapter()->makeShoppingCartCampaign();
64
+ return parent::getCampaigns();
65
}
66
+ return array();
67
}
68
69
app/code/community/FACTFinder/Campaigns/Model/Handler/Page.php ADDED
@@ -0,0 +1,73 @@
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author tuegeb
8
+ * @copyright Copyright (c) 2016, tuegeb
9
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
10
+ */
11
+
12
+ /**
13
+ * Class FACTFinder_Campaigns_Model_Handler_Page
14
+ *
15
+ * @category Mage
16
+ * @package FACTFinder_Campaigns
17
+ * @author tuegeb
18
+ * @copyright Copyright (c) 2016, tuegeb
19
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
20
+ */
21
+ class FACTFinder_Campaigns_Model_Handler_Page extends FACTFinder_Campaigns_Model_Handler_Abstract
22
+ {
23
+ /**
24
+ * Class constructor
25
+ *
26
+ * @param string $pageId
27
+ */
28
+ public function __construct($pageId)
29
+ {
30
+ $this->_pageId = $pageId;
31
+ parent::__construct();
32
+ }
33
+
34
+ /**
35
+ * Get name of the method to be executed in the adapter
36
+ *
37
+ * @return string
38
+ */
39
+ protected function _getDoParam()
40
+ {
41
+ return 'getPageCampaigns';
42
+ }
43
+
44
+ /**
45
+ * Get page id
46
+ *
47
+ * @return string
48
+ */
49
+ protected function _getPageIdParam()
50
+ {
51
+ if (Mage::helper('factfinder_campaigns')->getIsOnLandingPage()) {
52
+ $this->_pageId = Mage::registry('current_category')->getId();
53
+ } else if (Mage::helper('factfinder_campaigns')->getIsOnStartPage()) {
54
+ $this->_pageId = 'start';
55
+ }
56
+ return $this->_pageId;
57
+ }
58
+
59
+ /**
60
+ * Get array of campaigns available
61
+ *
62
+ * @return array
63
+ */
64
+ public function getCampaigns()
65
+ {
66
+ if (isset($this->_pageId)) {
67
+ $this->_getFacade()->getProductCampaignAdapter()->makePageCampaign();
68
+ return parent::getCampaigns();
69
+ }
70
+ return array();
71
+ }
72
+
73
+ }
app/code/community/FACTFinder/Campaigns/Model/Handler/Product.php CHANGED
@@ -58,9 +58,9 @@ class FACTFinder_Campaigns_Model_Handler_Product extends FACTFinder_Campaigns_Mo
58
{
59
if (!empty($this->_productIds)) {
60
$this->_getFacade()->getProductCampaignAdapter()->makeProductCampaign();
61
}
62
-
63
- return parent::getCampaigns();
64
}
65
66
58
{
59
if (!empty($this->_productIds)) {
60
$this->_getFacade()->getProductCampaignAdapter()->makeProductCampaign();
61
+ return parent::getCampaigns();
62
}
63
+ return array();
64
}
65
66
app/code/community/FACTFinder/Campaigns/etc/system.xml CHANGED
@@ -17,24 +17,44 @@
17
<groups>
18
<config>
19
<fields>
20
- <campaigns_identifier translate="label">
21
- <label>Campaigns Product Identifier</label>
22
<frontend_type>select</frontend_type>
23
- <source_model>factfinder/system_config_source_identifier</source_model>
24
- <sort_order>11</sort_order>
25
<show_in_default>1</show_in_default>
26
<show_in_website>1</show_in_website>
27
<show_in_store>1</show_in_store>
28
- </campaigns_identifier>
29
- <enable_campaigns_on_prod_page>
30
- <label>Enable campaigns on product page</label>
31
<frontend_type>select</frontend_type>
32
<source_model>adminhtml/system_config_source_yesno</source_model>
33
- <sort_order>12</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
- </enable_campaigns_on_prod_page>
38
</fields>
39
</config>
40
</groups>
17
<groups>
18
<config>
19
<fields>
20
+ <enable_campaigns_on_prod_page>
21
+ <label>Enable campaigns on product page</label>
22
<frontend_type>select</frontend_type>
23
+ <source_model>adminhtml/system_config_source_yesno</source_model>
24
+ <sort_order>25</sort_order>
25
<show_in_default>1</show_in_default>
26
<show_in_website>1</show_in_website>
27
<show_in_store>1</show_in_store>
28
+ </enable_campaigns_on_prod_page>
29
+ <enable_landing_page_campaigns>
30
+ <label>Enable campaigns on landing page</label>
31
<frontend_type>select</frontend_type>
32
<source_model>adminhtml/system_config_source_yesno</source_model>
33
+ <sort_order>30</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
+ <comment><![CDATA[Requires FACT-Finder >= 7.2.]]></comment>
38
+ </enable_landing_page_campaigns>
39
+ <enable_start_page_campaigns>
40
+ <label>Enable campaigns on start page</label>
41
+ <frontend_type>select</frontend_type>
42
+ <source_model>adminhtml/system_config_source_yesno</source_model>
43
+ <sort_order>31</sort_order>
44
+ <show_in_default>1</show_in_default>
45
+ <show_in_website>1</show_in_website>
46
+ <show_in_store>1</show_in_store>
47
+ <comment><![CDATA[Requires FACT-Finder >= 7.2.]]></comment>
48
+ </enable_start_page_campaigns>
49
+ <campaigns_identifier translate="label">
50
+ <label>Campaigns Product Identifier</label>
51
+ <frontend_type>select</frontend_type>
52
+ <source_model>factfinder/system_config_source_identifier</source_model>
53
+ <sort_order>45</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>1</show_in_website>
56
+ <show_in_store>1</show_in_store>
57
+ </campaigns_identifier>
58
</fields>
59
</config>
60
</groups>
app/code/community/FACTFinder/Core/Block/Catalog/Product/List/Toolbar.php CHANGED
@@ -455,7 +455,11 @@ class FACTFinder_Core_Block_Catalog_Product_List_Toolbar extends Mage_Catalog_Bl
455
if ($this->_handler && Mage::helper('factfinder/search')->useResultsPerPageOptions()) {
456
$currentLimit = $this->getRequest()->getParam($this->getLimitVarName());
457
if ($currentLimit == null && $this->_handler->getResultsPerPageOptions() != null) {
458
- $currentLimit = $this->_handler->getResultsPerPageOptions()->getDefaultOption()->getLabel();
459
}
460
461
return $currentLimit;
@@ -528,9 +532,9 @@ class FACTFinder_Core_Block_Catalog_Product_List_Toolbar extends Mage_Catalog_Bl
528
public function getDefaultPerPageValue()
529
{
530
if ($this->_handler && Mage::helper('factfinder/search')->useResultsPerPageOptions()
531
- && $this->_handler->getResultsPerPageOptions() != null
532
) {
533
- return $this->_handler->getResultsPerPageOptions()->getDefaultOption()->getLabel();
534
}
535
536
return parent::getDefaultPerPageValue();
455
if ($this->_handler && Mage::helper('factfinder/search')->useResultsPerPageOptions()) {
456
$currentLimit = $this->getRequest()->getParam($this->getLimitVarName());
457
if ($currentLimit == null && $this->_handler->getResultsPerPageOptions() != null) {
458
+ if ($this->_handler->getDefaultPerPageOption()) {
459
+ $currentLimit = $this->_handler->getDefaultPerPageOption()->getLabel();
460
+ } else {
461
+ $currentLimit = parent::getLimit();
462
+ }
463
}
464
465
return $currentLimit;
532
public function getDefaultPerPageValue()
533
{
534
if ($this->_handler && Mage::helper('factfinder/search')->useResultsPerPageOptions()
535
+ && $this->_handler->getDefaultPerPageOption()
536
) {
537
+ return $this->_handler->getDefaultPerPageOption()->getLabel();
538
}
539
540
return parent::getDefaultPerPageValue();
app/code/community/FACTFinder/Core/Block/Catalog/Product/Pager.php CHANGED
@@ -66,7 +66,7 @@ class FACTFinder_Core_Block_Catalog_Product_Pager extends Mage_Page_Block_Html_P
66
*/
67
public function getPagerUrl($params = array())
68
{
69
- if (!$this->_handler || !$this->_handler->getPaging()) {
70
return parent::getPagerUrl($params);
71
}
72
@@ -75,7 +75,7 @@ class FACTFinder_Core_Block_Catalog_Product_Pager extends Mage_Page_Block_Html_P
75
if (!isset($this->_pagingUrls[$pageNum])) {
76
$this->_pagingUrls[$pageNum] = '';
77
/** @var \FACTFinder\Data\Page $pageItem */
78
- foreach ($this->_handler->getPaging() as $pageItem) {
79
if ($pageItem->getPageNumber() == $pageNum) {
80
$this->_pagingUrls[$pageNum] = $pageItem->getUrl();
81
break;
@@ -87,4 +87,79 @@ class FACTFinder_Core_Block_Catalog_Product_Pager extends Mage_Page_Block_Html_P
87
}
88
89
90
}
66
*/
67
public function getPagerUrl($params = array())
68
{
69
+ if (!$this->getPaging()) {
70
return parent::getPagerUrl($params);
71
}
72
75
if (!isset($this->_pagingUrls[$pageNum])) {
76
$this->_pagingUrls[$pageNum] = '';
77
/** @var \FACTFinder\Data\Page $pageItem */
78
+ foreach ($this->getPaging() as $pageItem) {
79
if ($pageItem->getPageNumber() == $pageNum) {
80
$this->_pagingUrls[$pageNum] = $pageItem->getUrl();
81
break;
87
}
88
89
90
+ /**
91
+ * Get paging from handler or null
92
+ *
93
+ * @return \FACTFinder\Data\Paging|null
94
+ */
95
+ protected function getPaging()
96
+ {
97
+ if (!$this->_handler || !$this->_handler->getPaging()) {
98
+ return null;
99
+ }
100
+
101
+ return $this->_handler->getPaging();
102
+ }
103
+
104
+
105
+ /**
106
+ * Get last page URL
107
+ *
108
+ * @return string
109
+ */
110
+ public function getLastPageUrl()
111
+ {
112
+ if ($this->getPaging() && $this->getPaging()->getLastPage()) {
113
+ return $this->getPaging()->getLastPage()->getUrl();
114
+ }
115
+
116
+ return parent::getLastPageUrl();
117
+ }
118
+
119
+
120
+ /**
121
+ * Get first page URL
122
+ *
123
+ * @return string
124
+ */
125
+ public function getFirstPageUrl()
126
+ {
127
+ if ($this->getPaging() && $this->getPaging()->getFirstPage()) {
128
+ return $this->getPaging()->getFirstPage()->getUrl();
129
+ }
130
+
131
+ return parent::getFirstPageUrl();
132
+ }
133
+
134
+
135
+ /**
136
+ * Get next page URL
137
+ *
138
+ * @return string
139
+ */
140
+ public function getNextPageUrl()
141
+ {
142
+ if ($this->getPaging() && $this->getPaging()->getNextPage()) {
143
+ return $this->getPaging()->getNextPage()->getUrl();
144
+ }
145
+
146
+ return parent::getNextPageUrl();
147
+ }
148
+
149
+
150
+ /**
151
+ * Get previous page URL
152
+ *
153
+ * @return string
154
+ */
155
+ public function getPreviousPageUrl()
156
+ {
157
+ if ($this->getPaging() && $this->getPaging()->getPreviousPage()) {
158
+ return $this->getPaging()->getPreviousPage()->getUrl();
159
+ }
160
+
161
+ return parent::getPreviousPageUrl();
162
+ }
163
+
164
+
165
}
app/code/community/FACTFinder/Core/Helper/Data.php CHANGED
@@ -33,20 +33,21 @@ class FACTFinder_Core_Helper_Data extends Mage_Core_Helper_Abstract
33
* Check if the module is enabled
34
*
35
* @param string|null $feature
36
*
37
* @return bool
38
*/
39
- public function isEnabled($feature = null)
40
{
41
if ($this->_getRequest()->getParam(self::SKIP_FF_PARAM_NAME)
42
- && Mage::getStoreConfig(self::USE_FALLBACK_CONFIG_PATH)
43
) {
44
return false;
45
}
46
47
- $result = (bool) Mage::app()->getStore()->getConfig('factfinder/search/enabled');
48
if ($feature !== null) {
49
- $result &= (bool) Mage::app()->getStore()->getConfig('factfinder/modules/' . $feature);
50
}
51
52
return $result;
33
* Check if the module is enabled
34
*
35
* @param string|null $feature
36
+ * @param null|int $storeId
37
*
38
* @return bool
39
*/
40
+ public function isEnabled($feature = null, $storeId = null)
41
{
42
if ($this->_getRequest()->getParam(self::SKIP_FF_PARAM_NAME)
43
+ && Mage::getStoreConfig(self::USE_FALLBACK_CONFIG_PATH, $storeId)
44
) {
45
return false;
46
}
47
48
+ $result = (bool) Mage::app()->getStore($storeId)->getConfig('factfinder/search/enabled');
49
if ($feature !== null) {
50
+ $result &= (bool) Mage::app()->getStore($storeId)->getConfig('factfinder/modules/' . $feature);
51
}
52
53
return $result;
app/code/community/FACTFinder/Core/Helper/Export.php CHANGED
@@ -28,6 +28,7 @@ class FACTFinder_Core_Helper_Export extends Mage_Core_Helper_Abstract
28
const EXPORT_IMAGE_TYPE = 'suggest_image_type';
29
const EXPORT_URLS_IMAGES = 'urls';
30
const OUT_OF_STOCK_PRODUCTS = 'out_of_stock_products';
31
32
/**
33
* @var int
@@ -227,20 +228,27 @@ class FACTFinder_Core_Helper_Export extends Mage_Core_Helper_Abstract
227
public function archiveFiles($storeId)
228
{
229
$dir = $this->getExportDirectory();
230
-
231
$archiveName = sprintf(self::ARCHIVE_PATTERN, $storeId);
232
233
$zip = new ZipArchive();
234
- $zip->open($dir . DS . $archiveName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
235
foreach ($this->getExportTypes() as $type) {
236
- $model = Mage::getModel('factfinder/export_' . $type);
237
$filename = $model->getFilenameForStore($storeId);
238
$zip->addFile($dir . DS . $filename, $filename);
239
}
240
241
$zip->close();
242
243
- return $dir . DS . $archiveName;
244
}
245
246
@@ -285,7 +293,8 @@ class FACTFinder_Core_Helper_Export extends Mage_Core_Helper_Abstract
285
public function getExportImageWidth($storeId = 0)
286
{
287
$width = $this->getExportConfigValue(self::EXPORT_IMAGE_SIZE, $storeId);
288
- $width = array_shift(explode('x', $width));
289
290
return $width;
291
}
@@ -301,7 +310,8 @@ class FACTFinder_Core_Helper_Export extends Mage_Core_Helper_Abstract
301
public function getExportImageHeight($storeId = 0)
302
{
303
$height = $this->getExportConfigValue(self::EXPORT_IMAGE_SIZE, $storeId);
304
- $height = array_pop(explode('x', $height));
305
306
return $height ? $height : $this->getExportImageWidth();
307
}
@@ -321,13 +331,13 @@ class FACTFinder_Core_Helper_Export extends Mage_Core_Helper_Abstract
321
322
323
/**
324
- * Check if images and deeplinks should be exported
325
*
326
* @param int $storeId
327
*
328
* @return null|string
329
*/
330
- public function shouldExportImagesAndDeeplinks($storeId = 0)
331
{
332
return $this->getExportConfigValue(self::EXPORT_URLS_IMAGES, $storeId);
333
}
@@ -346,4 +356,41 @@ class FACTFinder_Core_Helper_Export extends Mage_Core_Helper_Abstract
346
}
347
348
349
}
28
const EXPORT_IMAGE_TYPE = 'suggest_image_type';
29
const EXPORT_URLS_IMAGES = 'urls';
30
const OUT_OF_STOCK_PRODUCTS = 'out_of_stock_products';
31
+ const VALIDATION_DISABLED = 'disabled_validation';
32
33
/**
34
* @var int
228
public function archiveFiles($storeId)
229
{
230
$dir = $this->getExportDirectory();
231
$archiveName = sprintf(self::ARCHIVE_PATTERN, $storeId);
232
+ $archivePath = $dir . DS . $archiveName;
233
234
$zip = new ZipArchive();
235
+ $zip->open($archivePath, ZipArchive::CREATE | ZipArchive::OVERWRITE);
236
foreach ($this->getExportTypes() as $type) {
237
+ $model = Mage::getModel('factfinder/export_type_' . $type);
238
$filename = $model->getFilenameForStore($storeId);
239
+
240
+ if ($this->isValidationEnabled($storeId) && !$this->_validateFile($model, $dir, $filename)) {
241
+ $zip->close();
242
+ @unlink($archivePath);
243
+ break;
244
+ }
245
+
246
$zip->addFile($dir . DS . $filename, $filename);
247
}
248
249
$zip->close();
250
251
+ return $archivePath;
252
}
253
254
293
public function getExportImageWidth($storeId = 0)
294
{
295
$width = $this->getExportConfigValue(self::EXPORT_IMAGE_SIZE, $storeId);
296
+ $width = explode('x', $width);
297
+ $width = array_shift($width);
298
299
return $width;
300
}
310
public function getExportImageHeight($storeId = 0)
311
{
312
$height = $this->getExportConfigValue(self::EXPORT_IMAGE_SIZE, $storeId);
313
+ $height = explode('x', $height);
314
+ $height = array_pop($height);
315
316
return $height ? $height : $this->getExportImageWidth();
317
}
331
332
333
/**
334
+ * Check if images should be exported
335
*
336
* @param int $storeId
337
*
338
* @return null|string
339
*/
340
+ public function shouldExportImages($storeId = 0)
341
{
342
return $this->getExportConfigValue(self::EXPORT_URLS_IMAGES, $storeId);
343
}
356
}
357
358
359
+ /**
360
+ * Check if file is valid
361
+ *
362
+ * @param FACTFinder_Core_Model_Export_Type_Interface $model
363
+ * @param string $dir
364
+ * @param string $filename
365
+ *
366
+ * @return bool
367
+ */
368
+ protected function _validateFile($model, $dir, $filename)
369
+ {
370
+ if (!defined($model::FILE_VALIDATOR)) {
371
+ return true;
372
+ }
373
+
374
+ /** @var FACTFinder_Core_Model_File $file */
375
+ $file = Mage::getModel('factfinder/file');
376
+ $file->open($dir, $filename);
377
+ $file->setValidator(Mage::getModel($model::FILE_VALIDATOR));
378
+
379
+ return $file->isValid();
380
+ }
381
+
382
+
383
+ /**
384
+ * Check if file validation for store is enabled
385
+ *
386
+ * @param int $storeId
387
+ *
388
+ * @return null|string
389
+ */
390
+ public function isValidationEnabled($storeId = 0)
391
+ {
392
+ return !$this->getExportConfigValue(self::VALIDATION_DISABLED, $storeId);
393
+ }
394
+
395
+
396
}
app/code/community/FACTFinder/Core/Model/Export/Observer.php CHANGED
@@ -20,12 +20,18 @@ class FACTFinder_Core_Model_Export_Observer
20
*/
21
public function triggerImportAfterExport($observer)
22
{
23
$helper = Mage::helper('factfinder');
24
$storeId = $observer->getStoreId();
25
26
$this->uploadFileToFtp($observer);
27
28
- if ($helper->isEnabled() && Mage::helper('factfinder/export')->isImportTriggerEnabled($storeId)) {
29
$channel = $helper->getPrimaryChannel($storeId);
30
$download = !Mage::helper('factfinder/export')->useFtp($storeId);
31
$facade = Mage::getModel('factfinder/facade');
@@ -85,7 +91,7 @@ class FACTFinder_Core_Model_Export_Observer
85
public function exportAll($observer)
86
{
87
foreach (Mage::helper('factfinder/export')->getExportTypes() as $type) {
88
- Mage::getModel('factfinder/export_' . $type)->saveAll();
89
}
90
}
91
20
*/
21
public function triggerImportAfterExport($observer)
22
{
23
+ $file = $observer->getFile();
24
+
25
+ if (!$file instanceof FACTFinder_Core_Model_File || !$file->isValid()) {
26
+ return;
27
+ }
28
+
29
$helper = Mage::helper('factfinder');
30
$storeId = $observer->getStoreId();
31
32
$this->uploadFileToFtp($observer);
33
34
+ if (Mage::helper('factfinder/export')->isImportTriggerEnabled($storeId)) {
35
$channel = $helper->getPrimaryChannel($storeId);
36
$download = !Mage::helper('factfinder/export')->useFtp($storeId);
37
$facade = Mage::getModel('factfinder/facade');
91
public function exportAll($observer)
92
{
93
foreach (Mage::helper('factfinder/export')->getExportTypes() as $type) {
94
+ Mage::getModel('factfinder/export_type_' . $type)->saveAll();
95
}
96
}
97
app/code/community/FACTFinder/Core/Model/Export/Semaphore.php ADDED
@@ -0,0 +1,125 @@
1
+ <?php
2
+ /**
3
+ * Semaphore.php
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2016 Flagbit GmbH & Co. KG
9
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Semaphore class
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Core
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2016 Flagbit GmbH & Co. KG (http://www.flagbit.de)
20
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Core_Model_Export_Semaphore
24
+ {
25
+ const LOCK_PREFIX = 'ffexport_';
26
+
27
+ /**
28
+ * @var string
29
+ */
30
+ protected $_locksDir;
31
+
32
+ /**
33
+ * @var int
34
+ */
35
+ protected $_storeId = 0;
36
+
37
+ /**
38
+ * @var string
39
+ */
40
+ protected $_type = '';
41
+
42
+
43
+ /**
44
+ * FACTFinder_Core_Model_Export_Semaphore constructor.
45
+ */
46
+ public function __construct()
47
+ {
48
+ $this->_locksDir = Mage::getBaseDir('var') . DS . 'locks';
49
+ Mage::getConfig()->createDirIfNotExists($this->_locksDir);
50
+ }
51
+
52
+
53
+ /**
54
+ * Set store id
55
+ *
56
+ * @param int $storeId
57
+ *
58
+ * @return $this
59
+ */
60
+ public function setStoreId($storeId)
61
+ {
62
+ $this->_storeId = $storeId;
63
+
64
+ return $this;
65
+ }
66
+
67
+
68
+ /**
69
+ * Set export type
70
+ *
71
+ * @param string $type
72
+ *
73
+ * @return $this
74
+ */
75
+ public function setType($type)
76
+ {
77
+ $this->_type = $type;
78
+
79
+ return $this;
80
+ }
81
+
82
+
83
+ /**
84
+ * Create lock by making a lock file
85
+ *
86
+ * Throws an exception if it was already locked and the timeout has not run out yet
87
+ *
88
+ * @return void
89
+ *
90
+ * @throws RuntimeException
91
+ */
92
+ public function lock()
93
+ {
94
+ $mtime = @filemtime($this->getLockFileName());
95
+ $semaphoreTimeout = FACTFinderCustom_Configuration::DEFAULT_SEMAPHORE_TIMEOUT;
96
+ if ($mtime && time() - $mtime < $semaphoreTimeout) {
97
+ throw new RuntimeException();
98
+ }
99
+ @touch($this->getLockFileName());
100
+ }
101
+
102
+
103
+ /**
104
+ * Retrieve the name of lock file
105
+ *
106
+ * @return string
107
+ */
108
+ public function getLockFileName()
109
+ {
110
+ return $this->_locksDir . DS . self::LOCK_PREFIX . $this->_type . $this->_storeId . '.lock';
111
+ }
112
+
113
+
114
+ /**
115
+ * Remove the lock file
116
+ *
117
+ * @return void
118
+ */
119
+ public function release()
120
+ {
121
+ @unlink($this->getLockFileName());
122
+ }
123
+
124
+
125
+ }
app/code/community/FACTFinder/Core/Model/Export/Type/Interface.php ADDED
@@ -0,0 +1,44 @@
1
+ <?php
2
+ interface FACTFinder_Core_Model_Export_Type_Interface
3
+ {
4
+
5
+ /**
6
+ * Export file for store. Return file path or false
7
+ *
8
+ * @param int|null $storeId
9
+ *
10
+ * @return string|false
11
+ */
12
+ public function saveExport($storeId);
13
+
14
+
15
+ /**
16
+ * Save all stores
17
+ * Return array of file paths
18
+ *
19
+ * @return array
20
+ */
21
+ public function saveAll();
22
+
23
+
24
+ /**
25
+ * Get expected number of rows to export
26
+ *
27
+ * @param int $storeId
28
+ *
29
+ * @return int
30
+ */
31
+ public function getSize($storeId);
32
+
33
+
34
+ /**
35
+ * Get export filename for store
36
+ *
37
+ * @param $storeId
38
+ *
39
+ * @return string
40
+ */
41
+ public function getFilenameForStore($storeId);
42
+
43
+
44
+ }
app/code/community/FACTFinder/Core/Model/Export/{Price.php → Type/Price.php} RENAMED
@@ -23,10 +23,13 @@
23
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
24
* @link http://www.flagbit.de
25
*/
26
- class FACTFinder_Core_Model_Export_Price extends Mage_Core_Model_Resource_Db_Abstract
27
{
28
29
const FILENAME_PATTERN = 'store_%s_price.csv';
30
31
/**
32
* defines Export Columns
@@ -83,6 +86,7 @@ class FACTFinder_Core_Model_Export_Price extends Mage_Core_Model_Resource_Db_Abs
83
$dir = Mage::helper('factfinder/export')->getExportDirectory();
84
$fileName = $this->getFilenameForStore($storeId);
85
$this->_file = Mage::getModel('factfinder/file');
86
$this->_file->open($dir, $fileName);
87
}
88
@@ -100,31 +104,41 @@ class FACTFinder_Core_Model_Export_Price extends Mage_Core_Model_Resource_Db_Abs
100
*/
101
protected function _addCsvRow($data, $storeId = 0)
102
{
103
- return $this->_getFile($storeId)->writeCsv($data, ';');
104
}
105
106
107
/**
108
* Export price data
109
- * Write the data to file
110
*
111
* @param int $storeId Store Id
112
*
113
- * @return $this
114
*/
115
public function saveExport($storeId = null)
116
{
117
- $this->_addCsvRow($this->_exportColumns, $storeId);
118
119
- $page = 1;
120
- $stocks = $this->_getPrices($storeId, $page);
121
122
- while ($stocks) {
123
- foreach ($stocks as $stock) {
124
- $this->_addCsvRow($stock, $storeId);
125
- }
126
127
- $stocks = $this->_getPrices($storeId, $page++);
128
}
129
130
return $this->_getFile($storeId)->getPath();
@@ -144,7 +158,7 @@ class FACTFinder_Core_Model_Export_Price extends Mage_Core_Model_Resource_Db_Abs
144
{
145
146
$store = Mage::app()->getStore($storeId);
147
- $select = $this->_getWriteAdapter()->select()
148
->from(
149
array('e' => $this->getTable('catalog/product_index_price')),
150
$this->_exportColumns);
@@ -156,7 +170,7 @@ class FACTFinder_Core_Model_Export_Price extends Mage_Core_Model_Resource_Db_Abs
156
$select->limitPage($part, $limit)
157
->order('e.entity_id');
158
159
- return $this->_getWriteAdapter()->fetchAll($select);
160
}
161
162
@@ -170,9 +184,16 @@ class FACTFinder_Core_Model_Export_Price extends Mage_Core_Model_Resource_Db_Abs
170
$paths = array();
171
$stores = Mage::app()->getStores();
172
foreach ($stores as $id => $store) {
173
try {
174
- $price = Mage::getModel('factfinder/export_price');
175
- $paths[] = $price->saveExport($id);
176
} catch (Exception $e) {
177
Mage::logException($e);
178
}
@@ -182,4 +203,54 @@ class FACTFinder_Core_Model_Export_Price extends Mage_Core_Model_Resource_Db_Abs
182
}
183
184
185
}
23
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
24
* @link http://www.flagbit.de
25
*/
26
+ class FACTFinder_Core_Model_Export_Type_Price extends Mage_Core_Model_Resource_Db_Abstract
27
+ implements FACTFinder_Core_Model_Export_Type_Interface
28
{
29
30
const FILENAME_PATTERN = 'store_%s_price.csv';
31
+ const FILE_VALIDATOR = 'factfinder/file_validator_price';
32
+ const CSV_DELIMITER = ';';
33
34
/**
35
* defines Export Columns
86
$dir = Mage::helper('factfinder/export')->getExportDirectory();
87
$fileName = $this->getFilenameForStore($storeId);
88
$this->_file = Mage::getModel('factfinder/file');
89
+ $this->_file->setValidator(Mage::getModel(self::FILE_VALIDATOR));
90
$this->_file->open($dir, $fileName);
91
}
92
104
*/
105
protected function _addCsvRow($data, $storeId = 0)
106
{
107
+ return $this->_getFile($storeId)->writeCsv($data, self::CSV_DELIMITER);
108
}
109
110
111
/**
112
* Export price data
113
*
114
* @param int $storeId Store Id
115
*
116
+ * @return string|bool
117
*/
118
public function saveExport($storeId = null)
119
{
120
+ /** @var FACTFinder_Core_Model_Export_Semaphore $semaphore */
121
+ $semaphore = Mage::getModel('factfinder/export_semaphore');
122
+ $semaphore->setStoreId($storeId)
123
+ ->setType('price');
124
125
126
+ try {
127
+ $semaphore->lock();
128
129
+ $this->_saveExport($storeId);
130
+
131
+ $semaphore->release();
132
+ } catch (RuntimeException $e) {
133
+ Mage::helper('factfinder/debug')->log('Export action was locked', true);
134
+ return false;
135
+ } catch (Exception $e) {
136
+ Mage::logException($e);
137
+ $semaphore->release();
138
+ }
139
+
140
+ if (Mage::helper('factfinder/export')->isValidationEnabled($storeId) && !$this->_getFile($storeId)->isValid()) {
141
+ return false;
142
}
143
144
return $this->_getFile($storeId)->getPath();
158
{
159
160
$store = Mage::app()->getStore($storeId);
161
+ $select = $this->_getReadAdapter()->select()
162
->from(
163
array('e' => $this->getTable('catalog/product_index_price')),
164
$this->_exportColumns);
170
$select->limitPage($part, $limit)
171
->order('e.entity_id');
172
173
+ return $this->_getReadAdapter()->fetchAll($select);
174
}
175
176
184
$paths = array();
185
$stores = Mage::app()->getStores();
186
foreach ($stores as $id => $store) {
187
+ if (!Mage::helper('factfinder')->isEnabled(null, $id)) {
188
+ continue;
189
+ }
190
+
191
try {
192
+ $price = Mage::getModel('factfinder/export_type_price');
193
+ $filePath = $price->saveExport($id);
194
+ if ($filePath) {
195
+ $paths[] = $filePath;
196
+ }
197
} catch (Exception $e) {
198
Mage::logException($e);
199
}
203
}
204
205
206
+ /**
207
+ * Get number of entries to be exported
208
+ *
209
+ * @param int $storeId
210
+ *
211
+ * @return int
212
+ */
213
+ public function getSize($storeId)
214
+ {
215
+ $select = $this->_getWriteAdapter()->select()
216
+ ->from(
217
+ array('e' => $this->getTable('catalog/product_index_price')),
218
+ new Zend_Db_Expr('count(*)')
219
+ );
220
+
221
+ $store = Mage::app()->getStore($storeId);
222
+ if ($storeId !== null) {
223
+ $select->where('e.website_id = ?', $store->getWebsiteId());
224
+ }
225
+
226
+ return (int) $this->_getReadAdapter()->fetchOne($select);
227
+ }
228
+
229
+
230
+ /**
231
+ * Perform export actions and write to file
232
+ *
233
+ * @param int $storeId
234
+ *
235
+ * @return FACTFinder_Core_Model_Export_Type_Price
236
+ */
237
+ protected function _saveExport($storeId)
238
+ {
239
+ $this->_addCsvRow($this->_exportColumns, $storeId);
240
+
241
+ $page = 1;
242
+ $stocks = $this->_getPrices($storeId, $page);
243
+
244
+ while ($stocks) {
245
+ foreach ($stocks as $stock) {
246
+ $this->_addCsvRow($stock, $storeId);
247
+ }
248
+
249
+ $stocks = $this->_getPrices($storeId, ++$page);
250
+ }
251
+
252
+ return $this;
253
+ }
254
+
255
+
256
}
app/code/community/FACTFinder/Core/Model/Export/{Product.php → Type/Product.php} RENAMED
@@ -16,6 +16,8 @@
16
*
17
* This class provides the Product export
18
*
19
* @category Mage
20
* @package FACTFinder_Core
21
* @author Flagbit Magento Team <magento@flagbit.de>
@@ -23,10 +25,13 @@
23
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
24
* @link http://www.flagbit.de
25
*/
26
- class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
27
{
28
29
const FILENAME_PATTERN = 'store_%s_product.csv';
30
31
/**
32
* Option ID to Value Mapping Array
@@ -113,15 +118,12 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
113
* @param array $data Array of data
114
* @param int $storeId
115
*
116
- * @return FACTFinder_Core_Model_Export_Product
117
*/
118
protected function _writeCsvRow($data, $storeId)
119
{
120
- foreach ($data as &$item) {
121
- $item = str_replace(array("\r", "\n", "\""), array(" ", " ", "\\\""), $item);
122
- }
123
124
- $this->_getFile($storeId)->writeCsv($data, ';');
125
return $this;
126
}
127
@@ -192,9 +194,9 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
192
$additionalColumns = array();
193
if (Mage::getStoreConfigFlag('factfinder/export/urls', $storeId)) {
194
$additionalColumns[] = 'image';
195
- $additionalColumns[] = 'deeplink';
196
$this->_imageHelper = Mage::helper('catalog/image');
197
}
198
199
// get dynamic Attributes
200
foreach ($this->_getSearchableAttributes(null, 'system', $storeId) as $attribute) {
@@ -249,8 +251,15 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
249
$paths = array();
250
$stores = Mage::app()->getStores();
251
foreach ($stores as $id => $store) {
252
try {
253
- $paths[] = $this->saveExport($id);
254
} catch (Exception $e) {
255
Mage::logException($e);
256
}
@@ -269,17 +278,27 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
269
*/
270
public function saveExport($storeId = 0)
271
{
272
- $fileName = $this->getFilenameForStore($storeId);
273
- $dir = $this->getExportDirectory();
274
275
try {
276
- $this->doExport($storeId);
277
} catch (Exception $e) {
278
- Mage::throwException($e);
279
- return '';
280
}
281
282
- return $dir . DS . $fileName;
283
}
284
285
@@ -298,9 +317,11 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
298
$dir = $this->getExportDirectory();
299
$fileName = $this->getFilenameForStore($storeId);
300
301
- $this->_file[$storeId] = Mage::getModel('factfinder/file');
302
303
- $this->_file[$storeId]->open($dir, $fileName);
304
}
305
306
return $this->_file[$storeId];
@@ -313,7 +334,7 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
313
*
314
* @param int $storeId Store View Id
315
*
316
- * @return array
317
*/
318
public function doExport($storeId = null)
319
{
@@ -350,10 +371,8 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
350
$productChildren = $this->getResource()
351
->getProductChildIds($productData['entity_id'], $productData['type_id']);
352
$productRelations[$productData['entity_id']] = $productChildren;
353
- if ($productChildren) {
354
- foreach ($productChildren as $productChild) {
355
- $productAttributes[$productChild['entity_id']] = $productChild;
356
- }
357
}
358
}
359
@@ -399,46 +418,48 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
399
$this->_writeCsvRow($productIndex, $storeId);
400
401
$productChildren = $productRelations[$productData['entity_id']];
402
- if ($productChildren) {
403
- foreach ($productChildren as $productChild) {
404
- if (isset($productAttributes[$productChild['entity_id']])) {
405
-
406
- $productAttr = $productAttributes[$productChild['entity_id']];
407
-
408
- $subProductIndex = array(
409
- $productChild['entity_id'],
410
- $productData[$idFieldName],
411
- $productChild['sku'],
412
- $this->_getCategoryPath($productData['entity_id'], $storeId),
413
- $this->_formatAttributes('filterable', $productAttr, $storeId),
414
- $this->_formatAttributes('searchable', $productAttr, $storeId),
415
- $this->_formatAttributes('numerical', $productAttr, $storeId),
416
- );
417
- if ($this->getHelper()->shouldExportImagesAndDeeplinks($storeId)) {
418
- //dont need to add image and deeplink to child product, just add empty values
419
- $subProductIndex[] = '';
420
- $subProductIndex[] = '';
421
- }
422
-
423
- $subProductIndex = $this->_getAttributesRowArray(
424
- $subProductIndex,
425
- $productAttributes[$productChild['entity_id']],
426
- $storeId
427
- );
428
-
429
- $this->_writeCsvRow($subProductIndex, $storeId);
430
}
431
}
432
}
433
}
434
}
435
436
Mage::dispatchEvent('factfinder_export_after', array(
437
'store_id' => $storeId,
438
'file' => $this->_getFile($storeId),
439
));
440
441
- return $this->_lines;
442
}
443
444
@@ -792,15 +813,13 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
792
{
793
$helper = $this->getHelper();
794
795
- if (!$helper->shouldExportImagesAndDeeplinks($storeId)) {
796
- return $productIndex;
797
- }
798
-
799
// emulate store
800
$oldStore = Mage::app()->getStore()->getId();
801
Mage::app()->setCurrentStore($storeId);
802
803
- $productIndex[] = $this->getProductImageUrl($productData['entity_id'], $storeId);
804
$productIndex[] = $this->getProductUrl($productData['entity_id'], $storeId);
805
806
// finish emulation
@@ -860,13 +879,13 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
860
}
861
foreach ($attributeValues as &$attributeValue) {
862
// decode html entities
863
- $attributeValue = html_entity_decode($attributeValue, null, 'UTF-8');
864
- // Add spaces before HTML Tags, so that strip_tags() does not join word which were in different block elements
865
- // Additional spaces are not an issue, because they will be removed in the next step anyway
866
- $attributeValue = preg_replace('/</u', ' <', $attributeValue);
867
- $attributeValue = preg_replace("#\s+#siu", ' ', trim(strip_tags($attributeValue)));
868
// remove rest html entities
869
- $attributeValue = preg_replace("/&(?:[a-z\d]|#\d|#x[a-f\d]){2,8};/i", '', $attributeValue);
870
}
871
$value = implode("|", $attributeValues);
872
}
@@ -997,4 +1016,106 @@ class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
997
}
998
999
1000
}
16
*
17
* This class provides the Product export
18
*
19
+ * @method getResource() FACTFinder_Core_Model_Resource_Export
20
+ *
21
* @category Mage
22
* @package FACTFinder_Core
23
* @author Flagbit Magento Team <magento@flagbit.de>
25
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
26
* @link http://www.flagbit.de
27
*/
28
+ class FACTFinder_Core_Model_Export_Type_Product extends Mage_Core_Model_Abstract
29
+ implements FACTFinder_Core_Model_Export_Type_Interface
30
{
31
32
const FILENAME_PATTERN = 'store_%s_product.csv';
33
+ const CSV_DELIMITER = ';';
34
+ const FILE_VALIDATOR = 'factfinder/file_validator_product';
35
36
/**
37
* Option ID to Value Mapping Array
118
* @param array $data Array of data
119
* @param int $storeId
120
*
121
+ * @return FACTFinder_Core_Model_Export_Type_Product
122
*/
123
protected function _writeCsvRow($data, $storeId)
124
{
125
+ $this->_getFile($storeId)->writeCsv($data, self::CSV_DELIMITER);
126
127
return $this;
128
}
129
194
$additionalColumns = array();
195
if (Mage::getStoreConfigFlag('factfinder/export/urls', $storeId)) {
196
$additionalColumns[] = 'image';
197
$this->_imageHelper = Mage::helper('catalog/image');
198
}
199
+ $additionalColumns[] = 'deeplink';
200
201
// get dynamic Attributes
202
foreach ($this->_getSearchableAttributes(null, 'system', $storeId) as $attribute) {
251
$paths = array();
252
$stores = Mage::app()->getStores();
253
foreach ($stores as $id => $store) {
254
+ if (!Mage::helper('factfinder')->isEnabled(null, $id)) {
255
+ continue;
256
+ }
257
+
258
try {
259
+ $filePath = $this->saveExport($id);
260
+ if ($filePath) {
261
+ $paths[] = $filePath;
262
+ }
263
} catch (Exception $e) {
264
Mage::logException($e);
265
}
278
*/
279
public function saveExport($storeId = 0)
280
{
281
+ $path = '';
282
+
283
+ /** @var FACTFinder_Core_Model_Export_Semaphore $semaphore */
284
+ $semaphore = Mage::getModel('factfinder/export_semaphore');
285
+ $semaphore->setStoreId($storeId)
286
+ ->setType('product');
287
288
try {
289
+ $semaphore->lock();
290
+
291
+ $path = $this->doExport($storeId);
292
+
293
+ $semaphore->release();
294
+ } catch (RuntimeException $e) {
295
+ Mage::helper('factfinder/debug')->log('Export action was locked', true);
296
} catch (Exception $e) {
297
+ Mage::logException($e);
298
+ $semaphore->release();
299
}
300
301
+ return $path;
302
}
303
304
317
$dir = $this->getExportDirectory();
318
$fileName = $this->getFilenameForStore($storeId);
319
320
+ $file = Mage::getModel('factfinder/file');
321
+ $file->setValidator(Mage::getModel(self::FILE_VALIDATOR))
322
+ ->open($dir, $fileName);
323
324
+ $this->_file[$storeId] = $file;
325
}
326
327
return $this->_file[$storeId];
334
*
335
* @param int $storeId Store View Id
336
*
337
+ * @return string|bool
338
*/
339
public function doExport($storeId = null)
340
{
371
$productChildren = $this->getResource()
372
->getProductChildIds($productData['entity_id'], $productData['type_id']);
373
$productRelations[$productData['entity_id']] = $productChildren;
374
+ foreach ($productChildren as $productChild) {
375
+ $productAttributes[$productChild['entity_id']] = $productChild;
376
}
377
}
378
418
$this->_writeCsvRow($productIndex, $storeId);
419
420
$productChildren = $productRelations[$productData['entity_id']];
421
+ foreach ($productChildren as $productChild) {
422
+ if (isset($productAttributes[$productChild['entity_id']])) {
423
+
424
+ $productAttr = $productAttributes[$productChild['entity_id']];
425
+
426
+ $subProductIndex = array(
427
+ $productChild['entity_id'],
428
+ $productData[$idFieldName],
429
+ $productChild['sku'],
430
+ $this->_getCategoryPath($productData['entity_id'], $storeId),
431
+ $this->_formatAttributes('filterable', $productAttr, $storeId),
432
+ $this->_formatAttributes('searchable', $productAttr, $storeId),
433
+ $this->_formatAttributes('numerical', $productAttr, $storeId),
434
+ );
435
+ //dont need to add image and deeplink to child product, just add empty values
436
+ if ($this->getHelper()->shouldExportImages($storeId)) {
437
+ $subProductIndex[] = '';
438
}
439
+ $subProductIndex[] = '';
440
+
441
+ $subProductIndex = $this->_getAttributesRowArray(
442
+ $subProductIndex,
443
+ $productAttributes[$productChild['entity_id']],
444
+ $storeId
445
+ );
446
+
447
+ $this->_writeCsvRow($subProductIndex, $storeId);
448
}
449
}
450
}
451
}
452
453
+ if ($this->getHelper()->isValidationEnabled($storeId) && !$this->_getFile($storeId)->isValid()) {
454
+ return false;
455
+ }
456
+
457
Mage::dispatchEvent('factfinder_export_after', array(
458
'store_id' => $storeId,
459
'file' => $this->_getFile($storeId),
460
));
461
462
+ return $this->_getFile($storeId)->getPath();
463
}
464
465
813
{
814
$helper = $this->getHelper();
815
816
// emulate store
817
$oldStore = Mage::app()->getStore()->getId();
818
Mage::app()->setCurrentStore($storeId);
819
820
+ if ($helper->shouldExportImages($storeId)) {
821
+ $productIndex[] = $this->getProductImageUrl($productData['entity_id'], $storeId);
822
+ }
823
$productIndex[] = $this->getProductUrl($productData['entity_id'], $storeId);
824
825
// finish emulation
879
}
880
foreach ($attributeValues as &$attributeValue) {
881
// decode html entities
882
+ $attributeValue = html_entity_decode($attributeValue, null, 'UTF-8');
883
+ // Add spaces before HTML Tags, so that strip_tags() does not join word which were in different block elements
884
+ // Additional spaces are not an issue, because they will be removed in the next step anyway
885
+ $attributeValue = preg_replace('/</u', ' <', $attributeValue);
886
+ $attributeValue = preg_replace("#\s+#siu", ' ', trim(strip_tags($attributeValue)));
887
// remove rest html entities
888
+ $attributeValue = preg_replace("/&(?:[a-z\d]|#\d|#x[a-f\d]){2,8};/i", '', $attributeValue);
889
}
890
$value = implode("|", $attributeValues);
891
}
1016
}
1017
1018
1019
+ /**
1020
+ * Get number of products that should be exported
1021
+ *
1022
+ * @param int $storeId
1023
+ *
1024
+ * @return int
1025
+ */
1026
+ public function getSize($storeId)
1027
+ {
1028
+ $staticFields = $this->_getStaticFields($storeId);
1029
+ $dynamicFields = $this->_getDynamicFields();
1030
+
1031
+ $count = 0;
1032
+
1033
+ $lastId = 0;
1034
+ while (true) {
1035
+ $products = $this->getResource()->getSearchableProducts($storeId, $staticFields, $lastId);
1036
+ if (!$products) {
1037
+ break;
1038
+ }
1039
+
1040
+ $attributes = array();
1041
+ $relations = array();
1042
+ foreach ($products as $productData) {
1043
+ $attributes[$productData['entity_id']] = $productData['entity_id'];
1044
+ $children = $this->getResource()->getProductChildIds($productData['entity_id'], $productData['type_id']);
1045
+ $relations[$productData['entity_id']] = $children;
1046
+ if ($children) {
1047
+ foreach ($children as $child) {
1048
+ $attributes[$child['entity_id']] = $child;
1049
+ }
1050
+ }
1051
+ }
1052
+
1053
+ $lastId = $productData['entity_id'];
1054
+
1055
+ $attributes = $this->getResource()->getProductAttributes($storeId, array_keys($attributes), $dynamicFields);
1056
+ foreach ($products as $productData) {
1057
+
1058
+ if ($this->shouldSkipProduct($attributes, $productData)) {
1059
+ continue;
1060
+ }
1061
+
1062
+ $categoryPath = $this->_getCategoryPath($productData['entity_id'], $storeId);
1063
+
1064
+ if ($categoryPath == '' && !$this->_isExportProductsWithoutCategories($storeId)) {
1065
+ continue;
1066
+ }
1067
+
1068
+ $count++;
1069
+
1070
+
1071
+ $children = $relations[$productData['entity_id']];
1072
+ foreach ($children as $child) {
1073
+ if (isset($attributes[$child['entity_id']])) {
1074
+ $count++;
1075
+ }
1076
+ }
1077
+ }
1078
+ }
1079
+
1080
+
1081
+ return $count;
1082
+ }
1083
+
1084
+
1085
+ /**
1086
+ * Check if product should be skipped in export
1087
+ *
1088
+ * @param $attributes
1089
+ * @param $productData
1090
+ *
1091
+ * @return bool
1092
+ */
1093
+ protected function shouldSkipProduct($attributes, $productData)
1094
+ {
1095
+
1096
+ if (!isset($attributes[$productData['entity_id']])) {
1097
+ return true;
1098
+ }
1099
+
1100
+ // status and visibility filter
1101
+ $visibilityId = $this->getResource()->getSearchableAttribute('visibility')->getId();
1102
+ $statusId = $this->getResource()->getSearchableAttribute('status')->getId();
1103
+
1104
+ $visibilities = Mage::getSingleton('catalog/product_visibility')->getVisibleInSearchIds();
1105
+ $statuses = Mage::getSingleton('catalog/product_status')->getVisibleStatusIds();
1106
+
1107
+ $productAttributes = $attributes[$productData['entity_id']];
1108
+
1109
+ if (!isset($productAttributes[$visibilityId])
1110
+ || !isset($productAttributes[$statusId])
1111
+ || !in_array($productAttributes[$visibilityId], $visibilities)
1112
+ || !in_array($productAttributes[$statusId], $statuses)
1113
+ ) {
1114
+ return true;
1115
+ }
1116
+
1117
+ return false;
1118
+ }
1119
+
1120
+
1121
}
app/code/community/FACTFinder/Core/Model/Export/{Stock.php → Type/Stock.php} RENAMED
@@ -23,10 +23,13 @@
23
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
24
* @link http://www.flagbit.de
25
*/
26
- class FACTFinder_Core_Model_Export_Stock extends Mage_Core_Model_Resource_Db_Abstract
27
{
28
29
const FILENAME_PATTERN = 'store_%s_stock.csv';
30
31
/**
32
* defines Export Columns
@@ -84,6 +87,7 @@ class FACTFinder_Core_Model_Export_Stock extends Mage_Core_Model_Resource_Db_Abs
84
$dir = Mage::helper('factfinder/export')->getExportDirectory();
85
$fileName = $this->getFilenameForStore($storeId);
86
$this->_file = Mage::getModel('factfinder/file');
87
$this->_file->open($dir, $fileName);
88
}
89
@@ -101,31 +105,40 @@ class FACTFinder_Core_Model_Export_Stock extends Mage_Core_Model_Resource_Db_Abs
101
*/
102
protected function _addCsvRow($data, $storeId = 0)
103
{
104
- return $this->_getFile($storeId)->writeCsv($data, ';');
105
}
106
107
108
/**
109
- * export Stock Data
110
- * Write the data to file
111
*
112
- * @param int $storeId Store Id
113
*
114
- * @return $this
115
*/
116
public function saveExport($storeId = null)
117
{
118
- $this->_addCsvRow($this->_exportColumns, $storeId);
119
120
- $page = 1;
121
- $stocks = $this->_getStockData($storeId, $page);
122
123
- while ($stocks) {
124
- foreach($stocks as $stock){
125
- $this->_addCsvRow($stock, $storeId);
126
- }
127
128
- $stocks = $this->_getStockData($storeId, $page++);
129
}
130
131
return $this->_getFile($storeId)->getPath();
@@ -143,9 +156,8 @@ class FACTFinder_Core_Model_Export_Stock extends Mage_Core_Model_Resource_Db_Abs
143
*/
144
protected function _getStockData($storeId, $part = 1, $limit = 100)
145
{
146
-
147
$store = Mage::app()->getStore($storeId);
148
- $select = $this->_getWriteAdapter()->select()
149
->from(
150
array('e' => $this->getTable('cataloginventory/stock_status')),
151
$this->_exportColumns
@@ -158,7 +170,7 @@ class FACTFinder_Core_Model_Export_Stock extends Mage_Core_Model_Resource_Db_Abs
158
$select->limitPage($part, $limit)
159
->order('e.product_id');
160
161
- return $this->_getWriteAdapter()->fetchAll($select);
162
}
163
164
@@ -172,9 +184,17 @@ class FACTFinder_Core_Model_Export_Stock extends Mage_Core_Model_Resource_Db_Abs
172
$paths = array();
173
$stores = Mage::app()->getStores();
174
foreach ($stores as $store) {
175
try {
176
- $stock = Mage::getModel('factfinder/export_stock');
177
- $paths[] = $stock->saveExport($store->getId());
178
} catch (Exception $e) {
179
Mage::logException($e);
180
}
@@ -184,4 +204,54 @@ class FACTFinder_Core_Model_Export_Stock extends Mage_Core_Model_Resource_Db_Abs
184
}
185
186
187
}
23
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
24
* @link http://www.flagbit.de
25
*/
26
+ class FACTFinder_Core_Model_Export_Type_Stock extends Mage_Core_Model_Resource_Db_Abstract
27
+ implements FACTFinder_Core_Model_Export_Type_Interface
28
{
29
30
const FILENAME_PATTERN = 'store_%s_stock.csv';
31
+ const FILE_VALIDATOR = 'factfinder/file_validator_stock';
32
+ const CSV_DELIMITER = ';';
33
34
/**
35
* defines Export Columns
87
$dir = Mage::helper('factfinder/export')->getExportDirectory();
88
$fileName = $this->getFilenameForStore($storeId);
89
$this->_file = Mage::getModel('factfinder/file');
90
+ $this->_file->setValidator(Mage::getModel(self::FILE_VALIDATOR));
91
$this->_file->open($dir, $fileName);
92
}
93
105
*/
106
protected function _addCsvRow($data, $storeId = 0)
107
{
108
+ return $this->_getFile($storeId)->writeCsv($data, self::CSV_DELIMITER);
109
}
110
111
112
/**
113
+ * Export Stock Data
114
*
115
+ * @param int $storeId Store ID
116
*
117
+ * @return bool|string
118
*/
119
public function saveExport($storeId = null)
120
{
121
+ /** @var FACTFinder_Core_Model_Export_Semaphore $semaphore */
122
+ $semaphore = Mage::getModel('factfinder/export_semaphore');
123
+ $semaphore->setStoreId($storeId)
124
+ ->setType('stock');
125
126
+ try {
127
+ $semaphore->lock();
128
129
+ $this->_saveExport($storeId);
130
131
+ $semaphore->release();
132
+ } catch (RuntimeException $e) {
133
+ Mage::helper('factfinder/debug')->log('Export action was locked', true);
134
+ return false;
135
+ } catch (Exception $e) {
136
+ Mage::logException($e);
137
+ $semaphore->release();
138
+ }
139
+
140
+ if (Mage::helper('factfinder/export')->isValidationEnabled($storeId) && !$this->_getFile($storeId)->isValid()) {
141
+ return false;
142
}
143
144
return $this->_getFile($storeId)->getPath();
156
*/
157
protected function _getStockData($storeId, $part = 1, $limit = 100)
158
{
159
$store = Mage::app()->getStore($storeId);
160
+ $select = $this->_getReadAdapter()->select()
161
->from(
162
array('e' => $this->getTable('cataloginventory/stock_status')),
163
$this->_exportColumns
170
$select->limitPage($part, $limit)
171
->order('e.product_id');
172
173
+ return $this->_getReadAdapter()->fetchAll($select);
174
}
175
176
184
$paths = array();
185
$stores = Mage::app()->getStores();
186
foreach ($stores as $store) {
187
+ if (!Mage::helper('factfinder')->isEnabled(null, $store->getId())) {
188
+ continue;
189
+ }
190
+
191
try {
192
+ /** @var FACTFinder_Core_Model_Export_Type_Stock $stock */
193
+ $stock = Mage::getModel('factfinder/export_type_stock');
194
+ $filePath = $stock->saveExport($store->getId());
195
+ if ($filePath) {
196
+ $paths[] = $filePath;
197
+ }
198
} catch (Exception $e) {
199
Mage::logException($e);
200
}
204
}
205
206
207
+ /**
208
+ * Get number of rows to be exported
209
+ *
210
+ * @param $storeId
211
+ *
212
+ * @return int
213
+ */
214
+ public function getSize($storeId)
215
+ {
216
+ $store = Mage::app()->getStore($storeId);
217
+ $select = $this->_getReadAdapter()->select()
218
+ ->from(
219
+ array('e' => $this->getTable('cataloginventory/stock_status')),
220
+ new Zend_Db_Expr('count(*)')
221
+ );
222
+
223
+ if ($storeId !== null) {
224
+ $select->where('e.website_id = ?', $store->getWebsiteId());
225
+ }
226
+
227
+ return (int) $this->_getReadAdapter()->fetchOne($select);
228
+ }
229
+
230
+
231
+ /**
232
+ * Perform export action and try to write that to file
233
+ *
234
+ * @param int $storeId
235
+ *
236
+ * @return FACTFinder_Core_Model_Export_Type_Stock
237
+ */
238
+ protected function _saveExport($storeId)
239
+ {
240
+ $this->_addCsvRow($this->_exportColumns, $storeId);
241
+
242
+ $page = 1;
243
+ $stocks = $this->_getStockData($storeId, $page);
244
+
245
+ while ($stocks) {
246
+ foreach ($stocks as $stock) {
247
+ $this->_addCsvRow($stock, $storeId);
248
+ }
249
+
250
+ $stocks = $this->_getStockData($storeId, ++$page);
251
+ }
252
+
253
+ return $this;
254
+ }
255
+
256
+
257
}
app/code/community/FACTFinder/Core/Model/File.php CHANGED
@@ -23,6 +23,7 @@
23
*/
24
class FACTFinder_Core_Model_File
25
{
26
27
/**
28
* @var Varien_Io_File
@@ -32,7 +33,35 @@ class FACTFinder_Core_Model_File
32
/**
33
* @var string
34
*/
35
- protected $_path;
36
37
/**
38
* Class constructor
@@ -43,6 +72,42 @@ class FACTFinder_Core_Model_File
43
}
44
45
46
/**
47
* Make directory
48
*
@@ -63,19 +128,25 @@ class FACTFinder_Core_Model_File
63
*
64
* @param string $dir
65
* @param string $filename
66
*
67
* @return bool
68
- *
69
- * @throws \Exception
70
*/
71
- public function open($dir, $filename)
72
{
73
- $this->_path = $dir . DS . $filename;
74
75
$this->_file->mkdir($dir);
76
$this->_file->open(array('path' => $dir));
77
78
- return $this->_file->streamOpen($filename);
79
}
80
81
@@ -91,29 +162,38 @@ class FACTFinder_Core_Model_File
91
return $this->_file->streamWrite($str);
92
}
93
94
/**
95
* Write array as comma separated values to file
96
*
97
- * @param array $data
98
* @param string $delimiter
99
* @param string $enclosure
100
* @return bool|int
101
*/
102
public function writeCsv(array $data, $delimiter = ',', $enclosure = '"')
103
{
104
return $this->_file->streamWriteCsv($data, $delimiter, $enclosure);
105
}
106
107
/**
108
- * Returns path of current file
109
*
110
* @return string
111
*/
112
public function getPath()
113
{
114
- return $this->_path;
115
}
116
117
/**
118
* Close stream
119
*
@@ -121,7 +201,13 @@ class FACTFinder_Core_Model_File
121
*/
122
public function close()
123
{
124
- return $this->_file->streamClose();
125
}
126
127
@@ -132,4 +218,89 @@ class FACTFinder_Core_Model_File
132
{
133
$this->close();
134
}
135
}
23
*/
24
class FACTFinder_Core_Model_File
25
{
26
+ const BACKUP_DIR = 'bak';
27
28
/**
29
* @var Varien_Io_File
33
/**
34
* @var string
35
*/
36
+ protected $_currentPath;
37
+
38
+ /**
39
+ * @var bool
40
+ */
41
+ protected $_useTmpFile = true;
42
+
43
+ /**
44
+ * @var string
45
+ */
46
+ protected $_dir;
47
+
48
+ /**
49
+ * @var string
50
+ */
51
+ protected $_filename;
52
+
53
+
54
+ /**
55
+ * @var FACTFinder_Core_Model_File_Validator_Abstract
56
+ */
57
+ protected $_validator;
58
+
59
+
60
+ /**
61
+ * @var null|bool
62
+ */
63
+ protected $_isValid = null;
64
+
65
66
/**
67
* Class constructor
72
}
73
74
75
+ /**
76
+ * Set validator object
77
+ *
78
+ * @param FACTFinder_Core_Model_File_Validator_Abstract $validator
79
+ *
80
+ * @return $this
81
+ *
82
+ * @throws Exception
83
+ */
84
+ public function setValidator(FACTFinder_Core_Model_File_Validator_Abstract $validator)
85
+ {
86
+ if (!$validator instanceof FACTFinder_Core_Model_File_Validator_Abstract) {
87
+ throw new Exception('Validator must be an instance of FACTFinder_Core_Model_File_Validator_Abstract!');
88
+ }
89
+
90
+ $this->_validator = $validator;
91
+
92
+ return $this;
93
+ }
94
+
95
+
96
+ /**
97
+ * Set if a temporary file should be used
98
+ *
99
+ * @param bool $value
100
+ *
101
+ * @return $this
102
+ */
103
+ public function setUseTmpFile($value)
104
+ {
105
+ $this->_useTmpFile = $value;
106
+
107
+ return $this;
108
+ }
109
+
110
+
111
/**
112
* Make directory
113
*
128
*
129
* @param string $dir
130
* @param string $filename
131
+ * @param string $mode
132
*
133
* @return bool
134
*/
135
+ public function open($dir, $filename, $mode = 'w+')
136
{
137
+ $this->_filename = $filename;
138
+ $this->_dir = $dir;
139
+
140
+ if ($this->_useTmpFile) {
141
+ $filename = $this->getTmpFilename($filename);
142
+ }
143
+
144
+ $this->_currentPath = $dir . DS . $filename;
145
146
$this->_file->mkdir($dir);
147
$this->_file->open(array('path' => $dir));
148
149
+ return $this->_file->streamOpen($filename, $mode);
150
}
151
152
162
return $this->_file->streamWrite($str);
163
}
164
165
+
166
/**
167
* Write array as comma separated values to file
168
*
169
+ * @param array $data
170
* @param string $delimiter
171
* @param string $enclosure
172
+ *
173
* @return bool|int
174
*/
175
public function writeCsv(array $data, $delimiter = ',', $enclosure = '"')
176
{
177
+ // sanitize data
178
+ foreach ($data as &$row) {
179
+ $row = str_replace(array("\r", "\n", "\\{$enclosure}"), array(" ", " ", $enclosure), $row);
180
+ }
181
+
182
return $this->_file->streamWriteCsv($data, $delimiter, $enclosure);
183
}
184
185
/**
186
+ * Returns "proper" path of current file
187
+ * If a tmp file is used, this still gives the name of the target file
188
*
189
* @return string
190
*/
191
public function getPath()
192
{
193
+ return $this->_dir . DS . $this->_filename;
194
}
195
196
+
197
/**
198
* Close stream
199
*
201
*/
202
public function close()
203
{
204
+ $success = $this->_file->streamClose();
205
+
206
+ if ($this->_useTmpFile) {
207
+ $this->_processTmpFile();
208
+ }
209
+
210
+ return $success;
211
}
212
213
218
{
219
$this->close();
220
}
221
+
222