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
- app/code/community/Hawksearch/Datafeed/Block/System/Config/Form.php +20 -0
- app/code/community/Hawksearch/Datafeed/Block/System/Config/Form/Field/Version.php +24 -0
- app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generate.php +75 -0
- app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generate/Js.php +33 -0
- app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generateimagecache.php +75 -0
- app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Generateimagecache/Js.php +33 -0
- app/code/community/Hawksearch/Datafeed/Block/System/Config/Frontend/Feed/Next.php +45 -0
- app/code/community/Hawksearch/Datafeed/Helper/Data.php +225 -0
- app/code/community/Hawksearch/Datafeed/Helper/Feed.php +219 -0
- app/code/community/Hawksearch/Datafeed/Model/Cron.php +41 -0
- app/code/community/Hawksearch/Datafeed/Model/Email.php +55 -0
- app/code/community/Hawksearch/Datafeed/Model/Feed.php +928 -0
- app/code/community/Hawksearch/Datafeed/Model/System/Config/Backend/Cron.php +77 -0
- app/code/community/Hawksearch/Datafeed/controllers/SearchController.php +178 -0
- app/code/community/Hawksearch/Datafeed/etc/adminhtml.xml +32 -0
- app/code/community/Hawksearch/Datafeed/etc/config.xml +101 -0
- app/code/community/Hawksearch/Datafeed/etc/system.xml +235 -0
- app/code/community/Hawksearch/Datafeed/sql/hawksearch_datafeed_setup/install-1.0.0.0.php +19 -0
- app/design/adminhtml/default/default/template/hawksearch/search/sysconfig/generate/js.phtml +50 -0
- app/design/adminhtml/default/default/template/hawksearch/search/sysconfig/generateimagecache/js.phtml +50 -0
- app/etc/modules/Hawksearch_Datafeed.xml +9 -0
- 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
|
| 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>
|
