HawkSearch_Datafeed - Version 1.0.0.0

Version Notes

Should have url generation for Magento 1.13
Should have category generation for attributes file

Download this release

Release Info

Developer Hawksearch Inc.
Extension HawkSearch_Datafeed
Version 1.0.0.0
Comparing to
See all releases


Version 1.0.0.0

Files changed (22) hide show
  1. app/code/community/Hawksearch/Datafeed/Block/System/Config/Form.php +20 -0
  2. app/code/community/Hawksearch/Datafeed/Block/System/Config/Form/Field/Version.php +24 -0
  3. app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generate.php +75 -0
  4. app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generate/Js.php +33 -0
  5. app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generateimagecache.php +75 -0
  6. app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generateimagecache/Js.php +33 -0
  7. app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Next.php +45 -0
  8. app/code/community/Hawksearch/Datafeed/Helper/Data.php +225 -0
  9. app/code/community/Hawksearch/Datafeed/Helper/Feed.php +219 -0
  10. app/code/community/Hawksearch/Datafeed/Model/Cron.php +41 -0
  11. app/code/community/Hawksearch/Datafeed/Model/Email.php +55 -0
  12. app/code/community/Hawksearch/Datafeed/Model/Feed.php +928 -0
  13. app/code/community/Hawksearch/Datafeed/Model/System/Config/Backend/Cron.php +77 -0
  14. app/code/community/Hawksearch/Datafeed/controllers/SearchController.php +178 -0
  15. app/code/community/Hawksearch/Datafeed/etc/adminhtml.xml +32 -0
  16. app/code/community/Hawksearch/Datafeed/etc/config.xml +101 -0
  17. app/code/community/Hawksearch/Datafeed/etc/system.xml +235 -0
  18. app/code/community/Hawksearch/Datafeed/sql/hawksearch_datafeed_setup/install-1.0.0.0.php +19 -0
  19. app/design/adminhtml/default/default/template/hawksearch/search/sysconfig/generate/js.phtml +50 -0
  20. app/design/adminhtml/default/default/template/hawksearch/search/sysconfig/generateimagecache/js.phtml +50 -0
  21. app/etc/modules/Hawksearch_Datafeed.xml +9 -0
  22. package.xml +19 -0
app/code/community/Hawksearch/Datafeed/Block/System/Config/Form.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Block_System_Config_Form extends Mage_Adminhtml_Block_System_Config_Form {
12
+
13
+ protected function _getAdditionalElementTypes()
14
+ {
15
+ $types = parent::_getAdditionalElementTypes();
16
+ $types["version"] = Mage::getConfig()->getBlockClassName('hawksearch_datafeed/system_config_form_field_version');
17
+ return $types;
18
+ }
19
+
20
+ }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Form/Field/Version.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Block_System_Config_Form_Field_Version extends Mage_Adminhtml_Block_System_Config_Form_Field //extends Varien_Data_Form_Element_Abstract
12
+ {
13
+
14
+ public function getElementHtml() {
15
+
16
+ $modules = Mage::getConfig()->getNode('modules')->children();
17
+ $info = $modules->Hawksearch_Datafeed->asArray();
18
+
19
+ return isset($info['version']) ? $info['version'] : '';
20
+ }
21
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
22
+ return $this->getElementHtml();
23
+ }
24
+ }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generate.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+
12
+ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Generate extends Mage_Adminhtml_Block_System_Config_Form_Field {
13
+
14
+ protected $_buttonId = "generate_feed_button";
15
+
16
+ /**
17
+ * Programmatically include the generate feed javascript in the adminhtml JS block.
18
+ *
19
+ * @return <type>
20
+ */
21
+
22
+ protected function _prepareLayout() {
23
+ $block = $this->getLayout()->createBlock("hawksearch_datafeed/system_config_frontend_feed_generate_js");
24
+ $block->setData("button_id", $this->_buttonId);
25
+
26
+ $this->getLayout()->getBlock('js')->append($block);
27
+ return parent::_prepareLayout();
28
+ }
29
+
30
+ /**
31
+ * Return element html
32
+ *
33
+ * @param Varien_Data_Form_Element_Abstract $element
34
+ * @return string
35
+ */
36
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
37
+ $button = $this->getButtonHtml();
38
+
39
+ $notice = "";
40
+ if ($this->_feedGenIsLocked()) {
41
+ $notice = "<p id='hawksearch_display_msg' class='note'>".Mage::getModel("hawksearch_datafeed/feed")->getAjaxNotice()."</p>";
42
+ }
43
+ return $button.$notice;
44
+ }
45
+
46
+ /**
47
+ * Generate button html for the feed button
48
+ *
49
+ * @return string
50
+ */
51
+ public function getButtonHtml() {
52
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
53
+ ->setData(array(
54
+ 'id' => $this->_buttonId,
55
+ 'label' => $this->helper('hawksearch_datafeed')->__('Generate Feeds'),
56
+ 'onclick' => 'javascript:hawkSearchFeed.generateFeed(); return false;'
57
+ ));
58
+
59
+ if ($this->_feedGenIsLocked()) {
60
+ $button->setData('class', 'disabled');
61
+ }
62
+
63
+ return $button->toHtml();
64
+ }
65
+
66
+ /**
67
+ * Check to see if there are any locks for any feeds
68
+ *
69
+ * @return boolean
70
+ */
71
+ protected function _feedGenIsLocked() {
72
+ return Mage::helper('hawksearch_datafeed/feed')->thereAreFeedLocks();
73
+ }
74
+
75
+ }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generate/Js.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Generate_Js extends Mage_Adminhtml_Block_Template {
12
+
13
+ /**
14
+ * Sets javascript template to be included in the adminhtml js text_list block
15
+ */
16
+ protected function _construct() {
17
+ parent::_construct();
18
+ $this->setTemplate('hawksearch/search/sysconfig/generate/js.phtml');
19
+ }
20
+
21
+ /**
22
+ * Returns the run all feeds async url
23
+ *
24
+ * @return string
25
+ */
26
+ public function getGenerateUrl() {
27
+ $curStore = Mage::app()->getStore();
28
+ Mage::app()->setCurrentStore(1); //default storeID will always be 1
29
+ $myUrl = Mage::getUrl('hawksearch_datafeed/search/runFeedGeneration');
30
+ Mage::app()->setCurrentStore($curStore);
31
+ return $myUrl;
32
+ }
33
+ }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generateimagecache.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+
12
+ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Generateimagecache extends Mage_Adminhtml_Block_System_Config_Form_Field {
13
+
14
+ protected $_buttonId = "generateimagecache_feed_button";
15
+
16
+ /**
17
+ * Programmatically include the generate feed javascript in the adminhtml JS block.
18
+ *
19
+ * @return <type>
20
+ */
21
+
22
+ protected function _prepareLayout() {
23
+ $block = $this->getLayout()->createBlock("hawksearch_datafeed/system_config_frontend_feed_generateimagecache_js");
24
+ $block->setData("button_id", $this->_buttonId);
25
+
26
+ $this->getLayout()->getBlock('js')->append($block);
27
+ return parent::_prepareLayout();
28
+ }
29
+
30
+ /**
31
+ * Return element html
32
+ *
33
+ * @param Varien_Data_Form_Element_Abstract $element
34
+ * @return string
35
+ */
36
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
37
+ $button = $this->getButtonHtml();
38
+
39
+ $notice = "";
40
+ if ($this->_feedGenIsLocked()) {
41
+ $notice = "<p id='hawksearch_display_msg' class='note'>".Mage::getModel("hawksearch_datafeed/feed")->getAjaxNoticeImageCache()."</p>";
42
+ }
43
+ return $button.$notice;
44
+ }
45
+
46
+ /**
47
+ * Generate button html for the feed button
48
+ *
49
+ * @return string
50
+ */
51
+ public function getButtonHtml() {
52
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
53
+ ->setData(array(
54
+ 'id' => $this->_buttonId,
55
+ 'label' => $this->helper('hawksearch_datafeed')->__('Generate Image Cache'),
56
+ 'onclick' => 'javascript:hawkSearchCache.generateImageCache(); return false;'
57
+ ));
58
+
59
+ if ($this->_feedGenIsLocked()) {
60
+ $button->setData('class', 'disabled');
61
+ }
62
+
63
+ return $button->toHtml();
64
+ }
65
+
66
+ /**
67
+ * Check to see if there are any locks for any feeds
68
+ *
69
+ * @return boolean
70
+ */
71
+ protected function _feedGenIsLocked() {
72
+ return Mage::helper('hawksearch_datafeed/feed')->thereAreFeedLocks();
73
+ }
74
+
75
+ }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generateimagecache/Js.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Generateimagecache_Js extends Mage_Adminhtml_Block_Template {
12
+
13
+ /**
14
+ * Sets javascript template to be included in the adminhtml js text_list block
15
+ */
16
+ protected function _construct() {
17
+ parent::_construct();
18
+ $this->setTemplate('hawksearch/search/sysconfig/generateimagecache/js.phtml');
19
+ }
20
+
21
+ /**
22
+ * Returns the run all feeds async url
23
+ *
24
+ * @return string
25
+ */
26
+ public function getGenerateUrl() {
27
+ $curStore = Mage::app()->getStore();
28
+ Mage::app()->setCurrentStore(1); //default storeID will always be 1
29
+ $myUrl = Mage::getUrl('hawksearch_datafeed/search/runImageCacheGeneration');
30
+ Mage::app()->setCurrentStore($curStore);
31
+ return $myUrl;
32
+ }
33
+ }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Next.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Next extends Mage_Adminhtml_Block_System_Config_Form_Field {
12
+
13
+ /**
14
+ * Returns the config xml set job code for the cron job
15
+ *
16
+ * @return string
17
+ */
18
+ protected function _getHawkSearchCronJobCode() {
19
+
20
+ $jobCode = Mage::getConfig()->getNode('crontab/hawksearch_datafeed/job_code');
21
+
22
+ if (!$jobCode) {
23
+ if(Mage::helper('hawksearch_datafeed/data')->isLoggingEnabled()) {
24
+ Mage::log("No cron job code set for hawksearch_datafeed cron job in config xml.", null,'hawksearch_errors.log');
25
+ }
26
+ Mage::throwException("No cron job code set for hawksearch_datafeed cron job in config xml.");
27
+ }
28
+ return $jobCode;
29
+ }
30
+
31
+ /**
32
+ * Renders the next scheduled cron time.
33
+ *
34
+ * @param Varien_Data_Form_Element_Abstract $element
35
+ * @return <type>
36
+ */
37
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
38
+ $helper = Mage::helper('hawksearch_datafeed');
39
+ $scheduledAt = $helper->getNextRunDateFromCronTime();
40
+
41
+ return $scheduledAt;
42
+ }
43
+
44
+
45
+ }
app/code/community/Hawksearch/Datafeed/Helper/Data.php ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Helper_Data extends Mage_Core_Helper_Abstract {
12
+
13
+ const SECTION = "hawksearch_datafeed/";
14
+ const GENERAL_GROUP = "general/";
15
+ const FEED_GROUP = "feed/";
16
+ const CRON_GROUP = "cron/";
17
+
18
+ /**
19
+ * Returns true/false on whether or not the module is enabled
20
+ *
21
+ * @return boolean
22
+ */
23
+
24
+ public function isEnabled($store_id = 0) {
25
+ return (bool) Mage::app()->getStore($store_id)->getConfig(self::SECTION . self::GENERAL_GROUP . 'enabled');
26
+ }
27
+
28
+ /**
29
+ * Returns an integer which is the log level
30
+ *
31
+ * @return int
32
+ */
33
+ public function isLoggingEnabled($store_id = 0) {
34
+ return (int) Mage::app()->getStore($store_id)->getConfig(self::SECTION . self::GENERAL_GROUP . 'logging_enabled');
35
+ }
36
+
37
+ /**
38
+ * Returns true/false on whether or not to include out of stock items in feed
39
+ *
40
+ * @return boolean
41
+ */
42
+ public function isIncludeOutOfStockItems($store_id = 0) {
43
+ return (bool) Mage::app()->getStore($store_id)->getConfig(self::SECTION . self::FEED_GROUP . "stockstatus");
44
+ }
45
+
46
+ /**
47
+ * Returns true/false on whether or not to include disabled categories in feed
48
+ *
49
+ * @return boolean
50
+ */
51
+ public function isIncludeDisabledCategories($store_id = 0) {
52
+ return (bool) Mage::app()->getStore($store_id)->getConfig(self::SECTION . self::FEED_GROUP . "categorystatus");
53
+ }
54
+ /**
55
+ * Returns the Batch Limit for Product Export Feed
56
+ *
57
+ * @return string
58
+ */
59
+ public function getBatchLimit() {
60
+ return Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . "batch_limit");
61
+ }
62
+
63
+ /**
64
+ * Returns the Image Width
65
+ *
66
+ * @return string
67
+ */
68
+ public function getImageWidth() {
69
+ return Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . "image_width");
70
+ }
71
+
72
+ /**
73
+ * Returns the Image Height
74
+ *
75
+ * @return string
76
+ */
77
+ public function getImageHeight() {
78
+ return Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . "image_height");
79
+ }
80
+
81
+ /**
82
+ * Returns the Brand Attribute Value for Product Export Feed
83
+ *
84
+ * @return string
85
+ */
86
+ public function getBrandAttribute() {
87
+ return Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . "brand_attribute");
88
+ }
89
+
90
+ public function getAllowDisabledAttribute(){
91
+ $res = Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . "itemstatus");
92
+ if(isset($res) && $res == 0) {
93
+ return false;
94
+ }
95
+ return true;
96
+ }
97
+ /**
98
+ * Returns the email to send notifications to when the cron runs
99
+ *
100
+ * @return string
101
+ */
102
+ public function getCronEmail() {
103
+ return Mage::getStoreConfig(self::SECTION . self::CRON_GROUP . "email");
104
+ }
105
+
106
+ /**
107
+ * Returns the frequency that the cron should run.
108
+ *
109
+ * @return string
110
+ */
111
+ public function getCronFrequency() {
112
+ return Mage::getStoreConfig(self::SECTION . self::CRON_GROUP . "frequency");
113
+ }
114
+
115
+ /**
116
+ * Returns the time of day that the cron should run at.
117
+ *
118
+ * @return string
119
+ */
120
+ public function getCronTime() {
121
+ return Mage::getStoreConfig(self::SECTION . self::CRON_GROUP . "time");
122
+ }
123
+
124
+ /**
125
+ * Return crontab formatted time for cron set time.
126
+ *
127
+ * @param string $frequency
128
+ * @param array $time
129
+ * @return string
130
+ */
131
+ public function getCronTimeAsCrontab($crontime) {
132
+
133
+ $timescheduled = "";
134
+ switch ($crontime) {
135
+ case "every_minute" :
136
+ $timescheduled = "* * * * *";
137
+ break;
138
+ case "every_5min" :
139
+ $timescheduled = "*/5 * * * *";
140
+ break;
141
+ case "every_15min" :
142
+ $timescheduled = "*/15 * * * *";
143
+ break;
144
+ case "every_30min" :
145
+ $timescheduled = "0,30 * * * *";
146
+ break;
147
+ case "every_hour" :
148
+ $timescheduled = "0 * * * *";
149
+ break;
150
+ case "8_hours" :
151
+ $timescheduled = "0 */8 * * *";
152
+ break;
153
+ case "daily" :
154
+ $timescheduled = "0 0 * * *";
155
+ break;
156
+ default :
157
+ $timescheduled = "";
158
+ }
159
+ return $timescheduled;
160
+ }
161
+
162
+ /**
163
+ * Gets the next run date based on cron settings.
164
+ *
165
+ * @return Zend_Date
166
+ */
167
+ public function getNextRunDateFromCronTime() {
168
+ $now = Mage::app()->getLocale()->date();
169
+ $frequency = $this->getCronFrequency();
170
+ list($hours, $minutes, $seconds) = explode(',', $this->getCronTime());
171
+
172
+ $time = Mage::app()->getLocale()->date();
173
+ $time->setHour($hours)->setMinute($minutes)->setSecond($seconds);
174
+
175
+ //Parse through frequencies
176
+ switch ($frequency) {
177
+ case "D":
178
+ if ($time->compare($now) == -1) {
179
+ $time->addDay(1);
180
+ }
181
+ break;
182
+ case "W":
183
+ $time->setWeekday(7);
184
+ if ($time->compare($now) == -1) {
185
+ $time->addWeek(1);
186
+ }
187
+ break;
188
+ case "M":
189
+ $time->setDay(1);
190
+ if ($time->compare($now) == -1) {
191
+ $time->addMonth(1);
192
+ }
193
+ break;
194
+ }
195
+
196
+ return $time;
197
+ }
198
+
199
+ /**
200
+ * Gets the output file delimiter character
201
+ *
202
+ * @return string
203
+ */
204
+ public function getOutputFileDelimiter() {
205
+ $v = Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . 'output_file_delimiter');
206
+ $o = array('tab' => "\t", 'comma' => ",");
207
+ return isset($o[$v]) ? $o[$v] : "\t";
208
+ }
209
+ public function getBufferSize() {
210
+ $size = Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . 'buffer_size');
211
+ return is_numeric($size) ? $size : null;
212
+ }
213
+ public function getOutputFileExtension() {
214
+ return Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . 'output_file_ext');
215
+ }
216
+ public function getFeedFilePath() {
217
+ return Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . 'feed_path');
218
+ }
219
+ function mtime() {
220
+ list($usec, $sec) = explode(" ", microtime());
221
+ return ((float) $usec + (float) $sec);
222
+ }
223
+
224
+
225
+ }
app/code/community/Hawksearch/Datafeed/Helper/Feed.php ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Helper_Feed {
12
+
13
+ protected $_feedFilePath = null;
14
+
15
+ /**
16
+ * Open socket to feed generation url with store id as passed parameter.
17
+ *
18
+ * @param Mage_Core_Model_Store $store
19
+ * @param array $urlParts
20
+ * @throws Mage_Core_Exception
21
+ */
22
+ #public function postToGenerateFeed($store, $urlParts) {
23
+ public function postToGenerateFeed($urlParts) {
24
+ $feedSocket = @fsockopen($urlParts['host'], 80, $errNo, $errStr, 10);
25
+
26
+ if (!$feedSocket) {
27
+ Mage::throwException("Err. #$errNo: Cannot access feed generation uri.");
28
+ }
29
+
30
+ #$storeParam = "storeId={$store->getId()}";
31
+ $storeParam = "storeId={1}";
32
+ $storeParamLen = strlen($storeParam);
33
+ $EOL = "\r\n";
34
+
35
+ $username = Mage::getStoreConfig('hawksearch_datafeed/feed/optional_htaccess_user', Mage::app ()->getStore ());
36
+ $password = Mage::getStoreConfig('hawksearch_datafeed/feed/optional_htaccess_password', Mage::app ()->getStore ());
37
+
38
+ $request = "POST {$urlParts['path']} HTTP/1.1$EOL";
39
+ $request .= "HOST: {$urlParts['host']}$EOL";
40
+ if($username !="" && $password !="") {
41
+ $request .= "Authorization: Basic " . base64_encode("$username:$password") . $EOL;
42
+ }
43
+ $request .= "Content-Length: $storeParamLen$EOL";
44
+ $request .= "Content-Type: application/x-www-form-urlencoded$EOL";
45
+ $request .= "Connection: Close$EOL$EOL";
46
+ $request .= "$storeParam";
47
+
48
+ $result = fwrite($feedSocket, $request);
49
+
50
+ if (!$result) {
51
+ Mage::throwException("Error writing to feed generation uri.");
52
+ }
53
+
54
+ fclose($feedSocket);
55
+ }
56
+
57
+ /**
58
+ * Returns url that controls feed generation
59
+ *
60
+ * @return string
61
+ */
62
+
63
+ public function getGenerateFeedUrl() {
64
+ $curStore = Mage::app()->getStore();
65
+ Mage::app()->setCurrentStore(1); //default storeID will always be 1
66
+ $myUrl = Mage::getUrl('hawksearch_datafeed/search/generateFeed');
67
+ Mage::app()->setCurrentStore($curStore);
68
+ return $myUrl;
69
+ }
70
+
71
+ /**
72
+ * Asynchronously starts a feed generation for each store
73
+ */
74
+ public function generateFeedsForAllStores() {
75
+ if ($this->thereAreFeedLocks()) {
76
+ Mage::throwException("One or more feeds are being generated. Generation temporarily locked.");
77
+ }
78
+
79
+ if($this->CreateFeedLocks()) {
80
+ $feedUrl = $this->getGenerateFeedUrl();
81
+ $urlParts = parse_url($feedUrl);
82
+
83
+ if(Mage::helper('hawksearch_datafeed/data')->isLoggingEnabled()) {
84
+ Mage::log($feedUrl);
85
+ Mage::log($urlParts);
86
+ }
87
+ try
88
+ {
89
+ $this->postToGenerateFeed($urlParts);
90
+ /*
91
+ $stores = Mage::getResourceModel('core/store_collection');
92
+ foreach($stores as $store) {
93
+ $this->postToGenerateFeed($store, $urlParts);
94
+ }
95
+ */
96
+ }
97
+ catch (Exception $e) {
98
+ Mage::logException($e);
99
+ }
100
+ } else {
101
+ Mage::throwException("Error Generating Feed Locks. Generation temporarily locked.");
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Returns the feed file path
107
+ *
108
+ * @return string
109
+ */
110
+ public function getFeedFilePath() {
111
+ if ($this->_feedFilePath === null) {
112
+ $this->_feedFilePath = $this->makeVarPath(array('hawksearch', 'feeds'));
113
+ }
114
+ return $this->_feedFilePath;
115
+ }
116
+
117
+ /**
118
+ * Create path within var folder if necessary given an array of directory names
119
+ *
120
+ * @param array $directories
121
+ * @return string
122
+ */
123
+ public function makeVarPath($directories) {
124
+ $path = Mage::getBaseDir('var');
125
+ foreach ($directories as $dir) {
126
+ $path .= DS . $dir;
127
+ if (!is_dir($path)) {
128
+ @mkdir($path, 0777);
129
+ }
130
+ }
131
+ return $path;
132
+ }
133
+ /**
134
+ * Remove locks currently in place
135
+ *
136
+ * @return boolean
137
+ */
138
+ public function CreateFeedLocks() {
139
+
140
+ $path = $this->getFeedFilePath();
141
+ $filename = $path . "/hawksearchfeeds.lock";
142
+ $content = date("Y-m-d H:i:s");
143
+
144
+ if(!file_exists($filename))
145
+ {
146
+ $handle = fopen($filename, "w+");
147
+ fclose($handle);
148
+ }
149
+
150
+ if (is_writable($filename)) {
151
+ if (!$handle = fopen($filename, 'w+')) {
152
+ if(Mage::helper('hawksearch_datafeed/data')->isLoggingEnabled()) {
153
+ Mage::log("Cannot open lock file (".$filename.")", null,'hawksearch_errors.log');
154
+ }
155
+ return false;
156
+ }
157
+ if (fwrite($handle, $content) === FALSE) {
158
+ if(Mage::helper('hawksearch_datafeed/data')->isLoggingEnabled()) {
159
+ Mage::log("Cannot write to lock file (".$filename.")", null,'hawksearch_errors.log');
160
+ }
161
+ return false;
162
+ }
163
+ return true;
164
+ fclose($handle);
165
+ }
166
+ return false;
167
+ }
168
+
169
+ /**
170
+ * Whether or not there are feed generation locks currently in place
171
+ *
172
+ * @return boolean
173
+ */
174
+ public function thereAreFeedLocks() {
175
+ $path = $this->getFeedFilePath();
176
+ foreach (scandir($path) as $file) {
177
+ $fullFile = $path.DS.$file;
178
+ if (is_file($fullFile) && !is_dir($fullFile) && is_numeric(strpos($file, '.lock'))) {
179
+ return true;
180
+ }
181
+ }
182
+ return false;
183
+ }
184
+ /**
185
+ * Remove locks currently in place
186
+ *
187
+ * @return boolean
188
+ */
189
+ public function RemoveFeedLocks() {
190
+ $path = $this->getFeedFilePath();
191
+ foreach (scandir($path) as $file) {
192
+ $fullFile = $path.DS.$file;
193
+ if (is_file($fullFile) && !is_dir($fullFile) && is_numeric(strpos($file, '.lock'))) {
194
+ unlink($fullFile);
195
+ return true;
196
+ }
197
+ }
198
+ return false;
199
+ }
200
+
201
+ public function deleteDir($dirPath) {
202
+ if (! is_dir($dirPath)) {
203
+ throw new InvalidArgumentException("$dirPath must be a directory");
204
+ }
205
+ if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
206
+ $dirPath .= '/';
207
+ }
208
+ $files = glob($dirPath . '*', GLOB_MARK);
209
+ foreach ($files as $file) {
210
+ if (is_dir($file)) {
211
+ self::deleteDir($file);
212
+ } else {
213
+ unlink($file);
214
+ }
215
+ }
216
+ rmdir($dirPath);
217
+ }
218
+
219
+ }
app/code/community/Hawksearch/Datafeed/Model/Cron.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Model_Cron {
12
+
13
+ /**
14
+ * Generates the feeds and sends email of status when done
15
+ */
16
+
17
+ public function generateFeeds() {
18
+ if(!Mage::getStoreConfig('hawksearch_datafeed/cron/disabled'))
19
+ {
20
+ try {
21
+ Mage::helper('hawksearch_datafeed/feed')->generateFeedsForAllStores();
22
+ $msg = "HawkSeach Feed Generated!";
23
+ }
24
+ catch (Exception $e) {
25
+ $msg = $e->getMessage();
26
+ }
27
+ catch (Exception $e) {
28
+ $msg = "Unknown Error: {$e->getMessage()} in {$e->getFile()} on line {$e->getLine()}. Please contact HawkSearch.";
29
+ }
30
+
31
+ $this->_sendEmail($msg);
32
+ }
33
+ }
34
+
35
+ /**
36
+ * If there is a system config email set, send out the cron notification email.
37
+ */
38
+ protected function _sendEmail($msg) {
39
+ Mage::getModel('hawksearch_datafeed/email')->setData('msg', $msg)->send();
40
+ }
41
+ }
app/code/community/Hawksearch/Datafeed/Model/Email.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Model_Email extends Mage_Core_Model_Abstract {
12
+
13
+ /**
14
+ * Set up some default variables that can be set from sys config
15
+ */
16
+ public function __construct() {
17
+ $this->setFromName(Mage::getStoreConfig('trans_email/ident_general/name'));
18
+ $this->setFromEmail(Mage::getStoreConfig('trans_email/ident_general/email'));
19
+ $this->setType('text');
20
+ }
21
+
22
+ /**
23
+ * Hawksearch feed generation email subject
24
+ *
25
+ * @return string
26
+ */
27
+ public function getSubject() {
28
+ return "HawkSearch Scheduled Feed Generation";
29
+ }
30
+
31
+ /**
32
+ * Hawksearch feed generation email body
33
+ *
34
+ * @return string
35
+ */
36
+ public function getBody() {
37
+ return <<<BODY
38
+ {$this->getData('msg')}
39
+
40
+ Please check HawkSearch log files for more information (if an error is reported above)
41
+
42
+ Sincerely,
43
+ HawkSearch Administrator
44
+
45
+ BODY;
46
+ }
47
+
48
+ public function send() {
49
+ $email = Mage::helper('hawksearch_datafeed')->getCronEmail();
50
+ if ($email) {
51
+ mail($email, $this->getSubject(), $this->getBody(), "From: {$this->getFromName()} <{$this->getFromEmail()}>\r\nReply-To: {$this->getFromEmail()}");
52
+ }
53
+ }
54
+
55
+ }
app/code/community/Hawksearch/Datafeed/Model/Feed.php ADDED
@@ -0,0 +1,928 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ #error_reporting(E_ALL);
4
+ #ini_set('display_errors', '1');
5
+ /**
6
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
7
+ *
8
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
9
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
10
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
11
+ * PARTICULAR PURPOSE.
12
+ */
13
+ class Hawksearch_Datafeed_Model_Feed extends Mage_Core_Model_Abstract {
14
+ protected $_ajaxNotice,
15
+ $_batchSize,
16
+ $_categoryTypeId,
17
+ $_dbConnection,
18
+ $_excludedFields,
19
+ $_tablePrefix,
20
+ $_entityTypeId,
21
+ $_feedPath,
22
+ $isLoggingEnabled,
23
+ $_totalProductCount,
24
+ $_optionType;
25
+
26
+ private $countryMap;
27
+ private $outputFileDelimiter;
28
+ private $bufferSize;
29
+ private $outputFileExtension;
30
+ protected $multiSelectValues;
31
+
32
+ /**
33
+ * Constructor
34
+ */
35
+ function __construct() {
36
+
37
+ // Ignore user aborts and allow the script
38
+ // to run forever
39
+ ignore_user_abort(true); // If Varnish decides that the results timed out. Browsers are better behaved.
40
+ set_time_limit(0); // Even with DB calls not counting towards execution time, it's still a long running script. Vampiric bite FTW.
41
+ /** @var $helper Hawksearch_Datafeed_Helper_Data */
42
+ $helper = Mage::helper('hawksearch_datafeed/data');
43
+
44
+ $this->_ajaxNotice = 'Generating feeds. Please wait.';
45
+ $this->_tablePrefix = (string)Mage::getConfig()->getTablePrefix();
46
+ $this->_entityTypeId = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId();
47
+ $this->_excludedFields = Mage::getStoreConfig('hawksearch_datafeed/feed/exclude_fields', Mage::app()->getStore());
48
+ $this->_categoryTypeId = Mage::getModel('eav/entity')->setType('catalog_category')->getTypeId();
49
+ $this->isLoggingEnabled = Mage::helper('hawksearch_datafeed/data')->isLoggingEnabled();
50
+ $this->_optionType = Mage::getStoreConfig('hawksearch_datafeed/feed/option_type', Mage::app()->getSafeStore());
51
+
52
+ $this->_feedPath = $helper->getFeedFilePath();
53
+ if (empty($this->_feedPath)) {
54
+ $this->_feedPath = 'var/hawksearch/feeds';
55
+ }
56
+
57
+ $this->_batchSize = $helper->getBatchLimit();
58
+ if (empty($this->_batchSize)) {
59
+ $this->_batchSize = 10000;
60
+ }
61
+
62
+ $this->_imageWidth = $helper->getImageWidth();
63
+ if (empty($this->_imageWidth)) {
64
+ $this->_imageWidth = 135;
65
+ }
66
+
67
+ $this->_imageHeight = $helper->getImageHeight();
68
+
69
+ $this->outputFileDelimiter = $helper->getOutputFileDelimiter();
70
+ $this->bufferSize = $helper->getBufferSize();
71
+ $this->outputFileExtension = $helper->getOutputFileExtension();
72
+
73
+ parent::__construct();
74
+ }
75
+
76
+ /**
77
+ * Retrieves the values of select/multiselect fields, to be dereferenced into values useful to Hawk
78
+ *
79
+ * @return array
80
+ */
81
+ protected function getMultiSelectValues() {
82
+ if (!empty($this->multiSelectValues)) {
83
+ return $this->multiSelectValues;
84
+ }
85
+
86
+ $eavTable = $this->_tablePrefix . 'eav_attribute';
87
+ $eavAttributeTable = $this->_tablePrefix . 'eav_attribute';
88
+ $eavOptionValueTable = $this->_tablePrefix . 'eav_attribute_option_value';
89
+ $catalogProdEntityInt = $this->_tablePrefix . 'catalog_product_entity_int';
90
+ $catalogProdEntityVarchar = $this->_tablePrefix . 'catalog_product_entity_varchar';
91
+
92
+ $write = $this->_getConnection();
93
+ $entity_type_id = $this->_entityTypeId;
94
+ $attributeIds = array();
95
+ $idList = "";
96
+
97
+
98
+ $brandAttribute = Mage::helper('hawksearch_datafeed/data')->getBrandAttribute();
99
+ if (!empty($brandAttribute)) {
100
+ $attributeIds[$brandAttribute] = "";
101
+ }
102
+
103
+ // Get the list of attribute IDs to dereference and the attribute_codes that they match
104
+ $sql = <<<EOSQL
105
+ SELECT
106
+ v.value, a.attribute_code
107
+ FROM
108
+ $catalogProdEntityVarchar v
109
+ LEFT JOIN
110
+ $eavAttributeTable a ON v.attribute_id = a.attribute_id
111
+ WHERE
112
+ v.entity_type_id = $entity_type_id
113
+ AND
114
+ a.frontend_input IN ('select', 'multiselect')
115
+ AND a.attribute_code != 'msrp_enabled' AND a.attribute_code != 'msrp_display_actual_price_type' AND a.attribute_code != 'is_recurring' AND a.attribute_code != 'enable_googlecheckout' AND a.attribute_code != 'tax_class_id' AND a.attribute_code != 'visibility' AND a.attribute_code != 'status'
116
+ EOSQL;
117
+
118
+ // Prepare the array of attribute codes and compile a unique list of IDs to dereference
119
+
120
+ //die($sql.'Andrew');
121
+
122
+ if ($rows = $write->fetchAll($sql)) {
123
+ foreach ($rows as $row) {
124
+ $opts = explode(',', $row['value']);
125
+ foreach ($opts as $opt) {
126
+ #print_r($opt);
127
+ if (isset($attributeIds[$row['attribute_code']])) {
128
+ if ((is_numeric($opt)) && !in_array($opt, $attributeIds[$row['attribute_code']])) {
129
+ $attributeIds[$row['attribute_code']][$opt] = $opt;
130
+ $attributeIds['ids'][$opt] = $opt;
131
+ }
132
+ }
133
+ }
134
+ }
135
+ if (!empty($attributeIds['ids'])) {
136
+ $idList = "'" . implode("', '", $attributeIds['ids']) . "'";
137
+ }
138
+ }
139
+
140
+ // Get the list of attribute IDs to dereference and the attribute_codes that they match
141
+ $sql = <<<EOSQL
142
+ SELECT
143
+ v.value, a.attribute_code
144
+ FROM
145
+ $catalogProdEntityInt v
146
+ LEFT JOIN
147
+ $eavAttributeTable a ON v.attribute_id = a.attribute_id
148
+ WHERE
149
+ v.entity_type_id = $this->_entityTypeId
150
+ AND
151
+ a.frontend_input IN ('select', 'multiselect')
152
+ AND a.attribute_code != 'msrp_enabled' AND a.attribute_code != 'msrp_display_actual_price_type' AND a.attribute_code != 'is_recurring' AND a.attribute_code != 'enable_googlecheckout' AND a.attribute_code != 'tax_class_id' AND a.attribute_code != 'visibility' AND a.attribute_code != 'status'
153
+ EOSQL;
154
+
155
+ // Prepare the array of attribute codes and compile a unique list of IDs to dereference
156
+ if ($rows = $write->fetchAll($sql)) {
157
+ foreach ($rows as $row) {
158
+ $opts = explode(',', $row['value']);
159
+ foreach ($opts as $opt) {
160
+ #print_r($opt);
161
+ if (isset($attributeIds[$row['attribute_code']])) {
162
+ if ((is_numeric($opt)) && !empty($attributeIds['ids']) && !in_array($opt, $attributeIds[$row['attribute_code']])) {
163
+ $attributeIds[$row['attribute_code']][$opt] = $opt;
164
+ $attributeIds['ids'][$opt] = $opt;
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ if (!empty($attributeIds['ids'])) {
171
+ $idList = "'" . implode("', '", $attributeIds['ids']) . "'";
172
+ }
173
+ }
174
+
175
+
176
+ if (!empty($idList)) {
177
+ // Get the dereferenced values
178
+ $sql = <<<EOSQL
179
+ SELECT
180
+ value,
181
+ option_id
182
+ FROM
183
+ $eavOptionValueTable
184
+ WHERE
185
+ option_id IN ($idList)
186
+ EOSQL;
187
+
188
+ // Replace the IDs with their values
189
+ if ($rows = $write->fetchAll($sql)) {
190
+ foreach ($rows as $row) {
191
+ foreach ($attributeIds as &$attrGroup) {
192
+ if (!empty($attrGroup[$row['option_id']])) {
193
+ $attrGroup[$row['option_id']] = $row['value'];
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+
200
+ // Cheating, I know, but it saves a tick.
201
+ return $this->multiSelectValues = $attributeIds;
202
+ }
203
+
204
+ /**
205
+ * Generate feed based on store and returns success
206
+ *
207
+ * @return boolean
208
+ */
209
+
210
+ protected function _getAttributeData() {
211
+ // Initializations
212
+ //$path = $this->_feedPath;
213
+ $done = false;
214
+ $offset = 0;
215
+
216
+ $filename = $this->_feedPath . DS . "attributes" . '.' . $this->outputFileExtension;
217
+ $arrayExcludeFields = explode(",", $this->_excludedFields);
218
+
219
+ $eavAttributeTable = $this->_tablePrefix . 'eav_attribute';
220
+ $productEntityTable = $this->_tablePrefix . 'catalog_product_entity';
221
+ $eavOptionValueTable = $this->_tablePrefix . 'eav_attribute_option_value';
222
+ $categoryProductTable = $this->_tablePrefix . 'catalog_category_product';
223
+ $productEntityValueTable = $this->_tablePrefix . 'catalog_product_entity_';
224
+
225
+ $tables = array(
226
+ 'int',
227
+ 'text',
228
+ 'varchar',
229
+ 'decimal',
230
+ 'datetime',
231
+ 'catalog_category_product',
232
+ );
233
+
234
+ $multiSelectValues = $this->getMultiSelectValues();
235
+
236
+ $write = $this->_getConnection();
237
+
238
+ // This _should_ be escaped to prevent SQL injection... however the source of data is in the
239
+ // admin panel so _should_ be generally safe. TODO: Check the Magento writer DB object for ways
240
+ // to escape content.
241
+ $excludeFields = implode("', '", $arrayExcludeFields);
242
+ if (!empty($excludeFields)) {
243
+ $excludeFields = " AND attribute_code NOT IN ('" . $excludeFields . "')";
244
+ }
245
+
246
+ $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
247
+ $output->appendRow(array('unique_id', 'key', 'value'));
248
+
249
+ //$content = "unique_id\tkey\tvalue\n";
250
+
251
+ // Loop through each of the catalog_product_entity_XXX tables separately. Despite tribal knowledge to the contrary
252
+ // among DB developers, in this specific case multiple queries happens to be faster than multiple joins.
253
+ foreach ($tables as $table) {
254
+ $done = false;
255
+ $offset = 0;
256
+ $valueTable = $productEntityValueTable . $table;
257
+ if ($table == "catalog_category_product") {
258
+
259
+ $selectQry = <<<EOSQL
260
+ SELECT
261
+ e.entity_id,
262
+ e.sku,
263
+ a.attribute_code,
264
+ a.attribute_code As value
265
+ FROM
266
+ $productEntityTable e
267
+ LEFT JOIN
268
+ $eavAttributeTable a ON e.entity_type_id = a.entity_type_id
269
+ WHERE
270
+ e.entity_type_id = $this->_entityTypeId AND a.attribute_code = 'category_ids'
271
+ ORDER BY e.entity_id ASC
272
+ EOSQL;
273
+
274
+ //die($selectQry);
275
+ } elseif ($this->_optionType == 'eav') {
276
+ // No temporary table any more, after exhaustive testing. It takes just as long to itterate
277
+ // through the temp table as it does through a fresh query, plus the temp table has the
278
+ // overhead of being set up in the first place. This query takes less than 2 seconds each
279
+ // time it is called, compared to the over 5 minutes it took previously, when the temp
280
+ // table was a good idea.
281
+ $valColumn = 'v.value';
282
+ $eaovTable = '';
283
+ if ($table == 'int') {
284
+ $valColumn = "case when a.frontend_input = 'select' and (a.source_model = 'eav/entity_attribute_source_table' or a.source_model = '') then eaov.value else v.value end AS value";
285
+ $eaovTable = "LEFT JOIN $eavOptionValueTable eaov ON eaov.option_id = v.value";
286
+ }
287
+ $selectQry = <<<EOSQL
288
+ SELECT
289
+ e.entity_id,
290
+ e.sku,
291
+ a.attribute_code,
292
+ $valColumn
293
+ FROM
294
+ $productEntityTable e
295
+ LEFT JOIN
296
+ $valueTable v ON e.entity_id = v.entity_id
297
+ LEFT JOIN
298
+ $eavAttributeTable a ON v.attribute_id = a.attribute_id
299
+ $eaovTable
300
+ WHERE
301
+ e.entity_type_id = $this->_entityTypeId
302
+ $excludeFields
303
+ ORDER BY e.entity_id ASC
304
+ EOSQL;
305
+ Mage::log($selectQry);
306
+
307
+ } else {
308
+ $selectQry = <<<EOSQL
309
+ SELECT
310
+ e.entity_id,
311
+ e.sku,
312
+ a.attribute_code,
313
+ v.value
314
+ FROM
315
+ $productEntityTable e
316
+ FF0000LEFT JOIN
317
+ $valueTable v ON e.entity_id = v.entity_id
318
+ LEFT JOIN
319
+ $eavAttributeTable a ON v.attribute_id = a.attribute_id
320
+ WHERE
321
+ e.entity_type_id = $this->_entityTypeId
322
+ $excludeFields
323
+ ORDER BY e.entity_id ASC
324
+ EOSQL;
325
+ }
326
+
327
+ while (!$done) {
328
+ //echo "TableName: " . $table;
329
+ //die( "select Query: " . $selectQry);
330
+
331
+ try {
332
+ // Messy, messy, messy. I appologize in advance.
333
+ // Perhaps some prose will help.
334
+ // The fetchAll() within this first if() statement runs the query, including the LIMIT and OFFSET.
335
+ // Then, we itterate through the results. If the value is a number or a list of comma-separated numbers, then
336
+ // we attempt to dereference to the actual values for the field.
337
+ // Finally, at the end of itterating through the results, we write to disk and reset our loop-specific variables before
338
+ // launching back through the while() above and doing fetchAll() again.
339
+ // Also note the foreach (tables as table) above, which moves us to the next DB table.
340
+ if (($rows = $write->fetchAll($selectQry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) && (count($rows) > 0)) {
341
+ foreach ($rows as $row) {
342
+ $values = explode(',', $row['value']);
343
+
344
+ if ($values[0] == "category_ids" && $row['attribute_code'] == 'category_ids') {
345
+ $category_ids_for_export = "";
346
+ $select_qry = 'SELECT category_id FROM ' . $categoryProductTable . ' WHERE product_id = "' . $row['entity_id'] . '"';
347
+ $rows1 = $write->fetchAll($select_qry);
348
+ foreach ($rows1 as $category_data) {
349
+ //$content .= "\"" . $row['sku'] . "\"\t\"category_id\"\t\"" . $category_data['category_id'] . "\"\n";
350
+ $output->appendRow(array($row['sku'], 'category_id', $category_data['category_id']));
351
+ }
352
+ } elseif ($row['attribute_code'] == 'country_of_manufacture') {
353
+ //$content .= "\"" . $row['sku'] . "\"\t\"" . $row['attribute_code'] . "\"\t\"" . str_replace("\"", "\"\"", $countryMap[$row['value']]) . "\"\n";
354
+ $output->appendRow(array($row['sku'], $row['attribute_code'], $this->getCountryName($row['value'])));
355
+
356
+ } else if (is_numeric($values[0])) {
357
+ foreach ($values as $val) {
358
+ if (!empty($multiSelectValues[$row['attribute_code']][$val])) {
359
+ //$content .= "\"" . $row['sku'] . "\"\t\"" . $row['attribute_code'] . "\"\t\"" . str_replace("\"", "\"\"", $multiSelectValues[$row['attribute_code']][$val]) . "\"\n";
360
+ $output->appendRow(array($row['sku'], $row['attribute_code'], $multiSelectValues[$row['attribute_code']][$val]));
361
+ } else {
362
+ //$content .= "\"" . $row['sku'] . "\"\t\"" . $row['attribute_code'] . "\"\t\"" . str_replace("\"", "\"\"", $val) . "\"\n";
363
+ $output->appendRow(array($row['sku'], $row['attribute_code'], $val));
364
+ }
365
+ }
366
+ } // Otherwise, add each individually.
367
+ else {
368
+ //$content .= "\"" . $row['sku'] . "\"\t\"" . $row['attribute_code'] . "\"\t\"" . str_replace("\"", "\"\"", $row['value']) . "\"\n";
369
+ $output->appendRow(array($row['sku'], $row['attribute_code'], $row['value']));
370
+ }
371
+ }
372
+
373
+
374
+ //$this->writeFile($filename, '', $content, ($firstRecord ? 1 : 2));
375
+
376
+ // Reset for the next iteration.
377
+ // Commentary: It is necessary to set for next iteration at the end, rather than the beginning, because the first
378
+ // iteration has special cases, such as setting the TSV header and removing/re-creating the file itself.
379
+ // $firstRecord = false;
380
+ // $content = '';
381
+ $offset += $this->_batchSize;
382
+ } else {
383
+ $done = true;
384
+ }
385
+ } catch (Exception $e) {
386
+ // remove lock
387
+ Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
388
+
389
+ if ($this->isLoggingEnabled) {
390
+ Mage::log(date('c') . " - Exception thrown on line " . $e->getLine() . " of " . $e->getFile() . ": " . $e, null, 'hawksearch_errors.log');
391
+ }
392
+ return false;
393
+ }
394
+ }
395
+ }
396
+
397
+ return true;
398
+ }
399
+
400
+ protected function _getCategoryData() {
401
+ $done = false;
402
+ $offset = 0;
403
+ $filename = $this->_feedPath . DS . "hierarchy" . '.' . $this->outputFileExtension;
404
+
405
+ //$firstRecord = true;
406
+
407
+ $categoryTable = $this->_tablePrefix . 'catalog_category_entity';
408
+ $eavAttributesTable = $this->_tablePrefix . 'eav_attribute';
409
+ $categoryVarCharTable = $this->_tablePrefix . 'catalog_category_entity_varchar';
410
+
411
+ $write = $this->_getConnection();
412
+
413
+ $selectQry = <<<EOSQL
414
+ SELECT
415
+ a.entity_id,
416
+ a.parent_id,
417
+ b.value,
418
+ a.position
419
+ FROM
420
+ $categoryTable AS a
421
+ LEFT JOIN
422
+ $categoryVarCharTable AS b ON a.entity_id = b.entity_id
423
+ WHERE
424
+ b.attribute_id IN
425
+ (
426
+ SELECT
427
+ attribute_id
428
+ FROM
429
+ $eavAttributesTable
430
+ WHERE
431
+ attribute_code = 'name'
432
+ )
433
+ AND
434
+ b.store_id = '0'
435
+ AND
436
+ a.parent_id != '0'
437
+ ORDER BY
438
+ a.position ASC
439
+ EOSQL;
440
+
441
+ //$content = "category_id\tcategory_name\tparent_category_id\tsort_order\n1\tRoot\t0\t0\n";
442
+ $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
443
+ $output->appendRow(array('category_id', 'category_name', 'parent_category_id','sort_order'));
444
+ $output->appendRow(array('1', 'Root', '0', '0'));
445
+
446
+ while (!$done) {
447
+ try {
448
+ if ($rows = $write->fetchAll($selectQry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) {
449
+ if (count($rows) > 0) {
450
+ foreach ($rows as $row) {
451
+ //$content .= $row['entity_id'] . "\t" . $row['value'] . "\t" . $row['parent_id'] . "\t" . $row['position'] . "\n";
452
+ $output->appendRow(array($row['entity_id'], $row['value'], $row['parent_id'], $row['position']));
453
+ }
454
+ $offset += $this->_batchSize;
455
+ //$this->writeFile($filename, '', $content, ($firstRecord ? 1 : 2));
456
+ //$firstRecord = false;
457
+ //$content = '';
458
+ }
459
+ } else {
460
+ $done = true;
461
+ }
462
+ } catch (Exception $e) {
463
+ // remove lock
464
+ Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
465
+
466
+ if ($this->isLoggingEnabled) {
467
+ Mage::log("SQL ERROR: (" . $e . ")", null, 'hawksearch_errors.log');
468
+ }
469
+ return false;
470
+ }
471
+ } //end whiledone loop
472
+
473
+ return true;
474
+ }
475
+
476
+ protected function _getProductData() {
477
+ $done = false;
478
+ $offset = 0;
479
+ $filename = $this->_feedPath . DS . "items" . '.' . $this->outputFileExtension;
480
+ $brand_sql = "";
481
+ $attrCodes = array();
482
+ $brand_select = "";
483
+ $entity_type_id = $this->_entityTypeId;
484
+
485
+ $this->_batchSize = 10000;
486
+
487
+ $eavTable = $this->_tablePrefix . 'eav_attribute';
488
+ $productEntityTable = $this->_tablePrefix . 'catalog_product_entity';
489
+ $eavOptionValueTable = $this->_tablePrefix . 'eav_attribute_option_value';
490
+ $productRelationTable = $this->_tablePrefix . 'catalog_product_relation';
491
+ $productEntityIntTable = $this->_tablePrefix . 'catalog_product_entity_int';
492
+ $productEntityTextTable = $this->_tablePrefix . 'catalog_product_entity_text';
493
+ $productEntityVarCharTable = $this->_tablePrefix . 'catalog_product_entity_varchar';
494
+ $productEntityDecimalTable = $this->_tablePrefix . 'catalog_product_entity_decimal';
495
+ $productEntityDateTimeTable = $this->_tablePrefix . 'catalog_product_entity_datetime';
496
+ $catalogInventoryStockTable = $this->_tablePrefix . 'cataloginventory_stock_item';
497
+ $productEntityUrlTable = $this->_tablePrefix . 'catalog_product_entity_url_key';
498
+
499
+ //$baseurl = Mage::getUrl();
500
+ //$mediaurl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA);
501
+ $brandAttribute = Mage::helper('hawksearch_datafeed/data')->getBrandAttribute();
502
+ $allowDisabled = Mage::helper('hawksearch_datafeed/data')->getAllowDisabledAttribute();
503
+
504
+ $write = $this->_getConnection();
505
+
506
+ $attrCodesQuery = <<<EOSQL
507
+ SELECT attribute_id, attribute_code
508
+ FROM $eavTable
509
+ WHERE attribute_code IN
510
+ (
511
+ 'name',
512
+ 'url_key',
513
+ 'image',
514
+ 'description',
515
+ 'short_description',
516
+ 'meta_keyword',
517
+ 'visibility',
518
+ 'price',
519
+ 'special_from_date',
520
+ 'special_to_date',
521
+ 'msrp',
522
+ 'special_price',
523
+ 'status',
524
+ '$brandAttribute'
525
+ )
526
+ AND entity_type_id = '$entity_type_id'
527
+ EOSQL;
528
+
529
+ if ($codeRows = $write->fetchAll($attrCodesQuery)) {
530
+ foreach ($codeRows as $row) {
531
+ $attrCodes[$row['attribute_code']] = $row['attribute_id'];
532
+ }
533
+ }
534
+
535
+ $disabled_sql = '';
536
+ $CONN = ' WHERE ';
537
+ if(!$allowDisabled){
538
+ $disabled_sql = "LEFT JOIN $productEntityIntTable AS T6 ON P.entity_id = T6.entity_id AND T6.attribute_id = '" . $attrCodes['status']. "'";
539
+ }
540
+
541
+ $brandAttribute = Mage::helper('hawksearch_datafeed/data')->getBrandAttribute();
542
+ if (!empty($brandAttribute)) {
543
+ $brand_select = ", B5.value AS Brand";
544
+ $brand_sql = "LEFT JOIN " . $productEntityIntTable . " AS B5 ON P.entity_id = B5.entity_id AND B5.attribute_id = '" . $attrCodes[$brandAttribute] . "'";
545
+ }
546
+
547
+ $select_qry = "SELECT P.attribute_set_id, P.entity_id AS ProductID, P.type_id, P.sku, P.has_options, V.value AS Name, T1.value AS ProdDesc, T2.value AS ShortDesc, T3.value AS MetaKeyword, T5.value AS visibility, D.value AS Price, S.value AS Special_Price, SDF.value As Special_Date_From, SDT.value As Special_Date_To, ST.qty, ST.is_in_stock AS IsInStock, X.value AS Msrp" . $brand_select . ", R.parent_id AS GroupID, CONCAT(V1.value, '.html') AS Link,
548
+ CASE
549
+ WHEN V2.Value IS NULL
550
+ THEN '/no-image.jpg'
551
+ ELSE CONCAT('', V2.value)
552
+ END AS Image
553
+ FROM $productEntityTable AS P
554
+ INNER JOIN " . $productEntityVarCharTable . " AS V ON P.entity_id = V.entity_id AND V.attribute_id = '" . $attrCodes['name'] . "'
555
+ INNER JOIN " . $catalogInventoryStockTable . " AS ST ON P.entity_id = ST.product_id
556
+ LEFT JOIN " . $productEntityUrlTable . " AS V1 ON P.entity_id = V1.entity_id AND V1.attribute_id = '" . $attrCodes['url_key'] . "'
557
+ LEFT JOIN " . $productEntityVarCharTable . " AS V2 ON P.entity_id = V2.entity_id AND V2.attribute_id = '" . $attrCodes['image'] . "'
558
+ LEFT JOIN " . $productEntityTextTable . " AS T1 ON P.entity_id = T1.entity_id AND T1.attribute_id = '" . $attrCodes['description'] . "'
559
+ LEFT JOIN " . $productEntityTextTable . " AS T2 ON P.entity_id = T2.entity_id AND T2.attribute_id = '" . $attrCodes['short_description'] . "'
560
+ LEFT JOIN " . $productEntityTextTable . " AS T3 ON P.entity_id = T3.entity_id AND T3.attribute_id = '" . $attrCodes['meta_keyword'] . "'
561
+ LEFT JOIN " . $productEntityIntTable . " AS T5 ON P.entity_id = T5.entity_id AND T5.attribute_id = '" . $attrCodes['visibility'] . "'
562
+ " . $disabled_sql . "
563
+ LEFT JOIN " . $productEntityDecimalTable . " AS D ON P.entity_id = D.entity_id AND D.attribute_id = '" . $attrCodes['price'] . "'
564
+ LEFT JOIN " . $productEntityDateTimeTable . " AS SDF ON P.entity_id = SDF.entity_id AND SDF.attribute_id = '" . $attrCodes['special_from_date'] . "'
565
+ LEFT JOIN " . $productEntityDateTimeTable . " AS SDT ON P.entity_id = SDT.entity_id AND SDT.attribute_id = '" . $attrCodes['special_to_date'] . "'
566
+ " . $brand_sql . "
567
+ LEFT JOIN " . $productEntityDecimalTable . " AS X ON P.entity_id = X.entity_id AND X.attribute_id = '" . $attrCodes['msrp'] . "'
568
+
569
+ LEFT JOIN " . $productRelationTable . " AS R ON P.entity_id = R.parent_id OR P.entity_id = R.child_id
570
+ LEFT JOIN " . $productEntityDecimalTable . " AS S ON P.entity_id = S.entity_id AND S.attribute_id = '" . $attrCodes['special_price'] . "'";
571
+
572
+ if (!Mage::helper('hawksearch_datafeed/data')->isIncludeOutOfStockItems()) {
573
+ $select_qry .= " $CONN ST.is_in_stock = 1";
574
+ $CONN = ' AND ';
575
+ }
576
+ if(!$allowDisabled) {
577
+ $select_qry .= " $CONN T6.value = 1 ";
578
+ $CONN = ' AND ';
579
+ }
580
+
581
+ // die($select_qry);
582
+ // $content = "\"product_id\"\t\"unique_id\"\t\"name\"\t\"url_detail\"\t\"image\"\t\"price_retail\"\t\"price_sale\"\t\"price_special\"\t\"price_special_from_date\"\t\"price_special_to_date\"\t\"group_id\"\t\"description_short\"\t\"description_long\"\t\"brand\"\t\"sku\"\t\"sort_default\"\t\"sort_rating\"\t\"is_free_shipping\"\t\"is_new\"\t\"is_on_sale\"\t\"keyword\"\t\"metric_inventory\"\n";
583
+ $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
584
+ $output->appendRow(array(
585
+ 'product_id',
586
+ 'unique_id',
587
+ 'name',
588
+ 'url_detail',
589
+ 'image',
590
+ 'price_retail',
591
+ 'price_sale',
592
+ 'price_special',
593
+ 'price_special_from_date',
594
+ 'price_special_to_date',
595
+ 'group_id',
596
+ 'description_short',
597
+ 'description_long',
598
+ 'brand',
599
+ 'sku',
600
+ 'sort_default',
601
+ 'sort_rating',
602
+ 'is_free_shipping',
603
+ 'is_new',
604
+ 'is_on_sale',
605
+ 'keyword',
606
+ 'metric_inventory'));
607
+
608
+ while (!$done) {
609
+ try {
610
+ if ($rows = $write->fetchAll($select_qry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) {
611
+ if (count($rows) > 0) {
612
+ foreach ($rows as $row) {
613
+ //$name = empty($row['Name']) ? $row['Name'] : str_replace("\"", "\"\"", $row['Name']);
614
+ //$description = empty($row['ProdDesc']) ? $row['ProdDesc'] : str_replace("\"", "\"\"", $row['ProdDesc']);
615
+ //$shortdescription = empty($row['ShortDesc']) ? $row['ShortDesc'] : str_replace("\"", "\"\"", $row['ShortDesc']);
616
+ //$metakeyword = empty($row['MetaKeyword']) ? $row['MetaKeyword'] : str_replace("\"", "\"\"", $row['MetaKeyword']);
617
+
618
+ $data_is_on_sale = empty($row['Special_Price']) ? 0 : 1;
619
+ if (isset($row['Brand'])) {
620
+ $select_brand_qry = $write->query("SELECT value FROM " . $eavOptionValueTable . " WHERE `option_id`=\"" . $row['Brand'] . "\" AND store_id ='0'");
621
+ $brandRow = $select_brand_qry->fetch();
622
+ $brand_text = $brandRow['value'];
623
+ } else {
624
+ $brand_text = "";
625
+ }
626
+ //$content .= "\"" . $row['ProductID'] . "\"\t\"" . $row['sku'] . "\"\t\"" . $name . "\"\t\"" . $row['Link'] . "\"\t\"" . $row['Image'] . "\"\t\"" . $row['Msrp'] . "\"\t\"" . $row['Price'] . "\"\t\"" . $row['Special_Price'] . "\"\t\"" . $row['Special_Date_From'] . "\"\t\"" . $row['Special_Date_To'] . "\"\t\"" . $row['GroupID'] . "\"\t\"" . $shortdescription . "\"\t\"" . $description . "\"\t\"" . $brand_text . "\"\t\"" . $row['sku'] . "\"\t\"0\"\t\"0\"\t\"0\"\t\"0\"\t\"" . $data_is_on_sale . "\"\t\"" . $metakeyword . "\"\t\"" . $row['qty'] . "\"\n";
627
+ $output->appendRow(array(
628
+ $row['ProductID'],
629
+ $row['sku'],
630
+ $row['Name'],
631
+ $row['Link'],
632
+ $row['Image'],
633
+ $row['Msrp'],
634
+ $row['Price'],
635
+ $row['Special_Price'],
636
+ $row['Special_Date_From'],
637
+ $row['Special_Date_To'],
638
+ $row['GroupID'],
639
+ $row['ShortDesc'],
640
+ $row['ProdDesc'],
641
+ $brand_text,
642
+ $row['sku'],
643
+ 0, // sort_default
644
+ 0, // sort_rating
645
+ 0, // is_free_shipping
646
+ 0, // is_new
647
+ $data_is_on_sale,
648
+ $row['MetaKeyword'],
649
+ $row['qty']));
650
+
651
+ }
652
+ $offset += $this->_batchSize;
653
+ //$this->writeFile($filename, '', $content, ($firstRecord ? 1 : 2));
654
+ //$firstRecord = false;
655
+ //$content = '';
656
+ }
657
+ } else {
658
+ $done = true;
659
+ }
660
+ } catch (Exception $e) {
661
+ // remove lock
662
+ Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
663
+
664
+ if ($this->isLoggingEnabled) {
665
+ Mage::log("SQL ERROR: (" . $e . ")", null, 'hawksearch_errors.log');
666
+ }
667
+
668
+ return false;
669
+ }
670
+ } // end while
671
+ return true;
672
+ }
673
+
674
+ protected function _getContentData() {
675
+ //$resource = Mage::getSingleton('core/resource');
676
+
677
+ $done = false;
678
+ $offset = 0;
679
+ $baseurl = Mage::getUrl();
680
+ //$filename = $this->_feedPath . "/content.txt";
681
+ $filename = $this->_feedPath . DS . "content" . '.' . $this->outputFileExtension;
682
+
683
+ //$firstRecord = true;
684
+ $cmsPageTable = $this->_tablePrefix . 'cms_page';
685
+
686
+
687
+ $select_qry = "SELECT page_id, title, CONCAT('" . $baseurl . "', identifier) AS Link, content_heading, content, creation_time, is_active FROM " . $cmsPageTable . "";
688
+
689
+ $write = $this->_getConnection();
690
+
691
+ //$content = "unique_id\tname\turl_detail\tdescription_short\tcreated_date\n";
692
+ $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
693
+ $output->appendRow(array('unique_id', 'name', 'url_detail', 'description_short', 'created_date'));
694
+
695
+ while (!$done) {
696
+ try {
697
+ if ($rows = $write->fetchAll($select_qry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) {
698
+ if (($numRows = count($rows)) && $numRows > 0) {
699
+ foreach ($rows as $row) {
700
+ //$content .= $row['page_id'] . "\t" . $row['title'] . "\t" . $row['Link'] . "\t" . $row['content_heading'] . "\t" . $row['creation_time'] . "\n";
701
+ $output->appendRow(array($row['page_id'], $row['title'], $row['Link'], $row['content_heading'], $row['creation_time']));
702
+ }
703
+
704
+ $offset += $this->_batchSize;
705
+ // $this->writeFile($filename, '', $content, ($firstRecord ? 1 : 2));
706
+ // $firstRecord = false;
707
+ // $content = '';
708
+ } else {
709
+ $done = true;
710
+ }
711
+ } else {
712
+ $done = true;
713
+ }
714
+ } catch (Exception $e) {
715
+ // remove lock
716
+ Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
717
+
718
+ if ($this->isLoggingEnabled) {
719
+ Mage::log("SQL ERROR: (" . $e . ")", null, 'hawksearch_errors.log');
720
+ }
721
+ return false;
722
+ }
723
+ } // end while
724
+ return true;
725
+ }
726
+
727
+ /*private function writeFile($filename, $header, $content, $recordcount) {
728
+ if ($recordcount === 1) {
729
+ if (file_exists($filename)) {
730
+ unlink($filename);
731
+ }
732
+ }
733
+
734
+ if (!file_exists($filename)) {
735
+ $handle = fopen($filename, "a");
736
+ fclose($handle);
737
+ }
738
+
739
+ if (is_writable($filename)) {
740
+ if (!$handle = fopen($filename, 'a')) {
741
+ if ($this->isLoggingEnabled) {
742
+ Mage::log("Cannot open file (" . $filename . ")", null, 'hawksearch_errors.log');
743
+ }
744
+ return false;
745
+ }
746
+ if (fwrite($handle, $content) === FALSE) {
747
+ if ($this->isLoggingEnabled) {
748
+ Mage::log("Cannot write to file (" . $filename . ")", null, 'hawksearch_errors.log');
749
+ }
750
+ return false;
751
+ }
752
+ return true; // Success, wrote ($somecontent) to file ($filename);
753
+ fclose($handle);
754
+ } else {
755
+ if ($this->isLoggingEnabled) {
756
+ Mage::log("The file " . $filename . " is not writable", null, 'hawksearch_errors.log');
757
+ }
758
+ }
759
+ return true;
760
+ }*/
761
+
762
+ public function getCountryName($code) {
763
+ /* map friendly country_of_origin names */
764
+ if(!isset($this->countryMap)){
765
+ $options = Mage::getModel('directory/country')->getResourceCollection()->toOptionArray();
766
+
767
+ $this->countryMap = array();
768
+ foreach ($options as $option) {
769
+ if ($option['value'] != '') {
770
+ $this->countryMap[$option['value']] = $option['label'];
771
+ }
772
+ }
773
+ }
774
+ return isset($this->countryMap[$code]) ? $this->countryMap[$code]: $code;
775
+ }
776
+
777
+ public function generateFeed($price_feed = false) {
778
+ try {
779
+ //exports Attribute Data
780
+ $this->_getAttributeData();
781
+
782
+ //exports Category Data
783
+ $this->_getCategoryData();
784
+
785
+ //exports Product Data
786
+ $this->_getProductData();
787
+
788
+ //exports CMS / Content Data
789
+ $this->_getContentData();
790
+
791
+ //refresh image cache
792
+ $this->refreshImageCache();
793
+
794
+ // remove locks
795
+ Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
796
+ } catch (Exception $e) {
797
+ // remove lock
798
+ Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
799
+ #Mage::log("Exception: {$e->getMessage()}");
800
+ if ($this->isLoggingEnabled) {
801
+ Mage::log(sprintf('Exception: %s', $e->getMessage()), null, 'hawksearch_errors.log');
802
+ }
803
+ }
804
+ }
805
+
806
+ public function refreshImageCache() {
807
+ $products = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect(array('image', 'small_image'));
808
+ $products->setPageSize(1000);
809
+
810
+ $pages = $products->getLastPageNumber();
811
+ $currentPage = 1;
812
+
813
+ do {
814
+ $products->setCurPage($currentPage);
815
+ $products->load();
816
+
817
+ foreach ($products as $product) {
818
+ if (empty($this->_imageHeight)) {
819
+ Mage::helper('catalog/image')->init($product, 'small_image')->resize($this->_imageWidth) . '';
820
+ } else {
821
+ Mage::helper('catalog/image')->init($product, 'small_image')->resize($this->_imageWidth, $this->_imageHeight) . '';
822
+ }
823
+ }
824
+
825
+ $currentPage++;
826
+
827
+ //clear collection and free memory
828
+ $products->clear();
829
+
830
+ } while ($currentPage <= $pages);
831
+ }
832
+
833
+ /**
834
+ * Returns the total number of products in the store catalog
835
+ *
836
+ * @return int
837
+ */
838
+ protected function _getProductCount() {
839
+ if ($this->_totalProductCount === null) {
840
+ $count = $this->_getConnection()->query("select count(entity_id) from " . Mage::getSingleton('core/resource')->getTableName('catalog/product'));
841
+ $this->_totalProductCount = ($count) ? $count->fetch(PDO::FETCH_COLUMN) : 0;
842
+ }
843
+ return $this->_totalProductCount;
844
+ }
845
+
846
+ /**
847
+ * Returns the database connection used by the feed
848
+ *
849
+ * @return PDO
850
+ */
851
+ protected function _getConnection() {
852
+ if (!$this->_dbConnection) {
853
+ $this->_dbConnection = Mage::getSingleton('core/resource')->getConnection('core_write');
854
+ } else {
855
+ $this->_dbConnection->closeConnection();
856
+ $this->_dbConnection->getConnection();
857
+ }
858
+
859
+ return $this->_dbConnection;
860
+ }
861
+
862
+ public function getAjaxNotice() {
863
+ $this->_ajaxNotice = "<span style='color:red'>Currently generating feeds... containing up to {$this->_getProductCount()} products. </span>";
864
+ return $this->_ajaxNotice;
865
+ }
866
+
867
+ public function getAjaxNoticeImageCache() {
868
+ $this->_ajaxNotice = "<span style='color:red'>Currently re-generating image cache... containing up to {$this->_getProductCount()} products. </span>";
869
+ return $this->_ajaxNotice;
870
+ }
871
+ }
872
+ /**
873
+ * CsvWriter
874
+ *
875
+ * The purpose of this class is to allow uniform escaping of CSV data via the fputcsv()
876
+ * along with handling the boilerplate of file operations.
877
+ */
878
+ class CsvWriter {
879
+ private $finalDestinationPath;
880
+ private $outputFile;
881
+ private $outputOpen = false;
882
+ private $delimiter;
883
+ private $bufferSize;
884
+
885
+ public function __construct($destFile, $delim, $buffSize = null) {
886
+ $this->finalDestinationPath = $destFile;
887
+ if (file_exists($this->finalDestinationPath)) {
888
+ if (false === unlink($this->finalDestinationPath)) {
889
+ throw new Exception("CsvWriteBuffer: unable to remove old file '$this->finalDestinationPath'");
890
+ }
891
+ }
892
+ $this->delimiter = $delim;
893
+ $this->bufferSize = $buffSize;
894
+ }
895
+
896
+ public function __destruct() {
897
+ $this->closeOutput();
898
+ }
899
+
900
+ public function appendRow(array $fields) {
901
+ if(!$this->outputOpen){
902
+ $this->openOutput();
903
+ }
904
+ if(false === fputcsv($this->outputFile, $fields, $this->delimiter)) {
905
+ throw new Exception("CsvWriter: failed to write row.");
906
+ }
907
+ }
908
+
909
+ public function openOutput() {
910
+ if (false === ($this->outputFile = fopen($this->finalDestinationPath, 'a'))) {
911
+ throw new Exception("CsvWriter: Failed to open destination file '$this->finalDestinationPath'.");
912
+ }
913
+ if(!is_null($this->bufferSize)) {
914
+ stream_set_write_buffer($this->outputFile, $this->bufferSize);
915
+ }
916
+ $this->outputOpen = true;
917
+ }
918
+
919
+ public function closeOutput() {
920
+ if (!$this->outputOpen) {
921
+ if(false === fclose($this->outputFile)) {
922
+ throw new Exception("CsvWriter: Failed to close destination file'$this->finalDestinationPath'.");
923
+ }
924
+ $this->outputOpen = false;
925
+ }
926
+ }
927
+
928
+ }
app/code/community/Hawksearch/Datafeed/Model/System/Config/Backend/Cron.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_Model_System_Config_Backend_Cron extends Mage_Core_Model_Config_Data {
12
+
13
+ const CRON_STRING_PATH = 'crontab/jobs/hawksearch_datafeed/schedule/cron_expr';
14
+ const CRON_MODEL_PATH = 'crontab/jobs/hawksearch_datafeed/run/model';
15
+
16
+ const XML_PATH_CRON_DISABLED = 'groups/cron/fields/disabled/value';
17
+ const XML_PATH_CRON_TIME = 'groups/cron/fields/time/value';
18
+ const XML_PATH_CRON_FREQUENCY = 'groups/cron/fields/frequency/value';
19
+
20
+ /**
21
+ * When frequency system configuration saves, save the values from the frequency and time as a cron string to a parsable path that the crontab will pick up
22
+ */
23
+ protected function _afterSave()
24
+ {
25
+ $disabled = $this->getData(self::XML_PATH_CRON_DISABLED);
26
+ $frequncy = $this->getData(self::XML_PATH_CRON_FREQUENCY);
27
+ $time = $this->getData(self::XML_PATH_CRON_TIME);
28
+
29
+ $frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
30
+ $frequencyWeekly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_WEEKLY;
31
+ $frequencyMonthly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_MONTHLY;
32
+ $cronDayOfWeek = date('N');
33
+
34
+ $cronExprArray = array(
35
+ intval($time[1]), # Minute
36
+ intval($time[0]), # Hour
37
+ ($frequncy == $frequencyMonthly) ? '1' : '*', # Day of the Month
38
+ '*', # Month of the Year
39
+ ($frequncy == $frequencyWeekly) ? '1' : '*', # Day of the Week
40
+ );
41
+
42
+ $cronExprString = join(' ', $cronExprArray);
43
+
44
+ try {
45
+ Mage::getModel('core/config_data')
46
+ ->load(self::CRON_STRING_PATH, 'path')
47
+ ->setValue($cronExprString)
48
+ ->setPath(self::CRON_STRING_PATH)
49
+ ->save();
50
+ Mage::getModel('core/config_data')
51
+ ->load(self::CRON_MODEL_PATH, 'path')
52
+ ->setValue((string) Mage::getConfig()->getNode(self::CRON_MODEL_PATH))
53
+ ->setPath(self::CRON_MODEL_PATH)
54
+ ->save();
55
+ } catch (Exception $e) {
56
+ throw new Exception(Mage::helper('cron')->__('Unable to save the cron expression.'));
57
+ }
58
+ }
59
+
60
+
61
+ /**
62
+ * Saves the necessary core config data entries for the cron to pull them from the database
63
+ */
64
+ public function saveCronTab($cronTab) {
65
+ Mage::getModel('core/config_data')
66
+ ->load(self::CRON_STRING_PATH, 'path')
67
+ ->setValue($cronTab)
68
+ ->setPath(self::CRON_STRING_PATH)
69
+ ->save();
70
+ Mage::getModel('core/config_data')
71
+ ->load(self::CRON_MODEL_PATH, 'path')
72
+ ->setValue((string) Mage::getConfig()->getNode(self::CRON_MODEL_PATH))
73
+ ->setPath(self::CRON_MODEL_PATH)
74
+ ->save();
75
+ }
76
+
77
+ }
app/code/community/Hawksearch/Datafeed/controllers/SearchController.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ class Hawksearch_Datafeed_SearchController extends Mage_Core_Controller_Front_Action {
12
+
13
+ public function templateAction() {
14
+ $this->loadLayout();
15
+ $this->renderLayout();
16
+ }
17
+
18
+ public function indexAction () {
19
+ $coupon_code = $this->getRequest()->getParam('coupon_code'); //to automatically apply a coupon code
20
+ if ($coupon_code != '')
21
+ {
22
+ Mage::getSingleton("checkout/session")->setData("coupon_code",$coupon_code);
23
+ Mage::getSingleton('checkout/cart')->getQuote()->setCouponCode($coupon_code)->save();
24
+ Mage::getSingleton('core/session')->addSuccess($this->__('Coupon was automatically applied'));
25
+ }
26
+ $product_id = $this->getRequest()->getParam('product');
27
+ $qty = $this->getRequest()->getParam('qty'); //used if your qty is not hard coded
28
+ $cart = Mage::getModel('checkout/cart');
29
+ $cart->init();
30
+ if ($product_id == '') {
31
+ $this->_redirect('/');
32
+ }
33
+ $productModel = Mage::getModel('catalog/product')->load($product_id);
34
+ if (TRUE) {
35
+ try
36
+ {
37
+ $cart->addProduct($productModel, array('qty' => '1')); //qty is hard coded
38
+ }
39
+ catch (Exception $e) {
40
+ $this->_redirect('/');
41
+ }
42
+ }
43
+ $cart->save();
44
+ if ($this->getRequest()->isXmlHttpRequest()) {
45
+ exit('1');
46
+ }
47
+ $this->_redirect('checkout/cart');
48
+ }
49
+ /**
50
+ * API Call for Image CacheKey to get images from cache on auto resize.
51
+ */
52
+ public function getCacheKeyAction() {
53
+ $response = array("error" => false);
54
+ try {
55
+ $resource = Mage::getSingleton('core/resource');
56
+ $read = $resource->getConnection('core_read');
57
+ $productCatalogTable = (string)Mage::getConfig()->getTablePrefix() . 'catalog_product_entity';
58
+
59
+ $select_qry =$read->query("SELECT entity_id FROM ".$productCatalogTable." LIMIT 1");
60
+ $newrow = $select_qry->fetch();
61
+ $entity_id = $newrow['entity_id'];
62
+ $product = Mage::getModel('catalog/product')->load($entity_id);
63
+ $full_path_url = Mage::helper('catalog/image')->init($product, 'thumbnail');
64
+ $imageArray = explode("/", $full_path_url);
65
+
66
+ if(isset($imageArray[9])) {
67
+ $cache_key = $imageArray[9];
68
+ } else {
69
+ $cache_key = "";
70
+ }
71
+
72
+ $response['cache_key'] = $cache_key;
73
+ $response['date_time'] = date('Y-m-d H:i:s');
74
+ }
75
+ catch (Exception $e) {
76
+ $response['error'] = $e->getMessage();
77
+ }
78
+ catch (Exception $e) {
79
+ Mage::logException($e);
80
+ $response['error'] = "An unknown error occurred.";
81
+ }
82
+ $this->getResponse()
83
+ ->setHeader("Content-Type", "application/json")
84
+ ->setBody(json_encode($response));
85
+ }
86
+
87
+ /*public function getFormKeyAction() {
88
+
89
+ $response = array("error" => false);
90
+ try {
91
+
92
+ $formKey = Mage::getSingleton('core/session')->getFormKey();
93
+ $formGuid = Mage::helper('core/url')->getEncodedUrl();
94
+ $response['form_guid'] = $formGuid;
95
+ $response['form_key'] = $formKey;
96
+ $response['date_time'] = date('Y-m-d H:i:s');
97
+ }
98
+ catch (Exception $e) {
99
+ $response['error'] = $e->getMessage();
100
+ }
101
+ catch (Exception $e) {
102
+ Mage::logException($e);
103
+ $response['error'] = "An unknown error occurred.";
104
+ }
105
+ $this->getResponse()
106
+ ->setHeader("Content-Type", "application/json")
107
+ ->setBody(json_encode($response));
108
+
109
+ }*/
110
+
111
+ /**
112
+ * Asynchronous posting to feed generation url for each store.
113
+ */
114
+ public function runFeedGenerationAction() {
115
+ $response = array("error" => false);
116
+
117
+ try {
118
+ Mage::helper('hawksearch_datafeed/feed')->generateFeedsForAllStores();
119
+ }
120
+ catch (Exception $e) {
121
+ $response['error'] = $e->getMessage();
122
+ }
123
+ catch (Exception $e) {
124
+ Mage::logException($e);
125
+ $response['error'] = "An unknown error occurred.";
126
+ }
127
+ $this->getResponse()
128
+ ->setHeader("Content-Type", "application/json")
129
+ ->setBody(json_encode($response));
130
+ }
131
+
132
+ /**
133
+ * Refreshes image cache based on passed in store id. Defaults store id to default store
134
+ */
135
+ public function runImageCacheGenerationAction() {
136
+ $response = "";
137
+ try {
138
+ $storeId = $this->getRequest()->getParam("storeId");
139
+
140
+ if (!$storeId) {
141
+ $storeId = Mage::app()->getDefaultStoreView()->getId();
142
+ }
143
+
144
+ Mage::getModel('hawksearch_datafeed/feed')->setData('store_id', $storeId)->refreshImageCache();
145
+ }
146
+ catch (Exception $e) {
147
+ $response = $e->getMessage();
148
+ }
149
+ catch (Exception $e) {
150
+ Mage::logException($e);
151
+ $response = "An unknown error occurred.";
152
+ }
153
+ $this->getResponse()->setBody($response);
154
+ }
155
+
156
+ /**
157
+ * Generates a feed based on passed in store id. Defaults store id to default store
158
+ */
159
+ public function generateFeedAction() {
160
+ $response = "";
161
+ try {
162
+ $storeId = $this->getRequest()->getParam("storeId");
163
+
164
+ if (!$storeId) {
165
+ $storeId = Mage::app()->getDefaultStoreView()->getId();
166
+ }
167
+ Mage::getModel('hawksearch_datafeed/feed')->setData('store_id', $storeId)->generateFeed(true);
168
+ }
169
+ catch (Exception $e) {
170
+ $response = $e->getMessage();
171
+ }
172
+ catch (Exception $e) {
173
+ Mage::logException($e);
174
+ $response = "An unknown error occurred.";
175
+ }
176
+ $this->getResponse()->setBody($response);
177
+ }
178
+ }
app/code/community/Hawksearch/Datafeed/etc/adminhtml.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
5
+ *
6
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
7
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
8
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
9
+ * PARTICULAR PURPOSE.
10
+ */
11
+ -->
12
+ <config>
13
+ <acl>
14
+ <resources>
15
+ <admin>
16
+ <children>
17
+ <system>
18
+ <children>
19
+ <config>
20
+ <children>
21
+ <hawksearch_datafeed translate="title" module="hawksearch_datafeed">
22
+ <title>Hawksearch Datafeed Section</title>
23
+ </hawksearch_datafeed>
24
+ </children>
25
+ </config>
26
+ </children>
27
+ </system>
28
+ </children>
29
+ </admin>
30
+ </resources>
31
+ </acl>
32
+ </config>
app/code/community/Hawksearch/Datafeed/etc/config.xml ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
5
+ *
6
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
7
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
8
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
9
+ * PARTICULAR PURPOSE.
10
+ */
11
+ -->
12
+ <config>
13
+ <modules>
14
+ <Hawksearch_Datafeed>
15
+ <version>1.0.0.0</version>
16
+ </Hawksearch_Datafeed>
17
+ </modules>
18
+ <global>
19
+ <blocks>
20
+ <hawksearch_datafeed>
21
+ <class>Hawksearch_Datafeed_Block</class>
22
+ </hawksearch_datafeed>
23
+ <!--
24
+ <adminhtml>
25
+ <rewrite>
26
+ <system_config_form>Hawksearch_Datafeed_Block_System_Config_Form</system_config_form>
27
+ </rewrite>
28
+ </adminhtml>
29
+ -->
30
+ </blocks>
31
+ <helpers>
32
+ <hawksearch_datafeed>
33
+ <class>Hawksearch_Datafeed_Helper</class>
34
+ </hawksearch_datafeed>
35
+ </helpers>
36
+ <models>
37
+ <hawksearch_datafeed>
38
+ <class>Hawksearch_Datafeed_Model</class>
39
+ </hawksearch_datafeed>
40
+ </models>
41
+ <resources>
42
+ <hawksearch_datafeed_setup>
43
+ <setup>
44
+ <module>Hawksearch_Datafeed</module>
45
+ </setup>
46
+ </hawksearch_datafeed_setup>
47
+ </resources>
48
+ </global>
49
+ <frontend>
50
+ <routers>
51
+ <hawksearch_datafeed>
52
+ <use>standard</use>
53
+ <args>
54
+ <module>Hawksearch_Datafeed</module>
55
+ <frontName>hawksearch</frontName>
56
+ </args>
57
+ </hawksearch_datafeed>
58
+ </routers>
59
+ </frontend>
60
+ <default>
61
+ <hawksearch_datafeed>
62
+ <general>
63
+ <enabled>1</enabled>
64
+ <logging_enabled>1</logging_enabled>
65
+ </general>
66
+ <feed>
67
+ <generate/>
68
+ <submittal/>
69
+ <batch_limit>10000</batch_limit>
70
+ <image_width>135</image_width>
71
+ <brand_attribute/>
72
+ <exclude_fields>description,short_description,options_container,gift_message_available,visibility,status,tax_class_id,required_options,msrp_display_actual_price_type,enable_googlecheckout,created_at,updated_at,sku</exclude_fields>
73
+ <stockstatus>1</stockstatus>
74
+ <itemstatus>0</itemstatus>
75
+ <option_type>eav</option_type>
76
+ <delimiter>tab</delimiter>
77
+ <buffer_size>65536</buffer_size>
78
+ <output_file_ext>txt</output_file_ext>
79
+ <feed_path>var/hawksearch/feeds</feed_path>
80
+ </feed>
81
+ <cron>
82
+ <email/>
83
+ <frequency backend_model="adminhtml/system_config_backend_product_alert_cron">every_5min</frequency>
84
+ <disabled>0</disabled>
85
+ <time>02,00,00</time>
86
+ </cron>
87
+ </hawksearch_datafeed>
88
+ </default>
89
+ <crontab>
90
+ <hawksearch_datafeed>
91
+ <job_code>hawksearch_datafeed</job_code>
92
+ </hawksearch_datafeed>
93
+ <jobs>
94
+ <hawksearch_datafeed>
95
+ <run>
96
+ <model>hawksearch_datafeed/cron::generateFeeds</model>
97
+ </run>
98
+ </hawksearch_datafeed>
99
+ </jobs>
100
+ </crontab>
101
+ </config>
app/code/community/Hawksearch/Datafeed/etc/system.xml ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
5
+ *
6
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
7
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
8
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
9
+ * PARTICULAR PURPOSE.
10
+ */
11
+ -->
12
+ <config>
13
+ <tabs>
14
+ <hawksearch translate="label" module="hawksearch_datafeed">
15
+ <label>HawkSearch</label>
16
+ <sort_order>200</sort_order>
17
+ </hawksearch>
18
+ </tabs>
19
+ <sections>
20
+ <hawksearch_datafeed translate="label" module="hawksearch_datafeed">
21
+ <label>DataFeed Settings</label>
22
+ <tab>hawksearch</tab>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>100</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
+ <groups>
29
+ <general translate="label" module="hawksearch_datafeed">
30
+ <label>General</label>
31
+ <frontend_type>text</frontend_type>
32
+ <sort_order>1</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>1</show_in_website>
35
+ <show_in_store>1</show_in_store>
36
+ <fields>
37
+ <enabled translate="label">
38
+ <label>Enabled</label>
39
+ <frontend_type>select</frontend_type>
40
+ <source_model>adminhtml/system_config_source_yesno</source_model>
41
+ <sort_order>100</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
+ </enabled>
46
+ <logging_enabled>
47
+ <label>Enabled Logging</label>
48
+ <frontend_type>select</frontend_type>
49
+ <source_model>adminhtml/system_config_source_yesno</source_model>
50
+ <sort_order>200</sort_order>
51
+ <show_in_default>1</show_in_default>
52
+ <show_in_website>1</show_in_website>
53
+ <show_in_store>1</show_in_store>
54
+ </logging_enabled>
55
+ <version translate="label">
56
+ <label>Version</label>
57
+ <frontend_type>label</frontend_type>
58
+ <frontend_model>hawksearch_datafeed/system_config_form_field_version</frontend_model>
59
+ <sort_order>300</sort_order>
60
+ <show_in_default>1</show_in_default>
61
+ <show_in_website>1</show_in_website>
62
+ <show_in_store>1</show_in_store>
63
+ </version>
64
+ </fields>
65
+ </general>
66
+ <feed translate="label" module="hawksearch_datafeed">
67
+ <label>Feed Settings</label>
68
+ <frontend_type>text</frontend_type>
69
+ <sort_order>100</sort_order>
70
+ <show_in_default>1</show_in_default>
71
+ <show_in_website>1</show_in_website>
72
+ <show_in_store>1</show_in_store>
73
+ <fields>
74
+ <generate translate="label">
75
+ <label>Generate Feed</label>
76
+ <frontend_type>button</frontend_type>
77
+ <frontend_model>hawksearch_datafeed/system_config_frontend_feed_generate</frontend_model>
78
+ <comment>Manually generates feed.</comment>
79
+ <sort_order>100</sort_order>
80
+ <show_in_default>1</show_in_default>
81
+ <show_in_website>0</show_in_website>
82
+ <show_in_store>0</show_in_store>
83
+ </generate>
84
+ <generateimagecache translate="label">
85
+ <label>Generate Image Cache</label>
86
+ <frontend_type>button</frontend_type>
87
+ <frontend_model>hawksearch_datafeed/system_config_frontend_feed_generateimagecache</frontend_model>
88
+ <comment>Manually generates image cache.</comment>
89
+ <sort_order>150</sort_order>
90
+ <show_in_default>1</show_in_default>
91
+ <show_in_website>0</show_in_website>
92
+ <show_in_store>0</show_in_store>
93
+ </generateimagecache>
94
+ <submittal translate="label">
95
+ <label>Next Automatic Feed Generation</label>
96
+ <frontend_type>text</frontend_type>
97
+ <frontend_model>hawksearch_datafeed/system_config_frontend_feed_next</frontend_model>
98
+ <sort_order>200</sort_order>
99
+ <show_in_default>1</show_in_default>
100
+ <show_in_website>0</show_in_website>
101
+ <show_in_store>0</show_in_store>
102
+ </submittal>
103
+ <batch_limit translate="label">
104
+ <label>Batch Limit</label>
105
+ <frontend_type>text</frontend_type>
106
+ <comment>Set the block of blocks to batch at once</comment>
107
+ <sort_order>300</sort_order>
108
+ <show_in_default>1</show_in_default>
109
+ <show_in_website>0</show_in_website>
110
+ <show_in_store>0</show_in_store>
111
+ </batch_limit>
112
+ <image_width translate="label">
113
+ <label>Image Width</label>
114
+ <frontend_type>text</frontend_type>
115
+ <comment>Set the width of the small image saved in the cache</comment>
116
+ <sort_order>350</sort_order>
117
+ <show_in_default>1</show_in_default>
118
+ <show_in_website>0</show_in_website>
119
+ <show_in_store>0</show_in_store>
120
+ </image_width>
121
+ <image_height translate="label">
122
+ <label>Image Height</label>
123
+ <frontend_type>text</frontend_type>
124
+ <comment>Set the height of the small image saved in the cache</comment>
125
+ <sort_order>375</sort_order>
126
+ <show_in_default>1</show_in_default>
127
+ <show_in_website>0</show_in_website>
128
+ <show_in_store>0</show_in_store>
129
+ </image_height>
130
+ <brand_attribute translate="label">
131
+ <label>Brand Attribute Value</label>
132
+ <frontend_type>text</frontend_type>
133
+ <comment>Set attribute_code value for the Brand attribute</comment>
134
+ <sort_order>400</sort_order>
135
+ <show_in_default>1</show_in_default>
136
+ <show_in_website>0</show_in_website>
137
+ <show_in_store>0</show_in_store>
138
+ </brand_attribute>
139
+ <exclude_fields translate="label">
140
+ <label>Attributes to Exclude</label>
141
+ <frontend_type>textarea</frontend_type>
142
+ <comment>Comma Delimited List of attribute_code values to exclude</comment>
143
+ <sort_order>500</sort_order>
144
+ <show_in_default>1</show_in_default>
145
+ <show_in_website>0</show_in_website>
146
+ <show_in_store>0</show_in_store>
147
+ </exclude_fields>
148
+ <stockstatus translate="label">
149
+ <label>Allow Out of Stock Items</label>
150
+ <frontend_type>select</frontend_type>
151
+ <source_model>adminhtml/system_config_source_yesno</source_model>
152
+ <sort_order>600</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
+ </stockstatus>
157
+ <itemstatus>
158
+ <label>Allow Disabled Items</label>
159
+ <frontend_type>select</frontend_type>
160
+ <source_model>adminhtml/system_config_source_yesno</source_model>
161
+ <sort_order>700</sort_order>
162
+ <show_in_default>1</show_in_default>
163
+ <show_in_website>1</show_in_website>
164
+ <show_in_store>1</show_in_store>
165
+ </itemstatus>
166
+ <optional_htaccess_user translate="label">
167
+ <label>HTACCESS Username</label>
168
+ <frontend_type>text</frontend_type>
169
+ <comment>Optional Username setting for sites with .htaccess enabled. Leave blank if not in use</comment>
170
+ <sort_order>800</sort_order>
171
+ <show_in_default>1</show_in_default>
172
+ <show_in_website>0</show_in_website>
173
+ <show_in_store>0</show_in_store>
174
+ </optional_htaccess_user>
175
+ <optional_htaccess_password translate="label">
176
+ <label>HTACCESS Password</label>
177
+ <frontend_type>text</frontend_type>
178
+ <comment>Optional Username setting for sites with .htaccess enabled. Leave blank if not in use</comment>
179
+ <sort_order>900</sort_order>
180
+ <show_in_default>1</show_in_default>
181
+ <show_in_website>0</show_in_website>
182
+ <show_in_store>0</show_in_store>
183
+ </optional_htaccess_password>
184
+ </fields>
185
+ </feed>
186
+ <cron translate="label" module="hawksearch_datafeed">
187
+ <label>Cron Settings</label>
188
+ <frontend_type>text</frontend_type>
189
+ <sort_order>200</sort_order>
190
+ <show_in_default>1</show_in_default>
191
+ <show_in_website>0</show_in_website>
192
+ <show_in_store>0</show_in_store>
193
+ <fields>
194
+ <email translate="label">
195
+ <label>Cron Email</label>
196
+ <comment>When cron runs, email to send notification to.</comment>
197
+ <frontend_type>text</frontend_type>
198
+ <sort_order>100</sort_order>
199
+ <show_in_default>1</show_in_default>
200
+ <show_in_website>1</show_in_website>
201
+ <show_in_store>1</show_in_store>
202
+ </email>
203
+ <frequency translate="label">
204
+ <label>Frequency</label>
205
+ <frontend_type>select</frontend_type>
206
+ <source_model>adminhtml/system_config_source_cron_frequency</source_model>
207
+ <backend_model>hawksearch_datafeed/system_config_backend_cron</backend_model>
208
+ <sort_order>200</sort_order>
209
+ <show_in_default>1</show_in_default>
210
+ <show_in_website>1</show_in_website>
211
+ <show_in_store>1</show_in_store>
212
+ </frequency>
213
+ <time translate="label">
214
+ <label>Start Time</label>
215
+ <frontend_type>time</frontend_type>
216
+ <sort_order>300</sort_order>
217
+ <show_in_default>1</show_in_default>
218
+ <show_in_website>1</show_in_website>
219
+ <show_in_store>1</show_in_store>
220
+ </time>
221
+ <disabled translate="label">
222
+ <label>Disabled</label>
223
+ <frontend_type>select</frontend_type>
224
+ <source_model>adminhtml/system_config_source_yesno</source_model>
225
+ <sort_order>400</sort_order>
226
+ <show_in_default>1</show_in_default>
227
+ <show_in_website>1</show_in_website>
228
+ <show_in_store>1</show_in_store>
229
+ </disabled>
230
+ </fields>
231
+ </cron>
232
+ </groups>
233
+ </hawksearch_datafeed>
234
+ </sections>
235
+ </config>
app/code/community/Hawksearch/Datafeed/sql/hawksearch_datafeed_setup/install-1.0.0.0.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+
11
+ //Save cron job to the core config data table
12
+
13
+ $frequency = Mage::getConfig()->getNode('default/hawksearch_datafeed/cron/frequency');
14
+
15
+ $time = explode(",", Mage::getConfig()->getNode('default/hawksearch_datafeed/cron/time'));
16
+
17
+ $cronTab = Mage::helper('hawksearch_datafeed')->getCronTimeAsCrontab($frequency, $time);
18
+
19
+ Mage::getModel("hawksearch_datafeed/system_config_backend_cron")->saveCronTab($cronTab);
app/design/adminhtml/default/default/template/hawksearch/search/sysconfig/generate/js.phtml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+ ?>
11
+ <script type="text/javascript">
12
+ //<![CDATA[
13
+
14
+ var hawkSearchFeed = {
15
+ isInit : false,
16
+ buttonId : null,
17
+ init : function() {
18
+ this.url = '<?php echo $this->getGenerateUrl() ?>';
19
+ this.buttonId = '<?php echo $this->getButtonId()?>';
20
+ this.displayId = "hawksearch_display_msg";
21
+ this.isInit = true;
22
+ },
23
+ generateFeed : function() {
24
+ if (!this.isInit) {
25
+ this.init();
26
+ }
27
+ new Ajax.Request(this.url, {
28
+ onSuccess: function(transport) {
29
+ var response = transport.responseText.evalJSON();
30
+ this.displayResults(response);
31
+ }.bind(this)
32
+ });
33
+ },
34
+ displayResults : function(response) {
35
+ var responseEl = $(this.displayId);
36
+ if (responseEl == null) {
37
+ var responseEl = new Element('p', {id : this.displayId}).addClassName('note');
38
+ Element.insert($(this.buttonId) , {after: responseEl});
39
+ }
40
+ if (response.error) {
41
+ return responseEl.innerHTML = response.error;
42
+ }
43
+ $(this.buttonId).disabled = true;
44
+ $(this.buttonId).addClassName("disabled");
45
+ return responseEl.innerHTML = "<?php echo Mage::getModel('hawksearch_datafeed/feed')->getAjaxNotice(); ?>";
46
+ }
47
+ }
48
+
49
+ //]]>
50
+ </script>
app/design/adminhtml/default/default/template/hawksearch/search/sysconfig/generateimagecache/js.phtml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
4
+ *
5
+ * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
6
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
7
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
8
+ * PARTICULAR PURPOSE.
9
+ */
10
+ ?>
11
+ <script type="text/javascript">
12
+ //<![CDATA[
13
+
14
+ var hawkSearchCache = {
15
+ isInit : false,
16
+ buttonId : null,
17
+ init : function() {
18
+ this.url = '<?php echo $this->getGenerateUrl() ?>';
19
+ this.buttonId = '<?php echo $this->getButtonId()?>';
20
+ this.displayId = "hawksearch_display_msg";
21
+ this.isInit = true;
22
+ },
23
+ generateImageCache : function() {
24
+ if (!this.isInit) {
25
+ this.init();
26
+ }
27
+ new Ajax.Request(this.url, {
28
+ onSuccess: function(transport) {
29
+ var response = transport.responseText.evalJSON();
30
+ this.displayResults(response);
31
+ }.bind(this)
32
+ });
33
+ },
34
+ displayResults : function(response) {
35
+ var responseEl = $(this.displayId);
36
+ if (responseEl == null) {
37
+ var responseEl = new Element('p', {id : this.displayId}).addClassName('note');
38
+ Element.insert($(this.buttonId) , {after: responseEl});
39
+ }
40
+ if (response.error) {
41
+ return responseEl.innerHTML = response.error;
42
+ }
43
+ $(this.buttonId).disabled = true;
44
+ $(this.buttonId).addClassName("disabled");
45
+ return responseEl.innerHTML = "<?php echo Mage::getModel('hawksearch_datafeed/feed')->getAjaxNoticeImageCache(); ?>";
46
+ }
47
+ }
48
+
49
+ //]]>
50
+ </script>
app/etc/modules/Hawksearch_Datafeed.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Hawksearch_Datafeed>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Hawksearch_Datafeed>
8
+ </modules>
9
+ </config>
package.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>HawkSearch_Datafeed</name>
4
+ <version>1.0.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/OSL-3.0">Open Software License (OSL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>This package generates data feeds in the required format and can be consumed by Hawk Search.</summary>
10
+ <description>This package generates data feeds in the required format and can be consumed by Hawk Search.</description>
11
+ <notes>Should have url generation for Magento 1.13&#xD;
12
+ Should have category generation for attributes file</notes>
13
+ <authors><author><name>Hawksearch Inc.</name><user>hawksearch</user><email>mmunoz@thanxmedia.com</email></author></authors>
14
+ <date>2014-06-04</date>
15
+ <time>19:47:02</time>
16
+ <contents><target name="magecommunity"><dir name="Hawksearch"><dir name="Datafeed"><dir name="Block"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Version.php" hash="7f72ce91b67d40e68424454a449f1841"/></dir></dir><file name="Form.php" hash="1f6eaf265d3b8c78d3efd93cf93c7f2d"/><dir name="Frontend"><dir name="Feed"><dir name="Generate"><file name="Js.php" hash="b54e5207b5579648d7dfeb9515b3dfb2"/></dir><file name="Generate.php" hash="c73b0b2bd965b5c4e4cded455f23baa1"/><dir name="Generateimagecache"><file name="Js.php" hash="a8e2a4c5a6827eec8d9eebc88db9bbb9"/></dir><file name="Generateimagecache.php" hash="05a3585804163326b33d3a46ab7717b5"/><file name="Next.php" hash="92a25b140bc4d0f3b0c7b497fdf0ca6d"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="569bc6b857b652c80b933a6da02e4e19"/><file name="Feed.php" hash="8cf12219fcb541c409d1cde16b366de1"/></dir><dir name="Model"><file name="Cron.php" hash="2d5421315908619a744b96aa9d4d77cb"/><file name="Email.php" hash="f671df12afac28ae10713cd1972bef2c"/><file name="Feed.php" hash="d1c1fc9b1373cbf5c0cff5efbd9dcd93"/><dir name="System"><dir name="Config"><dir name="Backend"><file name="Cron.php" hash="2919385264c00276cbf09c105418d5ed"/></dir></dir></dir></dir><dir name="controllers"><file name="SearchController.php" hash="8250847b6e2526be19e04f807640d699"/></dir><dir name="etc"><file name="adminhtml.xml" hash="96daebeddbd749dfe0341818fe2eeabb"/><file name="config.xml" hash="8513047fa7d9020175957349cb968755"/><file name="system.xml" hash="3b763bc3073ce575eedb1632efc988a3"/></dir><dir name="sql"><dir name="hawksearch_datafeed_setup"><file name="install-1.0.0.0.php" hash="768e75fd75bbd9532c92859346d78ef2"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="hawksearch"><dir name="search"><dir name="sysconfig"><dir name="generate"><file name="js.phtml" hash="aa7a51511eaf9c2c1319df358181ae70"/></dir><dir name="generateimagecache"><file name="js.phtml" hash="aba0594893460ae5763ae243866e7e65"/></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Hawksearch_Datafeed.xml" hash="06b94625c6b60d1269fe61c4127d2146"/></dir></target></contents>
17
+ <compatible/>
18
+ <dependencies><required><php><min>5.1.0</min><max>8.1.0</max></php></required></dependencies>
19
+ </package>