HawkSearch_Datafeed - Version 1.0.3.0

Version Notes

Added debug logging, category url to hierarchy file.

Download this release

Release Info

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


Code changes from version 1.0.0.2 to 1.0.3.0

app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Clearts/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
+ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Clearts_Js
11
+ 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/datafeed/clearts/js.phtml');
19
+ }
20
+
21
+ /**
22
+ * Returns the run all feeds async url
23
+ *
24
+ * @return string
25
+ */
26
+ public function getClearUrl() {
27
+ $curStore = Mage::app()->getStore();
28
+ Mage::app()->setCurrentStore(1); //default storeID will always be 1
29
+ $myUrl = Mage::getUrl('hawksearch_datafeed/search/clearTimestamp');
30
+ Mage::app()->setCurrentStore($curStore);
31
+ return $myUrl;
32
+ }
33
+ }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generate/Js.php CHANGED
@@ -15,7 +15,7 @@ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Generate_Js extends
15
  */
16
  protected function _construct() {
17
  parent::_construct();
18
- $this->setTemplate('hawksearch/search/sysconfig/generate/js.phtml');
19
  }
20
 
21
  /**
@@ -24,10 +24,10 @@ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Generate_Js extends
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
  }
15
  */
16
  protected function _construct() {
17
  parent::_construct();
18
+ $this->setTemplate('hawksearch/datafeed/generate/js.phtml');
19
  }
20
 
21
  /**
24
  * @return string
25
  */
26
  public function getGenerateUrl() {
27
+ return Mage::getUrl('hawksearch_datafeed/search/runFeedGeneration/',
28
+ array(
29
+ '_secure' => true,
30
+ '_store' => Mage_Core_Model_App::ADMIN_STORE_ID
31
+ ));
32
  }
33
  }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generateimagecache/Js.php CHANGED
@@ -15,7 +15,7 @@ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Generateimagecache_J
15
  */
16
  protected function _construct() {
17
  parent::_construct();
18
- $this->setTemplate('hawksearch/search/sysconfig/generateimagecache/js.phtml');
19
  }
20
 
21
  /**
@@ -24,10 +24,10 @@ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Generateimagecache_J
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
  }
15
  */
16
  protected function _construct() {
17
  parent::_construct();
18
+ $this->setTemplate('hawksearch/datafeed/generateimagecache/js.phtml');
19
  }
20
 
21
  /**
24
  * @return string
25
  */
26
  public function getGenerateUrl() {
27
+ return Mage::getUrl('hawksearch_datafeed/search/runImageCacheGeneration/',
28
+ array(
29
+ '_secure' => true,
30
+ '_store' => Mage_Core_Model_App::ADMIN_STORE_ID
31
+ ));
32
  }
33
  }
app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Timestamp.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Hawksearch_Datafeed_Block_System_Config_Frontend_Feed_Timestamp
11
+ extends Mage_Adminhtml_Block_System_Config_Form_Field {
12
+
13
+ protected $_buttonId = 'clear_timestamp_button';
14
+
15
+ protected function _prepareLayout() {
16
+ $block = $this->getLayout()->createBlock('hawksearch_datafeed/system_config_frontend_feed_clearts_js');
17
+ $block->setData('button_id', $this->_buttonId);
18
+ $this->getLayout()->getBlock('js')->append($block);
19
+ return parent::_prepareLayout();
20
+
21
+ }
22
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
23
+ $timeinfo = $this->getTimeInfo();
24
+ $button = $this->getButton();
25
+ if($timeinfo == false) {
26
+ $timeinfo = '<p>Last generation time unknown, next generation will be a full export</p>';
27
+ $button->setData('class', 'disabled');
28
+ }
29
+ return $timeinfo . $button->toHtml();
30
+ }
31
+
32
+ private function getTimeInfo() {
33
+ $filename = Mage::helper('hawksearch_datafeed/data')->getFeedFilePath() . DS . "timestamp.txt";
34
+ if(!file_exists($filename)) {
35
+ return false;
36
+ }
37
+ $lines = file($filename);
38
+ $lastrun = new Zend_Date($lines[0]);
39
+ $lastrun->setTimezone(Mage::getStoreConfig('general/locale/timezone'));
40
+ return sprintf('<p id="hawksearch_lastgen_time">Last Generation at <strong>%s</strong> contained <strong>%d</strong> records</p>', $lastrun->toString("M/d/YYYY h:mm a"), $lines[1]);
41
+ }
42
+ private function getButton() {
43
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
44
+ ->setData(array(
45
+ 'id' => $this->_buttonId,
46
+ 'label' => $this->helper('hawksearch_datafeed')->__('Clear Timestamp'),
47
+ 'onclick' => 'javascript:hawkSearchTimestamp.clear(); return false;'
48
+ ));
49
+ return $button;
50
+ }
51
+ }
app/code/community/Hawksearch/Datafeed/Helper/Data.php CHANGED
@@ -214,7 +214,7 @@ class Hawksearch_Datafeed_Helper_Data extends Mage_Core_Helper_Abstract {
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());
214
  return Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . 'output_file_ext');
215
  }
216
  public function getFeedFilePath() {
217
+ return Mage::getBaseDir('base') . DS . Mage::getStoreConfig(self::SECTION . self::FEED_GROUP . 'feed_path');
218
  }
219
  function mtime() {
220
  list($usec, $sec) = explode(" ", microtime());
app/code/community/Hawksearch/Datafeed/Helper/Feed.php CHANGED
@@ -11,95 +11,47 @@
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
  /**
@@ -109,7 +61,7 @@ class Hawksearch_Datafeed_Helper_Feed {
109
  */
110
  public function getFeedFilePath() {
111
  if ($this->_feedFilePath === null) {
112
- $this->_feedFilePath = $this->makeVarPath(array('hawksearch', 'feeds'));
113
  }
114
  return $this->_feedFilePath;
115
  }
11
  class Hawksearch_Datafeed_Helper_Feed {
12
 
13
  protected $_feedFilePath = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ public function refreshImageCache($storeid) {
16
+ $tmppath = sys_get_temp_dir();
17
+ $tmpfile = tempnam($tmppath, 'hawkfeed_');
18
+
19
+ $parts = explode(DIRECTORY_SEPARATOR, __FILE__);
20
+ array_pop($parts);
21
+ $parts[] = 'runfeed.php';
22
+ $runfile = implode(DIRECTORY_SEPARATOR, $parts);
23
+ $root = getcwd();
24
+
25
+ $f = fopen($tmpfile, 'w');
26
+ fwrite($f, '#!/bin/sh' . "\n");
27
+ $phpbin = PHP_BINDIR . DIRECTORY_SEPARATOR . "php";
28
+
29
+ fwrite($f, "$phpbin $runfile -i $storeid -r $root -t $tmpfile\n");
30
+
31
+ shell_exec("/bin/sh $tmpfile > /dev/null 2>&1 &");
32
+
33
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  /**
35
  * Asynchronously starts a feed generation for each store
36
  */
37
  public function generateFeedsForAllStores() {
38
+ $tmppath = sys_get_temp_dir();
39
+ $tmpfile = tempnam($tmppath, 'hawkfeed_');
40
+
41
+ $parts = explode(DIRECTORY_SEPARATOR, __FILE__);
42
+ array_pop($parts);
43
+ $parts[] = 'runfeed.php';
44
+ $runfile = implode(DIRECTORY_SEPARATOR, $parts);
45
+ $root = getcwd();
46
+
47
+ $f = fopen($tmpfile, 'w');
48
+ fwrite($f, '#!/bin/sh' . "\n");
49
+ $phpbin = PHP_BINDIR . DIRECTORY_SEPARATOR . "php";
50
+
51
+ fwrite($f, "$phpbin $runfile -r $root -t $tmpfile\n");
52
+
53
+ shell_exec("/bin/sh $tmpfile > /dev/null 2>&1 &");
54
+
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
 
57
  /**
61
  */
62
  public function getFeedFilePath() {
63
  if ($this->_feedFilePath === null) {
64
+ $this->_feedFilePath = $this->makeVarPath(array('hawksearch', 'feeds'));
65
  }
66
  return $this->_feedFilePath;
67
  }
app/code/community/Hawksearch/Datafeed/Helper/runfeed.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
+ $opts = getopt('r:t:i:');
12
+ chdir($opts['r']);
13
+ require 'app/Mage.php';
14
+
15
+ Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
16
+ /** @var Mage $app */
17
+ $app = Mage::app();
18
+
19
+ $helper = Mage::helper('hawksearch_datafeed/feed');
20
+ $feed = Mage::getModel('hawksearch_datafeed/feed');
21
+
22
+ if ($helper->thereAreFeedLocks()) {
23
+ Mage::throwException("One or more feeds are being generated. Generation temporarily locked.");
24
+ }
25
+ if ($helper->CreateFeedLocks()) {
26
+ if (isset($opts['i'])) {
27
+ $feed->refreshImageCache($opts['i']);
28
+ } else {
29
+ $feed->generateFeed();
30
+ }
31
+ }
32
+ unlink($opts['t']);
33
+
app/code/community/Hawksearch/Datafeed/Model/Cron.php CHANGED
@@ -18,16 +18,12 @@ class Hawksearch_Datafeed_Model_Cron {
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
  }
18
  if(!Mage::getStoreConfig('hawksearch_datafeed/cron/disabled'))
19
  {
20
  try {
21
+ Mage::getModel('hawksearch_datafeed/feed')->generateFeed();
22
  $msg = "HawkSeach Feed Generated!";
23
  }
24
  catch (Exception $e) {
25
  $msg = $e->getMessage();
26
  }
 
 
 
 
27
  $this->_sendEmail($msg);
28
  }
29
  }
app/code/community/Hawksearch/Datafeed/Model/Feed.php CHANGED
@@ -1,7 +1,5 @@
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
  *
@@ -23,6 +21,7 @@ class Hawksearch_Datafeed_Model_Feed extends Mage_Core_Model_Abstract {
23
  $_totalProductCount,
24
  $_imageHeight,
25
  $_imageWidth,
 
26
  $_optionType;
27
 
28
  private $countryMap;
@@ -39,7 +38,7 @@ class Hawksearch_Datafeed_Model_Feed extends Mage_Core_Model_Abstract {
39
  // Ignore user aborts and allow the script
40
  // to run forever
41
  ignore_user_abort(true); // If Varnish decides that the results timed out. Browsers are better behaved.
42
- set_time_limit(0); // Even with DB calls not counting towards execution time, it's still a long running script. Vampiric bite FTW.
43
  /** @var $helper Hawksearch_Datafeed_Helper_Data */
44
  $helper = Mage::helper('hawksearch_datafeed/data');
45
 
@@ -53,7 +52,7 @@ class Hawksearch_Datafeed_Model_Feed extends Mage_Core_Model_Abstract {
53
 
54
  $this->_feedPath = $helper->getFeedFilePath();
55
  if (empty($this->_feedPath)) {
56
- $this->_feedPath = 'var/hawksearch/feeds';
57
  }
58
 
59
  $this->_batchSize = $helper->getBatchLimit();
@@ -71,10 +70,24 @@ class Hawksearch_Datafeed_Model_Feed extends Mage_Core_Model_Abstract {
71
  $this->outputFileDelimiter = $helper->getOutputFileDelimiter();
72
  $this->bufferSize = $helper->getBufferSize();
73
  $this->outputFileExtension = $helper->getOutputFileExtension();
 
74
 
75
  parent::__construct();
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  /**
79
  * Retrieves the values of select/multiselect fields, to be dereferenced into values useful to Hawk
80
  *
@@ -119,8 +132,6 @@ EOSQL;
119
 
120
  // Prepare the array of attribute codes and compile a unique list of IDs to dereference
121
 
122
- //die($sql.'Andrew');
123
-
124
  if ($rows = $write->fetchAll($sql)) {
125
  foreach ($rows as $row) {
126
  $opts = explode(',', $row['value']);
@@ -208,13 +219,8 @@ EOSQL;
208
  *
209
  * @return boolean
210
  */
211
-
212
  protected function _getAttributeData() {
213
- // Initializations
214
- //$path = $this->_feedPath;
215
- $done = false;
216
- $offset = 0;
217
-
218
  $filename = $this->_feedPath . DS . "attributes" . '.' . $this->outputFileExtension;
219
  $arrayExcludeFields = explode(",", $this->_excludedFields);
220
 
@@ -230,34 +236,30 @@ EOSQL;
230
  'varchar',
231
  'decimal',
232
  'datetime',
233
- // 'catalog_category_product',
234
  );
235
 
236
- $multiSelectValues = $this->getMultiSelectValues();
237
-
238
  $write = $this->_getConnection();
239
 
240
- // This _should_ be escaped to prevent SQL injection... however the source of data is in the
241
- // admin panel so _should_ be generally safe. TODO: Check the Magento writer DB object for ways
242
- // to escape content.
243
  $excludeFields = implode("', '", $arrayExcludeFields);
244
  if (!empty($excludeFields)) {
 
245
  $excludeFields = " AND attribute_code NOT IN ('" . $excludeFields . "')";
246
  }
247
 
 
248
  $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
 
249
  $output->appendRow(array('unique_id', 'key', 'value'));
 
250
 
251
- //$content = "unique_id\tkey\tvalue\n";
252
-
253
- // Loop through each of the catalog_product_entity_XXX tables separately. Despite tribal knowledge to the contrary
254
- // among DB developers, in this specific case multiple queries happens to be faster than multiple joins.
255
  foreach ($tables as $table) {
256
- //$output->appendRow(array('NOW', 'OUTPUTTING', $table));
 
257
  $done = false;
258
  $offset = 0;
259
  $valueTable = $productEntityValueTable . $table;
260
  if ($table == "catalog_category_product") {
 
261
 
262
  $selectQry = <<<EOSQL
263
  SELECT
@@ -265,6 +267,7 @@ SELECT
265
  e.sku,
266
  a.attribute_code,
267
  a.source_model,
 
268
  a.attribute_id,
269
  a.attribute_code As value
270
  FROM
@@ -276,13 +279,7 @@ WHERE
276
  ORDER BY e.entity_id ASC
277
  EOSQL;
278
 
279
- //die($selectQry);
280
- } elseif ($this->_optionType == 'eav') {
281
- // No temporary table any more, after exhaustive testing. It takes just as long to itterate
282
- // through the temp table as it does through a fresh query, plus the temp table has the
283
- // overhead of being set up in the first place. This query takes less than 2 seconds each
284
- // time it is called, compared to the over 5 minutes it took previously, when the temp
285
- // table was a good idea.
286
  $valColumn = "v.value";
287
  $eaovTable = '';
288
  if ($table == 'int') {
@@ -298,12 +295,13 @@ SELECT
298
  e.sku,
299
  a.attribute_code,
300
  a.source_model,
 
301
  a.attribute_id,
302
  $valColumn
303
  FROM
304
  $productEntityTable e
305
  LEFT JOIN
306
- $valueTable v ON e.entity_id = v.entity_id
307
  LEFT JOIN
308
  $eavAttributeTable a ON v.attribute_id = a.attribute_id
309
  $eaovTable
@@ -314,63 +312,18 @@ ORDER BY e.entity_id ASC
314
  EOSQL;
315
  Mage::log($selectQry);
316
 
317
- } else {
318
- $selectQry = <<<EOSQL
319
- SELECT
320
- e.entity_id,
321
- e.sku,
322
- a.attribute_code,
323
- a.source_model,
324
- a.attribute_id,
325
- v.value
326
- FROM
327
- $productEntityTable e
328
- FF0000LEFT JOIN
329
- $valueTable v ON e.entity_id = v.entity_id
330
- LEFT JOIN
331
- $eavAttributeTable a ON v.attribute_id = a.attribute_id
332
- WHERE
333
- e.entity_type_id = $this->_entityTypeId
334
- $excludeFields
335
- ORDER BY e.entity_id ASC
336
- EOSQL;
337
  }
338
 
339
  while (!$done) {
340
- //echo "TableName: " . $table;
341
- //die( "select Query: " . $selectQry);
342
-
343
  try {
344
- // Messy, messy, messy. I appologize in advance.
345
- // Perhaps some prose will help.
346
- // The fetchAll() within this first if() statement runs the query, including the LIMIT and OFFSET.
347
- // Then, we itterate through the results. If the value is a number or a list of comma-separated numbers, then
348
- // we attempt to dereference to the actual values for the field.
349
- // Finally, at the end of itterating through the results, we write to disk and reset our loop-specific variables before
350
- // launching back through the while() above and doing fetchAll() again.
351
- // Also note the foreach (tables as table) above, which moves us to the next DB table.
352
  if (($rows = $write->fetchAll($selectQry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) && (count($rows) > 0)) {
 
353
  foreach ($rows as $row) {
354
- $values = explode(',', $row['value']);
355
-
356
- if ($values[0] == "category_ids" && $row['attribute_code'] == 'category_ids') {
357
- $category_ids_for_export = "";
358
- $select_qry = 'SELECT category_id FROM ' . $categoryProductTable . ' WHERE product_id = "' . $row['entity_id'] . '"';
359
- $rows1 = $write->fetchAll($select_qry);
360
- foreach ($rows1 as $category_data) {
361
- //$content .= "\"" . $row['sku'] . "\"\t\"category_id\"\t\"" . $category_data['category_id'] . "\"\n";
362
- $output->appendRow(array($row['sku'], 'category_id', $category_data['category_id']));
363
- }
364
- } elseif ($row['attribute_code'] == 'country_of_manufacture') {
365
- //$content .= "\"" . $row['sku'] . "\"\t\"" . $row['attribute_code'] . "\"\t\"" . str_replace("\"", "\"\"", $countryMap[$row['value']]) . "\"\n";
366
- $output->appendRow(array($row['sku'], $row['attribute_code'], $this->getCountryName($row['value'])));
367
-
368
- } else if (is_numeric($values[0])) {
369
  foreach ($values as $val) {
370
- if (false && !empty($multiSelectValues[$row['attribute_code']][$val])) {
371
- //$content .= "\"" . $row['sku'] . "\"\t\"" . $row['attribute_code'] . "\"\t\"" . str_replace("\"", "\"\"", $multiSelectValues[$row['attribute_code']][$val]) . "\"\n";
372
- $output->appendRow(array($row['sku'], $row['attribute_code'], $multiSelectValues[$row['attribute_code']][$val]));
373
- } elseif ($table == 'int' && !empty($row['source_model'])) {
374
  $source = Mage::getSingleton($row['source_model']);
375
  if ($row['source_model'] == 'eav/entity_attribute_source_table') {
376
  $attribute = Mage::getModel('eav/entity_attribute')->load($row['attribute_id']);
@@ -378,65 +331,91 @@ EOSQL;
378
  }
379
  $output->appendRow(array($row['sku'], $row['attribute_code'], $source->getOptionText($row['value'])));
380
  } else {
381
- //$content .= "\"" . $row['sku'] . "\"\t\"" . $row['attribute_code'] . "\"\t\"" . str_replace("\"", "\"\"", $val) . "\"\n";
382
  $output->appendRow(array($row['sku'], $row['attribute_code'], $val));
383
  }
384
  }
385
- } // Otherwise, add each individually.
386
- else {
387
- //$content .= "\"" . $row['sku'] . "\"\t\"" . $row['attribute_code'] . "\"\t\"" . str_replace("\"", "\"\"", $row['value']) . "\"\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  $output->appendRow(array($row['sku'], $row['attribute_code'], $row['value']));
389
  }
390
  }
391
-
392
-
393
- //$this->writeFile($filename, '', $content, ($firstRecord ? 1 : 2));
394
-
395
- // Reset for the next iteration.
396
- // Commentary: It is necessary to set for next iteration at the end, rather than the beginning, because the first
397
- // iteration has special cases, such as setting the TSV header and removing/re-creating the file itself.
398
- // $firstRecord = false;
399
- // $content = '';
400
  $offset += $this->_batchSize;
401
  } else {
 
402
  $done = true;
403
  }
404
  } catch (Exception $e) {
405
  // remove lock
406
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
407
 
408
- if ($this->isLoggingEnabled) {
409
- Mage::log(date('c') . " - Exception thrown on line " . $e->getLine() . " of " . $e->getFile() . ": " . $e, null, 'hawksearch_errors.log');
410
- }
411
  return false;
412
  }
413
  }
414
  }
415
-
416
  /* custom attribute code/category_id */
417
  $collection = Mage::getModel('catalog/product')->getCollection();
418
  $collection->addAttributeToSelect('sku');
419
- $collection->addAttributeToFilter('visibility', array('neq' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE));
420
  if (!Mage::helper('hawksearch_datafeed/data')->getAllowDisabledAttribute()) {
 
421
  $collection->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
422
  }
423
- if(!Mage::helper('hawksearch_datafeed/data')->isIncludeOutOfStockItems()) {
 
424
  /** @var Mage_CatalogInventory_Model_Stock $stockfilter */
425
  $stockfilter = Mage::getSingleton('cataloginventory/stock');
426
  $stockfilter->addInStockFilterToCollection($collection);
427
  }
428
 
 
429
  $collection->setPageSize($this->_batchSize);
430
  $totalPages = $collection->getLastPageNumber();
 
431
 
432
  $currentPage = 1;
433
  do {
 
434
  $collection->setCurPage($currentPage);
 
 
 
 
 
 
 
 
 
 
435
  /** @var Mage_Catalog_Model_Product $product */
436
  foreach ($collection as $product) {
437
- foreach($product->getCategoryIds() as $id) {
438
  $output->appendRow(array($product->getSku(), 'category_id', $id));
439
  }
 
 
 
 
440
  /* Example of custom attribute generation */
441
  // $product->load('media_gallery');
442
  // /** @var Varien_Data_Collection $images */
@@ -455,90 +434,117 @@ EOSQL;
455
  // }
456
  // }
457
  }
458
- $collection->clear();
459
  $currentPage++;
460
  } while ($currentPage <= $totalPages);
461
 
 
462
  return true;
463
  }
464
 
 
 
 
 
465
  protected function _getCategoryData() {
466
- $done = false;
467
- $offset = 0;
468
  $filename = $this->_feedPath . DS . "hierarchy" . '.' . $this->outputFileExtension;
469
 
470
- //$firstRecord = true;
471
-
472
- $categoryTable = $this->_tablePrefix . 'catalog_category_entity';
473
- $eavAttributesTable = $this->_tablePrefix . 'eav_attribute';
474
- $categoryVarCharTable = $this->_tablePrefix . 'catalog_category_entity_varchar';
475
-
476
- $write = $this->_getConnection();
477
 
478
- $selectQry = <<<EOSQL
479
- SELECT
480
- a.entity_id,
481
- a.parent_id,
482
- b.value,
483
- a.position
484
- FROM
485
- $categoryTable AS a
486
- LEFT JOIN
487
- $categoryVarCharTable AS b ON a.entity_id = b.entity_id
488
- WHERE
489
- b.attribute_id IN
490
- (
491
- SELECT
492
- attribute_id
493
- FROM
494
- $eavAttributesTable
495
- WHERE
496
- attribute_code = 'name'
497
- )
498
- AND
499
- b.store_id = '0'
500
- AND
501
- a.parent_id != '0'
502
- ORDER BY
503
- a.position ASC
504
- EOSQL;
505
 
506
- //$content = "category_id\tcategory_name\tparent_category_id\tsort_order\n1\tRoot\t0\t0\n";
507
  $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
508
- $output->appendRow(array('category_id', 'category_name', 'parent_category_id', 'sort_order'));
509
- $output->appendRow(array('1', 'Root', '0', '0'));
 
 
 
510
 
511
- while (!$done) {
512
- try {
513
- if ($rows = $write->fetchAll($selectQry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) {
514
- if (count($rows) > 0) {
515
- foreach ($rows as $row) {
516
- //$content .= $row['entity_id'] . "\t" . $row['value'] . "\t" . $row['parent_id'] . "\t" . $row['position'] . "\n";
517
- $output->appendRow(array($row['entity_id'], $row['value'], $row['parent_id'], $row['position']));
518
- }
519
- $offset += $this->_batchSize;
520
- //$this->writeFile($filename, '', $content, ($firstRecord ? 1 : 2));
521
- //$firstRecord = false;
522
- //$content = '';
523
- }
524
- } else {
525
- $done = true;
526
  }
527
- } catch (Exception $e) {
528
- // remove lock
529
- Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
 
 
 
 
 
 
 
 
 
530
 
531
- if ($this->isLoggingEnabled) {
532
- Mage::log("SQL ERROR: (" . $e . ")", null, 'hawksearch_errors.log');
533
- }
534
- return false;
 
535
  }
536
- } //end whiledone loop
537
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
538
  return true;
539
  }
540
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
  protected function _getProductData() {
 
 
 
 
 
 
 
 
 
 
 
542
  $done = false;
543
  $offset = 0;
544
  $filename = $this->_feedPath . DS . "items" . '.' . $this->outputFileExtension;
@@ -586,33 +592,35 @@ WHERE attribute_code IN
586
  'msrp',
587
  'special_price',
588
  'status',
 
589
  '$brandAttribute'
590
  )
591
  AND entity_type_id = '$entity_type_id'
592
  EOSQL;
593
 
 
594
  if ($codeRows = $write->fetchAll($attrCodesQuery)) {
595
  foreach ($codeRows as $row) {
596
  $attrCodes[$row['attribute_code']] = $row['attribute_id'];
597
  }
598
  }
 
599
 
600
  $disabled_sql = '';
601
  $CONN = ' WHERE ';
602
  if (!$allowDisabled) {
603
- $disabled_sql = "LEFT JOIN $productEntityIntTable AS T6 ON P.entity_id = T6.entity_id AND T6.attribute_id = '" . $attrCodes['status'] . "'";
604
  }
605
 
606
- $brandAttribute = Mage::helper('hawksearch_datafeed/data')->getBrandAttribute();
607
  if (!empty($brandAttribute)) {
608
  $brand_select = ", B5.value AS Brand";
609
- $brand_sql = "LEFT JOIN " . $productEntityIntTable . " AS B5 ON P.entity_id = B5.entity_id AND B5.attribute_id = '" . $attrCodes[$brandAttribute] . "'";
610
  }
611
- $urlfield = ", CONCAT(V1.value, '.html') AS Link";
612
- $urljoin = "LEFT JOIN $productEntityUrlTable AS V1 ON P.entity_id = V1.entity_id AND V1.attribute_id = '" . $attrCodes['url_key'] . "'";
613
  if (!Mage::getSingleton('core/resource')->getConnection('core_write')->isTableExists('catalog_product_entity_url_key')) {
614
- $urlfield = '';
615
- $urljoin = '';
616
  }
617
 
618
  $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 $urlfield,
@@ -622,36 +630,40 @@ EOSQL;
622
  ELSE CONCAT('', V2.value)
623
  END AS Image
624
  FROM $productEntityTable AS P
625
- INNER JOIN " . $productEntityVarCharTable . " AS V ON P.entity_id = V.entity_id AND V.attribute_id = '" . $attrCodes['name'] . "'
626
- INNER JOIN " . $catalogInventoryStockTable . " AS ST ON P.entity_id = ST.product_id
 
627
  " . $urljoin . "
628
- LEFT JOIN " . $productEntityVarCharTable . " AS V2 ON P.entity_id = V2.entity_id AND V2.attribute_id = '" . $attrCodes['image'] . "'
629
- LEFT JOIN " . $productEntityTextTable . " AS T1 ON P.entity_id = T1.entity_id AND T1.attribute_id = '" . $attrCodes['description'] . "'
630
- LEFT JOIN " . $productEntityTextTable . " AS T2 ON P.entity_id = T2.entity_id AND T2.attribute_id = '" . $attrCodes['short_description'] . "'
631
- LEFT JOIN " . $productEntityTextTable . " AS T3 ON P.entity_id = T3.entity_id AND T3.attribute_id = '" . $attrCodes['meta_keyword'] . "'
632
- LEFT JOIN " . $productEntityIntTable . " AS T5 ON P.entity_id = T5.entity_id AND T5.attribute_id = '" . $attrCodes['visibility'] . "'
633
  " . $disabled_sql . "
634
- LEFT JOIN " . $productEntityDecimalTable . " AS D ON P.entity_id = D.entity_id AND D.attribute_id = '" . $attrCodes['price'] . "'
635
- LEFT JOIN " . $productEntityDateTimeTable . " AS SDF ON P.entity_id = SDF.entity_id AND SDF.attribute_id = '" . $attrCodes['special_from_date'] . "'
636
- LEFT JOIN " . $productEntityDateTimeTable . " AS SDT ON P.entity_id = SDT.entity_id AND SDT.attribute_id = '" . $attrCodes['special_to_date'] . "'
637
  " . $brand_sql . "
638
- LEFT JOIN " . $productEntityDecimalTable . " AS X ON P.entity_id = X.entity_id AND X.attribute_id = '" . $attrCodes['msrp'] . "'
639
-
640
  LEFT JOIN " . $productRelationTable . " AS R ON P.entity_id = R.parent_id OR P.entity_id = R.child_id
641
- LEFT JOIN " . $productEntityDecimalTable . " AS S ON P.entity_id = S.entity_id AND S.attribute_id = '" . $attrCodes['special_price'] . "'";
642
 
643
  if (!Mage::helper('hawksearch_datafeed/data')->isIncludeOutOfStockItems()) {
 
644
  $select_qry .= " $CONN ST.is_in_stock = 1";
645
  $CONN = ' AND ';
646
  }
647
  if (!$allowDisabled) {
 
648
  $select_qry .= " $CONN T6.value = 1 ";
649
  $CONN = ' AND ';
650
  }
651
 
652
- // die($select_qry);
653
- // $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";
 
654
  $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
 
655
  $output->appendRow(array(
656
  'product_id',
657
  'unique_id',
@@ -676,9 +688,13 @@ EOSQL;
676
  'keyword',
677
  'metric_inventory'));
678
 
 
679
  while (!$done) {
680
  try {
681
- if ($rows = $write->fetchAll($select_qry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) {
 
 
 
682
  if (count($rows) > 0) {
683
  foreach ($rows as $row) {
684
  //$name = empty($row['Name']) ? $row['Name'] : str_replace("\"", "\"\"", $row['Name']);
@@ -694,7 +710,6 @@ EOSQL;
694
  } else {
695
  $brand_text = "";
696
  }
697
- //$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";
698
  $output->appendRow(array(
699
  $row['ProductID'],
700
  $row['sku'],
@@ -721,30 +736,27 @@ EOSQL;
721
 
722
  }
723
  $offset += $this->_batchSize;
724
- //$this->writeFile($filename, '', $content, ($firstRecord ? 1 : 2));
725
- //$firstRecord = false;
726
- //$content = '';
727
  }
728
  } else {
 
729
  $done = true;
730
  }
731
  } catch (Exception $e) {
732
  // remove lock
733
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
734
 
735
- if ($this->isLoggingEnabled) {
736
- Mage::log("SQL ERROR: (" . $e . ")", null, 'hawksearch_errors.log');
737
- }
738
-
739
  return false;
740
  }
741
  } // end while
 
742
  return true;
743
  }
744
 
745
  protected function _getContentData() {
746
- //$resource = Mage::getSingleton('core/resource');
747
-
748
  $done = false;
749
  $offset = 0;
750
  $baseurl = Mage::getUrl();
@@ -759,13 +771,18 @@ EOSQL;
759
 
760
  $write = $this->_getConnection();
761
 
762
- //$content = "unique_id\tname\turl_detail\tdescription_short\tcreated_date\n";
763
  $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
 
764
  $output->appendRow(array('unique_id', 'name', 'url_detail', 'description_short', 'created_date'));
 
765
 
 
766
  while (!$done) {
767
  try {
768
- if ($rows = $write->fetchAll($select_qry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) {
 
 
769
  if (($numRows = count($rows)) && $numRows > 0) {
770
  foreach ($rows as $row) {
771
  //$content .= $row['page_id'] . "\t" . $row['title'] . "\t" . $row['Link'] . "\t" . $row['content_heading'] . "\t" . $row['creation_time'] . "\n";
@@ -773,9 +790,6 @@ EOSQL;
773
  }
774
 
775
  $offset += $this->_batchSize;
776
- // $this->writeFile($filename, '', $content, ($firstRecord ? 1 : 2));
777
- // $firstRecord = false;
778
- // $content = '';
779
  } else {
780
  $done = true;
781
  }
@@ -786,50 +800,16 @@ EOSQL;
786
  // remove lock
787
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
788
 
789
- if ($this->isLoggingEnabled) {
790
- Mage::log("SQL ERROR: (" . $e . ")", null, 'hawksearch_errors.log');
791
- }
792
  return false;
793
  }
794
  } // end while
 
795
  return true;
796
  }
797
 
798
- /*private function writeFile($filename, $header, $content, $recordcount) {
799
- if ($recordcount === 1) {
800
- if (file_exists($filename)) {
801
- unlink($filename);
802
- }
803
- }
804
-
805
- if (!file_exists($filename)) {
806
- $handle = fopen($filename, "a");
807
- fclose($handle);
808
- }
809
-
810
- if (is_writable($filename)) {
811
- if (!$handle = fopen($filename, 'a')) {
812
- if ($this->isLoggingEnabled) {
813
- Mage::log("Cannot open file (" . $filename . ")", null, 'hawksearch_errors.log');
814
- }
815
- return false;
816
- }
817
- if (fwrite($handle, $content) === FALSE) {
818
- if ($this->isLoggingEnabled) {
819
- Mage::log("Cannot write to file (" . $filename . ")", null, 'hawksearch_errors.log');
820
- }
821
- return false;
822
- }
823
- return true; // Success, wrote ($somecontent) to file ($filename);
824
- fclose($handle);
825
- } else {
826
- if ($this->isLoggingEnabled) {
827
- Mage::log("The file " . $filename . " is not writable", null, 'hawksearch_errors.log');
828
- }
829
- }
830
- return true;
831
- }*/
832
-
833
  public function getCountryName($code) {
834
  /* map friendly country_of_origin names */
835
  if (!isset($this->countryMap)) {
@@ -845,10 +825,18 @@ EOSQL;
845
  return isset($this->countryMap[$code]) ? $this->countryMap[$code] : $code;
846
  }
847
 
848
- public function generateFeed($price_feed = false) {
849
  try {
850
- //exports Attribute Data
851
- $this->_getAttributeData();
 
 
 
 
 
 
 
 
852
 
853
  //exports Category Data
854
  $this->_getCategoryData();
@@ -856,49 +844,74 @@ EOSQL;
856
  //exports Product Data
857
  $this->_getProductData();
858
 
 
 
 
859
  //exports CMS / Content Data
860
  $this->_getContentData();
861
 
862
- //refresh image cache
863
- $this->refreshImageCache();
864
-
865
  // remove locks
866
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
 
867
  } catch (Exception $e) {
868
  // remove lock
869
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
870
- #Mage::log("Exception: {$e->getMessage()}");
871
- if ($this->isLoggingEnabled) {
872
- Mage::log(sprintf('Exception: %s', $e->getMessage()), null, 'hawksearch_errors.log');
873
- }
874
  }
 
875
  }
876
 
877
- public function refreshImageCache() {
878
- $products = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect(array('image', 'small_image'));
879
- $products->setPageSize(1000);
 
 
 
 
 
 
 
 
 
880
 
 
 
 
881
  $pages = $products->getLastPageNumber();
 
882
  $currentPage = 1;
883
 
884
  do {
 
 
885
  $products->setCurPage($currentPage);
886
  $products->load();
887
 
888
  foreach ($products as $product) {
889
  if (empty($this->_imageHeight)) {
890
- Mage::helper('catalog/image')->init($product, 'small_image')->resize($this->_imageWidth) . '';
 
 
 
891
  } else {
892
- Mage::helper('catalog/image')->init($product, 'small_image')->resize($this->_imageWidth, $this->_imageHeight) . '';
 
 
 
893
  }
894
  }
895
 
896
  $currentPage++;
897
 
898
  //clear collection and free memory
899
- $products->clear();
900
 
901
  } while ($currentPage <= $pages);
 
 
 
902
  }
903
 
904
  /**
@@ -989,12 +1002,14 @@ class CsvWriter {
989
  }
990
 
991
  public function closeOutput() {
992
- if (!$this->outputOpen) {
 
 
 
993
  if (false === fclose($this->outputFile)) {
994
- throw new Exception("CsvWriter: Failed to close destination file'$this->finalDestinationPath'.");
995
  }
996
  $this->outputOpen = false;
997
  }
998
  }
999
-
1000
  }
1
  <?php
2
 
 
 
3
  /**
4
  * Copyright (c) 2013 Hawksearch (www.hawksearch.com) - All Rights Reserved
5
  *
21
  $_totalProductCount,
22
  $_imageHeight,
23
  $_imageWidth,
24
+ $_storeId,
25
  $_optionType;
26
 
27
  private $countryMap;
38
  // Ignore user aborts and allow the script
39
  // to run forever
40
  ignore_user_abort(true); // If Varnish decides that the results timed out. Browsers are better behaved.
41
+ set_time_limit(0); // Even with DB calls not counting towards execution time, it's still a long running script.
42
  /** @var $helper Hawksearch_Datafeed_Helper_Data */
43
  $helper = Mage::helper('hawksearch_datafeed/data');
44
 
52
 
53
  $this->_feedPath = $helper->getFeedFilePath();
54
  if (empty($this->_feedPath)) {
55
+ $this->_feedPath = Mage::getBaseDir('base') . DS . 'var/hawksearch/feeds';
56
  }
57
 
58
  $this->_batchSize = $helper->getBatchLimit();
70
  $this->outputFileDelimiter = $helper->getOutputFileDelimiter();
71
  $this->bufferSize = $helper->getBufferSize();
72
  $this->outputFileExtension = $helper->getOutputFileExtension();
73
+ $this->_storeId = 0;
74
 
75
  parent::__construct();
76
  }
77
 
78
+ /**
79
+ * Adds a log entry to the hawksearch proxy log. Logging must
80
+ * be enabled for both the module and Magneto
81
+ * (See System >> Configuration >> Developer >> Log Settings
82
+ *
83
+ * @param $message
84
+ */
85
+ public function log($message) {
86
+ if ($this->isLoggingEnabled) {
87
+ Mage::log("HAWKSEARCH: $message", null, 'hawksearch.log');
88
+ }
89
+ }
90
+
91
  /**
92
  * Retrieves the values of select/multiselect fields, to be dereferenced into values useful to Hawk
93
  *
132
 
133
  // Prepare the array of attribute codes and compile a unique list of IDs to dereference
134
 
 
 
135
  if ($rows = $write->fetchAll($sql)) {
136
  foreach ($rows as $row) {
137
  $opts = explode(',', $row['value']);
219
  *
220
  * @return boolean
221
  */
 
222
  protected function _getAttributeData() {
223
+ $this->log('starting _getAttributeData');
 
 
 
 
224
  $filename = $this->_feedPath . DS . "attributes" . '.' . $this->outputFileExtension;
225
  $arrayExcludeFields = explode(",", $this->_excludedFields);
226
 
236
  'varchar',
237
  'decimal',
238
  'datetime',
 
239
  );
240
 
 
 
241
  $write = $this->_getConnection();
242
 
 
 
 
243
  $excludeFields = implode("', '", $arrayExcludeFields);
244
  if (!empty($excludeFields)) {
245
+ $this->log('adding exclude fields');
246
  $excludeFields = " AND attribute_code NOT IN ('" . $excludeFields . "')";
247
  }
248
 
249
+ $this->log(sprintf('going to open feed file %s', $filename));
250
  $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
251
+ $this->log('feed file open, appending header');
252
  $output->appendRow(array('unique_id', 'key', 'value'));
253
+ $this->log('header appended');
254
 
 
 
 
 
255
  foreach ($tables as $table) {
256
+ $this->log(sprintf('starting to pull from attribute table %s', $table));
257
+
258
  $done = false;
259
  $offset = 0;
260
  $valueTable = $productEntityValueTable . $table;
261
  if ($table == "catalog_category_product") {
262
+ $this->log('creating query for catalog_category_product');
263
 
264
  $selectQry = <<<EOSQL
265
  SELECT
267
  e.sku,
268
  a.attribute_code,
269
  a.source_model,
270
+ a.frontend_input,
271
  a.attribute_id,
272
  a.attribute_code As value
273
  FROM
279
  ORDER BY e.entity_id ASC
280
  EOSQL;
281
 
282
+ } else {
 
 
 
 
 
 
283
  $valColumn = "v.value";
284
  $eaovTable = '';
285
  if ($table == 'int') {
295
  e.sku,
296
  a.attribute_code,
297
  a.source_model,
298
+ a.frontend_input,
299
  a.attribute_id,
300
  $valColumn
301
  FROM
302
  $productEntityTable e
303
  LEFT JOIN
304
+ $valueTable v ON e.entity_id = v.entity_id and v.store_id = 0
305
  LEFT JOIN
306
  $eavAttributeTable a ON v.attribute_id = a.attribute_id
307
  $eaovTable
312
  EOSQL;
313
  Mage::log($selectQry);
314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  }
316
 
317
  while (!$done) {
318
+ $this->log(sprintf('querying data for table %s at offset %d', $table, $offset));
 
 
319
  try {
 
 
 
 
 
 
 
 
320
  if (($rows = $write->fetchAll($selectQry . ' LIMIT ' . $offset . ', ' . $this->_batchSize)) && (count($rows) > 0)) {
321
+ $this->log(sprintf('fetch all succeeded for att type %s, processing %d rows', $table, count($rows)));
322
  foreach ($rows as $row) {
323
+ if ($row['frontend_input'] == 'multiselect') {
324
+ $values = explode(',', $row['value']);
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  foreach ($values as $val) {
326
+ if ($table == 'int' && !empty($row['source_model'])) {
 
 
 
327
  $source = Mage::getSingleton($row['source_model']);
328
  if ($row['source_model'] == 'eav/entity_attribute_source_table') {
329
  $attribute = Mage::getModel('eav/entity_attribute')->load($row['attribute_id']);
331
  }
332
  $output->appendRow(array($row['sku'], $row['attribute_code'], $source->getOptionText($row['value'])));
333
  } else {
 
334
  $output->appendRow(array($row['sku'], $row['attribute_code'], $val));
335
  }
336
  }
337
+ } else if ($row['attribute_code'] == 'category_ids' && $row['value'] == "category_ids") {
338
+ $select_qry = 'SELECT category_id FROM ' . $categoryProductTable . ' WHERE product_id = "' . $row['entity_id'] . '"';
339
+ $rows1 = $write->fetchAll($select_qry);
340
+ foreach ($rows1 as $category_data) {
341
+ $output->appendRow(array($row['sku'], 'category_id', $category_data['category_id']));
342
+ }
343
+ } elseif ($row['attribute_code'] == 'country_of_manufacture') {
344
+ $output->appendRow(array($row['sku'], $row['attribute_code'], $this->getCountryName($row['value'])));
345
+
346
+ } elseif ($table == 'int' && !empty($row['source_model']) && $row['source_model'] != 'eav/entity_attribute_source_table') {
347
+ try {
348
+ $source = Mage::getSingleton($row['source_model']);
349
+ $attribute = Mage::getModel('eav/entity_attribute')->load($row['attribute_id']);
350
+ $source->setAttribute($attribute);
351
+ $output->appendRow(array($row['sku'], $row['attribute_code'], $source->getOptionText($row['value'])));
352
+ } catch (Exception $e) {
353
+ $this->log(sprintf('%s - Caught Exception on line %d or %s: %s', date('c'), $e->getLine(), $e->getFile(), $e->getTraceAsString()));
354
+ $output->appendRow(array($row['sku'], $row['attribute_code'], $row['value']));
355
+ }
356
+ } else {
357
  $output->appendRow(array($row['sku'], $row['attribute_code'], $row['value']));
358
  }
359
  }
 
 
 
 
 
 
 
 
 
360
  $offset += $this->_batchSize;
361
  } else {
362
+ $this->log(sprintf('done with table %s', $table));
363
  $done = true;
364
  }
365
  } catch (Exception $e) {
366
  // remove lock
367
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
368
 
369
+ $this->log(sprintf('%s - Exception thrown on line %d or %s: %s', date('c'), $e->getLine(), $e->getFile(), $e->getTraceAsString()));
370
+ $this->log('exiting function _getAttributeData() due to exception');
 
371
  return false;
372
  }
373
  }
374
  }
375
+ $this->log('going to get product collection for category id selection');
376
  /* custom attribute code/category_id */
377
  $collection = Mage::getModel('catalog/product')->getCollection();
378
  $collection->addAttributeToSelect('sku');
379
+ //$collection->addAttributeToFilter('visibility', array('neq' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE));
380
  if (!Mage::helper('hawksearch_datafeed/data')->getAllowDisabledAttribute()) {
381
+ $this->log('adding status filter');
382
  $collection->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
383
  }
384
+ if (!Mage::helper('hawksearch_datafeed/data')->isIncludeOutOfStockItems()) {
385
+ $this->log('adding out of stock filter');
386
  /** @var Mage_CatalogInventory_Model_Stock $stockfilter */
387
  $stockfilter = Mage::getSingleton('cataloginventory/stock');
388
  $stockfilter->addInStockFilterToCollection($collection);
389
  }
390
 
391
+ $this->log(sprintf('setting page size to %d', $this->_batchSize));
392
  $collection->setPageSize($this->_batchSize);
393
  $totalPages = $collection->getLastPageNumber();
394
+ $this->log(sprintf('retrieved %d total pages', $totalPages));
395
 
396
  $currentPage = 1;
397
  do {
398
+ $this->log(sprintf('setting current page to %d', $currentPage));
399
  $collection->setCurPage($currentPage);
400
+ $collection->clear();
401
+ $this->log(sprintf('going to process %d products on page %d', $collection->count(), $currentPage));
402
+
403
+ /*
404
+ * add ratings information
405
+ */
406
+ /** @var Mage_Review_Model_Review $review */
407
+ $review = Mage::getSingleton('review/review');
408
+ $review->appendSummary($collection);
409
+
410
  /** @var Mage_Catalog_Model_Product $product */
411
  foreach ($collection as $product) {
412
+ foreach ($product->getCategoryIds() as $id) {
413
  $output->appendRow(array($product->getSku(), 'category_id', $id));
414
  }
415
+ if(($rs = $product->getRatingSummary()) && $rs->getReviewsCount() > 0){
416
+ $output->appendRow(array($product->getSku(), 'rating_summary', $rs->getRatingSummary()));
417
+ $output->appendRow(array($product->getSku(), 'reviews_count', $rs->getReviewsCount()));
418
+ }
419
  /* Example of custom attribute generation */
420
  // $product->load('media_gallery');
421
  // /** @var Varien_Data_Collection $images */
434
  // }
435
  // }
436
  }
 
437
  $currentPage++;
438
  } while ($currentPage <= $totalPages);
439
 
440
+ $this->log('done processing attributes');
441
  return true;
442
  }
443
 
444
+ /**
445
+ * @return bool
446
+ * @throws Mage_Core_Exception
447
+ */
448
  protected function _getCategoryData() {
449
+ $this->log('starting _getCategoryData()');
 
450
  $filename = $this->_feedPath . DS . "hierarchy" . '.' . $this->outputFileExtension;
451
 
452
+ $collection = Mage::getModel('catalog/category')->getCollection();
453
+ $collection->addAttributeToSelect(array('name', 'is_active', 'parent_id', 'position'));
454
+ $collection->addAttributeToFilter('is_active', array('eq' => '1'));
455
+ $collection->addAttributeToSort('entity_id')->addAttributeToSort('parent_id')->addAttributeToSort('position');
 
 
 
456
 
457
+ $collection->setPageSize($this->_batchSize);
458
+ $pages = $collection->getLastPageNumber();
459
+ $currentPage = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
 
461
+ $this->log(sprintf('going to open feed file %s', $filename));
462
  $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
463
+ $this->log('file open, going to append header and root');
464
+ $output->appendRow(array('category_id', 'category_name', 'parent_category_id', 'sort_order', 'is_active', 'category_url'));
465
+ $output->appendRow(array('1', 'Root', '0', '0', '1', '/'));
466
+ $this->log('header and root appended');
467
+ $base = Mage::app()->getStore()->getBaseUrl();
468
 
469
+ $cats = array();
470
+ do {
471
+ $this->log(sprintf('getting category page %d', $currentPage));
472
+ $collection->setCurPage($currentPage);
473
+ $collection->clear();
474
+ $collection->load();
475
+ foreach ($collection as $cat) {
476
+ $fullUrl = Mage::helper('catalog/category')->getCategoryUrl($cat);
477
+ $category_url = substr($fullUrl, strlen($base));
478
+ if(substr($category_url, 0, 1) != '/'){
479
+ $category_url = '/' . $category_url;
 
 
 
 
480
  }
481
+ $this->log(sprintf("got full category url: %s, returning relative url %s", $fullUrl, $category_url));
482
+ $cats[] = array(
483
+ 'id' => $cat->getId(),
484
+ 'name' => $cat->getName(),
485
+ 'pid' => $cat->getParentId(),
486
+ 'pos' => $cat->getPosition(),
487
+ 'ia' => $cat->getIsActive(),
488
+ 'url' => $category_url
489
+ );
490
+ }
491
+ $currentPage++;
492
+ } while ($currentPage <= $pages);
493
 
494
+ $rcid = Mage::app()->getStore()->getRootCategoryId();
495
+ $myCategories = array();
496
+ foreach($cats as $storecat){
497
+ if($storecat['id'] == $rcid){
498
+ $myCategories[] = $storecat;
499
  }
500
+ }
501
 
502
+ $this->r_find($rcid, $cats, $myCategories);
503
+
504
+ foreach($myCategories as $final) {
505
+ $output->appendRow(array(
506
+ $final['id'],
507
+ $final['name'],
508
+ $final['pid'],
509
+ $final['pos'],
510
+ $final['ia'],
511
+ $final['url']
512
+ ));
513
+ }
514
+
515
+ $this->log('done with _getCategoryData()');
516
  return true;
517
  }
518
 
519
+ /**
520
+ * Recursively sets up the category tree without introducing
521
+ * duplicate data.
522
+ *
523
+ * @param $pid
524
+ * @param $all
525
+ * @param $tree
526
+ */
527
+ private function r_find($pid, &$all, &$tree) {
528
+ foreach($all as $item) {
529
+ if($item['pid'] == $pid) {
530
+ $tree[] = $item;
531
+ $this->r_find($item['id'], $all, $tree);
532
+ }
533
+ }
534
+ }
535
+
536
  protected function _getProductData() {
537
+ $this->log('starting _getProductData()');
538
+ /** @var Mage_Catalog_Helper_Product $helper */
539
+ $helper = Mage::helper('catalog/product');
540
+ $urlSuffix = $helper->getProductUrlSuffix(0);
541
+ if (!empty($urlSuffix)) {
542
+ if (substr($urlSuffix, 0, 1) != '.') {
543
+ $urlSuffix = '.' . $urlSuffix;
544
+ }
545
+ }
546
+ $this->log(sprintf("using '%s' for the product url suffix", $urlSuffix));
547
+
548
  $done = false;
549
  $offset = 0;
550
  $filename = $this->_feedPath . DS . "items" . '.' . $this->outputFileExtension;
592
  'msrp',
593
  'special_price',
594
  'status',
595
+ 'url_key',
596
  '$brandAttribute'
597
  )
598
  AND entity_type_id = '$entity_type_id'
599
  EOSQL;
600
 
601
+ $this->log('fetching attribute codes');
602
  if ($codeRows = $write->fetchAll($attrCodesQuery)) {
603
  foreach ($codeRows as $row) {
604
  $attrCodes[$row['attribute_code']] = $row['attribute_id'];
605
  }
606
  }
607
+ $this->log(sprintf('found %d codes: %s', count($attrCodes), implode("', '", array_keys($attrCodes))));
608
 
609
  $disabled_sql = '';
610
  $CONN = ' WHERE ';
611
  if (!$allowDisabled) {
612
+ $disabled_sql = "LEFT JOIN $productEntityIntTable AS T6 ON P.entity_id = T6.entity_id AND T6.attribute_id = '" . $attrCodes['status'] . "' AND T6.store_id = '" . $this->_storeId . "'";
613
  }
614
 
 
615
  if (!empty($brandAttribute)) {
616
  $brand_select = ", B5.value AS Brand";
617
+ $brand_sql = "LEFT JOIN " . $productEntityIntTable . " AS B5 ON P.entity_id = B5.entity_id AND B5.attribute_id = '" . $attrCodes[$brandAttribute] . "' AND B5.store_id = '" . $this->_storeId . "'";
618
  }
619
+ $urlfield = ", CONCAT(V1.value, '" . $urlSuffix . "') AS Link";
620
+ $urljoin = "LEFT JOIN $productEntityUrlTable AS V1 ON P.entity_id = V1.entity_id AND V1.attribute_id = '" . $attrCodes['url_key'] . "' AND V1.store_id = '" . $this->_storeId . "'";
621
  if (!Mage::getSingleton('core/resource')->getConnection('core_write')->isTableExists('catalog_product_entity_url_key')) {
622
+ $this->log('using catalog_product_entity_url_table');
623
+ $urljoin = ' LEFT JOIN ' . $productEntityVarCharTable . " AS V1 ON P.entity_id = V1.entity_id AND V1.attribute_id = '" . $attrCodes['url_key'] . "' AND V1.store_id = '" . $this->_storeId . "'";
624
  }
625
 
626
  $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 $urlfield,
630
  ELSE CONCAT('', V2.value)
631
  END AS Image
632
  FROM $productEntityTable AS P
633
+ INNER JOIN " . $productEntityVarCharTable . " AS V ON P.entity_id = V.entity_id AND V.attribute_id = '" . $attrCodes['name'] . "' AND V.store_id = '" . $this->_storeId . "'
634
+ INNER JOIN " . $catalogInventoryStockTable . " AS ST ON P.entity_id = ST.product_id
635
+ INNER JOIN " . $productEntityIntTable . " AS VIS ON VIS.entity_id = P.entity_id AND VIS.value != 1
636
  " . $urljoin . "
637
+ LEFT JOIN " . $productEntityVarCharTable . " AS V2 ON P.entity_id = V2.entity_id AND V2.attribute_id = '" . $attrCodes['image'] . "' AND V2.store_id = '" . $this->_storeId . "'
638
+ LEFT JOIN " . $productEntityTextTable . " AS T1 ON P.entity_id = T1.entity_id AND T1.attribute_id = '" . $attrCodes['description'] . "' AND T1.store_id = '" . $this->_storeId . "'
639
+ LEFT JOIN " . $productEntityTextTable . " AS T2 ON P.entity_id = T2.entity_id AND T2.attribute_id = '" . $attrCodes['short_description'] . "' AND T2.store_id = '" . $this->_storeId . "'
640
+ LEFT JOIN " . $productEntityTextTable . " AS T3 ON P.entity_id = T3.entity_id AND T3.attribute_id = '" . $attrCodes['meta_keyword'] . "' AND T3 .store_id = '" . $this->_storeId . "'
641
+ LEFT JOIN " . $productEntityIntTable . " AS T5 ON P.entity_id = T5.entity_id AND T5.attribute_id = '" . $attrCodes['visibility'] . "' AND T5.store_id = '" . $this->_storeId . "'
642
  " . $disabled_sql . "
643
+ LEFT JOIN " . $productEntityDecimalTable . " AS D ON P.entity_id = D.entity_id AND D.attribute_id = '" . $attrCodes['price'] . "' AND D.store_id = '" . $this->_storeId . "'
644
+ LEFT JOIN " . $productEntityDateTimeTable . " AS SDF ON P.entity_id = SDF.entity_id AND SDF.attribute_id = '" . $attrCodes['special_from_date'] . "' AND SDF.store_id = '" . $this->_storeId . "'
645
+ LEFT JOIN " . $productEntityDateTimeTable . " AS SDT ON P.entity_id = SDT.entity_id AND SDT.attribute_id = '" . $attrCodes['special_to_date'] . "' AND SDT.store_id = '" . $this->_storeId . "'
646
  " . $brand_sql . "
647
+ LEFT JOIN " . $productEntityDecimalTable . " AS X ON P.entity_id = X.entity_id AND X.attribute_id = '" . $attrCodes['msrp'] . "' AND X.store_id = '" . $this->_storeId . "'
 
648
  LEFT JOIN " . $productRelationTable . " AS R ON P.entity_id = R.parent_id OR P.entity_id = R.child_id
649
+ LEFT JOIN " . $productEntityDecimalTable . " AS S ON P.entity_id = S.entity_id AND S.attribute_id = '" . $attrCodes['special_price'] . "' AND S.store_id = '" . $this->_storeId . "'";
650
 
651
  if (!Mage::helper('hawksearch_datafeed/data')->isIncludeOutOfStockItems()) {
652
+ $this->log('filtering for in-stock items');
653
  $select_qry .= " $CONN ST.is_in_stock = 1";
654
  $CONN = ' AND ';
655
  }
656
  if (!$allowDisabled) {
657
+ $this->log('filtering disabled items');
658
  $select_qry .= " $CONN T6.value = 1 ";
659
  $CONN = ' AND ';
660
  }
661
 
662
+ $select_qry .= " GROUP BY P.entity_id ";
663
+
664
+ $this->log(sprintf('going to open feed file %s', $filename));
665
  $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
666
+ $this->log('appending feed header');
667
  $output->appendRow(array(
668
  'product_id',
669
  'unique_id',
688
  'keyword',
689
  'metric_inventory'));
690
 
691
+ $full_query = 'not yet set';
692
  while (!$done) {
693
  try {
694
+ $full_query = $select_qry . ' LIMIT ' . $offset . ', ' . $this->_batchSize;
695
+ $this->log(sprintf('going to fetch %d products starting at offset %d', $this->_batchSize, $offset));
696
+ if ($rows = $write->fetchAll($full_query)) {
697
+ $this->log(sprintf('query returned %d rows', count($rows)));
698
  if (count($rows) > 0) {
699
  foreach ($rows as $row) {
700
  //$name = empty($row['Name']) ? $row['Name'] : str_replace("\"", "\"\"", $row['Name']);
710
  } else {
711
  $brand_text = "";
712
  }
 
713
  $output->appendRow(array(
714
  $row['ProductID'],
715
  $row['sku'],
736
 
737
  }
738
  $offset += $this->_batchSize;
 
 
 
739
  }
740
  } else {
741
+ $this->log('done fetching products');
742
  $done = true;
743
  }
744
  } catch (Exception $e) {
745
  // remove lock
746
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
747
 
748
+ $this->log(sprintf('%s - Exception thrown on line %d or %s: %s', date('c'), $e->getLine(), $e->getFile(), $e->getTraceAsString()));
749
+ $this->log(sprintf("\nSQL was:\n%s", $full_query));
750
+ $this->log('exiting function _getProductData() due to exception');
 
751
  return false;
752
  }
753
  } // end while
754
+ $this->log('done with _getProductData()');
755
  return true;
756
  }
757
 
758
  protected function _getContentData() {
759
+ $this->log('starting _getContentData()');
 
760
  $done = false;
761
  $offset = 0;
762
  $baseurl = Mage::getUrl();
771
 
772
  $write = $this->_getConnection();
773
 
774
+ $this->log(sprintf('going to open feed file %s', $filename));
775
  $output = new CsvWriter($filename, $this->outputFileDelimiter, $this->bufferSize);
776
+ $this->log('feed file open, going to append header');
777
  $output->appendRow(array('unique_id', 'name', 'url_detail', 'description_short', 'created_date'));
778
+ $this->log('header appended, going to fetch data');
779
 
780
+ $full_query = 'not yet set';
781
  while (!$done) {
782
  try {
783
+ $this->log(sprintf('going to fetch %d rows at offset %d', $this->_batchSize, $offset));
784
+ $full_query = $select_qry . ' LIMIT ' . $offset . ', ' . $this->_batchSize;
785
+ if ($rows = $write->fetchAll($full_query)) {
786
  if (($numRows = count($rows)) && $numRows > 0) {
787
  foreach ($rows as $row) {
788
  //$content .= $row['page_id'] . "\t" . $row['title'] . "\t" . $row['Link'] . "\t" . $row['content_heading'] . "\t" . $row['creation_time'] . "\n";
790
  }
791
 
792
  $offset += $this->_batchSize;
 
 
 
793
  } else {
794
  $done = true;
795
  }
800
  // remove lock
801
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
802
 
803
+ $this->log(sprintf('%s - Exception thrown on line %d or %s: %s', date('c'), $e->getLine(), $e->getFile(), $e->getTraceAsString()));
804
+ $this->log(sprintf("\nSQL was:\n%s", $full_query));
805
+ $this->log('exiting function _getContentData() due to exception');
806
  return false;
807
  }
808
  } // end while
809
+ $this->log('done fetching content data');
810
  return true;
811
  }
812
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
813
  public function getCountryName($code) {
814
  /* map friendly country_of_origin names */
815
  if (!isset($this->countryMap)) {
825
  return isset($this->countryMap[$code]) ? $this->countryMap[$code] : $code;
826
  }
827
 
828
+ public function generateFeed() {
829
  try {
830
+ $sid = Mage::app()->getWebsite()->getDefaultGroup()->getDefaultStoreId();
831
+ $h = Mage::helper("hawksearch_proxy");
832
+ if (!empty($h)) {
833
+ $sid = $h->getCategoryStoreId();
834
+ }
835
+
836
+ $this->log('starting environment for store id: ' . $sid);
837
+ /** @var Mage_Core_Model_App_Emulation $appEmulation */
838
+ $appEmulation = Mage::getSingleton('core/app_emulation');
839
+ $initialEnvironmentInfo = $appEmulation->startEnvironmentEmulation($sid);
840
 
841
  //exports Category Data
842
  $this->_getCategoryData();
844
  //exports Product Data
845
  $this->_getProductData();
846
 
847
+ //exports Attribute Data
848
+ $this->_getAttributeData();
849
+
850
  //exports CMS / Content Data
851
  $this->_getContentData();
852
 
853
+ //refresh image cache no longer part of feed generation
854
+ //$this->refreshImageCache();
855
+ $this->log('done generating data feed files, going to remove lock files.');
856
  // remove locks
857
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
858
+ $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
859
  } catch (Exception $e) {
860
  // remove lock
861
  Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
862
+ $this->log(sprintf("General Exception %s at generateFeed() line %d, stack:\n%s", $e->getMessage(), $e->getLine(), $e->getTraceAsString()));
 
 
 
863
  }
864
+ $this->log('done with generateFeed()');
865
  }
866
 
867
+ public function refreshImageCache($storeid = null) {
868
+ $this->log('starting refreshImageCache()');
869
+ $sid = Mage::app()->getWebsite()->getDefaultGroup()->getDefaultStoreId();
870
+ $h = Mage::helper("hawksearch_proxy");
871
+ if (!empty($h)) {
872
+ $sid = $h->getCategoryStoreId();
873
+ }
874
+
875
+ $this->log('starting environment for store id: ' . $sid);
876
+
877
+ $appEmulation = Mage::getSingleton('core/app_emulation');
878
+ $initialEnvironmentInfo = $appEmulation->startEnvironmentEmulation($sid);
879
 
880
+ $products = Mage::getModel('catalog/product')
881
+ ->getCollection()->addAttributeToSelect(array('image', 'small_image'));
882
+ $products->setPageSize(100);
883
  $pages = $products->getLastPageNumber();
884
+
885
  $currentPage = 1;
886
 
887
  do {
888
+ $this->log(sprintf('going to page %d of images', $currentPage));
889
+ $products->clear();
890
  $products->setCurPage($currentPage);
891
  $products->load();
892
 
893
  foreach ($products as $product) {
894
  if (empty($this->_imageHeight)) {
895
+ $this->log(
896
+ sprintf('going to resize image for url: %s',
897
+ Mage::helper('catalog/image')->init($product, 'small_image')->resize($this->_imageWidth
898
+ )));
899
  } else {
900
+ $this->log(
901
+ sprintf('going to resize image for url: %s',
902
+ Mage::helper('catalog/image')->init($product, 'small_image')->resize($this->_imageWidth, $this->_imageHeight
903
+ )));
904
  }
905
  }
906
 
907
  $currentPage++;
908
 
909
  //clear collection and free memory
 
910
 
911
  } while ($currentPage <= $pages);
912
+ $this->log('done generating image cache, going to remove locks.');
913
+ Mage::helper('hawksearch_datafeed/feed')->RemoveFeedLocks();
914
+ $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
915
  }
916
 
917
  /**
1002
  }
1003
 
1004
  public function closeOutput() {
1005
+ if ($this->outputOpen) {
1006
+ if (false === fflush($this->outputFile)) {
1007
+ throw new Exception(sprintf("CsvWriter: Failed to flush feed file: %s", $this->finalDestinationPath));
1008
+ }
1009
  if (false === fclose($this->outputFile)) {
1010
+ throw new Exception(sprintf("CsvWriter: Failed to close feed file ", $this->finalDestinationPath));
1011
  }
1012
  $this->outputOpen = false;
1013
  }
1014
  }
 
1015
  }
app/code/community/Hawksearch/Datafeed/controllers/SearchController.php CHANGED
@@ -15,58 +15,27 @@ class Hawksearch_Datafeed_SearchController extends Mage_Core_Controller_Front_Ac
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;
@@ -75,39 +44,11 @@ class Hawksearch_Datafeed_SearchController extends Mage_Core_Controller_Front_Ac
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
  */
@@ -115,7 +56,15 @@ class Hawksearch_Datafeed_SearchController extends Mage_Core_Controller_Front_Ac
115
  $response = array("error" => false);
116
 
117
  try {
118
- Mage::helper('hawksearch_datafeed/feed')->generateFeedsForAllStores();
 
 
 
 
 
 
 
 
119
  }
120
  catch (Exception $e) {
121
  Mage::logException($e);
@@ -137,8 +86,15 @@ class Hawksearch_Datafeed_SearchController extends Mage_Core_Controller_Front_Ac
137
  if (!$storeId) {
138
  $storeId = Mage::app()->getDefaultStoreView()->getId();
139
  }
 
 
 
140
 
141
- Mage::getModel('hawksearch_datafeed/feed')->setData('store_id', $storeId)->refreshImageCache();
 
 
 
 
142
  }
143
  catch (Exception $e) {
144
  Mage::logException($e);
@@ -148,24 +104,4 @@ class Hawksearch_Datafeed_SearchController extends Mage_Core_Controller_Front_Ac
148
  ->setHeader("Content-Type", "application/json")
149
  ->setBody(json_encode($response));
150
  }
151
-
152
- /**
153
- * Generates a feed based on passed in store id. Defaults store id to default store
154
- */
155
- public function generateFeedAction() {
156
- $response = "";
157
- try {
158
- $storeId = $this->getRequest()->getParam("storeId");
159
-
160
- if (!$storeId) {
161
- $storeId = Mage::app()->getDefaultStoreView()->getId();
162
- }
163
- Mage::getModel('hawksearch_datafeed/feed')->setData('store_id', $storeId)->generateFeed(true);
164
- }
165
- catch (Exception $e) {
166
- Mage::logException($e);
167
- $response = "An unknown error occurred.";
168
- }
169
- $this->getResponse()->setBody($response);
170
- }
171
  }
15
  $this->renderLayout();
16
  }
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  /**
19
  * API Call for Image CacheKey to get images from cache on auto resize.
20
  */
21
  public function getCacheKeyAction() {
22
  $response = array("error" => false);
23
  try {
24
+ /** @var Mage_Catalog_Model_Resource_Product_Collection $coll */
25
+ $coll = Mage::getModel('catalog/product')->getCollection();
26
+ $coll->addAttributeToSelect('small_image');
27
+ $coll->addAttributeToFilter('small_image', array(
28
+ 'notnull' => true
29
+ ));
30
+ $coll->getSelect()->limit(100);
31
+ $item = $coll->getLastItem();
32
+ $path = (string) Mage::helper('catalog/image')->init($item, 'small_image');
33
+ $imageArray = explode("/", $path);
34
+ $cache_key = "";
35
+ foreach($imageArray as $part) {
36
+ if(preg_match('/[0-9a-fA-F]{32}/', $part)) {
37
+ $cache_key = $part;
38
+ }
39
  }
40
 
41
  $response['cache_key'] = $cache_key;
44
  catch (Exception $e) {
45
  $response['error'] = $e->getMessage();
46
  }
 
 
 
 
47
  $this->getResponse()
48
  ->setHeader("Content-Type", "application/json")
49
  ->setBody(json_encode($response));
50
  }
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  /**
53
  * Asynchronous posting to feed generation url for each store.
54
  */
56
  $response = array("error" => false);
57
 
58
  try {
59
+ $disabledFuncs = explode(',', ini_get('disable_functions'));
60
+ $isShellDisabled = is_array($disabledFuncs) ? in_array('shell_exec', $disabledFuncs) : true;
61
+ $isShellDisabled = (stripos(PHP_OS, 'win') === false) ? $isShellDisabled : true;
62
+
63
+ if($isShellDisabled) {
64
+ $response['error'] = 'This installation cannot run one off feed generations. Must use cron.';
65
+ } else {
66
+ Mage::helper('hawksearch_datafeed/feed')->generateFeedsForAllStores();
67
+ }
68
  }
69
  catch (Exception $e) {
70
  Mage::logException($e);
86
  if (!$storeId) {
87
  $storeId = Mage::app()->getDefaultStoreView()->getId();
88
  }
89
+ $disabledFuncs = explode(',', ini_get('disable_functions'));
90
+ $isShellDisabled = is_array($disabledFuncs) ? in_array('shell_exec', $disabledFuncs) : true;
91
+ $isShellDisabled = (stripos(PHP_OS, 'win') === false) ? $isShellDisabled : true;
92
 
93
+ if($isShellDisabled) {
94
+ $response['error'] = 'This installation cannot run one-off cache generations. Must use cron.';
95
+ } else {
96
+ Mage::helper('hawksearch_datafeed/feed')->refreshImageCache($storeId);
97
+ }
98
  }
99
  catch (Exception $e) {
100
  Mage::logException($e);
104
  ->setHeader("Content-Type", "application/json")
105
  ->setBody(json_encode($response));
106
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  }
app/code/community/Hawksearch/Datafeed/etc/config.xml CHANGED
@@ -12,7 +12,7 @@
12
  <config>
13
  <modules>
14
  <Hawksearch_Datafeed>
15
- <version>1.0.0.2</version>
16
  </Hawksearch_Datafeed>
17
  </modules>
18
  <global>
@@ -20,13 +20,6 @@
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>
@@ -64,22 +57,17 @@
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>
@@ -87,9 +75,6 @@
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>
12
  <config>
13
  <modules>
14
  <Hawksearch_Datafeed>
15
+ <version>1.0.3.0</version>
16
  </Hawksearch_Datafeed>
17
  </modules>
18
  <global>
20
  <hawksearch_datafeed>
21
  <class>Hawksearch_Datafeed_Block</class>
22
  </hawksearch_datafeed>
 
 
 
 
 
 
 
23
  </blocks>
24
  <helpers>
25
  <hawksearch_datafeed>
57
  <logging_enabled>1</logging_enabled>
58
  </general>
59
  <feed>
 
 
60
  <batch_limit>10000</batch_limit>
61
  <image_width>135</image_width>
 
62
  <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>
63
+ <stockstatus>0</stockstatus>
64
  <itemstatus>0</itemstatus>
 
65
  <delimiter>tab</delimiter>
66
  <buffer_size>65536</buffer_size>
67
  <output_file_ext>txt</output_file_ext>
68
  <feed_path>var/hawksearch/feeds</feed_path>
69
  </feed>
70
  <cron>
 
71
  <frequency backend_model="adminhtml/system_config_backend_product_alert_cron">every_5min</frequency>
72
  <disabled>0</disabled>
73
  <time>02,00,00</time>
75
  </hawksearch_datafeed>
76
  </default>
77
  <crontab>
 
 
 
78
  <jobs>
79
  <hawksearch_datafeed>
80
  <run>
app/code/community/Hawksearch/Datafeed/etc/system.xml CHANGED
@@ -181,15 +181,6 @@
181
  <show_in_website>0</show_in_website>
182
  <show_in_store>0</show_in_store>
183
  </optional_htaccess_password>
184
- <option_type translate="label">
185
- <label>Attribute type</label>
186
- <frontend_type>text</frontend_type>
187
- <comment>Mode should generally be set to 'eav'</comment>
188
- <sort_order>900</sort_order>
189
- <show_in_default>1</show_in_default>
190
- <show_in_website>0</show_in_website>
191
- <show_in_store>0</show_in_store>
192
- </option_type>
193
  </fields>
194
  </feed>
195
  <cron translate="label" module="hawksearch_datafeed">
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">
app/design/adminhtml/default/default/template/hawksearch/datafeed/clearts/js.phtml ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 hawkSearchTimestamp = {
15
+ isInit : false,
16
+ buttonId : null,
17
+ init : function() {
18
+ this.url = '<?php echo $this->getClearUrl() ?>';
19
+ this.buttonId = '<?php echo $this->getButtonId()?>';
20
+ this.displayId = "hawksearch_display_msg";
21
+ this.isInit = true;
22
+ },
23
+ clear : function() {
24
+ var r = confirm("Clearing the timestamp will cause the next feed generation to produce a full result set. Are you sure you want to continue?");
25
+ if(r != true) {
26
+ return;
27
+ }
28
+ if (!this.isInit) {
29
+ this.init();
30
+ }
31
+ new Ajax.Request(this.url, {
32
+ onSuccess: function(transport) {
33
+ var response = transport.responseText.evalJSON();
34
+ this.displayResults(response);
35
+ }.bind(this)
36
+ });
37
+ },
38
+ displayResults : function(response) {
39
+ if(response.error) {
40
+ alert(response.error);
41
+ return;
42
+ }
43
+ var lastGen = $('hawksearch_lastgen_time');
44
+ lastGen.innerHTML = response.lastGen;
45
+ $(this.buttonId).disabled = true;
46
+ $(this.buttonId).addClassName("disabled");
47
+
48
+ /*
49
+ var responseEl = $(this.displayId);
50
+ if (responseEl == null) {
51
+ var responseEl = new Element('p', {id : this.displayId}).addClassName('note');
52
+ Element.insert($(this.buttonId) , {after: responseEl});
53
+ }
54
+ if (response.error) {
55
+ return responseEl.innerHTML = response.error;
56
+ }
57
+ $(this.buttonId).disabled = true;
58
+ $(this.buttonId).addClassName("disabled");
59
+ return responseEl.innerHTML = "<?php echo Mage::getModel('hawksearch_datafeed/feed')->getAjaxNotice(); ?>";
60
+ */
61
+ }
62
+ }
63
+
64
+ //]]>
65
+ </script>
app/design/adminhtml/default/default/template/hawksearch/datafeed/generate/js.phtml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ onFailure: function (response, rHeader) {
33
+ alert('there has been an error, status is: ');
34
+ }.bind(this),
35
+ onException: function(request, exception) {
36
+ alert('there has been an XHR exception');
37
+ }.bind(this)
38
+ });
39
+ },
40
+ displayResults: function (response) {
41
+ var responseEl = $(this.displayId);
42
+ if (responseEl == null) {
43
+ var responseEl = new Element('p', {id: this.displayId}).addClassName('note');
44
+ Element.insert($(this.buttonId), {after: responseEl});
45
+ }
46
+ if (response.error) {
47
+ return responseEl.innerHTML = response.error;
48
+ }
49
+ $(this.buttonId).disabled = true;
50
+ $(this.buttonId).addClassName("disabled");
51
+ return responseEl.innerHTML = "<?php echo Mage::getModel('hawksearch_datafeed/feed')->getAjaxNotice(); ?>";
52
+ }
53
+ }
54
+
55
+ //]]>
56
+ </script>
app/design/adminhtml/default/default/template/hawksearch/{search/sysconfig → datafeed}/generateimagecache/js.phtml RENAMED
File without changes
app/design/adminhtml/default/default/template/hawksearch/search/sysconfig/generate/js.phtml DELETED
@@ -1,50 +0,0 @@
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>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
package.xml CHANGED
@@ -1,20 +1,18 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>HawkSearch_Datafeed</name>
4
- <version>1.0.0.2</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&#xD;
13
- Minor fix for attributes returning int values.</notes>
14
  <authors><author><name>Hawksearch Inc.</name><user>hawksearch</user><email>mmunoz@thanxmedia.com</email></author></authors>
15
- <date>2014-08-07</date>
16
- <time>14:09:08</time>
17
- <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="a4973f0ebc2dca577d0bc29e2cca2da7"/><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="1455f555aab7bd397993f4153309a248"/></dir><dir name="etc"><file name="adminhtml.xml" hash="96daebeddbd749dfe0341818fe2eeabb"/><file name="config.xml" hash="af82af1e1b99f072bb69b6ce560ff27f"/><file name="system.xml" hash="eeeeee9921ae160ab321b8c3192fa2b8"/></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>
18
  <compatible/>
19
  <dependencies><required><php><min>5.1.0</min><max>8.1.0</max></php></required></dependencies>
20
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>HawkSearch_Datafeed</name>
4
+ <version>1.0.3.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>Added debug logging, category url to hierarchy file.</notes>
 
 
12
  <authors><author><name>Hawksearch Inc.</name><user>hawksearch</user><email>mmunoz@thanxmedia.com</email></author></authors>
13
+ <date>2015-02-18</date>
14
+ <time>14:14:33</time>
15
+ <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="Clearts"><file name="Js.php" hash="220b75f831af835d97be401798ec9461"/></dir><dir name="Generate"><file name="Js.php" hash="7e3f96c837b6602759160d4bb92635bf"/></dir><file name="Generate.php" hash="c73b0b2bd965b5c4e4cded455f23baa1"/><dir name="Generateimagecache"><file name="Js.php" hash="25ff246f556d518bcb05198101ec0d7f"/></dir><file name="Generateimagecache.php" hash="05a3585804163326b33d3a46ab7717b5"/><file name="Next.php" hash="92a25b140bc4d0f3b0c7b497fdf0ca6d"/><file name="Timestamp.php" hash="b12e57c577b7c86b346e0221256de97c"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="38cddf31605b88ea36cc83fa0d3e1f5f"/><file name="Feed.php" hash="07044195f931f3c59895b3b9b4059607"/><file name="runfeed.php" hash="aa1d25bd6e86ba401a03b0b54885be7e"/></dir><dir name="Model"><file name="Cron.php" hash="ca8d435d3c2f99b09758cb7644a5d141"/><file name="Email.php" hash="f671df12afac28ae10713cd1972bef2c"/><file name="Feed.php" hash="4da148d858cb296920d079765f2481ba"/><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="624b4a3ed9baa851174a8708cb15305b"/></dir><dir name="etc"><file name="adminhtml.xml" hash="96daebeddbd749dfe0341818fe2eeabb"/><file name="config.xml" hash="4596283312f96e6e1728eb7a50643762"/><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="datafeed"><dir name="clearts"><file name="js.phtml" hash="e277cac474bb3e0d84b47c82c76448ca"/></dir><dir name="generate"><file name="js.phtml" hash="bb03ad1f14206b2e8e5ee228ac0cb6bc"/></dir><dir name="generateimagecache"><file name="js.phtml" hash="aba0594893460ae5763ae243866e7e65"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Hawksearch_Datafeed.xml" hash="06b94625c6b60d1269fe61c4127d2146"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.1.0</min><max>8.1.0</max></php></required></dependencies>
18
  </package>