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
+
223
+ /**
224
+ * Get name for temporary file
225
+ *
226
+ * @param $filename
227
+ *
228
+ * @return string
229
+ */
230
+ protected function getTmpFilename($filename)
231
+ {
232
+ $filename .= sprintf('.%s%s', 'tmp', time());
233
+
234
+ return $filename;
235
+ }
236
+
237
+
238
+ /**
239
+ * Check if file is valid
240
+ *
241
+ * @return bool
242
+ */
243
+ public function isValid()
244
+ {
245
+ if (!$this->_validator) {
246
+ return true;
247
+ }
248
+
249
+ if ($this->_isValid === null) {
250
+ $this->_isValid = $this->_validator->validate($this->_currentPath);
251
+ }
252
+
253
+ return $this->_isValid;
254
+ }
255
+
256
+
257
+ /**
258
+ * Remove the current file
259
+ *
260
+ * @return FACTFinder_Core_Model_File
261
+ */
262
+ public function moveToBackup()
263
+ {
264
+ $this->_file->mkdir($this->getBackupPath());
265
+ $this->_file->mv($this->_currentPath, $this->getBackupPath() . DS . basename($this->_currentPath));
266
+
267
+ return $this;
268
+ }
269
+
270
+
271
+ /**
272
+ * Get backup directory for invalid files
273
+ *
274
+ * @return string
275
+ */
276
+ protected function getBackupPath()
277
+ {
278
+ return $this->_dir . DS . self::BACKUP_DIR;
279
+ }
280
+
281
+
282
+ /**
283
+ * Rename the temporary file to the regular name and replace the existing file,
284
+ * if it already exists
285
+ *
286
+ * @return $this
287
+ */
288
+ protected function _processTmpFile()
289
+ {
290
+ if (stripos(PHP_OS, 'win') === 0) {
291
+ sleep(1); // workaround for windows
292
+ }
293
+
294
+ if ($this->isValid()) {
295
+ $this->_file->mv($this->_currentPath, $this->getPath());
296
+ } else {
297
+ $this->moveToBackup();
298
+ }
299
+
300
+ $this->_currentPath = $this->getPath();
301
+
302
+ return $this;
303
+ }
304
+
305
+
306
  }
app/code/community/FACTFinder/Core/Model/File/Validator/Abstract.php ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
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
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2016 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ abstract class FACTFinder_Core_Model_File_Validator_Abstract
25
+ {
26
+ const DEFAULT_CSV_DELIMITER = ',';
27
+
28
+ const EXCEPTION_CSV_FIELDS_MISMATCH = 'Number of fields in row %s does not match number fields in the header';
29
+ const EXCEPTION_SIZE_MISMATCH = 'The actual number of CSV lines does not match the expected one';
30
+ const EXCEPTION_FILE_IS_EMPTY = 'File is empty!';
31
+
32
+
33
+ /**
34
+ * Check if the file is valid or not
35
+ *
36
+ * @param $file
37
+ *
38
+ * @return bool
39
+ */
40
+ abstract public function validate($file);
41
+
42
+
43
+ /**
44
+ * Check if all rows have the same number of records
45
+ *
46
+ * @param $file
47
+ *
48
+ * @return bool
49
+ *
50
+ * @throws Exception
51
+ */
52
+ protected function checkCsvConsistency($file)
53
+ {
54
+ $file = fopen($file, 'r');
55
+
56
+ $headerSize = count(fgetcsv($file, null, $this->getCsvDelimiter()));
57
+
58
+ $rowNumber = 1;
59
+ while ($row = fgetcsv($file, null, $this->getCsvDelimiter())) {
60
+ $rowNumber++;
61
+ if (!empty($row) && count($row) != $headerSize) {
62
+ throw new Exception(sprintf(self::EXCEPTION_CSV_FIELDS_MISMATCH, $rowNumber));
63
+ }
64
+ }
65
+ }
66
+
67
+
68
+ /**
69
+ * Return CSV delimiter that should be used
70
+ *
71
+ * @return string
72
+ */
73
+ protected function getCsvDelimiter()
74
+ {
75
+ return self::DEFAULT_CSV_DELIMITER;
76
+ }
77
+
78
+
79
+ /**
80
+ * Check if file is not empty
81
+ *
82
+ * @param $file
83
+ *
84
+ * @throws Exception
85
+ */
86
+ protected function checkIfEmpty($file)
87
+ {
88
+ if (!filesize($file)) {
89
+ throw new Exception(self::EXCEPTION_FILE_IS_EMPTY);
90
+ };
91
+ }
92
+
93
+
94
+ /**
95
+ * Get store ID based on filename and file pattern
96
+ *
97
+ * @param $file
98
+ * @param $filenamePattern
99
+ *
100
+ * @return int
101
+ */
102
+ protected function getStoreIdFromFile($file, $filenamePattern)
103
+ {
104
+ $filenamePattern = str_replace('%s', '([\d]+)', $filenamePattern);
105
+ if (preg_match("/$filenamePattern/", basename($file), $matches)) {
106
+ return $matches[1];
107
+ }
108
+
109
+ return 0;
110
+ }
111
+
112
+
113
+ /**
114
+ * Check if the file contains the expected number of lines
115
+ *
116
+ * @param string $file
117
+ * @param int $expectedSize
118
+ *
119
+ * @throws Exception
120
+ */
121
+ protected function checkNumberOfLines($file, $expectedSize)
122
+ {
123
+ $actualSize = 0;
124
+ $h = fopen($file, 'r');
125
+ while (fgetcsv($h)) {
126
+ $actualSize++;
127
+ }
128
+
129
+ // one extra line for the header
130
+ if ($actualSize - $expectedSize !== 1) {
131
+ throw new Exception(self::EXCEPTION_SIZE_MISMATCH);
132
+ }
133
+ }
134
+
135
+
136
+ /**
137
+ * Process exception
138
+ *
139
+ * @param $file
140
+ * @param Exception $exception
141
+ *
142
+ * @return void
143
+ */
144
+ protected function logException($file, Exception $exception)
145
+ {
146
+ $helper = Mage::helper('factfinder');
147
+
148
+ // log exception as normally
149
+ Mage::logException($exception);
150
+
151
+ $message = $helper->__('Invalid FACT-Finder export file detected: %s', basename($file));
152
+ $message .= " | " . $exception->getMessage();
153
+
154
+ // add an admin notification
155
+ $notification = Mage::getModel('adminnotification/inbox');
156
+ $notification->setData(
157
+ array(
158
+ 'severity' => 1,
159
+ 'title' => $helper->__('FACTFINDER EXPORT TROUBLES'),
160
+ 'description' => $message,
161
+ 'url' => '',
162
+ )
163
+ );
164
+ $notification->save();
165
+ }
166
+
167
+
168
+ }
app/code/community/FACTFinder/Core/Model/File/Validator/Price.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class FACTFinder_Core_Model_File_Validator_Price extends FACTFinder_Core_Model_File_Validator_Abstract
3
+ {
4
+
5
+
6
+ /**
7
+ * Validate file
8
+ *
9
+ * @param string $file
10
+ *
11
+ * @return bool
12
+ */
13
+ public function validate($file)
14
+ {
15
+ $result = true;
16
+
17
+ try {
18
+ $this->checkIfEmpty($file);
19
+ $this->checkCsvConsistency($file);
20
+
21
+ $storeId = $this->getStoreIdFromFile($file, FACTFinder_Core_Model_Export_Type_Price::FILENAME_PATTERN);
22
+ $expectedSize = Mage::getModel('factfinder/export_type_price')->getSize($storeId);
23
+
24
+ $this->checkNumberOfLines($file, $expectedSize);
25
+ } catch (Exception $e) {
26
+ $this->logException($file, $e);
27
+ $result = false;
28
+ }
29
+
30
+ return $result;
31
+ }
32
+
33
+
34
+ /**
35
+ * @return string
36
+ */
37
+ protected function getCsvDelimiter()
38
+ {
39
+ return FACTFinder_Core_Model_Export_Type_Price::CSV_DELIMITER;
40
+ }
41
+
42
+
43
+ }
app/code/community/FACTFinder/Core/Model/File/Validator/Product.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class FACTFinder_Core_Model_File_Validator_Product extends FACTFinder_Core_Model_File_Validator_Abstract
3
+ {
4
+
5
+
6
+ /**
7
+ * Validate file
8
+ *
9
+ * @param string $file
10
+ *
11
+ * @return bool
12
+ */
13
+ public function validate($file)
14
+ {
15
+ $result = true;
16
+
17
+ try {
18
+ $this->checkIfEmpty($file);
19
+ $this->checkCsvConsistency($file);
20
+
21
+ $storeId = $this->getStoreIdFromFile($file, FACTFinder_Core_Model_Export_Type_Product::FILENAME_PATTERN);
22
+ $expectedSize = Mage::getModel('factfinder/export_type_product')->getSize($storeId);
23
+
24
+ $this->checkNumberOfLines($file, $expectedSize);
25
+ } catch (Exception $e) {
26
+ $this->logException($file, $e);
27
+ $result = false;
28
+ }
29
+
30
+ return $result;
31
+ }
32
+
33
+
34
+ /**
35
+ * @return string
36
+ */
37
+ protected function getCsvDelimiter()
38
+ {
39
+ return FACTFinder_Core_Model_Export_Type_Product::CSV_DELIMITER;
40
+ }
41
+
42
+
43
+ }
app/code/community/FACTFinder/Core/Model/File/Validator/Stock.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class FACTFinder_Core_Model_File_Validator_Stock extends FACTFinder_Core_Model_File_Validator_Abstract
3
+ {
4
+
5
+
6
+ /**
7
+ * Validate file
8
+ *
9
+ * @param string $file
10
+ *
11
+ * @return bool
12
+ */
13
+ public function validate($file)
14
+ {
15
+ $result = true;
16
+
17
+ try {
18
+ $this->checkIfEmpty($file);
19
+ $this->checkCsvConsistency($file);
20
+
21
+ $storeId = $this->getStoreIdFromFile($file, FACTFinder_Core_Model_Export_Type_Stock::FILENAME_PATTERN);
22
+ $expectedSize = Mage::getModel('factfinder/export_type_stock')->getSize($storeId);
23
+
24
+ $this->checkNumberOfLines($file, $expectedSize);
25
+ } catch (Exception $e) {
26
+ $this->logException($file, $e);
27
+ $result = false;
28
+ }
29
+
30
+ return $result;
31
+ }
32
+
33
+
34
+ /**
35
+ * @return string
36
+ */
37
+ protected function getCsvDelimiter()
38
+ {
39
+ return FACTFinder_Core_Model_Export_Type_Stock::CSV_DELIMITER;
40
+ }
41
+
42
+
43
+ }
app/code/community/FACTFinder/Core/Model/Handler/Search.php CHANGED
@@ -23,6 +23,7 @@
23
  */
24
 
25
  use FACTFinder\Loader as FF;
 
26
 
27
  class FACTFinder_Core_Model_Handler_Search extends FACTFinder_Core_Model_Handler_Abstract
28
  {
@@ -126,9 +127,7 @@ class FACTFinder_Core_Model_Handler_Search extends FACTFinder_Core_Model_Handler
126
  $params['verbose'] = 'true';
127
  }
128
 
129
- if(Mage::getStoreConfigFlag('factfinder/config/personalization')) {
130
- $params['sid'] = Mage::helper('factfinder_tracking')->getSessionId();
131
- }
132
 
133
  return $params;
134
  }
@@ -299,4 +298,21 @@ class FACTFinder_Core_Model_Handler_Search extends FACTFinder_Core_Model_Handler
299
  }
300
 
301
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  }
23
  */
24
 
25
  use FACTFinder\Loader as FF;
26
+ use FACTFinder\Data as FFData;
27
 
28
  class FACTFinder_Core_Model_Handler_Search extends FACTFinder_Core_Model_Handler_Abstract
29
  {
127
  $params['verbose'] = 'true';
128
  }
129
 
130
+ $params['sid'] = Mage::helper('factfinder_tracking')->getSessionId();
 
 
131
 
132
  return $params;
133
  }
298
  }
299
 
300
 
301
+ /**
302
+ * Get default option for the "items per page" dropdown
303
+ *
304
+ * @return bool|FFData\Item
305
+ */
306
+ public function getDefaultPerPageOption()
307
+ {
308
+ $option = $this->getResultsPerPageOptions()->getDefaultOption();
309
+
310
+ if ($option instanceof FFData\Item) {
311
+ return $option;
312
+ }
313
+
314
+ return false;
315
+ }
316
+
317
+
318
  }
app/code/community/FACTFinder/Core/Model/Handler/Status.php CHANGED
@@ -173,12 +173,6 @@ class FACTFinder_Core_Model_Handler_Status extends FACTFinder_Core_Model_Handler
173
 
174
  if (isset ($this->_errorMapping[$statusCode])) {
175
  $errorMessage .= $helper->__($this->_errorMapping[$statusCode]);
176
- }
177
-
178
- $codeType = (int) floor($statusCode / 1000) * 1000;
179
-
180
- if (isset ($this->_errorMapping[$codeType])) {
181
- $errorMessage .= $helper->__($this->_errorMapping[$statusCode], $statusCode - $codeType);
182
  } else {
183
  $errorMessage .= $helper->__('An unknown error has occurred. Please contact FACT-Finder Support.');
184
  }
@@ -291,9 +285,9 @@ class FACTFinder_Core_Model_Handler_Status extends FACTFinder_Core_Model_Handler
291
  return FFE_HTTP_ERROR + $httpCode;
292
  }
293
 
294
- $stackTrace = $this->_getFacade()->getSearchAdapter()->getStackTrace();
295
  Mage::helper('factfinder/debug')->trace($stackTrace);
296
- preg_match('/^(.+?):?\s/', $stackTrace, $matches);
297
  $ffException = $matches[1];
298
 
299
  switch ($ffException) {
173
 
174
  if (isset ($this->_errorMapping[$statusCode])) {
175
  $errorMessage .= $helper->__($this->_errorMapping[$statusCode]);
 
 
 
 
 
 
176
  } else {
177
  $errorMessage .= $helper->__('An unknown error has occurred. Please contact FACT-Finder Support.');
178
  }
285
  return FFE_HTTP_ERROR + $httpCode;
286
  }
287
 
288
+ $stackTrace = $response->getContent();
289
  Mage::helper('factfinder/debug')->trace($stackTrace);
290
+ preg_match('/\"stacktrace\":\"([a-zA-Z0-9.]+)/', $stackTrace, $matches);
291
  $ffException = $matches[1];
292
 
293
  switch ($ffException) {
app/code/community/FACTFinder/Core/Model/Resource/Export.php CHANGED
@@ -267,7 +267,7 @@ class FACTFinder_Core_Model_Resource_Export extends Mage_CatalogSearch_Model_Res
267
  return $this->_getReadAdapter()->fetchAll($select);
268
  }
269
 
270
- return null;
271
  }
272
 
273
 
267
  return $this->_getReadAdapter()->fetchAll($select);
268
  }
269
 
270
+ return array();
271
  }
272
 
273
 
app/code/community/FACTFinder/Core/controllers/ExportController.php CHANGED
@@ -68,8 +68,17 @@ class FACTFinder_Core_ExportController extends Mage_Core_Controller_Front_Action
68
  */
69
  public function exportAction()
70
  {
 
 
 
 
 
 
 
71
  try {
72
- $this->lockSemaphore();
 
 
73
  } catch (RuntimeException $e) {
74
  $this->loadLayout()
75
  ->renderLayout();
@@ -77,19 +86,15 @@ class FACTFinder_Core_ExportController extends Mage_Core_Controller_Front_Action
77
  return;
78
  }
79
 
80
- $resource = Mage::app()->getRequest()->getParam('resource', 'product');
81
  Mage::helper('factfinder/debug')->log(
82
- 'Export action called: resource=' . $resource . ', store='. $this->_getStoreId(), true);
 
 
83
 
84
  try {
85
- $exportModel = Mage::getModel('factfinder/export_' . $resource);
86
- $exportModel->saveExport(
87
- $this->_getStoreId()
88
- );
89
-
90
- $this->releaseSemaphore(); // finally-workaround
91
  } catch (Exception $e) {
92
- $this->releaseSemaphore(); // finally-workaround
93
  Mage::helper('factfinder/debug')->error('Export action ' . $e->__toString());
94
  throw $e;
95
  }
@@ -165,41 +170,6 @@ class FACTFinder_Core_ExportController extends Mage_Core_Controller_Front_Action
165
  }
166
 
167
 
168
- /**
169
- * Locks the semaphore
170
- * Throws an exception, if semaphore is already locked
171
- **/
172
- protected function lockSemaphore()
173
- {
174
- $mtime = @filemtime($this->_getLockFileName());
175
- $semaphoreTimeout = FACTFinderCustom_Configuration::DEFAULT_SEMAPHORE_TIMEOUT;
176
- if ($mtime && time() - $mtime < $semaphoreTimeout) {
177
- throw new RuntimeException();
178
- }
179
- @touch($this->_getLockFileName());
180
- }
181
-
182
-
183
- /**
184
- * Release the semaphore
185
- */
186
- protected function releaseSemaphore()
187
- {
188
- @unlink($this->_getLockFileName());
189
- }
190
-
191
-
192
- /**
193
- * Retrieve the name of lockfile
194
- *
195
- * @return string
196
- */
197
- protected function _getLockFileName()
198
- {
199
- return Mage::getBaseDir('var') . DS . 'locks' . DS . 'ffexport_' . $this->_getStoreId() . '.lock';
200
- }
201
-
202
-
203
  /**
204
  * Used to forward actions from wrappers
205
  *
68
  */
69
  public function exportAction()
70
  {
71
+ $resource = Mage::app()->getRequest()->getParam('resource', 'product');
72
+
73
+ /** @var FACTFinder_Core_Model_Export_Semaphore $semaphore */
74
+ $semaphore = Mage::getModel('factfinder/export_semaphore');
75
+ $semaphore->setStoreId($this->_getStoreId())
76
+ ->setType($resource);
77
+
78
  try {
79
+ // only check if there's a lock
80
+ $semaphore->lock();
81
+ $semaphore->release();
82
  } catch (RuntimeException $e) {
83
  $this->loadLayout()
84
  ->renderLayout();
86
  return;
87
  }
88
 
 
89
  Mage::helper('factfinder/debug')->log(
90
+ 'Export action called: resource=' . $resource . ', store='. $this->_getStoreId(),
91
+ true
92
+ );
93
 
94
  try {
95
+ $exportModel = Mage::getModel('factfinder/export_type_' . $resource);
96
+ $exportModel->saveExport($this->_getStoreId());
 
 
 
 
97
  } catch (Exception $e) {
 
98
  Mage::helper('factfinder/debug')->error('Export action ' . $e->__toString());
99
  throw $e;
100
  }
170
  }
171
 
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  /**
174
  * Used to forward actions from wrappers
175
  *
app/code/community/FACTFinder/Core/etc/system.xml CHANGED
@@ -185,11 +185,20 @@
185
  <show_in_website>1</show_in_website>
186
  <show_in_store>1</show_in_store>
187
  <fields>
 
 
 
 
 
 
 
 
 
188
  <products_without_categories translate="label">
189
  <label>Export products without categories</label>
190
  <frontend_type>select</frontend_type>
191
  <source_model>adminhtml/system_config_source_yesno</source_model>
192
- <sort_order>10</sort_order>
193
  <show_in_default>1</show_in_default>
194
  <show_in_website>1</show_in_website>
195
  <show_in_store>1</show_in_store>
@@ -198,41 +207,25 @@
198
  <label>Export out of stock products</label>
199
  <frontend_type>select</frontend_type>
200
  <source_model>adminhtml/system_config_source_yesno</source_model>
201
- <sort_order>15</sort_order>
202
  <show_in_default>1</show_in_default>
203
  <show_in_website>1</show_in_website>
204
  <show_in_store>1</show_in_store>
205
  </out_of_stock_products>
206
- <remove_tags translate="label">
207
- <label>Remove html entities and tags</label>
208
- <frontend_type>select</frontend_type>
209
- <source_model>adminhtml/system_config_source_yesno</source_model>
210
- <sort_order>55</sort_order>
211
- <show_in_default>1</show_in_default>
212
- <show_in_website>1</show_in_website>
213
- <show_in_store>1</show_in_store>
214
- </remove_tags>
215
  <attributes translate="label">
216
  <label>Attributes</label>
217
  <frontend_model>factfinder/adminhtml_form_field_attributes</frontend_model>
218
  <backend_model>factfinder/system_config_backend_attributes</backend_model>
219
- <sort_order>50</sort_order>
220
  <show_in_default>1</show_in_default>
221
  <show_in_website>1</show_in_website>
222
  <show_in_store>1</show_in_store>
223
  </attributes>
224
- <export_url translate="label">
225
- <frontend_model>factfinder/adminhtml_exportlink</frontend_model>
226
- <sort_order>60</sort_order>
227
- <show_in_default>1</show_in_default>
228
- <show_in_website>1</show_in_website>
229
- <show_in_store>1</show_in_store>
230
- </export_url>
231
  <trigger_data_import translate="label">
232
  <label>Trigger Data Import</label>
233
  <frontend_type>select</frontend_type>
234
  <source_model>adminhtml/system_config_source_yesno</source_model>
235
- <sort_order>70</sort_order>
236
  <show_in_default>1</show_in_default>
237
  <show_in_website>1</show_in_website>
238
  <show_in_store>1</show_in_store>
@@ -242,7 +235,7 @@
242
  <label>Import Delay Enabled</label>
243
  <frontend_type>select</frontend_type>
244
  <source_model>adminhtml/system_config_source_yesno</source_model>
245
- <sort_order>75</sort_order>
246
  <show_in_default>1</show_in_default>
247
  <show_in_website>1</show_in_website>
248
  <show_in_store>1</show_in_store>
@@ -252,7 +245,7 @@
252
  <label>Upload files to FTP host</label>
253
  <frontend_type>select</frontend_type>
254
  <source_model>adminhtml/system_config_source_yesno</source_model>
255
- <sort_order>100</sort_order>
256
  <show_in_default>1</show_in_default>
257
  <show_in_website>1</show_in_website>
258
  <show_in_store>1</show_in_store>
@@ -261,7 +254,7 @@
261
  <ftp_host translate="label">
262
  <label>FTP Host</label>
263
  <frontend_type>text</frontend_type>
264
- <sort_order>110</sort_order>
265
  <show_in_default>1</show_in_default>
266
  <show_in_website>1</show_in_website>
267
  <show_in_store>1</show_in_store>
@@ -270,7 +263,7 @@
270
  <ftp_port translate="label">
271
  <label>FTP Port</label>
272
  <frontend_type>text</frontend_type>
273
- <sort_order>120</sort_order>
274
  <show_in_default>1</show_in_default>
275
  <show_in_website>1</show_in_website>
276
  <show_in_store>1</show_in_store>
@@ -279,7 +272,7 @@
279
  <ftp_user translate="label">
280
  <label>FTP User</label>
281
  <frontend_type>text</frontend_type>
282
- <sort_order>130</sort_order>
283
  <show_in_default>1</show_in_default>
284
  <show_in_website>1</show_in_website>
285
  <show_in_store>1</show_in_store>
@@ -288,7 +281,7 @@
288
  <ftp_password translate="label">
289
  <label>FTP Password</label>
290
  <frontend_type>password</frontend_type>
291
- <sort_order>140</sort_order>
292
  <show_in_default>1</show_in_default>
293
  <show_in_website>1</show_in_website>
294
  <show_in_store>1</show_in_store>
@@ -297,7 +290,7 @@
297
  <ftp_path translate="label">
298
  <label>FTP Path</label>
299
  <frontend_type>text</frontend_type>
300
- <sort_order>150</sort_order>
301
  <show_in_default>1</show_in_default>
302
  <show_in_website>1</show_in_website>
303
  <show_in_store>1</show_in_store>
@@ -307,13 +300,30 @@
307
  <label>Use SSL</label>
308
  <frontend_type>select</frontend_type>
309
  <source_model>adminhtml/system_config_source_yesno</source_model>
310
- <sort_order>150</sort_order>
311
  <show_in_default>1</show_in_default>
312
  <show_in_website>1</show_in_website>
313
  <show_in_store>1</show_in_store>
314
  <depends><use_ftp>1</use_ftp></depends>
315
  <comment><![CDATA[Yes for FTPS and No for FTP]]></comment>
316
  </ftp_ssl>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  </fields>
318
  </export>
319
  <config translate="label">
@@ -333,20 +343,11 @@
333
  <show_in_website>1</show_in_website>
334
  <show_in_store>1</show_in_store>
335
  </personalization>
336
- <identifier translate="label">
337
- <label>Product Identifier</label>
338
- <frontend_type>select</frontend_type>
339
- <source_model>factfinder/system_config_source_identifier</source_model>
340
- <sort_order>10</sort_order>
341
- <show_in_default>1</show_in_default>
342
- <show_in_website>1</show_in_website>
343
- <show_in_store>1</show_in_store>
344
- </identifier>
345
  <redirectOnSingleResult>
346
  <label>Redirect to product details page for single results</label>
347
  <frontend_type>select</frontend_type>
348
  <source_model>adminhtml/system_config_source_yesno</source_model>
349
- <sort_order>20</sort_order>
350
  <show_in_default>1</show_in_default>
351
  <show_in_website>1</show_in_website>
352
  <show_in_store>1</show_in_store>
@@ -355,7 +356,7 @@
355
  <label>Use sorting options</label>
356
  <frontend_type>select</frontend_type>
357
  <source_model>adminhtml/system_config_source_yesno</source_model>
358
- <sort_order>30</sort_order>
359
  <show_in_default>1</show_in_default>
360
  <show_in_website>1</show_in_website>
361
  <show_in_store>1</show_in_store>
@@ -365,17 +366,26 @@
365
  <label>Use results per page options</label>
366
  <frontend_type>select</frontend_type>
367
  <source_model>adminhtml/system_config_source_yesno</source_model>
368
- <sort_order>40</sort_order>
369
  <show_in_default>1</show_in_default>
370
  <show_in_website>1</show_in_website>
371
  <show_in_store>1</show_in_store>
372
  <comment><![CDATA[If enabled, it requires the configuration of default and alternative results per page options in the FACT-Finder backend.]]></comment>
373
  </use_resultsPerPage>
 
 
 
 
 
 
 
 
 
374
  <internal_ip translate="label">
375
  <label>Internal IPs</label>
376
  <comment>Enter your internal IP addresses. Multiple IP addresses should be separated by semicolons.</comment>
377
  <frontend_type>text</frontend_type>
378
- <sort_order>90</sort_order>
379
  <show_in_default>1</show_in_default>
380
  <show_in_website>1</show_in_website>
381
  <show_in_store>1</show_in_store>
@@ -384,7 +394,7 @@
384
  <label>Debug Log</label>
385
  <frontend_type>select</frontend_type>
386
  <source_model>adminhtml/system_config_source_yesno</source_model>
387
- <sort_order>100</sort_order>
388
  <show_in_default>1</show_in_default>
389
  <show_in_website>1</show_in_website>
390
  <show_in_store>1</show_in_store>
@@ -435,60 +445,60 @@
435
  <show_in_website>1</show_in_website>
436
  <show_in_store>1</show_in_store>
437
  <fields>
438
- <asn translate="label">
439
- <label>Enable FACT-Finder After Search Navigation</label>
440
  <frontend_type>select</frontend_type>
441
  <source_model>adminhtml/system_config_source_yesno</source_model>
442
- <sort_order>10</sort_order>
443
  <show_in_default>1</show_in_default>
444
  <show_in_website>1</show_in_website>
445
  <show_in_store>1</show_in_store>
446
- </asn>
447
  <suggest translate="label">
448
  <label>Enable FACT-Finder Suggest</label>
449
  <frontend_type>select</frontend_type>
450
  <source_model>adminhtml/system_config_source_yesno</source_model>
451
- <sort_order>20</sort_order>
452
  <show_in_default>1</show_in_default>
453
  <show_in_website>1</show_in_website>
454
  <show_in_store>1</show_in_store>
455
  </suggest>
456
- <recommendation translate="label">
457
- <label>Enable FACT-Finder Recommendation</label>
458
  <frontend_type>select</frontend_type>
459
  <source_model>adminhtml/system_config_source_yesno</source_model>
460
- <sort_order>30</sort_order>
461
  <show_in_default>1</show_in_default>
462
  <show_in_website>1</show_in_website>
463
  <show_in_store>1</show_in_store>
464
- </recommendation>
465
- <tagcloud translate="label">
466
- <label>Enable FACT-Finder Tag Cloud</label>
467
  <frontend_type>select</frontend_type>
468
  <source_model>adminhtml/system_config_source_yesno</source_model>
469
- <sort_order>40</sort_order>
470
  <show_in_default>1</show_in_default>
471
  <show_in_website>1</show_in_website>
472
  <show_in_store>1</show_in_store>
473
- </tagcloud>
474
- <tracking>
475
- <label>Enable FACT-Finder Tracking</label>
476
  <frontend_type>select</frontend_type>
477
  <source_model>adminhtml/system_config_source_yesno</source_model>
478
- <sort_order>50</sort_order>
479
  <show_in_default>1</show_in_default>
480
  <show_in_website>1</show_in_website>
481
  <show_in_store>1</show_in_store>
482
- </tracking>
483
- <campaigns>
484
- <label>Enable FACT-Finder Campaigns</label>
485
  <frontend_type>select</frontend_type>
486
  <source_model>adminhtml/system_config_source_yesno</source_model>
487
- <sort_order>60</sort_order>
488
  <show_in_default>1</show_in_default>
489
  <show_in_website>1</show_in_website>
490
  <show_in_store>1</show_in_store>
491
- </campaigns>
492
  </fields>
493
  </modules>
494
  </groups>
185
  <show_in_website>1</show_in_website>
186
  <show_in_store>1</show_in_store>
187
  <fields>
188
+ <remove_tags translate="label">
189
+ <label>Remove html entities and tags</label>
190
+ <frontend_type>select</frontend_type>
191
+ <source_model>adminhtml/system_config_source_yesno</source_model>
192
+ <sort_order>20</sort_order>
193
+ <show_in_default>1</show_in_default>
194
+ <show_in_website>1</show_in_website>
195
+ <show_in_store>1</show_in_store>
196
+ </remove_tags>
197
  <products_without_categories translate="label">
198
  <label>Export products without categories</label>
199
  <frontend_type>select</frontend_type>
200
  <source_model>adminhtml/system_config_source_yesno</source_model>
201
+ <sort_order>25</sort_order>
202
  <show_in_default>1</show_in_default>
203
  <show_in_website>1</show_in_website>
204
  <show_in_store>1</show_in_store>
207
  <label>Export out of stock products</label>
208
  <frontend_type>select</frontend_type>
209
  <source_model>adminhtml/system_config_source_yesno</source_model>
210
+ <sort_order>30</sort_order>
211
  <show_in_default>1</show_in_default>
212
  <show_in_website>1</show_in_website>
213
  <show_in_store>1</show_in_store>
214
  </out_of_stock_products>
 
 
 
 
 
 
 
 
 
215
  <attributes translate="label">
216
  <label>Attributes</label>
217
  <frontend_model>factfinder/adminhtml_form_field_attributes</frontend_model>
218
  <backend_model>factfinder/system_config_backend_attributes</backend_model>
219
+ <sort_order>35</sort_order>
220
  <show_in_default>1</show_in_default>
221
  <show_in_website>1</show_in_website>
222
  <show_in_store>1</show_in_store>
223
  </attributes>
 
 
 
 
 
 
 
224
  <trigger_data_import translate="label">
225
  <label>Trigger Data Import</label>
226
  <frontend_type>select</frontend_type>
227
  <source_model>adminhtml/system_config_source_yesno</source_model>
228
+ <sort_order>40</sort_order>
229
  <show_in_default>1</show_in_default>
230
  <show_in_website>1</show_in_website>
231
  <show_in_store>1</show_in_store>
235
  <label>Import Delay Enabled</label>
236
  <frontend_type>select</frontend_type>
237
  <source_model>adminhtml/system_config_source_yesno</source_model>
238
+ <sort_order>45</sort_order>
239
  <show_in_default>1</show_in_default>
240
  <show_in_website>1</show_in_website>
241
  <show_in_store>1</show_in_store>
245
  <label>Upload files to FTP host</label>
246
  <frontend_type>select</frontend_type>
247
  <source_model>adminhtml/system_config_source_yesno</source_model>
248
+ <sort_order>50</sort_order>
249
  <show_in_default>1</show_in_default>
250
  <show_in_website>1</show_in_website>
251
  <show_in_store>1</show_in_store>
254
  <ftp_host translate="label">
255
  <label>FTP Host</label>
256
  <frontend_type>text</frontend_type>
257
+ <sort_order>55</sort_order>
258
  <show_in_default>1</show_in_default>
259
  <show_in_website>1</show_in_website>
260
  <show_in_store>1</show_in_store>
263
  <ftp_port translate="label">
264
  <label>FTP Port</label>
265
  <frontend_type>text</frontend_type>
266
+ <sort_order>60</sort_order>
267
  <show_in_default>1</show_in_default>
268
  <show_in_website>1</show_in_website>
269
  <show_in_store>1</show_in_store>
272
  <ftp_user translate="label">
273
  <label>FTP User</label>
274
  <frontend_type>text</frontend_type>
275
+ <sort_order>65</sort_order>
276
  <show_in_default>1</show_in_default>
277
  <show_in_website>1</show_in_website>
278
  <show_in_store>1</show_in_store>
281
  <ftp_password translate="label">
282
  <label>FTP Password</label>
283
  <frontend_type>password</frontend_type>
284
+ <sort_order>70</sort_order>
285
  <show_in_default>1</show_in_default>
286
  <show_in_website>1</show_in_website>
287
  <show_in_store>1</show_in_store>
290
  <ftp_path translate="label">
291
  <label>FTP Path</label>
292
  <frontend_type>text</frontend_type>
293
+ <sort_order>75</sort_order>
294
  <show_in_default>1</show_in_default>
295
  <show_in_website>1</show_in_website>
296
  <show_in_store>1</show_in_store>
300
  <label>Use SSL</label>
301
  <frontend_type>select</frontend_type>
302
  <source_model>adminhtml/system_config_source_yesno</source_model>
303
+ <sort_order>80</sort_order>
304
  <show_in_default>1</show_in_default>
305
  <show_in_website>1</show_in_website>
306
  <show_in_store>1</show_in_store>
307
  <depends><use_ftp>1</use_ftp></depends>
308
  <comment><![CDATA[Yes for FTPS and No for FTP]]></comment>
309
  </ftp_ssl>
310
+ <export_url translate="label">
311
+ <frontend_model>factfinder/adminhtml_exportlink</frontend_model>
312
+ <sort_order>95</sort_order>
313
+ <show_in_default>1</show_in_default>
314
+ <show_in_website>1</show_in_website>
315
+ <show_in_store>1</show_in_store>
316
+ </export_url>
317
+ <disable_validation translate="label comment">
318
+ <label>Disable export feed validation</label>
319
+ <frontend_type>select</frontend_type>
320
+ <source_model>adminhtml/system_config_source_yesno</source_model>
321
+ <sort_order>120</sort_order>
322
+ <show_in_default>1</show_in_default>
323
+ <show_in_website>1</show_in_website>
324
+ <show_in_store>1</show_in_store>
325
+ <comment><![CDATA[This can be used in case of unpredicted problems with export data validation]]></comment>
326
+ </disable_validation>
327
  </fields>
328
  </export>
329
  <config translate="label">
343
  <show_in_website>1</show_in_website>
344
  <show_in_store>1</show_in_store>
345
  </personalization>
 
 
 
 
 
 
 
 
 
346
  <redirectOnSingleResult>
347
  <label>Redirect to product details page for single results</label>
348
  <frontend_type>select</frontend_type>
349
  <source_model>adminhtml/system_config_source_yesno</source_model>
350
+ <sort_order>10</sort_order>
351
  <show_in_default>1</show_in_default>
352
  <show_in_website>1</show_in_website>
353
  <show_in_store>1</show_in_store>
356
  <label>Use sorting options</label>
357
  <frontend_type>select</frontend_type>
358
  <source_model>adminhtml/system_config_source_yesno</source_model>
359
+ <sort_order>15</sort_order>
360
  <show_in_default>1</show_in_default>
361
  <show_in_website>1</show_in_website>
362
  <show_in_store>1</show_in_store>
366
  <label>Use results per page options</label>
367
  <frontend_type>select</frontend_type>
368
  <source_model>adminhtml/system_config_source_yesno</source_model>
369
+ <sort_order>20</sort_order>
370
  <show_in_default>1</show_in_default>
371
  <show_in_website>1</show_in_website>
372
  <show_in_store>1</show_in_store>
373
  <comment><![CDATA[If enabled, it requires the configuration of default and alternative results per page options in the FACT-Finder backend.]]></comment>
374
  </use_resultsPerPage>
375
+ <identifier translate="label">
376
+ <label>Product Identifier</label>
377
+ <frontend_type>select</frontend_type>
378
+ <source_model>factfinder/system_config_source_identifier</source_model>
379
+ <sort_order>35</sort_order>
380
+ <show_in_default>1</show_in_default>
381
+ <show_in_website>1</show_in_website>
382
+ <show_in_store>1</show_in_store>
383
+ </identifier>
384
  <internal_ip translate="label">
385
  <label>Internal IPs</label>
386
  <comment>Enter your internal IP addresses. Multiple IP addresses should be separated by semicolons.</comment>
387
  <frontend_type>text</frontend_type>
388
+ <sort_order>55</sort_order>
389
  <show_in_default>1</show_in_default>
390
  <show_in_website>1</show_in_website>
391
  <show_in_store>1</show_in_store>
394
  <label>Debug Log</label>
395
  <frontend_type>select</frontend_type>
396
  <source_model>adminhtml/system_config_source_yesno</source_model>
397
+ <sort_order>60</sort_order>
398
  <show_in_default>1</show_in_default>
399
  <show_in_website>1</show_in_website>
400
  <show_in_store>1</show_in_store>
445
  <show_in_website>1</show_in_website>
446
  <show_in_store>1</show_in_store>
447
  <fields>
448
+ <tracking>
449
+ <label>Enable FACT-Finder Tracking</label>
450
  <frontend_type>select</frontend_type>
451
  <source_model>adminhtml/system_config_source_yesno</source_model>
452
+ <sort_order>5</sort_order>
453
  <show_in_default>1</show_in_default>
454
  <show_in_website>1</show_in_website>
455
  <show_in_store>1</show_in_store>
456
+ </tracking>
457
  <suggest translate="label">
458
  <label>Enable FACT-Finder Suggest</label>
459
  <frontend_type>select</frontend_type>
460
  <source_model>adminhtml/system_config_source_yesno</source_model>
461
+ <sort_order>10</sort_order>
462
  <show_in_default>1</show_in_default>
463
  <show_in_website>1</show_in_website>
464
  <show_in_store>1</show_in_store>
465
  </suggest>
466
+ <asn translate="label">
467
+ <label>Enable FACT-Finder After Search Navigation</label>
468
  <frontend_type>select</frontend_type>
469
  <source_model>adminhtml/system_config_source_yesno</source_model>
470
+ <sort_order>15</sort_order>
471
  <show_in_default>1</show_in_default>
472
  <show_in_website>1</show_in_website>
473
  <show_in_store>1</show_in_store>
474
+ </asn>
475
+ <campaigns>
476
+ <label>Enable FACT-Finder Campaigns</label>
477
  <frontend_type>select</frontend_type>
478
  <source_model>adminhtml/system_config_source_yesno</source_model>
479
+ <sort_order>25</sort_order>
480
  <show_in_default>1</show_in_default>
481
  <show_in_website>1</show_in_website>
482
  <show_in_store>1</show_in_store>
483
+ </campaigns>
484
+ <recommendation translate="label">
485
+ <label>Enable FACT-Finder Recommendation</label>
486
  <frontend_type>select</frontend_type>
487
  <source_model>adminhtml/system_config_source_yesno</source_model>
488
+ <sort_order>30</sort_order>
489
  <show_in_default>1</show_in_default>
490
  <show_in_website>1</show_in_website>
491
  <show_in_store>1</show_in_store>
492
+ </recommendation>
493
+ <tagcloud translate="label">
494
+ <label>Enable FACT-Finder Tag Cloud</label>
495
  <frontend_type>select</frontend_type>
496
  <source_model>adminhtml/system_config_source_yesno</source_model>
497
+ <sort_order>35</sort_order>
498
  <show_in_default>1</show_in_default>
499
  <show_in_website>1</show_in_website>
500
  <show_in_store>1</show_in_store>
501
+ </tagcloud>
502
  </fields>
503
  </modules>
504
  </groups>
app/code/community/FACTFinder/Recommendation/Model/Observer.php CHANGED
@@ -104,6 +104,7 @@ class FACTFinder_Recommendation_Model_Observer
104
  'find_in_set(`e`.`' . $idFieldName . '`, ?)',
105
  implode(',', $recommendations)
106
  ));
 
107
  $select->order($order);
108
  } else {
109
  // do not load anything
@@ -157,6 +158,12 @@ class FACTFinder_Recommendation_Model_Observer
157
  */
158
  public function triggerImportAfterExport($observer)
159
  {
 
 
 
 
 
 
160
  $storeId = $observer->getStoreId();
161
  $helper = Mage::helper('factfinder_recommendation');
162
  if ($helper->shouldTriggerImport($storeId)) {
104
  'find_in_set(`e`.`' . $idFieldName . '`, ?)',
105
  implode(',', $recommendations)
106
  ));
107
+ $select->reset(Zend_Db_Select::ORDER); // ensure sort order is only determined by FF
108
  $select->order($order);
109
  } else {
110
  // do not load anything
158
  */
159
  public function triggerImportAfterExport($observer)
160
  {
161
+ $file = $observer->getFile();
162
+
163
+ if (!$file instanceof FACTFinder_Core_Model_File || !$file->isValid()) {
164
+ return;
165
+ }
166
+
167
  $storeId = $observer->getStoreId();
168
  $helper = Mage::helper('factfinder_recommendation');
169
  if ($helper->shouldTriggerImport($storeId)) {
app/code/community/FACTFinder/Suggest/Helper/Data.php CHANGED
@@ -136,7 +136,7 @@ class FACTFinder_Suggest_Helper_Data extends Mage_Core_Helper_Abstract
136
  }
137
  }
138
 
139
- $url = array_shift(explode('?', $url));
140
  $query = http_build_query($excludeParams);
141
 
142
  return $url . '?' . $query;
136
  }
137
  }
138
 
139
+ $url = strtok($url, '?');
140
  $query = http_build_query($excludeParams);
141
 
142
  return $url . '?' . $query;
app/code/community/FACTFinder/Suggest/Model/Observer.php CHANGED
@@ -51,6 +51,12 @@ class FACTFinder_Suggest_Model_Observer
51
  */
52
  public function triggerImportAfterExport($observer)
53
  {
 
 
 
 
 
 
54
  $storeId = $observer->getStoreId();
55
  $helper = Mage::helper('factfinder_suggest');
56
  if ($helper->shouldTriggerImport($storeId)) {
51
  */
52
  public function triggerImportAfterExport($observer)
53
  {
54
+ $file = $observer->getFile();
55
+
56
+ if (!$file instanceof FACTFinder_Core_Model_File || !$file->isValid()) {
57
+ return;
58
+ }
59
+
60
  $storeId = $observer->getStoreId();
61
  $helper = Mage::helper('factfinder_suggest');
62
  if ($helper->shouldTriggerImport($storeId)) {
app/code/community/FACTFinder/Suggest/etc/system.xml CHANGED
@@ -32,10 +32,10 @@
32
  <export>
33
  <fields>
34
  <urls translate="label">
35
- <label>Export Images and Deeplinks</label>
36
  <frontend_type>select</frontend_type>
37
  <source_model>adminhtml/system_config_source_yesno</source_model>
38
- <sort_order>10</sort_order>
39
  <show_in_default>1</show_in_default>
40
  <show_in_website>1</show_in_website>
41
  <show_in_store>1</show_in_store>
@@ -44,7 +44,7 @@
44
  <label>Size of Suggest images</label>
45
  <comment>Please enter the desired edge length of the Suggest images in pixels. If you do not want them to be resized, enter 0.</comment>
46
  <frontend_type>text</frontend_type>
47
- <sort_order>15</sort_order>
48
  <show_in_default>1</show_in_default>
49
  <show_in_website>1</show_in_website>
50
  <show_in_store>1</show_in_store>
@@ -53,7 +53,7 @@
53
  <label>Type of Suggest images</label>
54
  <frontend_type>select</frontend_type>
55
  <source_model>factfinder_suggest/system_config_source_imagetype</source_model>
56
- <sort_order>16</sort_order>
57
  <show_in_default>1</show_in_default>
58
  <show_in_website>1</show_in_website>
59
  <show_in_store>1</show_in_store>
@@ -62,7 +62,7 @@
62
  <label>Trigger Suggest Import</label>
63
  <frontend_type>select</frontend_type>
64
  <source_model>adminhtml/system_config_source_yesno</source_model>
65
- <sort_order>80</sort_order>
66
  <show_in_default>1</show_in_default>
67
  <show_in_website>1</show_in_website>
68
  <show_in_store>1</show_in_store>
@@ -76,7 +76,7 @@
76
  <label>Use Proxy for Suggest</label>
77
  <frontend_type>select</frontend_type>
78
  <source_model>adminhtml/system_config_source_yesno</source_model>
79
- <sort_order>10</sort_order>
80
  <show_in_default>1</show_in_default>
81
  <show_in_website>1</show_in_website>
82
  <show_in_store>1</show_in_store>
32
  <export>
33
  <fields>
34
  <urls translate="label">
35
+ <label>Export Images</label>
36
  <frontend_type>select</frontend_type>
37
  <source_model>adminhtml/system_config_source_yesno</source_model>
38
+ <sort_order>5</sort_order>
39
  <show_in_default>1</show_in_default>
40
  <show_in_website>1</show_in_website>
41
  <show_in_store>1</show_in_store>
44
  <label>Size of Suggest images</label>
45
  <comment>Please enter the desired edge length of the Suggest images in pixels. If you do not want them to be resized, enter 0.</comment>
46
  <frontend_type>text</frontend_type>
47
+ <sort_order>10</sort_order>
48
  <show_in_default>1</show_in_default>
49
  <show_in_website>1</show_in_website>
50
  <show_in_store>1</show_in_store>
53
  <label>Type of Suggest images</label>
54
  <frontend_type>select</frontend_type>
55
  <source_model>factfinder_suggest/system_config_source_imagetype</source_model>
56
+ <sort_order>15</sort_order>
57
  <show_in_default>1</show_in_default>
58
  <show_in_website>1</show_in_website>
59
  <show_in_store>1</show_in_store>
62
  <label>Trigger Suggest Import</label>
63
  <frontend_type>select</frontend_type>
64
  <source_model>adminhtml/system_config_source_yesno</source_model>
65
+ <sort_order>85</sort_order>
66
  <show_in_default>1</show_in_default>
67
  <show_in_website>1</show_in_website>
68
  <show_in_store>1</show_in_store>
76
  <label>Use Proxy for Suggest</label>
77
  <frontend_type>select</frontend_type>
78
  <source_model>adminhtml/system_config_source_yesno</source_model>
79
+ <sort_order>50</sort_order>
80
  <show_in_default>1</show_in_default>
81
  <show_in_website>1</show_in_website>
82
  <show_in_store>1</show_in_store>
app/code/community/FACTFinder/Tracking/Block/Recommendation.php CHANGED
@@ -33,7 +33,13 @@ class FACTFinder_Tracking_Block_Recommendation extends FACTFinder_Tracking_Block
33
  */
34
  protected function getProductResultCollection()
35
  {
36
- return Mage::registry('recommendation_collection');
 
 
 
 
 
 
37
  }
38
 
39
 
33
  */
34
  protected function getProductResultCollection()
35
  {
36
+ $collection = Mage::registry('recommendation_collection');
37
+
38
+ if (empty($collection)) {
39
+ $collection = array();
40
+ }
41
+
42
+ return $collection;
43
  }
44
 
45
 
app/code/community/FACTFinder/Tracking/Model/Observer.php CHANGED
@@ -223,6 +223,9 @@ class FACTFinder_Tracking_Model_Observer
223
  return;
224
  }
225
 
 
 
 
226
  $queue = Mage::getModel('factfinder_tracking/queue');
227
 
228
  try {
223
  return;
224
  }
225
 
226
+ // Autoloader is initialized on controller_front_init_before which is NOT called in cron context, load it now
227
+ Mage::getModel('factfinder/autoloader')->addAutoloader(new Varien_Event_Observer());
228
+
229
  $queue = Mage::getModel('factfinder_tracking/queue');
230
 
231
  try {
app/code/community/FACTFinder/Tracking/Model/Processor.php CHANGED
@@ -27,6 +27,7 @@ require_once BP . DS . 'lib' . DS . 'FACTFinder' . DS . 'Loader.php';
27
  */
28
  class FACTFinder_Tracking_Model_Processor
29
  {
 
30
 
31
  /**
32
  * FactFinder Facade
@@ -80,16 +81,21 @@ class FACTFinder_Tracking_Model_Processor
80
  return $this->_facade;
81
  }
82
 
 
83
  /**
84
- * Bypass app cache.
85
  *
86
  * @param string $content
87
  *
88
- * @return false
89
  */
90
  public function extractContent($content)
91
  {
92
- return false;
 
 
 
 
93
  }
94
 
95
  /**
@@ -111,4 +117,33 @@ class FACTFinder_Tracking_Model_Processor
111
  }
112
  return $this->_getFacade()->getTrackingAdapter()->doTrackingFromRequest($sessionId, $customerId);
113
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }
27
  */
28
  class FACTFinder_Tracking_Model_Processor
29
  {
30
+ const TRACKING_FRONT_NAME = 'ff_tracking';
31
 
32
  /**
33
  * FactFinder Facade
81
  return $this->_facade;
82
  }
83
 
84
+
85
  /**
86
+ * Bypass app cache if it's a tracking request
87
  *
88
  * @param string $content
89
  *
90
+ * @return string|bool
91
  */
92
  public function extractContent($content)
93
  {
94
+ if (strpos($this->_getRequestPath(), self::TRACKING_FRONT_NAME) !== false) {
95
+ return false;
96
+ };
97
+
98
+ return $content;
99
  }
100
 
101
  /**
117
  }
118
  return $this->_getFacade()->getTrackingAdapter()->doTrackingFromRequest($sessionId, $customerId);
119
  }
120
+
121
+
122
+ /**
123
+ * Return current page base url
124
+ *
125
+ * @return string
126
+ */
127
+ protected function _getRequestPath()
128
+ {
129
+ $url = false;
130
+
131
+ /**
132
+ * Define request URI
133
+ */
134
+ if (isset($_SERVER['REQUEST_URI'])) {
135
+ $url = $_SERVER['REQUEST_URI'];
136
+ } elseif (!empty($_SERVER['IIS_WasUrlRewritten']) && !empty($_SERVER['UNENCODED_URL'])) {
137
+ $url = $_SERVER['UNENCODED_URL'];
138
+ } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
139
+ $url = $_SERVER['ORIG_PATH_INFO'];
140
+ if (!empty($_SERVER['QUERY_STRING'])) {
141
+ $url .= $_SERVER['QUERY_STRING'];
142
+ }
143
+ }
144
+
145
+ return parse_url($url, PHP_URL_PATH);
146
+ }
147
+
148
+
149
  }
app/code/community/FACTFinder/Tracking/etc/config.xml CHANGED
@@ -15,7 +15,7 @@
15
  <config>
16
  <modules>
17
  <FACTFinder_Tracking>
18
- <version>4.1.2</version>
19
  </FACTFinder_Tracking>
20
  </modules>
21
  <global>
15
  <config>
16
  <modules>
17
  <FACTFinder_Tracking>
18
+ <version>4.1.11</version>
19
  </FACTFinder_Tracking>
20
  </modules>
21
  <global>
app/code/community/FACTFinder/Tracking/etc/system.xml CHANGED
@@ -22,7 +22,7 @@
22
  <label>Track product-clicks</label>
23
  <frontend_type>select</frontend_type>
24
  <source_model>adminhtml/system_config_source_yesno</source_model>
25
- <sort_order>20</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>
@@ -31,7 +31,7 @@
31
  <label>Track "Add to cart" events</label>
32
  <frontend_type>select</frontend_type>
33
  <source_model>adminhtml/system_config_source_yesno</source_model>
34
- <sort_order>30</sort_order>
35
  <show_in_default>1</show_in_default>
36
  <show_in_website>1</show_in_website>
37
  <show_in_store>1</show_in_store>
@@ -40,7 +40,7 @@
40
  <label>Track checkout</label>
41
  <frontend_type>select</frontend_type>
42
  <source_model>adminhtml/system_config_source_yesno</source_model>
43
- <sort_order>40</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>
@@ -53,7 +53,7 @@
53
  <label>Tracking Product Identifier</label>
54
  <frontend_type>select</frontend_type>
55
  <source_model>factfinder/system_config_source_identifier</source_model>
56
- <sort_order>12</sort_order>
57
  <show_in_default>1</show_in_default>
58
  <show_in_website>1</show_in_website>
59
  <show_in_store>1</show_in_store>
22
  <label>Track product-clicks</label>
23
  <frontend_type>select</frontend_type>
24
  <source_model>adminhtml/system_config_source_yesno</source_model>
25
+ <sort_order>100</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>
31
  <label>Track "Add to cart" events</label>
32
  <frontend_type>select</frontend_type>
33
  <source_model>adminhtml/system_config_source_yesno</source_model>
34
+ <sort_order>105</sort_order>
35
  <show_in_default>1</show_in_default>
36
  <show_in_website>1</show_in_website>
37
  <show_in_store>1</show_in_store>
40
  <label>Track checkout</label>
41
  <frontend_type>select</frontend_type>
42
  <source_model>adminhtml/system_config_source_yesno</source_model>
43
+ <sort_order>110</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>
53
  <label>Tracking Product Identifier</label>
54
  <frontend_type>select</frontend_type>
55
  <source_model>factfinder/system_config_source_identifier</source_model>
56
+ <sort_order>40</sort_order>
57
  <show_in_default>1</show_in_default>
58
  <show_in_website>1</show_in_website>
59
  <show_in_store>1</show_in_store>
app/code/community/FACTFinder/Tracking/sql/factfinder_tracking_setup/upgrade-4.1.2-4.1.11.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
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
+ * Install script
15
+ *
16
+ * Change tye of the column for Product ID
17
+ *
18
+ */
19
+
20
+ $installer = $this;
21
+ $installer->startSetup();
22
+
23
+ $table = $installer->getConnection()
24
+ ->modifyColumn(
25
+ $installer->getTable('factfinder_tracking/queue'),
26
+ 'product_id',
27
+ array(
28
+ 'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
29
+ 'length' => 255,
30
+ 'nullable' => true,
31
+ 'default' => null,
32
+ 'comment' => 'Product ID'
33
+ )
34
+ );
35
+ $installer->endSetup();
app/design/frontend/base/default/layout/factfinder/campaigns.xml CHANGED
@@ -67,6 +67,16 @@
67
 
68
  <catalog_category_view>
69
  <reference name="content">
 
 
 
 
 
 
 
 
 
 
70
  <block type="factfinder_campaigns/advisory_search" name="ff.search.advisory" before="-" template="factfinder/campaigns/advisory.phtml" />
71
  <!-- pushed products -->
72
  <block type="factfinder_campaigns/pushed_search" name="search.pushed" after="ff.search.advisory">
@@ -130,4 +140,19 @@
130
  </reference>
131
  </catalog_product_view>
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  </layout>
67
 
68
  <catalog_category_view>
69
  <reference name="content">
70
+ <!-- landing page pushed products -->
71
+ <block type="factfinder_campaigns/pushed_page" name="page.pushed" before="category.products">
72
+ <action method="setMaxColNum"><num>3</num></action>
73
+ <block type="factfinder_campaigns/feedback_page" before="page.pushed" name="ff.feedback.above.pushed" as="feedback_above">
74
+ <action method="setLabel"><label>above pushed product</label></action>
75
+ </block>
76
+ <block type="factfinder_campaigns/feedback_page" after="page.pushed" name="ff.feedback.below.pushed" as="feedback_below">
77
+ <action method="setLabel"><label>below pushed product</label></action>
78
+ </block>
79
+ </block>
80
  <block type="factfinder_campaigns/advisory_search" name="ff.search.advisory" before="-" template="factfinder/campaigns/advisory.phtml" />
81
  <!-- pushed products -->
82
  <block type="factfinder_campaigns/pushed_search" name="search.pushed" after="ff.search.advisory">
140
  </reference>
141
  </catalog_product_view>
142
 
143
+ <cms_page>
144
+ <reference name="content">
145
+ <!-- start page pushed products -->
146
+ <block type="factfinder_campaigns/pushed_page" name="page.pushed" after="page_content_heading">
147
+ <action method="setMaxColNum"><num>3</num></action>
148
+ <block type="factfinder_campaigns/feedback_page" before="page.pushed" name="ff.feedback.above.pushed" as="feedback_above">
149
+ <action method="setLabel"><label>above pushed product</label></action>
150
+ </block>
151
+ <block type="factfinder_campaigns/feedback_page" after="page.pushed" name="ff.feedback.below.pushed" as="feedback_below">
152
+ <action method="setLabel"><label>below pushed product</label></action>
153
+ </block>
154
+ </block>
155
+ </reference>
156
+ </cms_page>
157
+
158
  </layout>
app/design/frontend/rwd/enterprise/layout/factfinder/suggest.xml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Suggest
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Suggest
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2016 Flagbit GmbH & Co. KG
10
+ * @license https://opensource.org/licenses/MIT The MIT License (MIT)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <layout>
16
+
17
+ <factfinder_suggest_enabled>
18
+ <reference name="head">
19
+ <action method="addJs"><script>factfinder/jXHR.js</script></action>
20
+ <action method="addJs"><script>factfinder/suggest.js</script></action>
21
+ <action method="addCss"><stylesheet>css/factfinder_suggest.css</stylesheet></action>
22
+ </reference>
23
+ <reference name="header">
24
+ <block type="factfinder_suggest/topSearch" name="top.search" as="topSearch" template="factfinder/suggest/advancedsuggest.phtml"/>
25
+ </reference>
26
+ </factfinder_suggest_enabled>
27
+
28
+ </layout>
js/factfinder/suggest.js CHANGED
@@ -193,6 +193,7 @@ var FactFinderSuggest = Class.create(Varien.searchForm, {
193
  destinationElement,
194
  url,
195
  {
 
196
  parameters: 'format=JSONP',
197
  paramName: 'query',
198
  method: 'get',
193
  destinationElement,
194
  url,
195
  {
196
+ frequency: 0.1,
197
  parameters: 'format=JSONP',
198
  paramName: 'query',
199
  method: 'get',
js/factfinder/tracking.js CHANGED
@@ -40,14 +40,14 @@ var FactfinderTracking = Class.create({
40
 
41
  if(element.readAttribute('href')) {
42
  var match = this.regex.exec(element.readAttribute('href'));
43
- if(match && match[1]) {
44
  return this.prepareElement(element, match[1], 'click');
45
  }
46
  }
47
 
48
  if(element.readAttribute('onclick')) {
49
  var match = this.regex.exec(element.readAttribute('onclick'));
50
- if(match && match[1]) {
51
  return this.prepareElement(element, match[1], 'click');
52
  }
53
  }
@@ -70,5 +70,12 @@ var FactfinderTracking = Class.create({
70
  parameters: data
71
  });
72
  return false;
 
 
 
 
 
 
 
73
  }
74
  });
40
 
41
  if(element.readAttribute('href')) {
42
  var match = this.regex.exec(element.readAttribute('href'));
43
+ if(match && match[1] && !this.irrelevantLink(element.readAttribute('class'))) {
44
  return this.prepareElement(element, match[1], 'click');
45
  }
46
  }
47
 
48
  if(element.readAttribute('onclick')) {
49
  var match = this.regex.exec(element.readAttribute('onclick'));
50
+ if(match && match[1] && !this.irrelevantLink(element.readAttribute('class'))) {
51
  return this.prepareElement(element, match[1], 'click');
52
  }
53
  }
70
  parameters: data
71
  });
72
  return false;
73
+ },
74
+
75
+ irrelevantLink: function (classAttribute) {
76
+ if (classAttribute != null && (classAttribute.indexOf('link-wishlist') != -1 || classAttribute.indexOf('link-compare') != -1)) {
77
+ return true;
78
+ }
79
+ return false;
80
  }
81
  });
package.xml CHANGED
@@ -1,18 +1,18 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Flagbit_Factfinder</name>
4
- <version>4.1.10</version>
5
  <stability>stable</stability>
6
  <license uri="https://opensource.org/licenses/MIT">MIT</license>
7
  <channel>community</channel>
8
  <extends/>
9
- <summary>4.1.10 Release</summary>
10
- <description>4.1.10 Release</description>
11
  <notes>Release</notes>
12
  <authors><author><name>FACTFinder</name><user>FACT_Finder</user><email>info@flagbit.de</email></author></authors>
13
- <date>2016-09-02</date>
14
- <time>13:09:08</time>
15
- <contents><target name="magecommunity"><dir name="FACTFinder"><dir name="Asn"><dir name="Block"><dir name="Catalog"><dir name="Layer"><file name="Factfinder.php" hash="0e79d252a2752aab67f7490436350fe7"/><file name="State.php" hash="2bf2c99237e881372fdc074c3505d188"/></dir><dir name="Product"><dir name="List"><file name="Toolbar.php" hash="9b0c98e266174c8f8b02b896a556b769"/></dir><file name="Pager.php" hash="ec87967ba312a3d589e0af0afbacdd0a"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="668be3edd4c8f6d0e051252d2e52d545"/></dir><dir name="Model"><dir name="Catalog"><file name="Layer.php" hash="6dafe882395b5d09f84c102f3b785410"/></dir><dir name="Handler"><file name="Search.php" hash="bbec7bd87e1d2f15792fdda46f34eb52"/></dir><dir name="Layer"><dir name="Filter"><file name="Factfinder.php" hash="2666ae9c79aa939e9539a1af5b0f7784"/><file name="Item.php" hash="a68545b4cb4487691ae75cdbf47af377"/></dir></dir><file name="Observer.php" hash="9ec46432b3d3170b626cfb4439315209"/><dir name="Resource"><dir name="Product"><dir name="Attribute"><file name="Collection.php" hash="03b060fd637de1fd632f1b9784b1124c"/></dir></dir><dir name="Search"><file name="Collection.php" hash="3e7a88eb53ccfb79b4448f9eb7bd4177"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="e07b890b06b00d94bc4a4a5931325366"/><file name="system.xml" hash="d76e04ebe1d564be4113c1428fdfc637"/></dir></dir><dir name="Campaigns"><dir name="Block"><file name="Abstract.php" hash="cc5e41bb89f07f191be99430451221fa"/><dir name="Advisory"><file name="Search.php" hash="1d4bf82a7baffbe64be17216436c35d4"/></dir><dir name="Feedback"><file name="Abstract.php" hash="018e415bdd754127cfad8bfa5881c0ce"/><file name="Cart.php" hash="35f9fec2518383c909495af90b324b8b"/><file name="Product.php" hash="82999021756a26d81bf829b9aa4dd5cc"/><file name="Search.php" hash="ebf3d35f6425b771291b08f696169d04"/></dir><dir name="Pushed"><file name="Abstract.php" hash="fbfbf5cb5c1ebce8e588ac7af1f1458d"/><file name="Cart.php" hash="741d3bd71ce91cd583778a5e26be9ff5"/><file name="Product.php" hash="c1e774c4ceb71469080e49557887a893"/><file name="Search.php" hash="ae352cfd5ca8bdf2a0b46d1148c710ae"/></dir></dir><dir name="Helper"><file name="Data.php" hash="c7882a90dca46e639a5e4c64bef153ff"/></dir><dir name="Model"><file name="Facade.php" hash="44fc55139509b76f19b7c95c6a81eb4c"/><dir name="Handler"><file name="Abstract.php" hash="e6d76eeb23fb5bef16efbfa3da0fecdc"/><file name="Cart.php" hash="128dd5052d20384ea2220020469f7cf6"/><file name="Product.php" hash="8d48380fbccec220bc4caabbcb5d7d7d"/><file name="Search.php" hash="e039a207ca98655c647355ebf287566d"/></dir><file name="Observer.php" hash="043e7411be7ec13a656b07750a7811af"/><dir name="Resource"><dir name="Pushedproducts"><file name="Collection.php" hash="569856158dee935d611ebc30f426835c"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="8f6b7cec7cff39b149beeffb39764668"/><file name="system.xml" hash="54992bb35ac6088733d3f18408872fdb"/></dir></dir><dir name="Core"><dir name="Block"><dir name="Adminhtml"><file name="Exportlink.php" hash="7a845ee8974cfcf74d9a32fed2ac0b21"/><dir name="Form"><dir name="Field"><file name="Attribute.php" hash="bea2183e56100233e7aebaccd6680c6f"/><file name="Attributes.php" hash="292742f954dec1863caaee9313a237c9"/></dir></dir></dir><dir name="Catalog"><dir name="Product"><dir name="List"><file name="Toolbar.php" hash="b9438ae943def50b46531ac1265e0634"/></dir><file name="Pager.php" hash="aa301fb57966bafcc370fa510d2ad146"/></dir></dir><dir name="CatalogSearch"><file name="Layer.php" hash="ad3dcdd26b5a723e43c7b8011a4ea25f"/></dir><dir name="EnterpriseSearch"><file name="Layer.php" hash="19455e36be3e0c14cabba762ccbdef1a"/></dir></dir><dir name="Helper"><file name="Backend.php" hash="f30c89ca668b193a8fc8bf00eda34413"/><file name="Data.php" hash="5108935421d26c45a63676b6b97f3044"/><file name="Debug.php" hash="c563d343c68db980e9256dc510e78ea1"/><file name="Export.php" hash="5b84cbf3c114593cd691e192f2ece920"/><file name="Rewrite.php" hash="30921c0924e535d669ecdd7e9592f883"/><file name="Search.php" hash="fd1e90271d620c57a0cb7b80e33f536f"/></dir><dir name="Model"><file name="Autoloader.php" hash="29370ccbcd483f93be86999485889900"/><dir name="CatalogSearch"><file name="Layer.php" hash="8d15e27cca249cd3827d33e9acdbb369"/><file name="Query.php" hash="4f5b732eb28a7c1efde28eb602c38772"/></dir><dir name="Export"><file name="Observer.php" hash="03a94f73f89b923c374a2663b03e3497"/><file name="Price.php" hash="1128559eb16cf0d562ad22af9ccdd1a4"/><file name="Product.php" hash="efddf1144d043892d1cf0fa46e8fb294"/><file name="Stock.php" hash="d6531c28c572968ab82d3282eda9b29a"/></dir><file name="Facade.php" hash="b2fd0c05a687db4c784111ecb4da9ef8"/><file name="File.php" hash="77cc3d2067b42c2cad6f21dcb6d7a73e"/><file name="Ftp.php" hash="d70cfab0ce607aca6efa32d82d3a85c3"/><dir name="Handler"><file name="Abstract.php" hash="1924821d13996f9f672369b63a05ac08"/><file name="Search.php" hash="31e58f2022169272740ad0d79674d0d8"/><file name="Status.php" hash="635b9cb62808803be64d373dc2a0e808"/></dir><file name="Observer.php" hash="e5decfa3b52571cb75335dd41b1927f5"/><dir name="Resource"><file name="Export.php" hash="b0db501cd527c64278519796cf8f39f1"/><file name="Fulltext.php" hash="dfbece11e5fe8224c94d1e1bb7affe3e"/><dir name="Search"><file name="Collection.php" hash="50596cf9508d0d96a4bb315a50f35984"/><file name="Engine.php" hash="602547a2d224f80933b6681db1cb3cc4"/></dir></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Attributes.php" hash="d877a4da13c592f5b8260b202bcead13"/><file name="Cron.php" hash="f24b6995fea6309acb720876f3156270"/><file name="Enabled.php" hash="cb13a29b7100518350a7e5830180e9bd"/><file name="Engine.php" hash="ef1f702d79c7ed0fe72437ca4bf13a19"/></dir><dir name="Source"><file name="Authtype.php" hash="7ce07da0f6bcb8e88b5699ace77e6f31"/><file name="Engine.php" hash="8f1c2f344aa3182c312a665488661fa5"/><file name="Identifier.php" hash="a80606fe94b2eaf78f8d07628f2a64f0"/><file name="Protocol.php" hash="310b7fd8648b60f5cc9c3e3c9f87345c"/></dir></dir></dir><file name="Url.php" hash="57e5e87457b3051cec9bc3c988f79282"/></dir><dir name="controllers"><file name="ExportController.php" hash="4e0800619796d128a9466c84fecd3b56"/></dir><dir name="etc"><file name="adminhtml.xml" hash="0247e1b846aefb3fb9c5c0706681a586"/><file name="config.xml" hash="471974367bce221b6795be5f4015a6e9"/><file name="system.xml" hash="8722773df22bda2a415e2cb3f87ee2f1"/></dir></dir><dir name="Recommendation"><dir name="Helper"><file name="Data.php" hash="6312dfdef17070694f59139acbb2d5e1"/></dir><dir name="Model"><file name="Facade.php" hash="ed9c246bc831c7f3950a88853d401288"/><dir name="Handler"><file name="Recommendations.php" hash="f5645b78a6dca466af5b22ff0456ca71"/></dir><file name="Observer.php" hash="4db52b3863efccd17b19e92e6ff2521e"/></dir><dir name="etc"><file name="config.xml" hash="03ec96e0fa78fdfbc3d4d5fac7193704"/><file name="system.xml" hash="f841228bf8a5397fe18da6186c5e3208"/></dir></dir><dir name="Suggest"><dir name="Block"><file name="TopSearch.php" hash="96fc7e73d907a0438111253ae6c5fc6f"/><dir name="XmlConnect"><dir name="Catalog"><dir name="Search"><file name="Suggest.php" hash="150658cb1d7bc7ae5b4566ed1331bb12"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="1d9e6e162f27abc911a1e19d02ea86a3"/></dir><dir name="Model"><file name="Facade.php" hash="254f13fa4cbbe9602ae40c5cd124282e"/><dir name="Handler"><file name="Suggest.php" hash="948fd13668d507ba4ebed7c9a2055be4"/></dir><file name="Observer.php" hash="f23771ea8bd4d679a90282714275aeb7"/><file name="Processor.php" hash="f37cf3fb0c72464f1e651f34d64b44dd"/><dir name="System"><dir name="Config"><dir name="Source"><file name="Imagetype.php" hash="a8a39dc5d44080a3b070bc72f103efef"/></dir></dir></dir></dir><dir name="controllers"><file name="ProxyController.php" hash="68fc8cee37a52a538762252e47f340a1"/></dir><dir name="etc"><file name="config.xml" hash="5e6b384d971afc4a0c6b7cc4d437badf"/><file name="system.xml" hash="10d1692d1a09edc2edb5344d41a1d9ae"/></dir></dir><dir name="Tagcloud"><dir name="Block"><file name="TagCloud.php" hash="d0c6c681b3da27ef349ff1295c5e26a9"/></dir><dir name="Helper"><file name="Data.php" hash="ea2c8093a1d87a8148f1205e8b73cc2d"/></dir><dir name="Model"><file name="Facade.php" hash="69069badc93509011f7c4fa2b1ca3e72"/><dir name="Handler"><file name="TagCloud.php" hash="e2e5ba229002ad3cfa5769a9f74d808b"/></dir></dir><dir name="etc"><file name="config.xml" hash="3ff00cc34fdbaed962f704204ce47f1a"/></dir></dir><dir name="Tracking"><dir name="Block"><file name="Abstract.php" hash="24419c96d9768b86ec890a1b38278e0f"/><file name="Click.php" hash="9fe6720543830930d97d7eb16f7fb489"/><file name="Recommendation.php" hash="0ed995b57afb6efa4a72d414dc7db3bf"/></dir><dir name="Helper"><file name="Data.php" hash="f0018ce83f815b057fab66351e58fdb6"/></dir><dir name="Model"><file name="Facade.php" hash="f8684a20a82bff4b668af460af476d41"/><dir name="Handler"><file name="Tracking.php" hash="9672d838ac3775c8a7dc4ef70593ca7e"/></dir><file name="Observer.php" hash="69e6c0236f629cb7f5b168b7ce3b6b84"/><file name="Processor.php" hash="9fd3af06f452ca2cb719d135b6ecda52"/><file name="Queue.php" hash="046d6d464d56a609b71574c6e0a3c4d1"/><dir name="Resource"><dir name="Queue"><file name="Collection.php" hash="daecedd55cb992ae3988305324c8c1b9"/></dir><file name="Queue.php" hash="3be1d09978ae6e8c56fb673931b05479"/></dir></dir><dir name="controllers"><file name="ProxyController.php" hash="33f25104bc086fcbe998459baccdd0b3"/></dir><dir name="etc"><file name="config.xml" hash="e3a33e4ca92d72192bcc0e73eb7db9a5"/><file name="system.xml" hash="3e5a4357f098832fa5e6ef67d1ceecaa"/></dir><dir name="sql"><dir name="factfinder_tracking_setup"><file name="install-1.0.0.php" hash="553ad063abd837a220ebff97618578b4"/><file name="upgrade-1.0.0-4.1.2.php" hash="a80b4f755d0bea172eefebe10b877cd6"/></dir></dir></dir></dir></target><target name="magelib"><dir name="FACTFinder"><dir name="Adapter"><file name="AbstractAdapter.php" hash="91eae466a803590699160600c430eab6"/><file name="Compare.php" hash="6b7cbae461ef45587c565affadbf8664"/><file name="ConfigurableResponse.php" hash="8ffa7eaa12d448a7bd4a9bba9975c573"/><file name="Import.php" hash="584eecdb7281603ba5ef901082fb52d7"/><file name="PersonalisedResponse.php" hash="6b62c326d25e123f686baa358a1b258b"/><file name="ProductCampaign.php" hash="945181a15218fd90721d3258eaf2fd17"/><file name="Recommendation.php" hash="0bcc4ccce41f40d343ebe19c901bea69"/><file name="Search.php" hash="202f3e5d444edb8be0b4e187bd98ea78"/><file name="SimilarRecords.php" hash="b80691760f993d2a43cbe2eb933090fe"/><file name="Suggest.php" hash="5f91090f7c7ea764f9fc21938aade3c8"/><file name="TagCloud.php" hash="fe1faf30373e91b96e57c08fb64df23a"/><file name="Tracking.php" hash="18948f9db1782730258a0e83f6f517b9"/></dir><dir name="Core"><file name="AbstractConfiguration.php" hash="d9341f7f13615a8a0c2805b2021cdfc8"/><file name="AbstractEncodingConverter.php" hash="7946720c77c47e3ed2070606a74a48cb"/><file name="ArrayConfiguration.php" hash="dc60873fa6eed180126944247cb4de99"/><dir name="Client"><file name="RequestParser.php" hash="bc5dabb648f7278db4a1c5f14af4dfa0"/><file name="UrlBuilder.php" hash="d73cc166fcf20b7623ea0f7c319d3224"/></dir><file name="ConfigurationInterface.php" hash="1158aaee6a7502cf81bf27b8ed0c76ff"/><file name="IConvEncodingConverter.php" hash="5c504a3229cc8a59c09f03f3bf2c9348"/><file name="ManualConfiguration.php" hash="a49d0b05cc319b807c40b37a861b060d"/><dir name="Page"><file name=".gitignore" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><file name="ParametersConverter.php" hash="9c01642c6de1842b8f1b4e8d9f93017e"/><dir name="Server"><file name="AbstractDataProvider.php" hash="8d33ddebe3d3e60b72893188d7f2369f"/><file name="ConnectionData.php" hash="c4246099ec93e7f589c0e22179d9557a"/><file name="EasyCurlDataProvider.php" hash="48f452cd3ca1dcf3b4e7cc4d8b59c8a9"/><file name="EasyCurlRequestFactory.php" hash="61f88e882120dca5e5e1964d1f898527"/><file name="FileSystemDataProvider.php" hash="30b428e2b76307b1143057a155371c34"/><file name="FileSystemRequestFactory.php" hash="f0a464725448393e64948a6063208d91"/><file name="MultiCurlDataProvider.php" hash="2e467a4976694ef4e7775d913dafedf4"/><file name="MultiCurlRequestFactory.php" hash="41f978e0dd60065026dc5adced1f9503"/><file name="NullResponse.php" hash="3a419c1ea234ef20e1330c7b445eb9c6"/><file name="Request.php" hash="08ddaaa7701558e1802408089d15b5dd"/><file name="RequestFactoryInterface.php" hash="65cfad6045407bdd63af980f6f996c99"/><file name="Response.php" hash="695c80ce5ee4e8dc38c78d0349e1f31b"/><file name="UrlBuilder.php" hash="6f468178b95a96f6217f44f9ef392cfb"/></dir><file name="Utf8EncodingConverter.php" hash="1cb05e6f174e36ed3cce6e2a7eb987ed"/><file name="XmlConfiguration.php" hash="faafd887682d6aa01f61604df24df277"/></dir><dir name="Custom"><file name=".gitignore" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><dir name="Data"><file name="AdvisorAnswer.php" hash="55ffe5c6f8e1363d1d02875feec202d1"/><file name="AdvisorQuestion.php" hash="baa784c529640f2976b22262ec6f8983"/><file name="AfterSearchNavigation.php" hash="f1d08832e73cf45b8a35d99020aa49ea"/><file name="ArticleNumberSearchStatus.php" hash="da1966d4016c32ea492b8b6b931d8222"/><file name="BreadCrumb.php" hash="84b69c8df53c6d9eb721950a29e4a84d"/><file name="BreadCrumbTrail.php" hash="324bb6a06c0058e53c58bd3f96fe0ff3"/><file name="BreadCrumbType.php" hash="c9c3568bbfa4989517ee8f3b9c779fa2"/><file name="Campaign.php" hash="23966a3bea56ac66ff2b795e11983c6a"/><file name="CampaignIterator.php" hash="503766bc960efe69e861c2f45dce77d2"/><file name="Filter.php" hash="aafda20fe7c992af46316d74be33ec73"/><file name="FilterGroup.php" hash="8820c34c807044489682a290e86466b6"/><file name="FilterSelectionType.php" hash="bd0d0676af5d0182f6b6631e6df8ecb9"/><file name="FilterStyle.php" hash="1299441866fb075e331d2f9ca2755091"/><file name="FilterType.php" hash="b073cf2f411298509337808624666687"/><file name="Item.php" hash="b91116ddeb81c0b90e76a2a4f7b51261"/><file name="Page.php" hash="35daab87fdc5e3b4732480996b982364"/><file name="Paging.php" hash="1b06374d761489582de08551f17a58a1"/><file name="Record.php" hash="cd62198f27ebbb1e0a88008642c7157a"/><file name="Result.php" hash="01b94e91b11b61d794fb9ff40d6148d3"/><file name="ResultsPerPageOptions.php" hash="ae22d184bf43cd7b11cad567489a2261"/><file name="SearchParameters.php" hash="e8e1f9d24396f864f0367c9c6d575a37"/><file name="SearchStatus.php" hash="356fd9774c237a0e26ac85a6186bccfd"/><file name="SingleWordSearchItem.php" hash="db057d7f0460f29c5b31ab9689b3906b"/><file name="SliderFilter.php" hash="344d226acde13ec85f59d5a97cf8afc5"/><file name="Sorting.php" hash="284b4811c99ad057d08caead45ea2dee"/><file name="SortingDirection.php" hash="ec86bc437928a4aa623a8c098c94f435"/><file name="SortingItem.php" hash="428e8c59a5372cafc5ec69bf868dea18"/><file name="SortingItems.php" hash="4fd36b79ed02099265103e1e81c71557"/><file name="SuggestQuery.php" hash="4011313cfd853eace88c399444ffa4cc"/><file name="TagQuery.php" hash="a4460d5e8a9f918eea820a029dc21290"/></dir><file name="Loader.php" hash="cf900585b0fd44978f97e7a2b2279a99"/><dir name="Util"><file name="Curl.php" hash="c9cbe7b2116dd6160b8db3a14b634561"/><file name="CurlHandle.php" hash="bea42fdebc33e31cf58889de18232d3e"/><file name="CurlInterface.php" hash="1858bc215b7706ba81ff6e14aa2f4750"/><file name="CurlMultiHandle.php" hash="2085a5a09c218971412a44c0dad6bf72"/><file name="CurlStub.php" hash="555c36a9a5352e1a6acfd65a68cf911b"/><file name="Log4PhpLogger.php" hash="d232fe476b310ec8692877edddc972e4"/><file name="LoggerInterface.php" hash="36dfa3ee8a089595ef285806d0068b27"/><file name="NullLogger.php" hash="51e1a2a9c89a9efba49d0a0d3ee9325d"/><file name="Parameters.php" hash="6bb6f333d55dd7bce2a0014f10edbc29"/><file name="Pimple.php" hash="fb5e70660a5fe56edfdf11bec1ba6009"/></dir></dir><dir name="FACTFinderCustom"><file name="Configuration.php" hash="93832ed3840c5899c9c761c702dec17b"/></dir><dir name="log4php"><file name="Logger.php" hash="39841035ea058cc62571fcb9b4f3aa43"/><file name="LoggerAppender.php" hash="a8b07b24ee26931cef9373163542128a"/><file name="LoggerAppenderPool.php" hash="7e44ee58fbd3c50ae51c98742aa4f327"/><file name="LoggerAutoloader.php" hash="5aa85dd61ff00167d2b9d482bf418c77"/><file name="LoggerConfigurable.php" hash="4c89cbf3c90a724930c6d46995da16bd"/><file name="LoggerConfigurator.php" hash="b8ac801c410e0515fbd5ec6b67dfb40b"/><file name="LoggerException.php" hash="c91fd8cc5bfee3cad373f8ed9440458c"/><file name="LoggerFilter.php" hash="39b6689eeb15e468781c0a62a8f482b5"/><file name="LoggerHierarchy.php" hash="be16af259ec43bef5c49bd1118e94859"/><file name="LoggerLayout.php" hash="7c089f20f7abba10699de2bd4423af7c"/><file name="LoggerLevel.php" hash="f380928eb1aac5ade3d7654f200ebb81"/><file name="LoggerLocationInfo.php" hash="33f1a195cfdcc7ebf681a3085eb6b228"/><file name="LoggerLoggingEvent.php" hash="f227e5ae0d04fef3a36899906d4ad478"/><file name="LoggerMDC.php" hash="64868651982829e59d3b316498145a79"/><file name="LoggerNDC.php" hash="482045e33b9fe22e53269c021cbfe877"/><file name="LoggerReflectionUtils.php" hash="174b22dd241ba4263aba8d978d37959f"/><file name="LoggerRoot.php" hash="0d762ed21fdff2708adab3068b94c2c3"/><file name="LoggerThrowableInformation.php" hash="76d98d20d55cf0e3bd4b1b138023c3af"/><dir name="appenders"><file name="LoggerAppenderConsole.php" hash="5eefc20589c86b11d2832f9a8fafa44f"/><file name="LoggerAppenderDailyFile.php" hash="f97b57f6b0b9dba2f650ae5e17d9f28b"/><file name="LoggerAppenderEcho.php" hash="76824ae7be6503e8c5ca3a9fc15b7816"/><file name="LoggerAppenderFile.php" hash="92481c41d6f9d3d2cf6cfc82c7c0ef22"/><file name="LoggerAppenderFirePHP.php" hash="1eccdf817ff2e0204265a5a77901f0a1"/><file name="LoggerAppenderMail.php" hash="a23d71d709af265b20797eeb0d71911e"/><file name="LoggerAppenderMailEvent.php" hash="f853e9e18511ab18873484882c744655"/><file name="LoggerAppenderMongoDB.php" hash="494b30e44a3add5eeb9c0d54ea88c29b"/><file name="LoggerAppenderNull.php" hash="ec6ca85fadc4d71f75b5e8e13df6e058"/><file name="LoggerAppenderPDO.php" hash="4388d8e542fe680228365ffd48d8ab6d"/><file name="LoggerAppenderPhp.php" hash="9853767b74b8234361ace83867c9f18d"/><file name="LoggerAppenderRollingFile.php" hash="5bc49b8f05b36842b800d699bfe05e45"/><file name="LoggerAppenderSocket.php" hash="6111536426fdf6f8a4adafb460510301"/><file name="LoggerAppenderSyslog.php" hash="afda0ccf876a87781e58d63104519bdc"/></dir><dir name="configurators"><file name="LoggerConfigurationAdapter.php" hash="b07bade9ae4809776742d3b36ca4feb7"/><file name="LoggerConfigurationAdapterINI.php" hash="bfbca46c36693f098334699c7b71b569"/><file name="LoggerConfigurationAdapterPHP.php" hash="9f9c0bd65cda5224c8e90726baebb363"/><file name="LoggerConfigurationAdapterXML.php" hash="42ec1e713dadb1c6c813df278e6c58cb"/><file name="LoggerConfiguratorDefault.php" hash="a27dd348466a605849ffa946a5fa7bdf"/></dir><dir name="filters"><file name="LoggerFilterDenyAll.php" hash="8800e84c773b87e2638d22d627baae51"/><file name="LoggerFilterLevelMatch.php" hash="2ea447c40baea629486a6b7a4f8f352d"/><file name="LoggerFilterLevelRange.php" hash="b4b6753e0d0a8d734471482bb7b4981c"/><file name="LoggerFilterStringMatch.php" hash="342113e5152ef6e9703807fa36e52785"/></dir><dir name="helpers"><file name="LoggerFormattingInfo.php" hash="89a5ed8f751e4a6a826275619266b911"/><file name="LoggerOptionConverter.php" hash="e02f5ffc3918a0352bf77121e5add1d5"/><file name="LoggerPatternParser.php" hash="a5d4dfeb2a66b022380e0e3d7ba9b318"/><file name="LoggerUtils.php" hash="90264a3263bc4e3a3dac1dbeb3cc35df"/></dir><dir name="layouts"><file name="LoggerLayoutHtml.php" hash="cf6066b51d7ac2de4accaf13f68fb442"/><file name="LoggerLayoutPattern.php" hash="10c48d2fa44953d20fcb3e3542a05ebf"/><file name="LoggerLayoutSerialized.php" hash="cef71f72176167a15c79f5cab5515a77"/><file name="LoggerLayoutSimple.php" hash="ba2aaa713c715b823c4e767a2f0b3e67"/><file name="LoggerLayoutTTCC.php" hash="1ecb0af018b78ad42f4a9d70e182f429"/><file name="LoggerLayoutXml.php" hash="b52409dbb1bacc1c7b4c5ddf66ed8afa"/></dir><dir name="pattern"><file name="LoggerPatternConverter.php" hash="fcbd56bf082b96f02fcf5b0b552de4c1"/><file name="LoggerPatternConverterClass.php" hash="e61c2f7544feee8ee9b966311471a2a7"/><file name="LoggerPatternConverterCookie.php" hash="465d359167443336f258d9b5a89095ef"/><file name="LoggerPatternConverterDate.php" hash="4a399075a3c2d7542e3c649f55162482"/><file name="LoggerPatternConverterEnvironment.php" hash="829265aa84843818bd9faf3bd42b0432"/><file name="LoggerPatternConverterFile.php" hash="a7091f0857b99db4e00c33b61df5e3d3"/><file name="LoggerPatternConverterLevel.php" hash="6219dcb0d8630e6f69cbf4ba669fd11f"/><file name="LoggerPatternConverterLine.php" hash="a27bf38b5c6453a9925d365bde65fe47"/><file name="LoggerPatternConverterLiteral.php" hash="a2cd9e35ca6253cde6a467320837a767"/><file name="LoggerPatternConverterLocation.php" hash="b88efadaccdf31b25b1fb14866c106a0"/><file name="LoggerPatternConverterLogger.php" hash="4342ab32fa26cdf53308896272c2e36b"/><file name="LoggerPatternConverterMDC.php" hash="d241043bc9ea9ecdbf3a0ae5d5a42206"/><file name="LoggerPatternConverterMessage.php" hash="cad3040a1a3d1d40dc6a26727bebe19d"/><file name="LoggerPatternConverterMethod.php" hash="3208fb30a3bc0a7e0fb281800c43ecef"/><file name="LoggerPatternConverterNDC.php" hash="2e68ba79896c47c5067bbf0b371df260"/><file name="LoggerPatternConverterNewLine.php" hash="291bd541e0f689484a5596323e3cac14"/><file name="LoggerPatternConverterProcess.php" hash="7421d9b9b6a5f8f51c3a9a1c796911a5"/><file name="LoggerPatternConverterRelative.php" hash="24495b25867aac190135610061cd244d"/><file name="LoggerPatternConverterRequest.php" hash="67a484d44fd7ddc06a654995904e9653"/><file name="LoggerPatternConverterServer.php" hash="bef42f8b51bc220453e3f4b1e67e7402"/><file name="LoggerPatternConverterSession.php" hash="7cd6290d364837cd2ff4358c03022e98"/><file name="LoggerPatternConverterSessionID.php" hash="fc7b37aa3cb28fbb09862eb7edc6d042"/><file name="LoggerPatternConverterSuperglobal.php" hash="6b984fb3d26fb0186595370d0f066659"/><file name="LoggerPatternConverterThrowable.php" hash="4ca10f0f20408a30243ff589415634c9"/></dir><dir name="renderers"><file name="LoggerRenderer.php" hash="332819a947805d55c2aa546ced274f01"/><file name="LoggerRendererDefault.php" hash="4c4003cde8e0a74cc562060ca7bccf61"/><file name="LoggerRendererException.php" hash="4b2def2de9aa459bd321e826c02e31c2"/><file name="LoggerRendererMap.php" hash="b9aadee6f31f7cb38210653141b94fa6"/></dir><dir name="xml"><file name="log4php.dtd" hash="fb7e60edf02964352b7ddee1f26d8924"/></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="factfinder"><file name="asn.xml" hash="05ee1b7d0d34d7e43de8c115aeaab69d"/><file name="campaigns.xml" hash="d722ded27e895f0f0aa15954c46f93f3"/><file name="core.xml" hash="fe920d8ef444afbcfa2053b72bc819fc"/><file name="suggest.xml" hash="9c1a761044cd33da5e028c92ce9abe4f"/><file name="tagcloud.xml" hash="0d31f54985019d96bb1b5af17ccdf0d3"/><file name="tracking.xml" hash="53ce8afeb32391a4b207121a372162a2"/></dir></dir><dir name="template"><dir name="factfinder"><dir name="asn"><dir name="layer"><dir name="filter"><file name="slider.phtml" hash="2004f809f803e17d9739a7173958ceca"/></dir><file name="slider.phtml" hash="d48c9aace222c7525430b5235acd4026"/></dir></dir><dir name="campaigns"><file name="advisory.phtml" hash="3341ee58f81da41020f85c2145048b8b"/><file name="feedback.phtml" hash="4c1868f038a13bd2ca270b7d9a077452"/><file name="pushed.phtml" hash="b76b7c5b064ee6dc86ccc94a363bdb05"/></dir><dir name="core"><dir name="export"><file name="locked.phtml" hash="f0948f48fcc40dfcb21a8da68ce29425"/><file name="nofile.phtml" hash="c304b037812f4c34d7e094fe3b70cd80"/></dir></dir><dir name="suggest"><file name="advancedsuggest.phtml" hash="9f74281e6e75d1d3aec83d5d7f026c17"/></dir><dir name="tracking"><file name="click.phtml" hash="3e545af810a201db7c76c0502f606308"/><file name="recommendation.phtml" hash="02dba2d0cc5e1608682a700916a963d8"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="."><file name="factfinder.xml" hash="f87803fd5c96fc784baff992c2bce96b"/></dir><dir name="modules"><file name="FACTFinder_Asn.xml" hash="a003a8010c577c396c8e2ee5b1ea4417"/><file name="FACTFinder_Campaigns.xml" hash="ccd3080cf57535193a6fe2e6946640fd"/><file name="FACTFinder_Core.xml" hash="80f5142c2acf5ceeca0fd552ddb7ce4c"/><file name="FACTFinder_Recommendation.xml" hash="9742344545ee435a4dc87eb2bb80bf19"/><file name="FACTFinder_Suggest.xml" hash="882806b936029f0ef04d4719542ecea3"/><file name="FACTFinder_Tagcloud.xml" hash="62d3ccec2191e7dfd8225e02912891d2"/><file name="FACTFinder_Tracking.xml" hash="779b734bdcafabab072a1afd9d0bf7c4"/></dir></target><target name="mage"><dir name="shell"><file name="factfinder.php" hash="f5d0ef5e78c29b1e700c822d2c2d491c"/></dir></target><target name="mageweb"><dir name="js"><dir name="factfinder"><file name="jXHR.js" hash="a62424da9902b49a76659683121618d0"/><file name="suggest.js" hash="fcae24ad674632753fc4e14e1c4d6d6c"/><file name="tracking.js" hash="f22da039733a2c67254d41cfa5e6ea9b"/></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="js"><dir name="factfinder_onetouchslider"><file name="234A0ACCECB3C19247FA8B7920453761.cache.js" hash="df488d926e6054769d4731148e707b58"/><file name="25E490B929D7CDBF44085E4E4D9D6F78.cache.js" hash="2a017b95cfbd8653a222660b60697419"/><file name="53ABFAE8983A4589B497F48695DB2A7C.cache.js" hash="b6b02347438384cc886b2509426826b5"/><file name="75B23D057185BAB61CFE100CE08C4D84.cache.js" hash="ec9c94e05e64372a9636ef03e688d451"/><file name="79DD9AE9135ADFDE204324DA7F1B1405.cache.png" hash="6ba720deee377e093c5f5b0423c152df"/><file name="9F0D0456482D7A7A901A2CD8F64EA019.cache.js" hash="dad64db53266865af02c620795c6ab13"/><file name="clear.cache.gif" hash="6d22e4f2d2057c6e8d6fab098e76e80f"/><file name="de.factfinder.asn.slider.OneTouchSlider.nocache.js" hash="f92d47fc9eb8cf8ff78173997f5a4a7a"/></dir></dir><dir name="css"><file name="factfinder_suggest.css" hash="1a8a97d65582535cbc74c5599fcb34e1"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="de_DE"><file name="FACTFinder_Suggest.csv" hash="3098dfae8ccf75366dfa093ce5c863f2"/></dir><dir name="en_US"><file name="FACTFinder_Suggest.csv" hash="2e9fd7bbc9407364430a7c281c94ec63"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.3.0</min><max>7.1.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Flagbit_Factfinder</name>
4
+ <version>4.1.11</version>
5
  <stability>stable</stability>
6
  <license uri="https://opensource.org/licenses/MIT">MIT</license>
7
  <channel>community</channel>
8
  <extends/>
9
+ <summary>4.1.11 Release</summary>
10
+ <description>4.1.11 Release</description>
11
  <notes>Release</notes>
12
  <authors><author><name>FACTFinder</name><user>FACT_Finder</user><email>info@flagbit.de</email></author></authors>
13
+ <date>2016-11-12</date>
14
+ <time>12:15:06</time>
15
+ <contents><target name="magecommunity"><dir name="FACTFinder"><dir name="Asn"><dir name="Block"><dir name="Catalog"><dir name="Layer"><file name="Factfinder.php" hash="0e79d252a2752aab67f7490436350fe7"/><file name="State.php" hash="2bf2c99237e881372fdc074c3505d188"/></dir><dir name="Product"><dir name="List"><file name="Toolbar.php" hash="9b0c98e266174c8f8b02b896a556b769"/></dir><file name="Pager.php" hash="ec87967ba312a3d589e0af0afbacdd0a"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="668be3edd4c8f6d0e051252d2e52d545"/></dir><dir name="Model"><dir name="Catalog"><file name="Layer.php" hash="6dafe882395b5d09f84c102f3b785410"/></dir><dir name="Handler"><file name="Search.php" hash="bbec7bd87e1d2f15792fdda46f34eb52"/></dir><dir name="Layer"><dir name="Filter"><file name="Factfinder.php" hash="2666ae9c79aa939e9539a1af5b0f7784"/><file name="Item.php" hash="a68545b4cb4487691ae75cdbf47af377"/></dir></dir><file name="Observer.php" hash="9ec46432b3d3170b626cfb4439315209"/><dir name="Resource"><dir name="Product"><dir name="Attribute"><file name="Collection.php" hash="03b060fd637de1fd632f1b9784b1124c"/></dir></dir><dir name="Search"><file name="Collection.php" hash="3e7a88eb53ccfb79b4448f9eb7bd4177"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="e07b890b06b00d94bc4a4a5931325366"/><file name="system.xml" hash="7a8a776e911a831b401900dbf9529b68"/></dir></dir><dir name="Campaigns"><dir name="Block"><file name="Abstract.php" hash="cbb92e501e5576dcc5ec121a708850a6"/><dir name="Advisory"><file name="Search.php" hash="1d4bf82a7baffbe64be17216436c35d4"/></dir><dir name="Feedback"><file name="Abstract.php" hash="018e415bdd754127cfad8bfa5881c0ce"/><file name="Cart.php" hash="35f9fec2518383c909495af90b324b8b"/><file name="Page.php" hash="b791d428663177b38acf568b424f9b62"/><file name="Product.php" hash="be7d867bb4d19510977ad6451918a110"/><file name="Search.php" hash="ebf3d35f6425b771291b08f696169d04"/></dir><dir name="Pushed"><file name="Abstract.php" hash="6dc968f84fb74d615e1441a3a18f34b7"/><file name="Cart.php" hash="741d3bd71ce91cd583778a5e26be9ff5"/><file name="Page.php" hash="f41d08224acf14ee5ebeb281117b43c3"/><file name="Product.php" hash="522cc331532f0e5c1b404429678d4145"/><file name="Search.php" hash="7db401a3ee1153ff5677b544fbb2a44e"/></dir></dir><dir name="Helper"><file name="Data.php" hash="92b1313e10cc6c448c6fae40fd113ba6"/></dir><dir name="Model"><file name="Facade.php" hash="44fc55139509b76f19b7c95c6a81eb4c"/><dir name="Handler"><file name="Abstract.php" hash="1784c503a2979f42dbd4e9698e482c47"/><file name="Cart.php" hash="d954c511b4f11d7f721c4117746de35a"/><file name="Page.php" hash="dcbde5a5d54da6893ccc6cbc678bfb45"/><file name="Product.php" hash="fbd9ced4527fce56144c7913af979b65"/><file name="Search.php" hash="e039a207ca98655c647355ebf287566d"/></dir><file name="Observer.php" hash="043e7411be7ec13a656b07750a7811af"/><dir name="Resource"><dir name="Pushedproducts"><file name="Collection.php" hash="569856158dee935d611ebc30f426835c"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="8f6b7cec7cff39b149beeffb39764668"/><file name="system.xml" hash="20ee896b686b17dc832a64b440d130bb"/></dir></dir><dir name="Core"><dir name="Block"><dir name="Adminhtml"><file name="Exportlink.php" hash="7a845ee8974cfcf74d9a32fed2ac0b21"/><dir name="Form"><dir name="Field"><file name="Attribute.php" hash="bea2183e56100233e7aebaccd6680c6f"/><file name="Attributes.php" hash="292742f954dec1863caaee9313a237c9"/></dir></dir></dir><dir name="Catalog"><dir name="Product"><dir name="List"><file name="Toolbar.php" hash="814a8b4935563e53db5f4e3b0a2b926e"/></dir><file name="Pager.php" hash="931dea1213da57df14fea950a5cacf43"/></dir></dir><dir name="CatalogSearch"><file name="Layer.php" hash="ad3dcdd26b5a723e43c7b8011a4ea25f"/></dir><dir name="EnterpriseSearch"><file name="Layer.php" hash="19455e36be3e0c14cabba762ccbdef1a"/></dir></dir><dir name="Helper"><file name="Backend.php" hash="f30c89ca668b193a8fc8bf00eda34413"/><file name="Data.php" hash="5f9e4fe2269743ac3ee81e3e1dc16b1e"/><file name="Debug.php" hash="c563d343c68db980e9256dc510e78ea1"/><file name="Export.php" hash="a417ba066deafb92cccb2256b6ca6932"/><file name="Rewrite.php" hash="30921c0924e535d669ecdd7e9592f883"/><file name="Search.php" hash="fd1e90271d620c57a0cb7b80e33f536f"/></dir><dir name="Model"><file name="Autoloader.php" hash="29370ccbcd483f93be86999485889900"/><dir name="CatalogSearch"><file name="Layer.php" hash="8d15e27cca249cd3827d33e9acdbb369"/><file name="Query.php" hash="4f5b732eb28a7c1efde28eb602c38772"/></dir><dir name="Export"><file name="Observer.php" hash="66968e7d4d8f1baa556e5955b27517dc"/><file name="Semaphore.php" hash="63def987da73dc369580845149bdba25"/><dir name="Type"><file name="Interface.php" hash="b29c7b7319fa52783eb546aabf5cb6e9"/><file name="Price.php" hash="47feaf492e4dec15f8a207a8e6f8104c"/><file name="Product.php" hash="121436b15485de7e052410f5fcbb8787"/><file name="Stock.php" hash="0e7b89cf2868569ce449c7736f544d27"/></dir></dir><file name="Facade.php" hash="b2fd0c05a687db4c784111ecb4da9ef8"/><dir name="File"><dir name="Validator"><file name="Abstract.php" hash="bae31d36c5307014bece14d3a0c18b79"/><file name="Price.php" hash="38a6be7fb1f41f4682eb1daa38554669"/><file name="Product.php" hash="31cf15e2204bb5a50136a06089d18afe"/><file name="Stock.php" hash="0dd23287ff233398f0d65106cccca029"/></dir></dir><file name="File.php" hash="ea54b7088ddb35c778a65ce97cfcd242"/><file name="Ftp.php" hash="d70cfab0ce607aca6efa32d82d3a85c3"/><dir name="Handler"><file name="Abstract.php" hash="1924821d13996f9f672369b63a05ac08"/><file name="Search.php" hash="303ba490e7113794e7398e457e645f31"/><file name="Status.php" hash="a70285cfc99c388ba826e501c0411a83"/></dir><file name="Observer.php" hash="e5decfa3b52571cb75335dd41b1927f5"/><dir name="Resource"><file name="Export.php" hash="4cf2df31bcfeb468f64b42d9140d7c86"/><file name="Fulltext.php" hash="dfbece11e5fe8224c94d1e1bb7affe3e"/><dir name="Search"><file name="Collection.php" hash="50596cf9508d0d96a4bb315a50f35984"/><file name="Engine.php" hash="602547a2d224f80933b6681db1cb3cc4"/></dir></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Attributes.php" hash="d877a4da13c592f5b8260b202bcead13"/><file name="Cron.php" hash="f24b6995fea6309acb720876f3156270"/><file name="Enabled.php" hash="cb13a29b7100518350a7e5830180e9bd"/><file name="Engine.php" hash="ef1f702d79c7ed0fe72437ca4bf13a19"/></dir><dir name="Source"><file name="Authtype.php" hash="7ce07da0f6bcb8e88b5699ace77e6f31"/><file name="Engine.php" hash="8f1c2f344aa3182c312a665488661fa5"/><file name="Identifier.php" hash="a80606fe94b2eaf78f8d07628f2a64f0"/><file name="Protocol.php" hash="310b7fd8648b60f5cc9c3e3c9f87345c"/></dir></dir></dir><file name="Url.php" hash="57e5e87457b3051cec9bc3c988f79282"/></dir><dir name="controllers"><file name="ExportController.php" hash="231a148e48c714363a5d0bd76b088853"/></dir><dir name="etc"><file name="adminhtml.xml" hash="0247e1b846aefb3fb9c5c0706681a586"/><file name="config.xml" hash="471974367bce221b6795be5f4015a6e9"/><file name="system.xml" hash="06071fe8f0a5c18f2f895e0b8d9c0914"/></dir></dir><dir name="Recommendation"><dir name="Helper"><file name="Data.php" hash="6312dfdef17070694f59139acbb2d5e1"/></dir><dir name="Model"><file name="Facade.php" hash="ed9c246bc831c7f3950a88853d401288"/><dir name="Handler"><file name="Recommendations.php" hash="f5645b78a6dca466af5b22ff0456ca71"/></dir><file name="Observer.php" hash="50cfe5f830cfd50c26061b7497f7e1a6"/></dir><dir name="etc"><file name="config.xml" hash="03ec96e0fa78fdfbc3d4d5fac7193704"/><file name="system.xml" hash="f841228bf8a5397fe18da6186c5e3208"/></dir></dir><dir name="Suggest"><dir name="Block"><file name="TopSearch.php" hash="96fc7e73d907a0438111253ae6c5fc6f"/><dir name="XmlConnect"><dir name="Catalog"><dir name="Search"><file name="Suggest.php" hash="150658cb1d7bc7ae5b4566ed1331bb12"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="ce3b53789b0bf025874a36789228abe5"/></dir><dir name="Model"><file name="Facade.php" hash="254f13fa4cbbe9602ae40c5cd124282e"/><dir name="Handler"><file name="Suggest.php" hash="948fd13668d507ba4ebed7c9a2055be4"/></dir><file name="Observer.php" hash="3a5bed9bd7b7c9bac85446c9172dfa48"/><file name="Processor.php" hash="f37cf3fb0c72464f1e651f34d64b44dd"/><dir name="System"><dir name="Config"><dir name="Source"><file name="Imagetype.php" hash="a8a39dc5d44080a3b070bc72f103efef"/></dir></dir></dir></dir><dir name="controllers"><file name="ProxyController.php" hash="68fc8cee37a52a538762252e47f340a1"/></dir><dir name="etc"><file name="config.xml" hash="5e6b384d971afc4a0c6b7cc4d437badf"/><file name="system.xml" hash="4cc10555be3b56982c6d67671c54f57b"/></dir></dir><dir name="Tagcloud"><dir name="Block"><file name="TagCloud.php" hash="d0c6c681b3da27ef349ff1295c5e26a9"/></dir><dir name="Helper"><file name="Data.php" hash="ea2c8093a1d87a8148f1205e8b73cc2d"/></dir><dir name="Model"><file name="Facade.php" hash="69069badc93509011f7c4fa2b1ca3e72"/><dir name="Handler"><file name="TagCloud.php" hash="e2e5ba229002ad3cfa5769a9f74d808b"/></dir></dir><dir name="etc"><file name="config.xml" hash="3ff00cc34fdbaed962f704204ce47f1a"/></dir></dir><dir name="Tracking"><dir name="Block"><file name="Abstract.php" hash="24419c96d9768b86ec890a1b38278e0f"/><file name="Click.php" hash="9fe6720543830930d97d7eb16f7fb489"/><file name="Recommendation.php" hash="aab0b759394df3f5e3571bb4e3e46cc2"/></dir><dir name="Helper"><file name="Data.php" hash="f0018ce83f815b057fab66351e58fdb6"/></dir><dir name="Model"><file name="Facade.php" hash="f8684a20a82bff4b668af460af476d41"/><dir name="Handler"><file name="Tracking.php" hash="9672d838ac3775c8a7dc4ef70593ca7e"/></dir><file name="Observer.php" hash="2ca991675d96e50d43d52b3e3e477b52"/><file name="Processor.php" hash="cf9d0d242166aab8eab66a8fdb7c952a"/><file name="Queue.php" hash="046d6d464d56a609b71574c6e0a3c4d1"/><dir name="Resource"><dir name="Queue"><file name="Collection.php" hash="daecedd55cb992ae3988305324c8c1b9"/></dir><file name="Queue.php" hash="3be1d09978ae6e8c56fb673931b05479"/></dir></dir><dir name="controllers"><file name="ProxyController.php" hash="33f25104bc086fcbe998459baccdd0b3"/></dir><dir name="etc"><file name="config.xml" hash="9fb1f1e9ed5d4098a4d8949299657caf"/><file name="system.xml" hash="2358dd767b2350084c83e2cf6aa360d3"/></dir><dir name="sql"><dir name="factfinder_tracking_setup"><file name="install-1.0.0.php" hash="553ad063abd837a220ebff97618578b4"/><file name="upgrade-1.0.0-4.1.2.php" hash="a80b4f755d0bea172eefebe10b877cd6"/><file name="upgrade-4.1.2-4.1.11.php" hash="7cdc830ef2799954e5ab4093d65a1f0e"/></dir></dir></dir></dir></target><target name="magelib"><dir name="FACTFinder"><dir name="Adapter"><file name="AbstractAdapter.php" hash="91eae466a803590699160600c430eab6"/><file name="Compare.php" hash="6b7cbae461ef45587c565affadbf8664"/><file name="ConfigurableResponse.php" hash="8ffa7eaa12d448a7bd4a9bba9975c573"/><file name="Import.php" hash="584eecdb7281603ba5ef901082fb52d7"/><file name="PersonalisedResponse.php" hash="6b62c326d25e123f686baa358a1b258b"/><file name="ProductCampaign.php" hash="945181a15218fd90721d3258eaf2fd17"/><file name="Recommendation.php" hash="0bcc4ccce41f40d343ebe19c901bea69"/><file name="Search.php" hash="202f3e5d444edb8be0b4e187bd98ea78"/><file name="SimilarRecords.php" hash="b80691760f993d2a43cbe2eb933090fe"/><file name="Suggest.php" hash="5f91090f7c7ea764f9fc21938aade3c8"/><file name="TagCloud.php" hash="fe1faf30373e91b96e57c08fb64df23a"/><file name="Tracking.php" hash="18948f9db1782730258a0e83f6f517b9"/></dir><dir name="Core"><file name="AbstractConfiguration.php" hash="d9341f7f13615a8a0c2805b2021cdfc8"/><file name="AbstractEncodingConverter.php" hash="7946720c77c47e3ed2070606a74a48cb"/><file name="ArrayConfiguration.php" hash="dc60873fa6eed180126944247cb4de99"/><dir name="Client"><file name="RequestParser.php" hash="bc5dabb648f7278db4a1c5f14af4dfa0"/><file name="UrlBuilder.php" hash="d73cc166fcf20b7623ea0f7c319d3224"/></dir><file name="ConfigurationInterface.php" hash="1158aaee6a7502cf81bf27b8ed0c76ff"/><file name="IConvEncodingConverter.php" hash="5c504a3229cc8a59c09f03f3bf2c9348"/><file name="ManualConfiguration.php" hash="a49d0b05cc319b807c40b37a861b060d"/><dir name="Page"><file name=".gitignore" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><file name="ParametersConverter.php" hash="9c01642c6de1842b8f1b4e8d9f93017e"/><dir name="Server"><file name="AbstractDataProvider.php" hash="8d33ddebe3d3e60b72893188d7f2369f"/><file name="ConnectionData.php" hash="c4246099ec93e7f589c0e22179d9557a"/><file name="EasyCurlDataProvider.php" hash="48f452cd3ca1dcf3b4e7cc4d8b59c8a9"/><file name="EasyCurlRequestFactory.php" hash="61f88e882120dca5e5e1964d1f898527"/><file name="FileSystemDataProvider.php" hash="30b428e2b76307b1143057a155371c34"/><file name="FileSystemRequestFactory.php" hash="f0a464725448393e64948a6063208d91"/><file name="MultiCurlDataProvider.php" hash="2e467a4976694ef4e7775d913dafedf4"/><file name="MultiCurlRequestFactory.php" hash="41f978e0dd60065026dc5adced1f9503"/><file name="NullResponse.php" hash="3a419c1ea234ef20e1330c7b445eb9c6"/><file name="Request.php" hash="08ddaaa7701558e1802408089d15b5dd"/><file name="RequestFactoryInterface.php" hash="65cfad6045407bdd63af980f6f996c99"/><file name="Response.php" hash="695c80ce5ee4e8dc38c78d0349e1f31b"/><file name="UrlBuilder.php" hash="6f468178b95a96f6217f44f9ef392cfb"/></dir><file name="Utf8EncodingConverter.php" hash="1cb05e6f174e36ed3cce6e2a7eb987ed"/><file name="XmlConfiguration.php" hash="faafd887682d6aa01f61604df24df277"/></dir><dir name="Custom"><file name=".gitignore" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><dir name="Data"><file name="AdvisorAnswer.php" hash="55ffe5c6f8e1363d1d02875feec202d1"/><file name="AdvisorQuestion.php" hash="baa784c529640f2976b22262ec6f8983"/><file name="AfterSearchNavigation.php" hash="f1d08832e73cf45b8a35d99020aa49ea"/><file name="ArticleNumberSearchStatus.php" hash="da1966d4016c32ea492b8b6b931d8222"/><file name="BreadCrumb.php" hash="84b69c8df53c6d9eb721950a29e4a84d"/><file name="BreadCrumbTrail.php" hash="324bb6a06c0058e53c58bd3f96fe0ff3"/><file name="BreadCrumbType.php" hash="c9c3568bbfa4989517ee8f3b9c779fa2"/><file name="Campaign.php" hash="23966a3bea56ac66ff2b795e11983c6a"/><file name="CampaignIterator.php" hash="503766bc960efe69e861c2f45dce77d2"/><file name="Filter.php" hash="aafda20fe7c992af46316d74be33ec73"/><file name="FilterGroup.php" hash="8820c34c807044489682a290e86466b6"/><file name="FilterSelectionType.php" hash="bd0d0676af5d0182f6b6631e6df8ecb9"/><file name="FilterStyle.php" hash="1299441866fb075e331d2f9ca2755091"/><file name="FilterType.php" hash="b073cf2f411298509337808624666687"/><file name="Item.php" hash="b91116ddeb81c0b90e76a2a4f7b51261"/><file name="Page.php" hash="35daab87fdc5e3b4732480996b982364"/><file name="Paging.php" hash="1b06374d761489582de08551f17a58a1"/><file name="Record.php" hash="cd62198f27ebbb1e0a88008642c7157a"/><file name="Result.php" hash="01b94e91b11b61d794fb9ff40d6148d3"/><file name="ResultsPerPageOptions.php" hash="ae22d184bf43cd7b11cad567489a2261"/><file name="SearchParameters.php" hash="e8e1f9d24396f864f0367c9c6d575a37"/><file name="SearchStatus.php" hash="356fd9774c237a0e26ac85a6186bccfd"/><file name="SingleWordSearchItem.php" hash="db057d7f0460f29c5b31ab9689b3906b"/><file name="SliderFilter.php" hash="344d226acde13ec85f59d5a97cf8afc5"/><file name="Sorting.php" hash="284b4811c99ad057d08caead45ea2dee"/><file name="SortingDirection.php" hash="ec86bc437928a4aa623a8c098c94f435"/><file name="SortingItem.php" hash="428e8c59a5372cafc5ec69bf868dea18"/><file name="SortingItems.php" hash="4fd36b79ed02099265103e1e81c71557"/><file name="SuggestQuery.php" hash="4011313cfd853eace88c399444ffa4cc"/><file name="TagQuery.php" hash="a4460d5e8a9f918eea820a029dc21290"/></dir><file name="Loader.php" hash="cf900585b0fd44978f97e7a2b2279a99"/><dir name="Util"><file name="Curl.php" hash="c9cbe7b2116dd6160b8db3a14b634561"/><file name="CurlHandle.php" hash="bea42fdebc33e31cf58889de18232d3e"/><file name="CurlInterface.php" hash="1858bc215b7706ba81ff6e14aa2f4750"/><file name="CurlMultiHandle.php" hash="2085a5a09c218971412a44c0dad6bf72"/><file name="CurlStub.php" hash="555c36a9a5352e1a6acfd65a68cf911b"/><file name="Log4PhpLogger.php" hash="d232fe476b310ec8692877edddc972e4"/><file name="LoggerInterface.php" hash="36dfa3ee8a089595ef285806d0068b27"/><file name="NullLogger.php" hash="51e1a2a9c89a9efba49d0a0d3ee9325d"/><file name="Parameters.php" hash="6bb6f333d55dd7bce2a0014f10edbc29"/><file name="Pimple.php" hash="fb5e70660a5fe56edfdf11bec1ba6009"/></dir></dir><dir name="FACTFinderCustom"><file name="Configuration.php" hash="93832ed3840c5899c9c761c702dec17b"/></dir><dir name="log4php"><file name="Logger.php" hash="39841035ea058cc62571fcb9b4f3aa43"/><file name="LoggerAppender.php" hash="a8b07b24ee26931cef9373163542128a"/><file name="LoggerAppenderPool.php" hash="7e44ee58fbd3c50ae51c98742aa4f327"/><file name="LoggerAutoloader.php" hash="5aa85dd61ff00167d2b9d482bf418c77"/><file name="LoggerConfigurable.php" hash="4c89cbf3c90a724930c6d46995da16bd"/><file name="LoggerConfigurator.php" hash="b8ac801c410e0515fbd5ec6b67dfb40b"/><file name="LoggerException.php" hash="c91fd8cc5bfee3cad373f8ed9440458c"/><file name="LoggerFilter.php" hash="39b6689eeb15e468781c0a62a8f482b5"/><file name="LoggerHierarchy.php" hash="be16af259ec43bef5c49bd1118e94859"/><file name="LoggerLayout.php" hash="7c089f20f7abba10699de2bd4423af7c"/><file name="LoggerLevel.php" hash="f380928eb1aac5ade3d7654f200ebb81"/><file name="LoggerLocationInfo.php" hash="33f1a195cfdcc7ebf681a3085eb6b228"/><file name="LoggerLoggingEvent.php" hash="f227e5ae0d04fef3a36899906d4ad478"/><file name="LoggerMDC.php" hash="64868651982829e59d3b316498145a79"/><file name="LoggerNDC.php" hash="482045e33b9fe22e53269c021cbfe877"/><file name="LoggerReflectionUtils.php" hash="174b22dd241ba4263aba8d978d37959f"/><file name="LoggerRoot.php" hash="0d762ed21fdff2708adab3068b94c2c3"/><file name="LoggerThrowableInformation.php" hash="76d98d20d55cf0e3bd4b1b138023c3af"/><dir name="appenders"><file name="LoggerAppenderConsole.php" hash="5eefc20589c86b11d2832f9a8fafa44f"/><file name="LoggerAppenderDailyFile.php" hash="f97b57f6b0b9dba2f650ae5e17d9f28b"/><file name="LoggerAppenderEcho.php" hash="76824ae7be6503e8c5ca3a9fc15b7816"/><file name="LoggerAppenderFile.php" hash="92481c41d6f9d3d2cf6cfc82c7c0ef22"/><file name="LoggerAppenderFirePHP.php" hash="1eccdf817ff2e0204265a5a77901f0a1"/><file name="LoggerAppenderMail.php" hash="a23d71d709af265b20797eeb0d71911e"/><file name="LoggerAppenderMailEvent.php" hash="f853e9e18511ab18873484882c744655"/><file name="LoggerAppenderMongoDB.php" hash="494b30e44a3add5eeb9c0d54ea88c29b"/><file name="LoggerAppenderNull.php" hash="ec6ca85fadc4d71f75b5e8e13df6e058"/><file name="LoggerAppenderPDO.php" hash="4388d8e542fe680228365ffd48d8ab6d"/><file name="LoggerAppenderPhp.php" hash="9853767b74b8234361ace83867c9f18d"/><file name="LoggerAppenderRollingFile.php" hash="5bc49b8f05b36842b800d699bfe05e45"/><file name="LoggerAppenderSocket.php" hash="6111536426fdf6f8a4adafb460510301"/><file name="LoggerAppenderSyslog.php" hash="afda0ccf876a87781e58d63104519bdc"/></dir><dir name="configurators"><file name="LoggerConfigurationAdapter.php" hash="b07bade9ae4809776742d3b36ca4feb7"/><file name="LoggerConfigurationAdapterINI.php" hash="bfbca46c36693f098334699c7b71b569"/><file name="LoggerConfigurationAdapterPHP.php" hash="9f9c0bd65cda5224c8e90726baebb363"/><file name="LoggerConfigurationAdapterXML.php" hash="42ec1e713dadb1c6c813df278e6c58cb"/><file name="LoggerConfiguratorDefault.php" hash="a27dd348466a605849ffa946a5fa7bdf"/></dir><dir name="filters"><file name="LoggerFilterDenyAll.php" hash="8800e84c773b87e2638d22d627baae51"/><file name="LoggerFilterLevelMatch.php" hash="2ea447c40baea629486a6b7a4f8f352d"/><file name="LoggerFilterLevelRange.php" hash="b4b6753e0d0a8d734471482bb7b4981c"/><file name="LoggerFilterStringMatch.php" hash="342113e5152ef6e9703807fa36e52785"/></dir><dir name="helpers"><file name="LoggerFormattingInfo.php" hash="89a5ed8f751e4a6a826275619266b911"/><file name="LoggerOptionConverter.php" hash="e02f5ffc3918a0352bf77121e5add1d5"/><file name="LoggerPatternParser.php" hash="a5d4dfeb2a66b022380e0e3d7ba9b318"/><file name="LoggerUtils.php" hash="90264a3263bc4e3a3dac1dbeb3cc35df"/></dir><dir name="layouts"><file name="LoggerLayoutHtml.php" hash="cf6066b51d7ac2de4accaf13f68fb442"/><file name="LoggerLayoutPattern.php" hash="10c48d2fa44953d20fcb3e3542a05ebf"/><file name="LoggerLayoutSerialized.php" hash="cef71f72176167a15c79f5cab5515a77"/><file name="LoggerLayoutSimple.php" hash="ba2aaa713c715b823c4e767a2f0b3e67"/><file name="LoggerLayoutTTCC.php" hash="1ecb0af018b78ad42f4a9d70e182f429"/><file name="LoggerLayoutXml.php" hash="b52409dbb1bacc1c7b4c5ddf66ed8afa"/></dir><dir name="pattern"><file name="LoggerPatternConverter.php" hash="fcbd56bf082b96f02fcf5b0b552de4c1"/><file name="LoggerPatternConverterClass.php" hash="e61c2f7544feee8ee9b966311471a2a7"/><file name="LoggerPatternConverterCookie.php" hash="465d359167443336f258d9b5a89095ef"/><file name="LoggerPatternConverterDate.php" hash="4a399075a3c2d7542e3c649f55162482"/><file name="LoggerPatternConverterEnvironment.php" hash="829265aa84843818bd9faf3bd42b0432"/><file name="LoggerPatternConverterFile.php" hash="a7091f0857b99db4e00c33b61df5e3d3"/><file name="LoggerPatternConverterLevel.php" hash="6219dcb0d8630e6f69cbf4ba669fd11f"/><file name="LoggerPatternConverterLine.php" hash="a27bf38b5c6453a9925d365bde65fe47"/><file name="LoggerPatternConverterLiteral.php" hash="a2cd9e35ca6253cde6a467320837a767"/><file name="LoggerPatternConverterLocation.php" hash="b88efadaccdf31b25b1fb14866c106a0"/><file name="LoggerPatternConverterLogger.php" hash="4342ab32fa26cdf53308896272c2e36b"/><file name="LoggerPatternConverterMDC.php" hash="d241043bc9ea9ecdbf3a0ae5d5a42206"/><file name="LoggerPatternConverterMessage.php" hash="cad3040a1a3d1d40dc6a26727bebe19d"/><file name="LoggerPatternConverterMethod.php" hash="3208fb30a3bc0a7e0fb281800c43ecef"/><file name="LoggerPatternConverterNDC.php" hash="2e68ba79896c47c5067bbf0b371df260"/><file name="LoggerPatternConverterNewLine.php" hash="291bd541e0f689484a5596323e3cac14"/><file name="LoggerPatternConverterProcess.php" hash="7421d9b9b6a5f8f51c3a9a1c796911a5"/><file name="LoggerPatternConverterRelative.php" hash="24495b25867aac190135610061cd244d"/><file name="LoggerPatternConverterRequest.php" hash="67a484d44fd7ddc06a654995904e9653"/><file name="LoggerPatternConverterServer.php" hash="bef42f8b51bc220453e3f4b1e67e7402"/><file name="LoggerPatternConverterSession.php" hash="7cd6290d364837cd2ff4358c03022e98"/><file name="LoggerPatternConverterSessionID.php" hash="fc7b37aa3cb28fbb09862eb7edc6d042"/><file name="LoggerPatternConverterSuperglobal.php" hash="6b984fb3d26fb0186595370d0f066659"/><file name="LoggerPatternConverterThrowable.php" hash="4ca10f0f20408a30243ff589415634c9"/></dir><dir name="renderers"><file name="LoggerRenderer.php" hash="332819a947805d55c2aa546ced274f01"/><file name="LoggerRendererDefault.php" hash="4c4003cde8e0a74cc562060ca7bccf61"/><file name="LoggerRendererException.php" hash="4b2def2de9aa459bd321e826c02e31c2"/><file name="LoggerRendererMap.php" hash="b9aadee6f31f7cb38210653141b94fa6"/></dir><dir name="xml"><file name="log4php.dtd" hash="fb7e60edf02964352b7ddee1f26d8924"/></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="factfinder"><file name="asn.xml" hash="05ee1b7d0d34d7e43de8c115aeaab69d"/><file name="campaigns.xml" hash="40a945b639f93c059f921b2d89664258"/><file name="core.xml" hash="fe920d8ef444afbcfa2053b72bc819fc"/><file name="suggest.xml" hash="9c1a761044cd33da5e028c92ce9abe4f"/><file name="tagcloud.xml" hash="0d31f54985019d96bb1b5af17ccdf0d3"/><file name="tracking.xml" hash="53ce8afeb32391a4b207121a372162a2"/></dir></dir><dir name="template"><dir name="factfinder"><dir name="asn"><dir name="layer"><dir name="filter"><file name="slider.phtml" hash="2004f809f803e17d9739a7173958ceca"/></dir><file name="slider.phtml" hash="d48c9aace222c7525430b5235acd4026"/></dir></dir><dir name="campaigns"><file name="advisory.phtml" hash="3341ee58f81da41020f85c2145048b8b"/><file name="feedback.phtml" hash="4c1868f038a13bd2ca270b7d9a077452"/><file name="pushed.phtml" hash="b76b7c5b064ee6dc86ccc94a363bdb05"/></dir><dir name="core"><dir name="export"><file name="locked.phtml" hash="f0948f48fcc40dfcb21a8da68ce29425"/><file name="nofile.phtml" hash="c304b037812f4c34d7e094fe3b70cd80"/></dir></dir><dir name="suggest"><file name="advancedsuggest.phtml" hash="9f74281e6e75d1d3aec83d5d7f026c17"/></dir><dir name="tracking"><file name="click.phtml" hash="3e545af810a201db7c76c0502f606308"/><file name="recommendation.phtml" hash="02dba2d0cc5e1608682a700916a963d8"/></dir></dir></dir></dir></dir><dir name="rwd"><dir name="enterprise"><dir name="layout"><dir name="factfinder"><file name="suggest.xml" hash="9c1a761044cd33da5e028c92ce9abe4f"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="."><file name="factfinder.xml" hash="f87803fd5c96fc784baff992c2bce96b"/></dir><dir name="modules"><file name="FACTFinder_Asn.xml" hash="a003a8010c577c396c8e2ee5b1ea4417"/><file name="FACTFinder_Campaigns.xml" hash="ccd3080cf57535193a6fe2e6946640fd"/><file name="FACTFinder_Core.xml" hash="80f5142c2acf5ceeca0fd552ddb7ce4c"/><file name="FACTFinder_Recommendation.xml" hash="9742344545ee435a4dc87eb2bb80bf19"/><file name="FACTFinder_Suggest.xml" hash="882806b936029f0ef04d4719542ecea3"/><file name="FACTFinder_Tagcloud.xml" hash="62d3ccec2191e7dfd8225e02912891d2"/><file name="FACTFinder_Tracking.xml" hash="779b734bdcafabab072a1afd9d0bf7c4"/></dir></target><target name="mage"><dir name="shell"><file name="factfinder.php" hash="86667fac5a3532b607bb622f23bd67ad"/></dir></target><target name="mageweb"><dir name="js"><dir name="factfinder"><file name="jXHR.js" hash="a62424da9902b49a76659683121618d0"/><file name="suggest.js" hash="3e235179d35a59cb07410251c2d9dd32"/><file name="tracking.js" hash="8c429f905c02793f28761e44764049da"/></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="js"><dir name="factfinder_onetouchslider"><file name="234A0ACCECB3C19247FA8B7920453761.cache.js" hash="df488d926e6054769d4731148e707b58"/><file name="25E490B929D7CDBF44085E4E4D9D6F78.cache.js" hash="2a017b95cfbd8653a222660b60697419"/><file name="53ABFAE8983A4589B497F48695DB2A7C.cache.js" hash="b6b02347438384cc886b2509426826b5"/><file name="75B23D057185BAB61CFE100CE08C4D84.cache.js" hash="ec9c94e05e64372a9636ef03e688d451"/><file name="79DD9AE9135ADFDE204324DA7F1B1405.cache.png" hash="6ba720deee377e093c5f5b0423c152df"/><file name="9F0D0456482D7A7A901A2CD8F64EA019.cache.js" hash="dad64db53266865af02c620795c6ab13"/><file name="clear.cache.gif" hash="6d22e4f2d2057c6e8d6fab098e76e80f"/><file name="de.factfinder.asn.slider.OneTouchSlider.nocache.js" hash="f92d47fc9eb8cf8ff78173997f5a4a7a"/></dir></dir><dir name="css"><file name="factfinder_suggest.css" hash="1a8a97d65582535cbc74c5599fcb34e1"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="de_DE"><file name="FACTFinder_Suggest.csv" hash="3098dfae8ccf75366dfa093ce5c863f2"/></dir><dir name="en_US"><file name="FACTFinder_Suggest.csv" hash="2e9fd7bbc9407364430a7c281c94ec63"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.3.0</min><max>7.1.0</max></php></required></dependencies>
18
  </package>
shell/factfinder.php CHANGED
@@ -10,7 +10,22 @@ class Mage_Shell_FactFinder extends Mage_Shell_Abstract
10
  const EXPORT_STORE_STOCK = 'exportStoreStock';
11
  const EXPORT_STORE = 'exportStore';
12
 
 
 
 
 
 
 
 
 
 
 
 
13
 
 
 
 
 
14
  public function run()
15
  {
16
  if ($this->getArg('exportAll') || $this->getArg('exportall')) {
@@ -69,7 +84,7 @@ USAGE;
69
  }
70
 
71
  foreach (Mage::helper('factfinder/export')->getExportTypes() as $type) {
72
- $file = Mage::getModel('factfinder/export_' . $type)
73
  ->saveExport($this->getArg(self::EXPORT_ALL_TYPES_FOR_STORE));
74
  printf("Successfully generated %s export to: %s\n", $type, $file);
75
  }
@@ -84,7 +99,7 @@ USAGE;
84
  private function exportAllTypesForAllStores()
85
  {
86
  foreach (array('stock', 'price', 'product') as $type) {
87
- $files = Mage::getModel('factfinder/export_' . $type)
88
  ->saveAll();
89
  foreach ($files as $file) {
90
  printf("Successfully generated %s export to: %s\n", $type, $file);
@@ -105,7 +120,7 @@ USAGE;
105
  return;
106
  }
107
 
108
- $file = Mage::getModel('factfinder/export_stock')->saveExport($this->getArg(self::EXPORT_STORE_STOCK));
109
  printf("Successfully generated stock export to: %s\n", $file);
110
  }
111
 
@@ -122,7 +137,7 @@ USAGE;
122
  return;
123
  }
124
 
125
- $file = Mage::getModel('factfinder/export_price')->saveExport($this->getArg(self::EXPORT_STORE_PRICE));
126
  printf("Successfully generated price export to: %s\n", $file);
127
  }
128
 
@@ -139,7 +154,7 @@ USAGE;
139
  return;
140
  }
141
 
142
- $file = Mage::getModel('factfinder/export_product')->saveExport($this->getArg(self::EXPORT_STORE));
143
  printf("Successfully generated export to: %s\n", $file);
144
  }
145
 
@@ -151,7 +166,7 @@ USAGE;
151
  */
152
  private function exportAll()
153
  {
154
- $files = Mage::getModel('factfinder/export_product')->saveAll();
155
  echo "Successfully generated the following files:\n";
156
  foreach ($files as $file) {
157
  echo $file . "\n";
10
  const EXPORT_STORE_STOCK = 'exportStoreStock';
11
  const EXPORT_STORE = 'exportStore';
12
 
13
+ /**
14
+ * Mage_Shell_FactFinder constructor.
15
+ */
16
+ public function __construct()
17
+ {
18
+ parent::__construct();
19
+
20
+ // Additionally add module autoloader
21
+ $autoloaderClass = new FACTFinder_Core_Model_Autoloader();
22
+ $autoloaderClass->addAutoloader(new Varien_Event_Observer());
23
+ }
24
 
25
+
26
+ /**
27
+ * @return void
28
+ */
29
  public function run()
30
  {
31
  if ($this->getArg('exportAll') || $this->getArg('exportall')) {
84
  }
85
 
86
  foreach (Mage::helper('factfinder/export')->getExportTypes() as $type) {
87
+ $file = Mage::getModel('factfinder/export_type_' . $type)
88
  ->saveExport($this->getArg(self::EXPORT_ALL_TYPES_FOR_STORE));
89
  printf("Successfully generated %s export to: %s\n", $type, $file);
90
  }
99
  private function exportAllTypesForAllStores()
100
  {
101
  foreach (array('stock', 'price', 'product') as $type) {
102
+ $files = Mage::getModel('factfinder/export_type_' . $type)
103
  ->saveAll();
104
  foreach ($files as $file) {
105
  printf("Successfully generated %s export to: %s\n", $type, $file);
120
  return;
121
  }
122
 
123
+ $file = Mage::getModel('factfinder/export_type_stock')->saveExport($this->getArg(self::EXPORT_STORE_STOCK));
124
  printf("Successfully generated stock export to: %s\n", $file);
125
  }
126
 
137
  return;
138
  }
139
 
140
+ $file = Mage::getModel('factfinder/export_type_price')->saveExport($this->getArg(self::EXPORT_STORE_PRICE));
141
  printf("Successfully generated price export to: %s\n", $file);
142
  }
143
 
154
  return;
155
  }
156
 
157
+ $file = Mage::getModel('factfinder/export_type_product')->saveExport($this->getArg(self::EXPORT_STORE));
158
  printf("Successfully generated export to: %s\n", $file);
159
  }
160
 
166
  */
167
  private function exportAll()
168
  {
169
+ $files = Mage::getModel('factfinder/export_type_product')->saveAll();
170
  echo "Successfully generated the following files:\n";
171
  foreach ($files as $file) {
172
  echo $file . "\n";