Tastehit_ProductRecommendation - Version 0.1.2

Version Notes

Stable version of the Magento extension for product recommendation from Tastehit

Download this release

Release Info

Developer Christopher Burger
Extension Tastehit_ProductRecommendation
Version 0.1.2
Comparing to
See all releases


Version 0.1.2

Files changed (24) hide show
  1. app/code/community/Tastehit/ProductRecommendation/Block/Adminhtml/System/Config/Button/Export.php +58 -0
  2. app/code/community/Tastehit/ProductRecommendation/Block/Adminhtml/System/Config/Info.php +107 -0
  3. app/code/community/Tastehit/ProductRecommendation/Block/Catalog/Category.php +23 -0
  4. app/code/community/Tastehit/ProductRecommendation/Block/Catalog/Product.php +23 -0
  5. app/code/community/Tastehit/ProductRecommendation/Block/Home.php +23 -0
  6. app/code/community/Tastehit/ProductRecommendation/Block/Js.php +20 -0
  7. app/code/community/Tastehit/ProductRecommendation/Helper/Data.php +184 -0
  8. app/code/community/Tastehit/ProductRecommendation/Model/Observer.php +250 -0
  9. app/code/community/Tastehit/ProductRecommendation/Model/System/Config/Backend/Cron.php +49 -0
  10. app/code/community/Tastehit/ProductRecommendation/Model/System/Config/Source/Placement/Category.php +34 -0
  11. app/code/community/Tastehit/ProductRecommendation/Model/System/Config/Source/Placement/Home.php +39 -0
  12. app/code/community/Tastehit/ProductRecommendation/Model/System/Config/Source/Placement/Products.php +44 -0
  13. app/code/community/Tastehit/ProductRecommendation/controllers/Adminhtml/TastehitController.php +23 -0
  14. app/code/community/Tastehit/ProductRecommendation/data/tastehit_productrecommendation_setup/data-install-0.1.0.php +15 -0
  15. app/code/community/Tastehit/ProductRecommendation/etc/adminhtml.xml +33 -0
  16. app/code/community/Tastehit/ProductRecommendation/etc/config.xml +86 -0
  17. app/code/community/Tastehit/ProductRecommendation/etc/system.xml +513 -0
  18. app/code/community/Tastehit/ProductRecommendation/sql/tastehit_productrecommendation_setup/install-0.1.0.php +15 -0
  19. app/code/community/Tastehit/ProductRecommendation/sql/tastehit_productrecommendation_setup/upgrade-0.1.0-0.1.1.php +20 -0
  20. app/design/adminhtml/default/default/template/tastehit/system/config/export-button.phtml +16 -0
  21. app/design/frontend/base/default/layout/tastehit_productrecommendation.xml +20 -0
  22. app/design/frontend/base/default/template/tastehit/js.phtml +23 -0
  23. app/etc/modules/Tastehit_ProductRecommendation.xml +19 -0
  24. package.xml +52 -0
app/code/community/Tastehit/ProductRecommendation/Block/Adminhtml/System/Config/Button/Export.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation Export Button Block
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Block_Adminhtml_System_Config_Button_Export extends Mage_Adminhtml_Block_System_Config_Form_Field
11
+ {
12
+ /**
13
+ * Set template
14
+ */
15
+ protected function _construct()
16
+ {
17
+ parent::_construct();
18
+ $this->setTemplate('tastehit/system/config/export-button.phtml');
19
+ }
20
+
21
+ /**
22
+ * Return element html
23
+ *
24
+ * @param Varien_Data_Form_Element_Abstract $element
25
+ * @return string
26
+ */
27
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
28
+ {
29
+ return $this->_toHtml();
30
+ }
31
+
32
+ /**
33
+ * Return ajax url for button
34
+ *
35
+ * @return string
36
+ */
37
+ public function getAjaxUrl()
38
+ {
39
+ return Mage::helper('adminhtml')->getUrl('adminhtml/tastehit/export');
40
+ }
41
+
42
+ /**
43
+ * Generate button html
44
+ *
45
+ * @return string
46
+ */
47
+ public function getButtonHtml()
48
+ {
49
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
50
+ ->setData(array(
51
+ 'id' => 'reindex_button',
52
+ 'label' => $this->helper('adminhtml')->__('Export Now'),
53
+ 'onclick' => 'javascript:export_now(); window.location.reload();;'
54
+ ));
55
+
56
+ return $button->toHtml();
57
+ }
58
+ }
app/code/community/Tastehit/ProductRecommendation/Block/Adminhtml/System/Config/Info.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation Info block
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Block_Adminhtml_System_Config_Info
11
+ extends Mage_Adminhtml_Block_Abstract
12
+ implements Varien_Data_Form_Element_Renderer_Interface
13
+ {
14
+ /**
15
+ * Render Info html
16
+ *
17
+ * @param Varien_Data_Form_Element_Abstract $element
18
+ * @return string
19
+ */
20
+ public function render(Varien_Data_Form_Element_Abstract $element)
21
+ {
22
+ $helper = Mage::helper('tastehit_productrecommendation');
23
+ $productExportDateTime = $helper->getProductExportDateTime();
24
+ $historyExportDateTime = $helper->getHistoryExportDateTime();
25
+ $catalogUrl = $helper->getExportUrl() . $helper::EXPORT_CATALOG_FILENAME;
26
+ $historyUrl = $helper->getExportUrl() . $helper::EXPORT_HISTORY_FILENAME;
27
+ $customerId = $helper->getCustomerId();
28
+ $html = <<<HTML
29
+ <a href="https://www.tastehit.com/login" target="_blank">
30
+ <img src="https://www.tastehit.com/static/img/th-logo.png">
31
+ </a>
32
+ <div class="content-header">
33
+ <h3>
34
+ <span>Current Status</span>
35
+ </h3>
36
+ </div>
37
+ <table cellspacing="0" class="form-list">
38
+ <colgroup class="label"></colgroup>
39
+ <colgroup class="value"></colgroup>
40
+ <tbody>
41
+ <tr id="row_productrecommendation_info_state">
42
+ <td class="label"><label for="productrecommendation_info_state">State of Service</label></td>
43
+ <td class="value" id="productrecommendation_info_state">
44
+ <div class="value label­danger">Not available</div>
45
+ </td>
46
+ </tr>
47
+ <tr id="row_productrecommendation_info_recommendations">
48
+ <td class="label"><label for="productrecommendation_info_recommendations">Recommendations</label></td>
49
+ <td class="value"> </td>
50
+ </tr>
51
+ <tr id="row_productrecommendation_info_catalog_url">
52
+ <td class="label"><label for="productrecommendation_info_catalog_url">Catalog URL</label></td>
53
+ <td class="value"><a href="$catalogUrl">$catalogUrl</a></td>
54
+ </tr>
55
+ <tr id="row_productrecommendation_info_history_url">
56
+ <td class="label"><label for="productrecommendation_info_history_url">Buying history URL</label></td>
57
+ <td class="value"><a href="$historyUrl">$historyUrl</a></td>
58
+ </tr>
59
+ <tr id="row_productrecommendation_info_catalog_export_date">
60
+ <td class="label"><label for="productrecommendation_info_catalog_export_date">Last catalog export</label></td>
61
+ <td class="value">$productExportDateTime</td>
62
+ </tr>
63
+ <tr id="row_productrecommendation_info_history_export_date">
64
+ <td class="label"><label for="productrecommendation_info_history_export_date">Last cart history export</label></td>
65
+ <td class="value">$historyExportDateTime</td>
66
+ </tr>
67
+ </tbody>
68
+ </table>
69
+ <script type="text/javascript">
70
+ //<![CDATA[
71
+ document.observe('dom:loaded', function(){
72
+ var requestUri = '//www.tastehit.com/api/' + "$customerId" + '/stats';
73
+ var container = $('productrecommendation_info_state').down();
74
+ var loader = $('loading-mask');
75
+ loader.show();
76
+
77
+ function loadXMLDoc() {
78
+ var xmlhttp = new XMLHttpRequest();
79
+ xmlhttp.onreadystatechange = function () {
80
+ if (xmlhttp.readyState == XMLHttpRequest.DONE) {
81
+ if (xmlhttp.status == 200) {
82
+ response = JSON.parse(xmlhttp.responseText);
83
+ if (response.engine && response.engine.ready) {
84
+ container.innerHTML = 'Online';
85
+ }
86
+ } else if (xmlhttp.status == 400) {
87
+ console.log('There was an error 400');
88
+ } else {
89
+ console.log('something else other than 200 was returned');
90
+ }
91
+ }
92
+ };
93
+
94
+ xmlhttp.open("GET", requestUri, true);
95
+ xmlhttp.send();
96
+ };
97
+
98
+ loadXMLDoc();
99
+ loader.hide();
100
+ });
101
+ //]]>
102
+ </script>
103
+ HTML;
104
+
105
+ return $html;
106
+ }
107
+ }
app/code/community/Tastehit/ProductRecommendation/Block/Catalog/Category.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation Category Widget block
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Block_Catalog_Category extends Mage_Core_Block_Template
11
+ {
12
+ /**
13
+ * Render block HTML
14
+ *
15
+ * @return string
16
+ */
17
+ public function _toHtml()
18
+ {
19
+ //TODO: move to template
20
+ $widgetId = $this->getWidgetId();
21
+ return '<div class="thRecommendations" data-widgetid="' . $widgetId . '"></div>';
22
+ }
23
+ }
app/code/community/Tastehit/ProductRecommendation/Block/Catalog/Product.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation Product Widget block
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Block_Catalog_Product extends Mage_Core_Block_Template
11
+ {
12
+ /**
13
+ * Render block HTML
14
+ *
15
+ * @return string
16
+ */
17
+ public function _toHtml()
18
+ {
19
+ //TODO: move to template
20
+ $widgetId = $this->getWidgetId();
21
+ return '<div class="thRecommendations" data-widgetid="' . $widgetId . '"></div>';
22
+ }
23
+ }
app/code/community/Tastehit/ProductRecommendation/Block/Home.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation Home Page Widget block
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Block_Home extends Mage_Core_Block_Template
11
+ {
12
+ /**
13
+ * Render block HTML
14
+ *
15
+ * @return string
16
+ */
17
+ public function _toHtml()
18
+ {
19
+ //TODO: move to template
20
+ $widgetId = $this->getWidgetId();
21
+ return '<div class="thRecommendations" data-widgetid="' . $widgetId . '"></div>';
22
+ }
23
+ }
app/code/community/Tastehit/ProductRecommendation/Block/Js.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation Js block
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Block_Js extends Mage_Core_Block_Template
11
+ {
12
+ /**
13
+ * Set template
14
+ */
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setTemplate('tastehit/js.phtml');
19
+ }
20
+ }
app/code/community/Tastehit/ProductRecommendation/Helper/Data.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation main helper
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Helper_Data extends Mage_Core_Helper_Abstract
11
+ {
12
+ const PLACEMENT_NODE = 'productrecommendation/placement/';
13
+
14
+ const EXPORT_CATALOG_FILENAME = 'products.csv';
15
+ const EXPORT_HISTORY_FILENAME = 'history.csv';
16
+ /**
17
+ * Is the module enabled in configuration.
18
+ *
19
+ * @return bool
20
+ */
21
+ public function isEnabled()
22
+ {
23
+ $storeId = Mage::app()->getStore()->getId();
24
+ return (bool)Mage::getStoreConfig('productrecommendation/general/enable', $storeId);
25
+ }
26
+
27
+ /**
28
+ * Get Customer ID from configuration.
29
+ *
30
+ * @return string
31
+ */
32
+ public function getCustomerId()
33
+ {
34
+ $code = Mage::getSingleton('adminhtml/config_data')->getStore();
35
+ $storeId = Mage::getModel('core/store')->load($code)->getId();
36
+
37
+ return (string)Mage::getStoreConfig('productrecommendation/general/customer_id', $storeId);
38
+ }
39
+
40
+ /**
41
+ * Get History export DateTime
42
+ *
43
+ * @return string
44
+ */
45
+ public function getHistoryExportDateTime()
46
+ {
47
+ $code = Mage::getSingleton('adminhtml/config_data')->getStore();
48
+ $storeId = Mage::getModel('core/store')->load($code)->getId();
49
+ return (string)Mage::getStoreConfig('productrecommendation/info/history_export', $storeId);
50
+ }
51
+
52
+ /**
53
+ * Get Product export DateTime
54
+ *
55
+ * @return string
56
+ */
57
+ public function getProductExportDateTime()
58
+ {
59
+ $code = Mage::getSingleton('adminhtml/config_data')->getStore();
60
+ $storeId = Mage::getModel('core/store')->load($code)->getId();
61
+ return (string)Mage::getStoreConfig('productrecommendation/info/product_export', $storeId);
62
+ }
63
+
64
+ /**
65
+ * Get Public Path for Exports from configuration.
66
+ *
67
+ * @return string
68
+ */
69
+ public function getPublicExportPath()
70
+ {
71
+ $storeId = Mage::app()->getStore()->getId();
72
+ return (string)Mage::getStoreConfig('productrecommendation/general/export_path', $storeId) . DS;
73
+ }
74
+
75
+ /**
76
+ * Get Export Directory Path
77
+ * @param $storeId
78
+ * @return string
79
+ */
80
+ public function getExportDirPath($storeId)
81
+ {
82
+ return Mage::getBaseDir('media') . DS . (string)Mage::getStoreConfig('productrecommendation/general/export_path', $storeId) . DS;
83
+ }
84
+
85
+
86
+ /**
87
+ * Get Export URL
88
+ *
89
+ * @return string
90
+ */
91
+ public function getExportUrl()
92
+ {
93
+ $code = Mage::getSingleton('adminhtml/config_data')->getStore();
94
+ $storeId = Mage::getModel('core/store')->load($code)->getId();
95
+ return Mage::getBaseUrl('media') . (string)Mage::getStoreConfig('productrecommendation/general/export_path', $storeId) . DS;
96
+ }
97
+
98
+
99
+ public function isDisplayOnHomePage()
100
+ {
101
+ $storeId = Mage::app()->getStore()->getId();
102
+ return Mage::getStoreConfigFlag(self::PLACEMENT_NODE . '' , $storeId);
103
+ }
104
+
105
+ /**
106
+ * Get Widgets Data from configuration
107
+ *
108
+ * @return array
109
+ */
110
+ public function getWidgetsData()
111
+ {
112
+ $storeId = Mage::app()->getStore()->getId();
113
+ $data = array();
114
+ $widgets = array('product_page', 'home_page', 'category_page');
115
+ // Limitation to 3 widgets of every kind
116
+ foreach ($widgets as $widget) {
117
+ if (Mage::getStoreConfigFlag(self::PLACEMENT_NODE . 'enable_' . $widget)) {
118
+ $data[$widget] = array();
119
+ for ($i = 1; $i <= 3; $i++) {
120
+ if (Mage::getStoreConfigFlag(self::PLACEMENT_NODE . $widget . '_enable_' . $i, $storeId)) {
121
+ $data[$widget][$i]['id'] = Mage::getStoreConfig(self::PLACEMENT_NODE . $widget . '_id_' . $i, $storeId);
122
+ $data[$widget][$i]['display'] = Mage::getStoreConfig(self::PLACEMENT_NODE . $widget . '_display_' . $i, $storeId);
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ return $data;
129
+ }
130
+
131
+
132
+ /**
133
+ * Generate Layout update
134
+ *
135
+ * @param $widget
136
+ * @param $id
137
+ * @param $position
138
+ * @return null|string
139
+ */
140
+ public function getLayoutUpdate($widget, $id, $position)
141
+ {
142
+ $update = null;
143
+ switch ($widget) {
144
+ case ($widget == 'product_page'):
145
+ switch ($position) {
146
+ case ($position == Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Products::AFTER_DESCRIPTION):
147
+ $update = '<reference name="content"><block type="tastehit_productrecommendation/catalog_product" name="tastehit.product.'. $id .'" after="product.info"><action method="setData"><name>widget_id</name><value>'. $id .'</value></action></block></reference>';
148
+ break;
149
+ case ($position == Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Products::BETWEEN_DESCRIPTION_AND_IMAGE):
150
+ $update = '<reference name="product.info.media.after"><block type="tastehit_productrecommendation/catalog_product" name="tastehit.product.'. $id .'"><action method="setData"><name>widget_id</name><value>'. $id .'</value></action></block></reference>';
151
+ break;
152
+ case ($position == Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Products::AFTER_ADD_TO_CART):
153
+ $update = '<reference name="product.info.extrahint"><block type="tastehit_productrecommendation/catalog_product" name="tastehit.product.'. $id .'"><action method="setData"><name>widget_id</name><value>'. $id .'</value></action></block></reference>';
154
+ break;
155
+ case ($position == Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Products::CUSTOM_POSITION):
156
+ $update = '<reference name="product.info"><block type="tastehit_productrecommendation/catalog_product" name="tastehit.product.'. $id .'"><action method="setData"><name>widget_id</name><value>'. $id .'</value></action></block></reference>';
157
+ break;
158
+ }
159
+ break;
160
+ case ($widget == 'home_page'):
161
+ switch ($position) {
162
+ case ($position == Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Home::BEFORE_CARROUSEL):
163
+ $update = '<reference name="content"><block type="tastehit_productrecommendation/home" name="tastehit.home.'. $id .'" before="-"><action method="setData"><name>widget_id</name><value>'. $id .'</value></action></block></reference>';
164
+ break;
165
+ case ($position == Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Home::BEFORE_FOOTER):
166
+ $update = '<reference name="content"><block type="tastehit_productrecommendation/home" name="tastehit.home.'. $id .'" after="-"><action method="setData"><name>widget_id</name><value>'. $id .'</value></action></block></reference>';
167
+ break;
168
+ }
169
+ break;
170
+ case ($widget == 'category_page'):
171
+ switch ($position) {
172
+ case ($position == Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Category::BEFORE_PRODUCT_LIST):
173
+ $update = '<reference name="content"><block type="tastehit_productrecommendation/catalog_category" name="tastehit.category.' . $id . '" before="product_list"><action method="setData"><name>widget_id</name><value>'. $id .'</value></action></block></reference>';
174
+ break;
175
+ case ($position == Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Category::AFTER_PRODUCT_LIST):
176
+ $update = '<reference name="content"><block type="tastehit_productrecommendation/catalog_category" name="tastehit.category.' . $id . '" after="product_list"><action method="setData"><name>widget_id</name><value>'. $id .'</value></action></block></reference>';
177
+ break;
178
+ }
179
+ break;
180
+ }
181
+
182
+ return $update;
183
+ }
184
+ }
app/code/community/Tastehit/ProductRecommendation/Model/Observer.php ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation Observer
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Model_Observer
11
+ {
12
+ /**
13
+ * Add Widgets
14
+ *
15
+ * @param Varien_Event_Observer $observer
16
+ * @return $this
17
+ */
18
+ public function addWidgets(Varien_Event_Observer $observer)
19
+ {
20
+ $helper = Mage::helper('tastehit_productrecommendation');
21
+ $widgets = array('product_page', 'home_page', 'category_page');
22
+ $routeName = Mage::app()->getRequest()->getRouteName();
23
+ $fullActionName = Mage::app()->getFrontController()->getAction()->getFullActionName();
24
+ $identifier = Mage::getSingleton('cms/page')->getIdentifier();
25
+ $layoutUpdate = $observer->getEvent()->getLayout()->getUpdate();
26
+ $widgetsData = Mage::helper('tastehit_productrecommendation')->getWidgetsData();
27
+ foreach ($widgetsData as $widget => $data) {
28
+ for ($i = 1; $i <= 3; $i++) {
29
+ $update = null;
30
+ if ($fullActionName == 'catalog_product_view' && Mage::getStoreConfigFlag('productrecommendation/placement/enable_product_page') && $widget == 'product_page') {
31
+ if (!empty($widgetsData['product_page']) && isset($data[$i]) && Mage::getStoreConfigFlag('productrecommendation/placement/product_page_enable_' . $i)) {
32
+ $update = $helper->getLayoutUpdate($widget, $data[$i]['id'], $data[$i]['display']);
33
+ if ($update) {
34
+ $layoutUpdate->addUpdate($update);
35
+ }
36
+ }
37
+ } elseif ($fullActionName == 'catalog_category_view' && Mage::getStoreConfigFlag('productrecommendation/placement/enable_category_page') && $widget == 'category_page') {
38
+ if (!empty($widgetsData['category_page']) && Mage::getStoreConfigFlag('productrecommendation/placement/category_page_enable_' . $i)) {
39
+ $update = $helper->getLayoutUpdate($widget, $data[$i]['id'], $data[$i]['display']);
40
+ if ($update) {
41
+ $layoutUpdate->addUpdate($update);
42
+ }
43
+ }
44
+ } elseif ($routeName == 'cms' && $identifier == 'home' && Mage::getStoreConfigFlag('productrecommendation/placement/enable_home_page') && $widget == 'home_page') {
45
+ if (!empty($widgetsData['home_page']) && Mage::getStoreConfigFlag('productrecommendation/placement/home_page_enable_' . $i)) {
46
+ $update = $helper->getLayoutUpdate($widget, $data[$i]['id'], $data[$i]['display']);
47
+ if ($update) {
48
+ $layoutUpdate->addUpdate($update);
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+ return $this;
56
+ }
57
+
58
+ /**
59
+ * Export csv files
60
+ */
61
+ public function export()
62
+ {
63
+ $helper = Mage::helper('tastehit_productrecommendation');
64
+ //TODO: Implement export for multistore setup
65
+ $store = Mage::app()->getDefaultStoreView();
66
+ $io = new Varien_Io_File();
67
+ $io->setAllowCreateFolders(true);
68
+
69
+ $storeCode = Mage::app()->getRequest()->getParam('store');
70
+ if ($storeCode) {
71
+ $storeIdFromRequest = $storeCode;
72
+ } else {
73
+ $storeIdFromRequest = $store->getId();
74
+ }
75
+ $exportPath = $helper->getExportDirPath($storeIdFromRequest);
76
+ $productExportFile = $exportPath . $helper::EXPORT_CATALOG_FILENAME;
77
+
78
+ $io->open(array('path' => $exportPath));
79
+ $io->streamOpen($productExportFile, 'w+');
80
+ $io->streamLock(true);
81
+
82
+ /** @var Mage_Catalog_Model_Resource_Product_Attribute_Collection $attributeCollection */
83
+ $attributeCollection = Mage::getResourceModel('catalog/product_attribute_collection');
84
+ $attributeCollection->addFieldToFilter('is_filterable', true);
85
+ foreach ($attributeCollection as $attribute) {
86
+ $attributeCodesArray[] = $attribute->getAttributeCode();
87
+ }
88
+ $productCsvHeader = array(
89
+ 'id',
90
+ 'sku',
91
+ 'availability',
92
+ 'item_url',
93
+ 'title',
94
+ 'description',
95
+ 'category',
96
+ 'sale_price',
97
+ 'image_url',
98
+ 'small_image_url',
99
+ 'thumbnail_url'
100
+ );
101
+
102
+ $io->streamWriteCsv(array_merge($productCsvHeader, $attributeCodesArray), '|', ' ');
103
+
104
+ $products = Mage::getModel('catalog/product')->getCollection()->addUrlRewrite()->addAttributeToSelect('*');
105
+ $products->addFieldToFilter('visibility',
106
+ array(
107
+ Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
108
+ Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
109
+ )
110
+ );
111
+ $products->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
112
+
113
+ foreach ($products as $product){
114
+ $product->setStoreId($store->getId());
115
+ $stockText = '';
116
+ $stockStatus = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getIsInStock();
117
+ if ($stockStatus == Mage_CatalogInventory_Model_Stock::STOCK_IN_STOCK) {
118
+ $stockText = 'In Stock';
119
+ } elseif (Mage_CatalogInventory_Model_Stock::STOCK_OUT_OF_STOCK) {
120
+ $stockText = 'Out of Stock';
121
+ }
122
+ $productUrl = preg_replace('/\?___store\=.*/', '', $product->getProductUrl());
123
+ $mainData = array(
124
+ $product->getId(),
125
+ $product->getSku(),
126
+ $stockText,
127
+ $productUrl,
128
+ str_replace('|', '_', $product->getName()),
129
+ str_replace('|', '_',$product->getDescription()),
130
+ $this->_getCategories($product->getCategoryIds()),
131
+ number_format($product->getPrice(), 2),
132
+ $product->getFinalPrice(),
133
+ $this->_getProductImage($product, 'image'),
134
+ $this->_getProductImage($product, 'small_image', 165),
135
+ $this->_getProductImage($product, 'thumbnail', 400)
136
+ );
137
+
138
+ $filterableAttributesData = array();
139
+ foreach ($attributeCodesArray as $attributeCode) {
140
+ $filterableAttributesData[] = (string)$product->getAttributeText($attributeCode);
141
+ }
142
+
143
+ $io->streamWriteCsv(array_merge($mainData, $filterableAttributesData), '|', ' ');
144
+ }
145
+
146
+ $io->streamUnlock();
147
+ $io->streamClose();
148
+ $productExportDateTime = Mage::getModel('core/date')->date('Y-m-d H:i:s');
149
+ Mage::getConfig()->saveConfig('productrecommendation/info/product_export', $productExportDateTime, 'default', $store->getId());
150
+
151
+ $previousSalesExportTime = $helper->getHistoryExportDateTime();
152
+ $salesExportFrequency = Mage::getStoreConfig('productrecommendation/info/export_frequency', $store->getId());
153
+ $to = date('Y-m-d H:i:s',time());
154
+
155
+ $salesExportFile = $exportPath . $helper::EXPORT_HISTORY_FILENAME;
156
+ $from = $previousSalesExportTime;
157
+
158
+ $soldProductCollection = $collection = Mage::getResourceModel('sales/order_item_collection');
159
+
160
+ $soldProductCollection
161
+ ->addFieldToFilter(
162
+ 'main_table.created_at', array('gt' => array($from))
163
+ )
164
+ ->addFieldToFilter(
165
+ 'main_table.created_at', array('lt' => array($to))
166
+ );
167
+ $soldProductCollection->join(
168
+ array('orders_table' => 'sales/order'),
169
+ 'orders_table.entity_id = main_table.order_id',
170
+ array('customer_id' => 'customer_id')
171
+ );
172
+
173
+ if ($soldProductCollection->count() > 0) {
174
+ $historyCsvHeader = array(
175
+ 'id_user',
176
+ 'product_id'
177
+ );
178
+ $io->open(array('path' => $exportPath));
179
+ $io->streamOpen($salesExportFile, 'w+');
180
+ $io->streamLock(true);
181
+ $io->streamWriteCsv($historyCsvHeader, ';', ' ');
182
+ foreach ($soldProductCollection as $item) {
183
+ $customerId = $item->getId();
184
+ $sku = $item->getSku();
185
+ if ($sku && $customerId) {
186
+ $io->streamWriteCsv(array($customerId, $sku), ';', ' ');
187
+ }
188
+
189
+ }
190
+ $io->streamUnlock();
191
+ $io->streamClose();
192
+ $historyExportDateTime = Mage::getModel('core/date')->date('Y-m-d H:i:s');
193
+ Mage::getConfig()->saveConfig('productrecommendation/info/history_export', $historyExportDateTime, 'default', $store->getId());
194
+ }
195
+
196
+ Mage::app()->getCacheInstance()->cleanType('config');
197
+ return true;
198
+ }
199
+
200
+
201
+ /**
202
+ * Get product Categories
203
+ *
204
+ * @param $categoryIds
205
+ * @return array|string
206
+ * @throws Mage_Core_Exception
207
+ */
208
+ protected function _getCategories($categoryIds)
209
+ {
210
+ $categoriesArray = array();
211
+ if ($categoryIds && !empty($categoryIds)) {
212
+ $categories = Mage::getModel('catalog/category')
213
+ ->getCollection()
214
+ ->addAttributeToSelect('*')
215
+ ->addAttributeToFilter('entity_id', $categoryIds);
216
+ foreach ($categories as $category) {
217
+ $categoriesArray[] = $category->getName();
218
+ }
219
+
220
+ return implode(', ',$categoriesArray);
221
+ } else {
222
+ return '';
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Get product image
228
+ *
229
+ * @param $product
230
+ * @param $imageType
231
+ * @param $size
232
+ * @return string
233
+ */
234
+ protected function _getProductImage($product, $imageType, $size = null)
235
+ {
236
+ $imgSrc = '';
237
+ try{
238
+ if ($size) {
239
+ $imgSrc = Mage::helper('catalog/image')->init($product, $imageType)->keepFrame(false)->resize($size);
240
+ } else {
241
+ $imgSrc = Mage::helper('catalog/image')->init($product, $imageType);
242
+ }
243
+ }
244
+ catch(Exception $e) {
245
+ $imgSrc = Mage::getDesign()->getSkinUrl('images/catalog/product/placeholder/small_image.jpg',array('_area'=>'frontend'));
246
+ }
247
+
248
+ return (string) $imgSrc;
249
+ }
250
+ }
app/code/community/Tastehit/ProductRecommendation/Model/System/Config/Backend/Cron.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Model_System_Config_Backend_Cron extends Mage_Core_Model_Config_Data
11
+ {
12
+ const CRON_STRING_PATH = 'crontab/jobs/tastehit_export/schedule/cron_expr';
13
+ const CRON_MODEL_PATH = 'crontab/jobs/tastehit_export/run/model';
14
+
15
+ /**
16
+ * Cron settings after save
17
+ *
18
+ * @return Tastehit_ProductRecommendation_Model_System_Config_Backend_Cron
19
+ */
20
+ protected function _afterSave()
21
+ {
22
+ $frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
23
+ $frequencyWeekly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_WEEKLY;
24
+ $frequencyMonthly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_MONTHLY;
25
+
26
+ $time = $this->getData('groups/general/fields/export_time/value');
27
+ $frequency = $this->getData('groups/general/fields/export_frequency/value');
28
+
29
+ $cronExprArray = array(
30
+ intval($time[1]), # Minute
31
+ intval($time[0]), # Hour
32
+ ($frequency == $frequencyMonthly) ? '1' : '*', # Day of the Month
33
+ '*', # Month of the Year
34
+ ($frequency == $frequencyWeekly) ? '1' : '*', # Day of the Week
35
+ );
36
+ $cronExprString = join(' ', $cronExprArray);
37
+
38
+ try {
39
+ Mage::getModel('core/config_data')
40
+ ->load(self::CRON_STRING_PATH, 'path')
41
+ ->setValue($cronExprString)
42
+ ->setPath(self::CRON_STRING_PATH)
43
+ ->save();
44
+ }
45
+ catch (Exception $e) {
46
+ Mage::throwException(Mage::helper('backup')->__('Unable to save the cron expression.'));
47
+ }
48
+ }
49
+ }
app/code/community/Tastehit/ProductRecommendation/Model/System/Config/Source/Placement/Category.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Category
11
+ {
12
+ protected static $_options;
13
+
14
+ const BEFORE_PRODUCT_LIST = 1;
15
+ const AFTER_PRODUCT_LIST = 2;
16
+
17
+ public function toOptionArray()
18
+ {
19
+ if (!self::$_options) {
20
+ self::$_options = array(
21
+ array(
22
+ 'label' => Mage::helper('tastehit_productrecommendation')->__('At the top of the page, before the category listings'),
23
+ 'value' => self::BEFORE_PRODUCT_LIST,
24
+ ),
25
+ array(
26
+ 'label' => Mage::helper('tastehit_productrecommendation')->__('At the bottom of the page, after the category listings'),
27
+ 'value' => self::AFTER_PRODUCT_LIST,
28
+ ),
29
+ );
30
+ }
31
+
32
+ return self::$_options;
33
+ }
34
+ }
app/code/community/Tastehit/ProductRecommendation/Model/System/Config/Source/Placement/Home.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Home
11
+ {
12
+ protected static $_options;
13
+
14
+ const BEFORE_CARROUSEL = 1;
15
+ const BEFORE_FOOTER = 2;
16
+ // const CUSTOM_POSITION = 3;
17
+
18
+ public function toOptionArray()
19
+ {
20
+ if (!self::$_options) {
21
+ self::$_options = array(
22
+ array(
23
+ 'label' => Mage::helper('tastehit_productrecommendation')->__('At the top of the page, before the main carrousel/block'),
24
+ 'value' => self::BEFORE_CARROUSEL,
25
+ ),
26
+ array(
27
+ 'label' => Mage::helper('tastehit_productrecommendation')->__('At the bottom of the home page, before the footer'),
28
+ 'value' => self::BEFORE_FOOTER,
29
+ ),
30
+ // array(
31
+ // 'label' => Mage::helper('tastehit_productrecommendation')->__('Custom Position'),
32
+ // 'value' => self::CUSTOM_POSITION,
33
+ // ),
34
+ );
35
+ }
36
+
37
+ return self::$_options;
38
+ }
39
+ }
app/code/community/Tastehit/ProductRecommendation/Model/System/Config/Source/Placement/Products.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Model_System_Config_Source_Placement_Products
11
+ {
12
+ protected static $_options;
13
+
14
+ const AFTER_DESCRIPTION = 1;
15
+ const BETWEEN_DESCRIPTION_AND_IMAGE = 2;
16
+ const AFTER_ADD_TO_CART = 3;
17
+ const CUSTOM_POSITION = 4;
18
+
19
+ public function toOptionArray()
20
+ {
21
+ if (!self::$_options) {
22
+ self::$_options = array(
23
+ array(
24
+ 'label' => Mage::helper('tastehit_productrecommendation')->__('After the product description'),
25
+ 'value' => self::AFTER_DESCRIPTION,
26
+ ),
27
+ array(
28
+ 'label' => Mage::helper('tastehit_productrecommendation')->__('Between the product picture and description'),
29
+ 'value' => self::BETWEEN_DESCRIPTION_AND_IMAGE,
30
+ ),
31
+ array(
32
+ 'label' => Mage::helper('tastehit_productrecommendation')->__('After Add to Cart button'),
33
+ 'value' => self::AFTER_ADD_TO_CART,
34
+ ),
35
+ array(
36
+ 'label' => Mage::helper('tastehit_productrecommendation')->__('Custom Position'),
37
+ 'value' => self::CUSTOM_POSITION,
38
+ ),
39
+ );
40
+ }
41
+
42
+ return self::$_options;
43
+ }
44
+ }
app/code/community/Tastehit/ProductRecommendation/controllers/Adminhtml/TastehitController.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ class Tastehit_ProductRecommendation_Adminhtml_TastehitController extends Mage_Adminhtml_Controller_Action
11
+ {
12
+ /**
13
+ * Export Action
14
+ *
15
+ * @return $this
16
+ */
17
+ public function exportAction()
18
+ {
19
+ $exportResult = Mage::getModel('tastehit_productrecommendation/observer')->export();
20
+
21
+ return $this;
22
+ }
23
+ }
app/code/community/Tastehit/ProductRecommendation/data/tastehit_productrecommendation_setup/data-install-0.1.0.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com/)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ /* @var $installer Mage_Core_Model_Resource_Setup */
11
+ $installer = $this;
12
+
13
+ $installer->startSetup();
14
+
15
+ $installer->endSetup();
app/code/community/Tastehit/ProductRecommendation/etc/adminhtml.xml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * ProductRecommendation
5
+ *
6
+ * @package Tastehit_ProductRecommendation
7
+ * @author Tastehit
8
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+ -->
12
+ <config>
13
+ <acl>
14
+ <resources>
15
+ <admin>
16
+ <children>
17
+ <system>
18
+ <children>
19
+ <config>
20
+ <children>
21
+ <productrecommendation translate="title">
22
+ <title>Tastehit Product Recommendation</title>
23
+ <sort_order>10</sort_order>
24
+ </productrecommendation>
25
+ </children>
26
+ </config>
27
+ </children>
28
+ </system>
29
+ </children>
30
+ </admin>
31
+ </resources>
32
+ </acl>
33
+ </config>
app/code/community/Tastehit/ProductRecommendation/etc/config.xml ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * ProductRecommendation
5
+ *
6
+ * @package Tastehit_ProductRecommendation
7
+ * @author Tastehit
8
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+ -->
12
+ <config>
13
+ <modules>
14
+ <Tastehit_ProductRecommendation>
15
+ <version>0.1.2</version>
16
+ </Tastehit_ProductRecommendation>
17
+ </modules>
18
+ <global>
19
+ <models>
20
+ <tastehit_productrecommendation>
21
+ <class>Tastehit_ProductRecommendation_Model</class>
22
+ <resourceModel>tastehit_productrecommendation_resource</resourceModel>
23
+ </tastehit_productrecommendation>
24
+ <tastehit_productrecommendation_resource>
25
+ <class>Tastehit_ProductRecommendation_Model_Resource</class>
26
+ </tastehit_productrecommendation_resource>
27
+ </models>
28
+ <blocks>
29
+ <tastehit_productrecommendation>
30
+ <class>Tastehit_ProductRecommendation_Block</class>
31
+ </tastehit_productrecommendation>
32
+ </blocks>
33
+ <helpers>
34
+ <tastehit_productrecommendation>
35
+ <class>Tastehit_ProductRecommendation_Helper</class>
36
+ </tastehit_productrecommendation>
37
+ </helpers>
38
+ <resources>
39
+ <tastehit_productrecommendation_setup>
40
+ <setup>
41
+ <module>Tastehit_ProductRecommendation</module>
42
+ </setup>
43
+ </tastehit_productrecommendation_setup>
44
+ </resources>
45
+ </global>
46
+ <admin>
47
+ <routers>
48
+ <adminhtml>
49
+ <args>
50
+ <modules>
51
+ <tastehit before="Mage_Adminhtml">Tastehit_ProductRecommendation_Adminhtml</tastehit>
52
+ </modules>
53
+ </args>
54
+ </adminhtml>
55
+ </routers>
56
+ </admin>
57
+ <frontend>
58
+ <layout>
59
+ <updates>
60
+ <tastehit_productrecommendation>
61
+ <file>tastehit_productrecommendation.xml</file>
62
+ </tastehit_productrecommendation>
63
+ </updates>
64
+ </layout>
65
+ <events>
66
+ <controller_action_layout_generate_xml_before>
67
+ <observers>
68
+ <tastehit_productrecommendation>
69
+ <type>singleton</type>
70
+ <class>tastehit_productrecommendation/observer</class>
71
+ <method>addWidgets</method>
72
+ </tastehit_productrecommendation>
73
+ </observers>
74
+ </controller_action_layout_generate_xml_before>
75
+ </events>
76
+ </frontend>
77
+ <crontab>
78
+ <jobs>
79
+ <tastehit_export>
80
+ <run>
81
+ <model>tastehit_productrecommendation/observer::export</model>
82
+ </run>
83
+ </tastehit_export>
84
+ </jobs>
85
+ </crontab>
86
+ </config>
app/code/community/Tastehit/ProductRecommendation/etc/system.xml ADDED
@@ -0,0 +1,513 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * ProductRecommendation
5
+ *
6
+ * @package Tastehit_ProductRecommendation
7
+ * @author Tastehit
8
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+ -->
12
+ <config>
13
+ <tabs>
14
+ <tastehit module="tastehit_productrecommendation" translate="label">
15
+ <label>Tastehit Extensions</label>
16
+ <sort_order>600</sort_order>
17
+ </tastehit>
18
+ </tabs>
19
+ <sections>
20
+ <productrecommendation translate="label" module="tastehit_productrecommendation">
21
+ <class>separator-top</class>
22
+ <label>Product Recommendation</label>
23
+ <tab>tastehit</tab>
24
+ <frontend_type>text</frontend_type>
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>
29
+ <groups>
30
+ <info module="tastehit_productrecommendation" translate="label comment">
31
+ <label>Information</label>
32
+ <frontend_type>text</frontend_type>
33
+ <sort_order>10</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
+ <expanded>1</expanded>
38
+ <fields>
39
+ <info module="tastehit_productrecommendation" translate="label">
40
+ <frontend_model>tastehit_productrecommendation/adminhtml_system_config_info</frontend_model>
41
+ <sort_order>10</sort_order>
42
+ <show_in_default>1</show_in_default>
43
+ <show_in_website>1</show_in_website>
44
+ <show_in_store>1</show_in_store>
45
+ </info>
46
+ </fields>
47
+ </info>
48
+ <general module="tastehit_productrecommendation" translate="label comment">
49
+ <label>General Settings</label>
50
+ <frontend_type>text</frontend_type>
51
+ <sort_order>20</sort_order>
52
+ <show_in_default>1</show_in_default>
53
+ <show_in_website>1</show_in_website>
54
+ <show_in_store>1</show_in_store>
55
+ <fields>
56
+ <enable module="tastehit_productrecommendation" translate="label">
57
+ <label>Enable</label>
58
+ <frontend_type>select</frontend_type>
59
+ <source_model>adminhtml/system_config_source_yesno</source_model>
60
+ <sort_order>10</sort_order>
61
+ <show_in_default>1</show_in_default>
62
+ <show_in_website>1</show_in_website>
63
+ <show_in_store>1</show_in_store>
64
+ </enable>
65
+ <customer_id module="tastehit_productrecommendation" translate="label">
66
+ <label>Customer ID</label>
67
+ <frontend_type>text</frontend_type>
68
+ <sort_order>20</sort_order>
69
+ <show_in_default>1</show_in_default>
70
+ <show_in_website>1</show_in_website>
71
+ <show_in_store>1</show_in_store>
72
+ <depends>
73
+ <enable>1</enable>
74
+ </depends>
75
+ </customer_id>
76
+ <export_path module="tastehit_productrecommendation" translate="label">
77
+ <label>Public Path To Exports</label>
78
+ <frontend_type>text</frontend_type>
79
+ <sort_order>30</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>
83
+ <depends>
84
+ <enable>1</enable>
85
+ </depends>
86
+ </export_path>
87
+ <export_time translate="label">
88
+ <label>Export Start Time</label>
89
+ <frontend_type>time</frontend_type>
90
+ <sort_order>40</sort_order>
91
+ <show_in_default>1</show_in_default>
92
+ <show_in_website>1</show_in_website>
93
+ <show_in_store>1</show_in_store>
94
+ </export_time>
95
+ <export_frequency module="tastehit_productrecommendation" translate="label">
96
+ <label>Exports Frequency</label>
97
+ <frontend_type>select</frontend_type>
98
+ <source_model>adminhtml/system_config_source_cron_frequency</source_model>
99
+ <backend_model>tastehit_productrecommendation/system_config_backend_cron</backend_model>
100
+ <sort_order>50</sort_order>
101
+ <show_in_default>1</show_in_default>
102
+ <show_in_website>1</show_in_website>
103
+ <show_in_store>1</show_in_store>
104
+ <depends>
105
+ <enable>1</enable>
106
+ </depends>
107
+ </export_frequency>
108
+ <reindex module="tastehit_productrecommendation" translate="label">
109
+ <label>Export Now</label>
110
+ <frontend_type>button</frontend_type>
111
+ <frontend_model>tastehit_productrecommendation/adminhtml_system_config_button_export</frontend_model>
112
+ <sort_order>60</sort_order>
113
+ <show_in_default>1</show_in_default>
114
+ <show_in_website>1</show_in_website>
115
+ <show_in_store>1</show_in_store>
116
+ <depends>
117
+ <enabled>1</enabled>
118
+ </depends>
119
+ </reindex>
120
+ </fields>
121
+ </general>
122
+ <placement>
123
+ <label>Placement Settings</label>
124
+ <frontend_type>text</frontend_type>
125
+ <sort_order>30</sort_order>
126
+ <show_in_default>1</show_in_default>
127
+ <show_in_website>1</show_in_website>
128
+ <show_in_store>1</show_in_store>
129
+ <fields>
130
+ <heading_product_pages module="tastehit_productrecommendation" translate="label">
131
+ <label>Product Pages Widgets</label>
132
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
133
+ <sort_order>5</sort_order>
134
+ <show_in_default>1</show_in_default>
135
+ <show_in_website>1</show_in_website>
136
+ <show_in_store>1</show_in_store>
137
+ </heading_product_pages>
138
+ <enable_product_page>
139
+ <label>Dispay on product pages</label>
140
+ <frontend_type>select</frontend_type>
141
+ <source_model>adminhtml/system_config_source_yesno</source_model>
142
+ <sort_order>10</sort_order>
143
+ <show_in_default>1</show_in_default>
144
+ <show_in_website>1</show_in_website>
145
+ <show_in_store>1</show_in_store>
146
+ <comment><![CDATA[For custom position please edit product page template app/design/frontend/PACKAGE_NAME/THEME_NAME/template/catalog/product/view.phtml and put "echo $this->getChildHtml('WIDGET_ID')"]]></comment>
147
+ </enable_product_page>
148
+ <product_page_enable_1 module="tastehit_productrecommendation" translate="label">
149
+ <label>Dispay Widget1</label>
150
+ <frontend_type>select</frontend_type>
151
+ <source_model>adminhtml/system_config_source_yesno</source_model>
152
+ <sort_order>15</sort_order>
153
+ <show_in_default>1</show_in_default>
154
+ <show_in_website>1</show_in_website>
155
+ <show_in_store>1</show_in_store>
156
+ <depends>
157
+ <enable_product_page>1</enable_product_page>
158
+ </depends>
159
+ </product_page_enable_1>
160
+ <product_page_id_1 module="tastehit_productrecommendation" translate="label">
161
+ <label>Product page widget1 ID</label>
162
+ <frontend_type>text</frontend_type>
163
+ <sort_order>20</sort_order>
164
+ <show_in_default>1</show_in_default>
165
+ <show_in_website>1</show_in_website>
166
+ <show_in_store>1</show_in_store>
167
+ <depends>
168
+ <product_page_enable_1>1</product_page_enable_1>
169
+ </depends>
170
+ </product_page_id_1>
171
+ <product_page_display_1 module="tastehit_productrecommendation" translate="label">
172
+ <label>Product page widget1 placement</label>
173
+ <frontend_type>select</frontend_type>
174
+ <source_model>tastehit_productrecommendation/system_config_source_placement_products</source_model>
175
+ <sort_order>30</sort_order>
176
+ <show_in_default>1</show_in_default>
177
+ <show_in_website>1</show_in_website>
178
+ <show_in_store>1</show_in_store>
179
+ <depends>
180
+ <product_page_enable_1>1</product_page_enable_1>
181
+ </depends>
182
+ </product_page_display_1>
183
+
184
+ <product_page_enable_2 module="tastehit_productrecommendation" translate="label">
185
+ <label>Dispay Widget2</label>
186
+ <frontend_type>select</frontend_type>
187
+ <source_model>adminhtml/system_config_source_yesno</source_model>
188
+ <sort_order>35</sort_order>
189
+ <show_in_default>1</show_in_default>
190
+ <show_in_website>1</show_in_website>
191
+ <show_in_store>1</show_in_store>
192
+ <depends>
193
+ <enable_product_page>1</enable_product_page>
194
+ </depends>
195
+ </product_page_enable_2>
196
+ <product_page_id_2 module="tastehit_productrecommendation" translate="label">
197
+ <label>Product page widget2 ID</label>
198
+ <frontend_type>text</frontend_type>
199
+ <sort_order>40</sort_order>
200
+ <show_in_default>1</show_in_default>
201
+ <show_in_website>1</show_in_website>
202
+ <show_in_store>1</show_in_store>
203
+ <depends>
204
+ <product_page_enable_1>1</product_page_enable_1>
205
+ </depends>
206
+ </product_page_id_2>
207
+ <product_page_display_2 module="tastehit_productrecommendation" translate="label">
208
+ <label>Product page widget2 placement</label>
209
+ <frontend_type>select</frontend_type>
210
+ <source_model>tastehit_productrecommendation/system_config_source_placement_products</source_model>
211
+ <sort_order>50</sort_order>
212
+ <show_in_default>1</show_in_default>
213
+ <show_in_website>1</show_in_website>
214
+ <show_in_store>1</show_in_store>
215
+ <depends>
216
+ <product_page_enable_2>1</product_page_enable_2>
217
+ </depends>
218
+ </product_page_display_2>
219
+
220
+ <product_page_enable_3 module="tastehit_productrecommendation" translate="label">
221
+ <label>Dispay Widget3</label>
222
+ <frontend_type>select</frontend_type>
223
+ <source_model>adminhtml/system_config_source_yesno</source_model>
224
+ <sort_order>55</sort_order>
225
+ <show_in_default>1</show_in_default>
226
+ <show_in_website>1</show_in_website>
227
+ <show_in_store>1</show_in_store>
228
+ <depends>
229
+ <enable_product_page>1</enable_product_page>
230
+ </depends>
231
+ </product_page_enable_3>
232
+ <product_page_id_3 module="tastehit_productrecommendation" translate="label">
233
+ <label>Product page widget3 ID</label>
234
+ <frontend_type>text</frontend_type>
235
+ <sort_order>60</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>
239
+ <depends>
240
+ <product_page_enable_1>1</product_page_enable_1>
241
+ </depends>
242
+ </product_page_id_3>
243
+ <product_page_display_3 module="tastehit_productrecommendation" translate="label">
244
+ <label>Product page widget3 placement</label>
245
+ <frontend_type>select</frontend_type>
246
+ <source_model>tastehit_productrecommendation/system_config_source_placement_products</source_model>
247
+ <sort_order>70</sort_order>
248
+ <show_in_default>1</show_in_default>
249
+ <show_in_website>1</show_in_website>
250
+ <show_in_store>1</show_in_store>
251
+ <depends>
252
+ <product_page_enable_3>1</product_page_enable_3>
253
+ </depends>
254
+ </product_page_display_3>
255
+
256
+
257
+ <heading_home_page module="tastehit_productrecommendation" translate="label">
258
+ <label>Home Page Widgets</label>
259
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
260
+ <sort_order>200</sort_order>
261
+ <show_in_default>1</show_in_default>
262
+ <show_in_website>1</show_in_website>
263
+ <show_in_store>1</show_in_store>
264
+ </heading_home_page>
265
+ <enable_home_page>
266
+ <label>Display on Home Page</label>
267
+ <frontend_type>select</frontend_type>
268
+ <source_model>adminhtml/system_config_source_yesno</source_model>
269
+ <sort_order>205</sort_order>
270
+ <show_in_default>1</show_in_default>
271
+ <show_in_website>1</show_in_website>
272
+ <show_in_store>1</show_in_store>
273
+ <comment><![CDATA[For custom position please edit you CMS page and put {{block type="tastehit_productrecommendation/home" widget_id="WIDGET_ID" }}]]></comment>
274
+ </enable_home_page>
275
+ <home_page_enable_1 module="tastehit_productrecommendation" translate="label">
276
+ <label>Display Widget1</label>
277
+ <frontend_type>select</frontend_type>
278
+ <source_model>adminhtml/system_config_source_yesno</source_model>
279
+ <sort_order>210</sort_order>
280
+ <show_in_default>1</show_in_default>
281
+ <show_in_website>1</show_in_website>
282
+ <show_in_store>1</show_in_store>
283
+ <depends>
284
+ <enable_home_page>1</enable_home_page>
285
+ </depends>
286
+ </home_page_enable_1>
287
+ <home_page_id_1 module="tastehit_productrecommendation" translate="label">
288
+ <label>Home page widget1 ID</label>
289
+ <frontend_type>text</frontend_type>
290
+ <sort_order>220</sort_order>
291
+ <show_in_default>1</show_in_default>
292
+ <show_in_website>1</show_in_website>
293
+ <show_in_store>1</show_in_store>
294
+ <depends>
295
+ <home_page_enable_1>1</home_page_enable_1>
296
+ </depends>
297
+ </home_page_id_1>
298
+ <home_page_display_1 module="tastehit_productrecommendation" translate="label">
299
+ <label>Product page widget1 placement</label>
300
+ <frontend_type>select</frontend_type>
301
+ <source_model>tastehit_productrecommendation/system_config_source_placement_home</source_model>
302
+ <sort_order>230</sort_order>
303
+ <show_in_default>1</show_in_default>
304
+ <show_in_website>1</show_in_website>
305
+ <show_in_store>1</show_in_store>
306
+ <depends>
307
+ <home_page_enable_1>1</home_page_enable_1>
308
+ </depends>
309
+ </home_page_display_1>
310
+
311
+ <home_page_enable_2 module="tastehit_productrecommendation" translate="label">
312
+ <label>Display Widget2</label>
313
+ <frontend_type>select</frontend_type>
314
+ <source_model>adminhtml/system_config_source_yesno</source_model>
315
+ <sort_order>235</sort_order>
316
+ <show_in_default>1</show_in_default>
317
+ <show_in_website>1</show_in_website>
318
+ <show_in_store>1</show_in_store>
319
+ <depends>
320
+ <enable_home_page>1</enable_home_page>
321
+ </depends>
322
+ </home_page_enable_2>
323
+ <home_page_id_2 module="tastehit_productrecommendation" translate="label">
324
+ <label>Home page widget2 ID</label>
325
+ <frontend_type>text</frontend_type>
326
+ <sort_order>240</sort_order>
327
+ <show_in_default>1</show_in_default>
328
+ <show_in_website>1</show_in_website>
329
+ <show_in_store>1</show_in_store>
330
+ <depends>
331
+ <home_page_enable_2>1</home_page_enable_2>
332
+ </depends>
333
+ </home_page_id_2>
334
+ <home_page_display_2 module="tastehit_productrecommendation" translate="label">
335
+ <label>Product page widget2 placement</label>
336
+ <frontend_type>select</frontend_type>
337
+ <source_model>tastehit_productrecommendation/system_config_source_placement_home</source_model>
338
+ <sort_order>250</sort_order>
339
+ <show_in_default>1</show_in_default>
340
+ <show_in_website>1</show_in_website>
341
+ <show_in_store>1</show_in_store>
342
+ <depends>
343
+ <home_page_enable_2>1</home_page_enable_2>
344
+ </depends>
345
+ </home_page_display_2>
346
+
347
+ <home_page_enable_3 module="tastehit_productrecommendation" translate="label">
348
+ <label>Display Widget3</label>
349
+ <frontend_type>select</frontend_type>
350
+ <source_model>adminhtml/system_config_source_yesno</source_model>
351
+ <sort_order>255</sort_order>
352
+ <show_in_default>1</show_in_default>
353
+ <show_in_website>1</show_in_website>
354
+ <show_in_store>1</show_in_store>
355
+ <depends>
356
+ <enable_home_page>1</enable_home_page>
357
+ </depends>
358
+ </home_page_enable_3>
359
+ <home_page_id_3 module="tastehit_productrecommendation" translate="label">
360
+ <label>Home page widget3 ID</label>
361
+ <frontend_type>text</frontend_type>
362
+ <sort_order>260</sort_order>
363
+ <show_in_default>1</show_in_default>
364
+ <show_in_website>1</show_in_website>
365
+ <show_in_store>1</show_in_store>
366
+ <depends>
367
+ <home_page_enable_3>1</home_page_enable_3>
368
+ </depends>
369
+ </home_page_id_3>
370
+ <home_page_display_3 module="tastehit_productrecommendation" translate="label">
371
+ <label>Product page widget3 placement</label>
372
+ <frontend_type>select</frontend_type>
373
+ <source_model>tastehit_productrecommendation/system_config_source_placement_home</source_model>
374
+ <sort_order>270</sort_order>
375
+ <show_in_default>1</show_in_default>
376
+ <show_in_website>1</show_in_website>
377
+ <show_in_store>1</show_in_store>
378
+ <depends>
379
+ <home_page_enable_3>1</home_page_enable_3>
380
+ </depends>
381
+ </home_page_display_3>
382
+
383
+ <heading_category_pages module="tastehit_productrecommendation" translate="label">
384
+ <label>Category Pages Widgets</label>
385
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
386
+ <sort_order>300</sort_order>
387
+ <show_in_default>1</show_in_default>
388
+ <show_in_website>1</show_in_website>
389
+ <show_in_store>1</show_in_store>
390
+ </heading_category_pages>
391
+ <enable_category_page>
392
+ <label>Display on Category Pages</label>
393
+ <frontend_type>select</frontend_type>
394
+ <source_model>adminhtml/system_config_source_yesno</source_model>
395
+ <sort_order>305</sort_order>
396
+ <show_in_default>1</show_in_default>
397
+ <show_in_website>1</show_in_website>
398
+ <show_in_store>1</show_in_store>
399
+ </enable_category_page>
400
+ <category_page_enable_1 module="tastehit_productrecommendation" translate="label">
401
+ <label>Display Widget1</label>
402
+ <frontend_type>select</frontend_type>
403
+ <source_model>adminhtml/system_config_source_yesno</source_model>
404
+ <sort_order>310</sort_order>
405
+ <show_in_default>1</show_in_default>
406
+ <show_in_website>1</show_in_website>
407
+ <show_in_store>1</show_in_store>
408
+ <depends>
409
+ <enable_category_page>1</enable_category_page>
410
+ </depends>
411
+ </category_page_enable_1>
412
+ <category_page_id_1 module="tastehit_productrecommendation" translate="label">
413
+ <label>Category page widget1 ID</label>
414
+ <frontend_type>text</frontend_type>
415
+ <sort_order>320</sort_order>
416
+ <show_in_default>1</show_in_default>
417
+ <show_in_website>1</show_in_website>
418
+ <show_in_store>1</show_in_store>
419
+ <depends>
420
+ <category_page_enable_1>1</category_page_enable_1>
421
+ </depends>
422
+ </category_page_id_1>
423
+ <category_page_display_1 module="tastehit_productrecommendation" translate="label">
424
+ <label>Category page widget1 placement</label>
425
+ <frontend_type>select</frontend_type>
426
+ <source_model>tastehit_productrecommendation/system_config_source_placement_category</source_model>
427
+ <sort_order>330</sort_order>
428
+ <show_in_default>1</show_in_default>
429
+ <show_in_website>1</show_in_website>
430
+ <show_in_store>1</show_in_store>
431
+ <depends>
432
+ <category_page_enable_1>1</category_page_enable_1>
433
+ </depends>
434
+ </category_page_display_1>
435
+
436
+ <category_page_enable_2 module="tastehit_productrecommendation" translate="label">
437
+ <label>Display Widget2</label>
438
+ <frontend_type>select</frontend_type>
439
+ <source_model>adminhtml/system_config_source_yesno</source_model>
440
+ <sort_order>335</sort_order>
441
+ <show_in_default>1</show_in_default>
442
+ <show_in_website>1</show_in_website>
443
+ <show_in_store>1</show_in_store>
444
+ <depends>
445
+ <enable_category_page>1</enable_category_page>
446
+ </depends>
447
+ </category_page_enable_2>
448
+ <category_page_id_2 module="tastehit_productrecommendation" translate="label">
449
+ <label>Category page widget2 ID</label>
450
+ <frontend_type>text</frontend_type>
451
+ <sort_order>340</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
+ <depends>
456
+ <category_page_enable_2>1</category_page_enable_2>
457
+ </depends>
458
+ </category_page_id_2>
459
+ <category_page_display_2 module="tastehit_productrecommendation" translate="label">
460
+ <label>Category page widget2 placement</label>
461
+ <frontend_type>select</frontend_type>
462
+ <source_model>tastehit_productrecommendation/system_config_source_placement_category</source_model>
463
+ <sort_order>350</sort_order>
464
+ <show_in_default>1</show_in_default>
465
+ <show_in_website>1</show_in_website>
466
+ <show_in_store>1</show_in_store>
467
+ <depends>
468
+ <category_page_enable_2>1</category_page_enable_2>
469
+ </depends>
470
+ </category_page_display_2>
471
+
472
+ <category_page_enable_3 module="tastehit_productrecommendation" translate="label">
473
+ <label>Display Widget3</label>
474
+ <frontend_type>select</frontend_type>
475
+ <source_model>adminhtml/system_config_source_yesno</source_model>
476
+ <sort_order>355</sort_order>
477
+ <show_in_default>1</show_in_default>
478
+ <show_in_website>1</show_in_website>
479
+ <show_in_store>1</show_in_store>
480
+ <depends>
481
+ <enable_category_page>1</enable_category_page>
482
+ </depends>
483
+ </category_page_enable_3>
484
+ <category_page_id_3 module="tastehit_productrecommendation" translate="label">
485
+ <label>Category page widget3 ID</label>
486
+ <frontend_type>text</frontend_type>
487
+ <sort_order>360</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
+ <depends>
492
+ <category_page_enable_3>1</category_page_enable_3>
493
+ </depends>
494
+ </category_page_id_3>
495
+ <category_page_display_3 module="tastehit_productrecommendation" translate="label">
496
+ <label>Category page widget3 placement</label>
497
+ <frontend_type>select</frontend_type>
498
+ <source_model>tastehit_productrecommendation/system_config_source_placement_category</source_model>
499
+ <sort_order>370</sort_order>
500
+ <show_in_default>1</show_in_default>
501
+ <show_in_website>1</show_in_website>
502
+ <show_in_store>1</show_in_store>
503
+ <depends>
504
+ <category_page_enable_3>1</category_page_enable_3>
505
+ </depends>
506
+ </category_page_display_3>
507
+
508
+ </fields>
509
+ </placement>
510
+ </groups>
511
+ </productrecommendation>
512
+ </sections>
513
+ </config>
app/code/community/Tastehit/ProductRecommendation/sql/tastehit_productrecommendation_setup/install-0.1.0.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ /* @var $installer Mage_Core_Model_Resource_Setup */
11
+ $installer = $this;
12
+
13
+ $installer->startSetup();
14
+
15
+ $installer->endSetup();
app/code/community/Tastehit/ProductRecommendation/sql/tastehit_productrecommendation_setup/upgrade-0.1.0-0.1.1.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ProductRecommendation
4
+ *
5
+ * @package Tastehit_ProductRecommendation
6
+ * @author Tastehit
7
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ */
10
+ /* @var $installer Mage_Core_Model_Resource_Setup */
11
+ $installer = $this;
12
+
13
+ $installer->startSetup();
14
+
15
+ $whitelistBlock = Mage::getModel('admin/block')->load('tastehit_productrecommendation/home', 'block_name');
16
+ $whitelistBlock->setData('block_name', 'tastehit_productrecommendation/home');
17
+ $whitelistBlock->setData('is_allowed', 1);
18
+ $whitelistBlock->save();
19
+
20
+ $installer->endSetup();
app/design/adminhtml/default/default/template/tastehit/system/config/export-button.phtml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ //<![CDATA[
3
+ function export_now() {
4
+ new Ajax.Request('<?php echo $this->getAjaxUrl() ?>', {
5
+ method: 'get',
6
+ onSuccess: function(transport){
7
+ if (transport.responseText){
8
+ alert('Export done')
9
+ }
10
+ }
11
+ });
12
+ }
13
+ //]]>
14
+ </script>
15
+
16
+ <?php echo $this->getButtonHtml() ?>
app/design/frontend/base/default/layout/tastehit_productrecommendation.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * ProductRecommendation
5
+ *
6
+ * @package Tastehit_ProductRecommendation
7
+ * @author Tastehit
8
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
9
+ * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License (GPL 2.0)
10
+ */
11
+ -->
12
+ <layout>
13
+
14
+ <default>
15
+ <reference name="before_body_end">
16
+ <block type="tastehit_productrecommendation/js" name="tastehit.js" ifconfig="productrecommendation/general/enable" />
17
+ </reference>
18
+ </default>
19
+
20
+ </layout>
app/design/frontend/base/default/template/tastehit/js.phtml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $_helper = Mage::helper('tastehit_productrecommendation'); ?>
2
+ <?php if ($_helper->isEnabled()): ?>
3
+ <script type="text/javascript">
4
+ //<![CDATA[
5
+ var _thq = _thq || [];
6
+ _thq.push(['setId', '<?php echo $_helper->getCustomerId(); ?>']);
7
+ _thq.push(['trackPageView']);
8
+ _thq.push(['trackEvents']);
9
+ _thq.push(['detectChanges']);
10
+ _thq.push(['displaySmartMenu']);
11
+
12
+ (function() {
13
+ var th=document.createElement('script');
14
+ th.type='text/javascript';th.async=true;
15
+ th.src=('https:'==document.location.protocol?
16
+ 'https://':'http://') +
17
+ 'www.tastehit.com/static/th.js';
18
+ var s=document.getElementsByTagName('script')[0];
19
+ s.parentNode.insertBefore(th, s);
20
+ })();
21
+ //]]>
22
+ </script>
23
+ <?php endif; ?>
app/etc/modules/Tastehit_ProductRecommendation.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * ProductRecommendation
5
+ *
6
+ * @package Tastehit_ProductRecommendation
7
+ * @author Tastehit
8
+ * @copyright Copyright (c) 2016 Tastehit. (https://www.tastehit.com)
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+ -->
12
+ <config>
13
+ <modules>
14
+ <Tastehit_ProductRecommendation>
15
+ <active>true</active>
16
+ <codePool>community</codePool>
17
+ </Tastehit_ProductRecommendation>
18
+ </modules>
19
+ </config>
package.xml ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Tastehit_ProductRecommendation</name>
4
+ <version>0.1.2</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">OSL 3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>TasteHit is a suite of personalization tools which adapt your Magento shop to each unique visitor's behavior.</summary>
10
+ <description>&lt;h2&gt;What is TasteHit?&lt;/h2&gt;&#xD;
11
+ Build an Amazon-like personalized browsing experience for every single visitor. TasteHit analyzes the behaviors of your visitors and displays the most relevant products from the shop to each unique visitor, in real-time.&#xD;
12
+ &lt;br&gt;&lt;br&gt;&#xD;
13
+ &lt;h2&gt;How does it work?&lt;/h2&gt;&#xD;
14
+ TasteHit collects anonymous data on your visitors (i.e. who clicked on what and when). We apply predictive algorithms on this data with the goal of predicting which product each visitor is likely to buy. We take into account the behavior of the user, the characteristics of your products (such as popularitya and price) and the specific rules you want to put in place.&#xD;
15
+ &lt;br&gt;&#xD;
16
+ By showing to visitors what is relevant to them, we help them discover products they will like. This increases your conversion rate and makes your visitors come back more often.&#xD;
17
+ &lt;br&gt;&lt;br&gt;&#xD;
18
+ &lt;h2&gt;Features&lt;/h2&gt;&#xD;
19
+ &lt;br&gt;&lt;br&gt;&lt;b&gt;Increase your sales&lt;/b&gt;&lt;br&gt;&#xD;
20
+ Using predictive algorithms, TasteHit is completely autonomous in finding the right product for the right visitor at the right time. We do that millions of times per day, at every page load, to increase your sales and make sure each visitor sees products he is likely to buy. &#xD;
21
+ &#xD;
22
+ &lt;br&gt;&lt;br&gt;&lt;b&gt;Easy to install&lt;/b&gt;&lt;br&gt;&#xD;
23
+ TasteHit is installed in one click. Just install our free Magento 1 or 2 extension, and you are ready to go. &#xD;
24
+ &#xD;
25
+ &lt;br&gt;&lt;br&gt;&lt;b&gt;Learning algorithms&lt;/b&gt;&lt;br&gt;&#xD;
26
+ The intelligence behind TasteHit is based on years of research in machine learning, the science of finding patterns in data automatically. We provide you with different algorithms which take into account different characteristics of products and users (popularity and sales performance of products, user browsing history, stock information, novelty).&#xD;
27
+ &#xD;
28
+ &lt;br&gt;&lt;br&gt;&lt;b&gt;Stay in control&lt;/b&gt;&lt;br&gt;&#xD;
29
+ We offer you an easy to use graphical configurator which allows you to tune the graphics, algorithms and filters of the product widgets you insert on your web pages and in your emails. All changes you make can be instantly applied in production. No technical expertise required.&#xD;
30
+ &lt;br&gt;&#xD;
31
+ The algorithms we provide can be tuned in different ways and you have complete control over what types of products you want TasteHit to recommend. You can easily set up filters which exclude certain categories of products.&#xD;
32
+ &#xD;
33
+ &lt;br&gt;&lt;br&gt;&lt;b&gt;Performance tracking and insights&lt;/b&gt;&lt;br&gt;&#xD;
34
+ TasteHit's dashboard gives you a detailed monitoring of the solution's performance. Track the performance of individual widgets, monitor the impact of your configuration changes and make sure you get what is best for your shop. Through this dashboard, we also give you access to useful insights on products (what products are being visited before/after a specific product, what products are bought together, what recommendations are the most effective/the most displayed). Everything is there to help you make your shop more interesting for your visitors.&#xD;
35
+ &#xD;
36
+ &lt;br&gt;&lt;br&gt;&lt;b&gt;Web and email&lt;/b&gt;&lt;br&gt;&#xD;
37
+ TasteHit widgets can be inserted in both web pages and emails. We offer the possibility to add personalized widgets to transactional emails as well as newsletters you may generate with external tools.&#xD;
38
+ &#xD;
39
+ &lt;br&gt;&lt;br&gt;&lt;b&gt;Developer friendly API&lt;/b&gt;&lt;br&gt;&#xD;
40
+ Do you want a specific feature? TasteHit provides a public API which can be used to create new personalized experiences: a specific widget, a new fully personalized page, a game app based on products from your shop.&#xD;
41
+ &#xD;
42
+ &lt;br&gt;&lt;br&gt;&lt;b&gt;Friendly pricing&lt;/b&gt;&lt;br&gt;&#xD;
43
+ Our pricing is based on the number of monthly visitors your site receives. Sites that have fewer than 10,000 visitors can use TasteHit for free. We don't take a commission on your sales through TasteHit, we are just happy to help you sell more. You don't have to worry about the features and the number of widgets you use: there are no restrictions on how you use TasteHit on your Magento shop.&#xD;
44
+ </description>
45
+ <notes>Stable version of the Magento extension for product recommendation from Tastehit</notes>
46
+ <authors><author><name>Christopher Burger</name><user>TasteHit</user><email>contact@tastehit.com</email></author></authors>
47
+ <date>2016-12-03</date>
48
+ <time>06:31:04</time>
49
+ <contents><target name="magecommunity"><dir name="Tastehit"><dir name="ProductRecommendation"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Button"><file name="Export.php" hash="e473c372f60dc64b2f024fc25eef6ec5"/></dir><file name="Info.php" hash="ad45bd1500d2a308fa79bd11833bb09f"/></dir></dir></dir><dir name="Catalog"><file name="Category.php" hash="6aea54c83bbbc0579542448bf7bbe905"/><file name="Product.php" hash="44396420129e22cb25aadd7a73ba1d7a"/></dir><file name="Home.php" hash="ea0ec3c659999324a7f722efb829fdc7"/><file name="Js.php" hash="8e76119ddf07590f928cf1d75282aa3c"/></dir><dir name="Helper"><file name="Data.php" hash="add132e7eb15280787e0665155fd6e5a"/></dir><dir name="Model"><file name="Observer.php" hash="0d5947fa3112e53621b9e3843f012445"/><dir name="System"><dir name="Config"><dir name="Backend"><file name="Cron.php" hash="2c9a05a9e306ba5e369a0524ba19cceb"/></dir><dir name="Source"><dir name="Placement"><file name="Category.php" hash="fe3002902b189c5c6fbac3539de519e0"/><file name="Home.php" hash="856307bb4aa8649562138642b4cd4fcb"/><file name="Products.php" hash="8b32ddbfb225882707f62a87cf7f636c"/></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="TastehitController.php" hash="96f37f7bf13b4a6ec6596b2cdf983163"/></dir></dir><dir name="data"><dir name="tastehit_productrecommendation_setup"><file name="data-install-0.1.0.php" hash="2b5117a4df5ffdc17559bd2a28c6bd0d"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="7f05f7dece08d1a9848134f252d4234b"/><file name="config.xml" hash="5f4d3ffb9bc14f6521f2c5e89198c9ce"/><file name="system.xml" hash="08b020b680b5dd7b064e305abf8312ff"/></dir><dir name="sql"><dir name="tastehit_productrecommendation_setup"><file name="install-0.1.0.php" hash="3a5886eb912fb7e924daee6363e96f17"/><file name="upgrade-0.1.0-0.1.1.php" hash="db8ae3210ea836e1f1d6056975d7587b"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Tastehit_ProductRecommendation.xml" hash="df3f921875fdd5e84193eab39abc24c0"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="tastehit"><dir name="system"><dir name="config"><file name="export-button.phtml" hash="712516c97b48d8cbfe9ade5c3af20091"/></dir></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="tastehit_productrecommendation.xml" hash="78da1a0f77cff28305ae006bf97618c6"/></dir><dir name="template"><dir name="tastehit"><file name="js.phtml" hash="8386a68481e69f40adb9a40db55d4b43"/></dir></dir></dir></dir></dir></target></contents>
50
+ <compatible/>
51
+ <dependencies><required><php><min>5.3.0</min><max>7.0.8</max></php></required></dependencies>
52
+ </package>