Version Notes
Initial stable release for Magento Connect. Covers integration with Cart Defender Service.
Download this release
Release Info
| Developer | Radoslaw Gliniecki |
| Extension | cartdefender_actions |
| Version | 1.1.0 |
| Comparing to | |
| See all releases | |
Version 1.1.0
- app/code/community/CartDefender/Actions/Block/Script.php +101 -0
- app/code/community/CartDefender/Actions/Helper/Data.php +114 -0
- app/code/community/CartDefender/Actions/Model/Observer.php +472 -0
- app/code/community/CartDefender/Actions/controllers/CartDefenderSenderController.php +82 -0
- app/code/community/CartDefender/Actions/etc/config.xml +319 -0
- app/code/community/CartDefender/Actions/etc/system.xml +94 -0
- app/design/frontend/base/default/layout/actions.xml +19 -0
- app/design/frontend/base/default/template/actions/script.phtml +23 -0
- app/etc/modules/CartDefender_Actions.xml +19 -0
- package.xml +18 -0
app/code/community/CartDefender/Actions/Block/Script.php
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
/**
|
| 4 |
+
* Cart Defender Actions plugin for Magento
|
| 5 |
+
*
|
| 6 |
+
* @category design_default
|
| 7 |
+
* @package CartDefender_Actions
|
| 8 |
+
* @author Heptium Ltd. (http://www.cartdefender.com/)
|
| 9 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 10 |
+
* @license Open Software License
|
| 11 |
+
*/
|
| 12 |
+
class CartDefender_Actions_Block_Script extends Mage_Core_Block_Template {
|
| 13 |
+
|
| 14 |
+
public function _construct() {
|
| 15 |
+
parent::_construct();
|
| 16 |
+
Mage::helper('actions')->log("Script Block constructing");
|
| 17 |
+
$api = Mage::helper('actions')->getApi();
|
| 18 |
+
if (Mage::helper('actions')->enabled() == true && !empty($api)) {
|
| 19 |
+
$this->setTemplate('actions/script.phtml');
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
/**
|
| 24 |
+
* Helper method to get configuration data
|
| 25 |
+
*/
|
| 26 |
+
public function getSetting($key) {
|
| 27 |
+
$data = Mage::helper('actions')->getSettings();
|
| 28 |
+
return isset($data[$key]) ? $data[$key] : null;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
/**
|
| 32 |
+
* Helper method to get CartDefender JavaScript URL
|
| 33 |
+
*/
|
| 34 |
+
public function getJavaScriptUrl() {
|
| 35 |
+
return $this->getHost() . CartDefender_Actions_Helper_Data::CD_SCRIPT_PATH;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
private function getHost() {
|
| 39 |
+
return $this->getSetting('test')
|
| 40 |
+
? $this->getSetting('test_server_url_start')
|
| 41 |
+
: CartDefender_Actions_Helper_Data::CD_HOST;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
private function getCurrentQuoteData() {
|
| 45 |
+
$quote = Mage::getSingleton('checkout/session')->getQuote();
|
| 46 |
+
// get array of all items which can be displayed directly
|
| 47 |
+
$itemsVisible = $quote->getAllVisibleItems();
|
| 48 |
+
$cart_items = array();
|
| 49 |
+
foreach ($itemsVisible as $item) {
|
| 50 |
+
$item_data = $item->getData();
|
| 51 |
+
$cart_items[] = $item_data;
|
| 52 |
+
}
|
| 53 |
+
//load data into array
|
| 54 |
+
$quoteData = $quote->getData();
|
| 55 |
+
$quoteData['itemsVisible'] = $cart_items;
|
| 56 |
+
return $quoteData;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
public function getVariables() {
|
| 60 |
+
// "static" to compute only once and return cached value later.
|
| 61 |
+
static $cdsvar_data;
|
| 62 |
+
|
| 63 |
+
if (empty($cdsvar_data)) {
|
| 64 |
+
$store = Mage::app()->getStore();
|
| 65 |
+
$storeGroup = $store->getGroup();
|
| 66 |
+
$storeId = $store->getId();
|
| 67 |
+
$website = Mage::app()->getWebsite(); // Gets the current website details
|
| 68 |
+
if (empty(CartDefender_Actions_Model_Observer::$correlation_id)) {
|
| 69 |
+
Mage::helper('actions')->log("Script Block Setting correlation because it's empty");
|
| 70 |
+
CartDefender_Actions_Model_Observer::setCorrelationId();
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
$cdsvar_data = array(
|
| 74 |
+
'website_url' => Mage::getStoreConfig('web/unsecure/base_url', 0),
|
| 75 |
+
'app_software_name' => 'Magento ' . Mage::getEdition(),
|
| 76 |
+
'app_software_version' => Mage::getVersion(),
|
| 77 |
+
'website_code' => $website->getCode(),
|
| 78 |
+
'website_name' => $website->getName(),
|
| 79 |
+
'website_default_shop_id' => $website->getDefaultGroupId(),
|
| 80 |
+
'website_is_default' => $website->getIsDefault(),
|
| 81 |
+
'shop_id' => $storeGroup->getGroupId(),
|
| 82 |
+
'shop_name' => $storeGroup->getName(),
|
| 83 |
+
'shop_root_category_id' => $storeGroup->getRootCategoryId(),
|
| 84 |
+
'shop_default_shop_view_id' => $storeGroup->getDefaultStoreId(),
|
| 85 |
+
'shop_view_id' => $store->getStoreId(),
|
| 86 |
+
'shop_view_code' => $store->getCode(),
|
| 87 |
+
'shop_view_name' => $store->getName(),
|
| 88 |
+
'shop_view_locale_code' => Mage::getStoreConfig('general/locale/code', $storeId),
|
| 89 |
+
'shop_view_url' => $store->getBaseUrl(),
|
| 90 |
+
'shop_view_home_url' => $store->getHomeUrl(),
|
| 91 |
+
'checkout_link' => Mage::helper('checkout/url')->getCheckoutUrl(),
|
| 92 |
+
'multishipping_checkout_link' => Mage::helper('checkout/url')->getMSCheckoutUrl(),
|
| 93 |
+
'request_route_name' => Mage::app()->getRequest()->getRouteName(),
|
| 94 |
+
'page_identifier' => Mage::getSingleton('cms/page')->getIdentifier()
|
| 95 |
+
);
|
| 96 |
+
}
|
| 97 |
+
$serialized_data = Zend_Json::encode($cdsvar_data, true);
|
| 98 |
+
return $serialized_data;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
}
|
app/code/community/CartDefender/Actions/Helper/Data.php
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
/**
|
| 4 |
+
* Cart Defender Actions plugin for Magento
|
| 5 |
+
*
|
| 6 |
+
* @category design_default
|
| 7 |
+
* @package CartDefender_Actions
|
| 8 |
+
* @author Heptium Ltd.
|
| 9 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 10 |
+
* @license Open Software License
|
| 11 |
+
*/
|
| 12 |
+
class CartDefender_Actions_Helper_Data extends Mage_Core_Helper_Abstract {
|
| 13 |
+
|
| 14 |
+
/**
|
| 15 |
+
* Value for missing or unknown data.
|
| 16 |
+
*/
|
| 17 |
+
const MISSING_VALUE = '(?MV?)';
|
| 18 |
+
|
| 19 |
+
/**
|
| 20 |
+
* The protocol & hostname of the Cart Defender server.
|
| 21 |
+
*/
|
| 22 |
+
const CD_HOST = 'https://app.cartdefender.com';
|
| 23 |
+
|
| 24 |
+
/*
|
| 25 |
+
* The CD_PLUGIN_BIZ_API_ constants refer to the CartDefender biz event API for shop platform
|
| 26 |
+
* plugins (e.g. WooCommerce, Magento, etc), as opposed to JSON REST API for custom shops.
|
| 27 |
+
*/
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
+
* The start of the path part of the biz API URL.
|
| 31 |
+
*/
|
| 32 |
+
const CD_PLUGIN_BIZ_API_PATH_START = '/plugin';
|
| 33 |
+
|
| 34 |
+
/**
|
| 35 |
+
* The version of the biz API.
|
| 36 |
+
*/
|
| 37 |
+
const CD_PLUGIN_BIZ_API_VERSION = 'v1-beta';
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* The end of the path part of the biz API URL.
|
| 41 |
+
*/
|
| 42 |
+
const CD_PLUGIN_BIZ_API_PATH_END = '/magentoBizEvent';
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* The path part of the URL to Cart Defender JavaScript file.
|
| 46 |
+
*/
|
| 47 |
+
const CD_SCRIPT_PATH = '/script/cartdefender.js';
|
| 48 |
+
|
| 49 |
+
public function getApi() {
|
| 50 |
+
return Mage::getStoreConfig('actions/settings/api');
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
public function enabled() {
|
| 54 |
+
return (bool) Mage::getStoreConfig('actions/settings/enabled');
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
private function test() {
|
| 58 |
+
return (bool) Mage::getStoreConfig('actions/settings/test');
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
private function getTestServerUrlStart() {
|
| 62 |
+
return Mage::getStoreConfig('actions/settings/test_server_url_start');
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
private function getUseRawTestUrlForBizApi() {
|
| 66 |
+
return (bool) Mage::getStoreConfig('actions/settings/use_raw_test_url_for_biz_api');
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
private function getCurrentSendKeyValue() {
|
| 70 |
+
return Mage::getStoreConfig('actions/settings/send_key');
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
/**
|
| 74 |
+
* Obtains an internal shared key to access the controller which is sending the business events.
|
| 75 |
+
*/
|
| 76 |
+
public function getSendKey() {
|
| 77 |
+
$send_key = $this->getCurrentSendKeyValue();
|
| 78 |
+
if (empty($send_key)) {
|
| 79 |
+
$send_key = hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
| 80 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
| 81 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
| 82 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)));
|
| 83 |
+
Mage::getConfig()->saveConfig('actions/settings/send_key', $send_key, 'default', 0);
|
| 84 |
+
}
|
| 85 |
+
return $send_key;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
public function getSettings() {
|
| 89 |
+
// "static" to compute only once and return cached value later.
|
| 90 |
+
static $data;
|
| 91 |
+
if (empty($data)) {
|
| 92 |
+
// Settings
|
| 93 |
+
$data = array(
|
| 94 |
+
'api' => $this->getApi(),
|
| 95 |
+
'enabled' => $this->enabled(),
|
| 96 |
+
'test' => $this->test(),
|
| 97 |
+
'test_server_url_start' => $this->getTestServerUrlStart(),
|
| 98 |
+
'use_raw_test_url_for_biz_api' => $this->getUseRawTestUrlForBizApi(),
|
| 99 |
+
'send_key' => $this->getSendKey()
|
| 100 |
+
);
|
| 101 |
+
}
|
| 102 |
+
return isset($data) ? $data : null;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
/**
|
| 106 |
+
* Logs a message if running in test mode.
|
| 107 |
+
*/
|
| 108 |
+
public function log($message) {
|
| 109 |
+
$settings = $this->getSettings();
|
| 110 |
+
if (!empty($settings) && $settings['test']) {
|
| 111 |
+
Mage::log($message);
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
}
|
app/code/community/CartDefender/Actions/Model/Observer.php
ADDED
|
@@ -0,0 +1,472 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
/**
|
| 4 |
+
* Cart Defender business event capture for Magento
|
| 5 |
+
*
|
| 6 |
+
* @package CartDefender_Actions
|
| 7 |
+
* @author Heptium Ltd.
|
| 8 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 9 |
+
* @license Open Software License
|
| 10 |
+
*/
|
| 11 |
+
class CartDefender_Actions_Model_Observer extends Varien_Event_Observer {
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Value for missing or unknown data taken from Helper class
|
| 15 |
+
*/
|
| 16 |
+
private $MISSING_VALUE = CartDefender_Actions_Helper_Data::MISSING_VALUE;
|
| 17 |
+
|
| 18 |
+
/**
|
| 19 |
+
* Whether the event "controller_front_send_response_before" was fired.
|
| 20 |
+
*
|
| 21 |
+
* @since 0.0.1
|
| 22 |
+
* @access private
|
| 23 |
+
*/
|
| 24 |
+
private static $response_started;
|
| 25 |
+
|
| 26 |
+
/**
|
| 27 |
+
* The CartDefender id used for correlating web and business events.
|
| 28 |
+
*
|
| 29 |
+
* @since 0.0.1
|
| 30 |
+
* @access public
|
| 31 |
+
* @var string $correlation_id The CartDefender correlation id.
|
| 32 |
+
*/
|
| 33 |
+
public static $correlation_id;
|
| 34 |
+
|
| 35 |
+
/**
|
| 36 |
+
* The name of the cookie storing the CartDefender correlation id.
|
| 37 |
+
*
|
| 38 |
+
* @since 0.0.1
|
| 39 |
+
*/
|
| 40 |
+
const CD_CORRELATION_COOKIE_NAME = "__cd_732655870348746856";
|
| 41 |
+
|
| 42 |
+
/**
|
| 43 |
+
* Number of seconds in 5 minutes.
|
| 44 |
+
*
|
| 45 |
+
* @since 0.0.1
|
| 46 |
+
*/
|
| 47 |
+
const FIVE_MINUTES = 300;
|
| 48 |
+
|
| 49 |
+
/**
|
| 50 |
+
* Threshold since last event was sent in seconds.
|
| 51 |
+
*
|
| 52 |
+
* @since 0.0.1
|
| 53 |
+
*/
|
| 54 |
+
const EVENT_TIME_THRESHOLD = 7200;
|
| 55 |
+
|
| 56 |
+
/**
|
| 57 |
+
* Key used to store on the session the time required to send the last biz event to our servers.
|
| 58 |
+
*/
|
| 59 |
+
const BIZ_EVENT_LATENCY_KEY = 'biz_event_latency_key';
|
| 60 |
+
|
| 61 |
+
/**
|
| 62 |
+
* Key used to store on the session the errors occurring during the sending of biz events.
|
| 63 |
+
*/
|
| 64 |
+
const BIZ_EVENT_SENDING_ERRORS_KEY = 'biz_event_sending_errors_key';
|
| 65 |
+
|
| 66 |
+
/**
|
| 67 |
+
* Key used to store on the session the latest sequence number of a biz event.
|
| 68 |
+
*/
|
| 69 |
+
const BIZ_EVENT_SEQUENCE_NO_KEY = 'biz_event_sequence_no_key';
|
| 70 |
+
const START_OF_SESSION = 'start_of_session';
|
| 71 |
+
|
| 72 |
+
private function connectionConfigSetup() {
|
| 73 |
+
// "static" to compute only once and return cached value later.
|
| 74 |
+
static $async_sender_api;
|
| 75 |
+
static $connection_scheme;
|
| 76 |
+
if (empty($async_sender_api) or empty($connection_scheme)) {
|
| 77 |
+
$async_sender_api = parse_url(Mage::getUrl('cartdefender/CartDefenderSender/sendEvents',
|
| 78 |
+
array('_secure' => true)));
|
| 79 |
+
if (empty($async_sender_api['port'])) {
|
| 80 |
+
if ($async_sender_api['scheme'] == 'http') {
|
| 81 |
+
$async_sender_api['port'] = 80;
|
| 82 |
+
}
|
| 83 |
+
if ($async_sender_api['scheme'] == 'https') {
|
| 84 |
+
$async_sender_api['port'] = 443;
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
$connection_scheme = ($async_sender_api['scheme'] == 'http') ? 'tcp://' : 'ssl://';
|
| 88 |
+
}
|
| 89 |
+
return array(
|
| 90 |
+
'api' => $async_sender_api,
|
| 91 |
+
'scheme' => $connection_scheme);
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
private function captureSessionData(&$sessionId, &$visitorData, &$customer_id, &$customerData,
|
| 95 |
+
&$is_logged_in) {
|
| 96 |
+
if (!session_id()) {
|
| 97 |
+
$sessionId = $this->MISSING_VALUE;
|
| 98 |
+
$visitorData = $this->MISSING_VALUE;
|
| 99 |
+
$customer_id = $this->MISSING_VALUE;
|
| 100 |
+
$customerData = $this->MISSING_VALUE;
|
| 101 |
+
$is_logged_in = $this->MISSING_VALUE;
|
| 102 |
+
$sessionCore = $this->MISSING_VALUE;
|
| 103 |
+
$sessionCustomer = $this->MISSING_VALUE;
|
| 104 |
+
} else {
|
| 105 |
+
$sessionCore = Mage::getSingleton("core/session");
|
| 106 |
+
$sessionCustomer = Mage::getSingleton('customer/session');
|
| 107 |
+
$visitorData = $sessionCore['visitor_data'];
|
| 108 |
+
$sessionId = $sessionCore->getEncryptedSessionId();
|
| 109 |
+
|
| 110 |
+
if (!isset($sessionCustomer)) {
|
| 111 |
+
$sessionCustomer = $this->MISSING_VALUE;
|
| 112 |
+
$customerData = $this->MISSING_VALUE;
|
| 113 |
+
$customer_id = $this->MISSING_VALUE;
|
| 114 |
+
$is_logged_in = false;
|
| 115 |
+
} else {
|
| 116 |
+
$customer_id = $sessionCustomer->getCustomerId();
|
| 117 |
+
$customerData = $sessionCustomer->getCustomer()->getData();
|
| 118 |
+
/* Remove personal details */
|
| 119 |
+
unset($customerData['email']);
|
| 120 |
+
unset($customerData['prefix']);
|
| 121 |
+
unset($customerData['firstname']);
|
| 122 |
+
unset($customerData['middlename']);
|
| 123 |
+
unset($customerData['lastname']);
|
| 124 |
+
unset($customerData['suffix']);
|
| 125 |
+
unset($customerData['taxvat']);
|
| 126 |
+
unset($customerData['password_hash']);
|
| 127 |
+
|
| 128 |
+
$is_logged_in = $sessionCustomer->isLoggedIn();
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
private function obtainCartFromQuote($quote) {
|
| 134 |
+
$cart_items = array();
|
| 135 |
+
$cart_data = array();
|
| 136 |
+
if (isset($quote)) {
|
| 137 |
+
$cart_data = $quote->getData();
|
| 138 |
+
/* Remove personal details */
|
| 139 |
+
unset($cart_data['customer_tax_class_id']);
|
| 140 |
+
unset($cart_data['customer_email']);
|
| 141 |
+
unset($cart_data['customer_prefix']);
|
| 142 |
+
unset($cart_data['customer_firstname']);
|
| 143 |
+
unset($cart_data['customer_middlename']);
|
| 144 |
+
unset($cart_data['customer_lastname']);
|
| 145 |
+
unset($cart_data['customer_suffix']);
|
| 146 |
+
unset($cart_data['customer_note']);
|
| 147 |
+
unset($cart_data['customer_taxvat']);
|
| 148 |
+
unset($cart_data['password_hash']);
|
| 149 |
+
|
| 150 |
+
$items = $quote->getAllVisibleItems();
|
| 151 |
+
foreach ($items as $item) {
|
| 152 |
+
$item_data = $item->getData();
|
| 153 |
+
$cart_items[] = $item_data;
|
| 154 |
+
}
|
| 155 |
+
} else {
|
| 156 |
+
$quote = $this->MISSING_VALUE;
|
| 157 |
+
$cart_data[] = $this->MISSING_VALUE;
|
| 158 |
+
$cart_items[] = $this->MISSING_VALUE;
|
| 159 |
+
}
|
| 160 |
+
return array('cart_data' => $cart_data, 'cart_items' => $cart_items);
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
private function captureCartData() {
|
| 164 |
+
return session_id()
|
| 165 |
+
? $this->obtainCartFromQuote(Mage::getSingleton('checkout/session')->getQuote())
|
| 166 |
+
: array($this->MISSING_VALUE);
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
private function captureOrderData($observer_data) {
|
| 170 |
+
$full_orders = array($this->MISSING_VALUE);
|
| 171 |
+
if (session_id() && isset($observer_data['order_ids'])) {
|
| 172 |
+
$orderIds = $observer_data['order_ids'];
|
| 173 |
+
foreach ($orderIds as $_orderId) {
|
| 174 |
+
$one_full_order = array(); //init empty var
|
| 175 |
+
$one_full_order['order_id'] = $_orderId;
|
| 176 |
+
|
| 177 |
+
$order = Mage::getModel('sales/order')->load($_orderId);
|
| 178 |
+
$order_data = $order->getData();
|
| 179 |
+
|
| 180 |
+
/* Remove personal details */
|
| 181 |
+
unset($order_data['customer_tax_class_id']);
|
| 182 |
+
unset($order_data['customer_email']);
|
| 183 |
+
unset($order_data['customer_prefix']);
|
| 184 |
+
unset($order_data['customer_firstname']);
|
| 185 |
+
unset($order_data['customer_middlename']);
|
| 186 |
+
unset($order_data['customer_lastname']);
|
| 187 |
+
unset($order_data['customer_suffix']);
|
| 188 |
+
unset($order_data['customer_note']);
|
| 189 |
+
unset($order_data['customer_taxvat']);
|
| 190 |
+
unset($order_data['password_hash']);
|
| 191 |
+
|
| 192 |
+
$one_full_order['order_data'] = $order_data;
|
| 193 |
+
|
| 194 |
+
$quote_id = $order_data['quote_id'];
|
| 195 |
+
$cart_from_order = Mage::getModel('sales/quote')->load($quote_id);
|
| 196 |
+
$one_full_order['cart'] = $this->obtainCartFromQuote($cart_from_order);
|
| 197 |
+
|
| 198 |
+
$items = $order->getAllVisibleItems();
|
| 199 |
+
$order_items = array(); //init empty var
|
| 200 |
+
foreach ($items as $item) {
|
| 201 |
+
$item_data = $item->getData();
|
| 202 |
+
$order_items[] = $item_data;
|
| 203 |
+
}
|
| 204 |
+
$one_full_order['order_items'] = $order_items;
|
| 205 |
+
|
| 206 |
+
$full_orders[] = $one_full_order;
|
| 207 |
+
}
|
| 208 |
+
}
|
| 209 |
+
return $full_orders;
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
private function prepareBizEventData($event_name, $observer_data, $async_sender_api, $event_no) {
|
| 213 |
+
$website = Mage::app()->getWebsite(); // Gets the current website details
|
| 214 |
+
$store = Mage::app()->getStore(); // Gets the current store's details
|
| 215 |
+
$storeId = $store->getStoreId();
|
| 216 |
+
$storeGroup = $store->getGroup();
|
| 217 |
+
|
| 218 |
+
$app_software_name = "Magento " . Mage::getEdition();
|
| 219 |
+
$app_software_version = Mage::getVersion();
|
| 220 |
+
$this->captureSessionData($sessionId, $visitorData, $customer_id, $customerData, $is_logged_in);
|
| 221 |
+
$cart = $this->captureCartData();
|
| 222 |
+
$full_orders = $this->captureOrderData($observer_data);
|
| 223 |
+
$event = array(
|
| 224 |
+
'api' => Mage::helper('actions')->getApi(),
|
| 225 |
+
'appSoftwareName' => $app_software_name,
|
| 226 |
+
'appSoftwareVersion' => $app_software_version,
|
| 227 |
+
'eventType' => $event_name,
|
| 228 |
+
'timestamp' => time(),
|
| 229 |
+
'shop_current_currency' => $store->getCurrentCurrencyCode(),
|
| 230 |
+
'cart' => $cart,
|
| 231 |
+
'orders' => $full_orders,
|
| 232 |
+
'eventNumber' => $event_no,
|
| 233 |
+
'website_id' => $website->getId(),
|
| 234 |
+
'website_code' => $website->getCode(),
|
| 235 |
+
'website_name' => $website->getName(),
|
| 236 |
+
'websiteData' => $website->getData(),
|
| 237 |
+
'shopData' => $storeGroup->getData(),
|
| 238 |
+
'shopViewData' => $store->getData(),
|
| 239 |
+
'shopViewLocaleCode' => Mage::getStoreConfig('general/locale/code', $storeId),
|
| 240 |
+
'shopViewBaseUrl' => $store->getBaseUrl(),
|
| 241 |
+
'shopViewHomeUrl' => $store->getHomeUrl(),
|
| 242 |
+
'checkout_link' => Mage::helper('checkout/url')->getCheckoutUrl(),
|
| 243 |
+
'multishipping_checkout_link' => Mage::helper('checkout/url')->getMSCheckoutUrl(),
|
| 244 |
+
'correlationId' => self::$correlation_id,
|
| 245 |
+
'visitorId' => isset($visitorData['visitor_id'])
|
| 246 |
+
? $visitorData['visitor_id'] : $this->MISSING_VALUE,
|
| 247 |
+
'visitorData' => $visitorData,
|
| 248 |
+
'isLoggedIn' => $is_logged_in,
|
| 249 |
+
'customerId' => $customer_id,
|
| 250 |
+
'customerData' => $customerData,
|
| 251 |
+
'previousBizEventLatency' => $this->MISSING_VALUE
|
| 252 |
+
);
|
| 253 |
+
return Zend_Json::encode($event, true);
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
private function shouldSendSessionState() {
|
| 257 |
+
if (session_id()) {
|
| 258 |
+
$now = time();
|
| 259 |
+
$last_event_at = Mage::getSingleton('core/session')->getLastEventTime();
|
| 260 |
+
$result = empty($last_event_at) || (($now - $last_event_at) > self::EVENT_TIME_THRESHOLD);
|
| 261 |
+
|
| 262 |
+
Mage::helper('actions')->log(" -->Last event time: "
|
| 263 |
+
. (empty($last_event_at) ? "never" : $last_event_at));
|
| 264 |
+
Mage::helper('actions')->log("Should send session state result: " . $result
|
| 265 |
+
. " Time difference: " . (empty($last_event_at) ? "N/A" : ($now - $last_event_at)));
|
| 266 |
+
return $result;
|
| 267 |
+
}
|
| 268 |
+
return false;
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
/**
|
| 272 |
+
* Main event observer function. See ../etc/config.xml for observer configuration.
|
| 273 |
+
*
|
| 274 |
+
* List of events: http://www.nicksays.co.uk/magento-events-cheat-sheet-1-7/
|
| 275 |
+
*/
|
| 276 |
+
public function captureEvent($observer) {
|
| 277 |
+
if (self::isCartDefenderEnabledAndIsRequestNonLocalAndIsRequestNonAdmin()) {
|
| 278 |
+
if (!isset(self::$response_started) && !isset(self::$correlation_id)) {
|
| 279 |
+
Mage::helper('actions')->log("Capture Event - Response not started yet, and no correlation "
|
| 280 |
+
. "ID so we set correlation ID - Event: " . $observer->getEvent()->getName());
|
| 281 |
+
self::setCorrelationId();
|
| 282 |
+
}
|
| 283 |
+
if (isset(self::$correlation_id)) { //do not send an event without correlation id
|
| 284 |
+
if ($this->shouldSendSessionState()) {
|
| 285 |
+
$this->sendStartOfSessionState();
|
| 286 |
+
Mage::helper('actions')->log("Capture Event - Sent Session State Update. Event: "
|
| 287 |
+
. $observer->getEvent()->getName());
|
| 288 |
+
}
|
| 289 |
+
$event_name = $observer->getEvent()->getName();
|
| 290 |
+
$observer_data = $observer->getData();
|
| 291 |
+
$this->sendEvent($event_name, $observer_data);
|
| 292 |
+
Mage::helper('actions')->log("Capture Event - Success - got the event name: ". $event_name);
|
| 293 |
+
}
|
| 294 |
+
}
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
/**
|
| 298 |
+
* Event observer function which should be called whenever a customer logs in.
|
| 299 |
+
* See ../etc/config.xml for observer configuration.
|
| 300 |
+
*/
|
| 301 |
+
public function handleCustomerLogin($observer) {
|
| 302 |
+
// Note that the customer_login event carries the pre-login cart.
|
| 303 |
+
$this->captureEvent($observer);
|
| 304 |
+
// This isn't cleared on login automatically even though Magento "frontend" cookie changes.
|
| 305 |
+
Mage::getSingleton('core/session')->unsLastEventTime();
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
+
/**
|
| 309 |
+
* Event observer function which should be called whenever a customer logs out.
|
| 310 |
+
* See ../etc/config.xml for observer configuration.
|
| 311 |
+
*/
|
| 312 |
+
public function handleCustomerLogout($observer) {
|
| 313 |
+
$this->captureEvent($observer);
|
| 314 |
+
// This isn't cleared on logout automatically even though Magento "frontend" cookie changes.
|
| 315 |
+
Mage::getSingleton('core/session')->unsLastEventTime();
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
/**
|
| 319 |
+
* Creates the text of a POST request (headers & contents) carrying a biz event, targeting
|
| 320 |
+
* the biz event sender script on localhost.
|
| 321 |
+
*
|
| 322 |
+
* @param string $biz_event_sender_url_path the URL path of the event sender
|
| 323 |
+
* @param string $biz_event_sender_host the hostname of localhost. We can't use "localhost" or
|
| 324 |
+
* "127.0.0.1" in case request is sent via SSL and the certificate doesn't include these two.
|
| 325 |
+
* @param int $event_no sequence number of the event, used for logging purposes.
|
| 326 |
+
* @param string $data_string the biz event data to send.
|
| 327 |
+
* @param bool $is_local_request is the request local for the same server ("PHP to PHP")
|
| 328 |
+
* @param string $correlation_id the correlation identifier for events
|
| 329 |
+
*/
|
| 330 |
+
private function createBizEventRequest($biz_event_sender_url_path, $biz_event_sender_host,
|
| 331 |
+
$event_no, $data_string, $is_local_request, $correlation_id) {
|
| 332 |
+
$settings = Mage::helper('actions')->getSettings();
|
| 333 |
+
$query_params = array(
|
| 334 |
+
'event_no' => $event_no,
|
| 335 |
+
'data' => $data_string,
|
| 336 |
+
'is_local_request' => $is_local_request,
|
| 337 |
+
'correlation_id' => $correlation_id,
|
| 338 |
+
'send_key' => $settings['send_key']
|
| 339 |
+
);
|
| 340 |
+
$postdata = http_build_query($query_params);
|
| 341 |
+
|
| 342 |
+
$req = "";
|
| 343 |
+
$req.= "POST " . $biz_event_sender_url_path . " HTTP/1.1\r\n";
|
| 344 |
+
$req.= "Host: " . $biz_event_sender_host . "\r\n";
|
| 345 |
+
$req.= "Content-type: application/x-www-form-urlencoded\r\n";
|
| 346 |
+
$req.= "Content-length: " . strlen($postdata) . "\r\n";
|
| 347 |
+
$req.= "\r\n";
|
| 348 |
+
$req.= $postdata;
|
| 349 |
+
$req.= "\r\n\r\n";
|
| 350 |
+
|
| 351 |
+
return $req;
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
/**
|
| 355 |
+
* If not set yet, sets a 64-bit Cart Defender correlation id for the current session.
|
| 356 |
+
* The value is either taken from a cookie, or generated and put on a new cookie,
|
| 357 |
+
* which we then try to store.
|
| 358 |
+
*
|
| 359 |
+
* NB: Cookie must be set before any content is sent to user's browser during a
|
| 360 |
+
* given PHP request processing. Call this using a very early hook.
|
| 361 |
+
* Mage::getModel(‘core/cookie’)->set($name, $value, $period);
|
| 362 |
+
*/
|
| 363 |
+
public static function setCorrelationId() {
|
| 364 |
+
if (self::isCartDefenderEnabledAndIsRequestNonLocalAndIsRequestNonAdmin()) {
|
| 365 |
+
if (!isset(self::$correlation_id)) {
|
| 366 |
+
Mage::helper('actions')->log("--->>>> Correlation variable not set, checking cookie.");
|
| 367 |
+
$cookie = Mage::getSingleton('core/cookie');
|
| 368 |
+
if (method_exists($cookie, 'get')) {
|
| 369 |
+
$correlation_cookie = $cookie->get(self::CD_CORRELATION_COOKIE_NAME);
|
| 370 |
+
if (!empty($correlation_cookie)) {
|
| 371 |
+
self::$correlation_id = $correlation_cookie;
|
| 372 |
+
Mage::helper('actions')->log("--->>>> Taking id from cookie: " . self::$correlation_id);
|
| 373 |
+
} else {
|
| 374 |
+
// Don't use 4 as param b/c hexdec() has a limit of 7fffffff.
|
| 375 |
+
self::$correlation_id = hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
| 376 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
| 377 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(2)));
|
| 378 |
+
/* This sets an HTTP response header. But if client browser has 1-st party cookies
|
| 379 |
+
disabled, the value won't be saved and returned to PHP engine on next call. We'll
|
| 380 |
+
try to regenerate it in the same way, again failing to make it permanent. However,
|
| 381 |
+
the web sensor will detect cookies disabled in JS and not load itself. The
|
| 382 |
+
eventual outcome will be no web events, and biz events with CD correlation ids varying
|
| 383 |
+
with each PHP request. Also, the nulls set corresponding settings to shop defaults. */
|
| 384 |
+
Mage::getSingleton('core/cookie')->set(self::CD_CORRELATION_COOKIE_NAME,
|
| 385 |
+
self::$correlation_id, 0, '/', null /* domain */,
|
| 386 |
+
null /* secure */, false /* HttpOnly */);
|
| 387 |
+
Mage::helper('actions')->log("--->>>> Cookie was empty, now: " . self::$correlation_id);
|
| 388 |
+
}
|
| 389 |
+
} else {
|
| 390 |
+
Mage::helper('actions')->log("--->>>> Could not get the correlation cookie from the "
|
| 391 |
+
. "browser. Server variable is: " . self::$correlation_id);
|
| 392 |
+
}
|
| 393 |
+
}
|
| 394 |
+
}
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
/**
|
| 398 |
+
* Event observer function which should be called whenever PHP is about to start sending a
|
| 399 |
+
* response to the browser. See ../etc/config.xml for observer configuration.
|
| 400 |
+
*/
|
| 401 |
+
public function ensureCookieSetBeforeResponse($observer) {
|
| 402 |
+
if (self::isCartDefenderEnabledAndIsRequestNonLocalAndIsRequestNonAdmin()) {
|
| 403 |
+
if (empty(self::$response_started)) {
|
| 404 |
+
self::$response_started = true;
|
| 405 |
+
self::setCorrelationId();
|
| 406 |
+
if ($this->shouldSendSessionState()) { //check if should send start of session
|
| 407 |
+
$this->sendStartOfSessionState();
|
| 408 |
+
Mage::helper('actions')->log("Ensure cookie set - Sent Session State Update. Event: "
|
| 409 |
+
. $observer->getEvent()->getName());
|
| 410 |
+
}
|
| 411 |
+
Mage::helper('actions')->log("Ensure cookie set - Response has not started yet - Event: "
|
| 412 |
+
. $observer->getEvent()->getName() . " Correlation ID: " . self::$correlation_id);
|
| 413 |
+
} else {
|
| 414 |
+
Mage::helper('actions')->log("Ensure cookie set - Response started, don't set id - Event: "
|
| 415 |
+
. $observer->getEvent()->getName() . " Correlation ID: " . $self::$correlation_id);
|
| 416 |
+
}
|
| 417 |
+
} else {
|
| 418 |
+
Mage::helper('actions')->log("Ensure cookie set - local/admin/disabled, don't set id - Event:"
|
| 419 |
+
. $observer->getEvent()->getName() . " Correlation ID: " . self::$correlation_id
|
| 420 |
+
. " is Admin: " . Mage::app()->getStore()->isAdmin());
|
| 421 |
+
}
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
private function sendStartOfSessionState() {
|
| 425 |
+
Mage::helper('actions')->log("--->>>> Before Start of Session State. " . time());
|
| 426 |
+
if (isset(self::$correlation_id)) { //do not send an event without correlation id
|
| 427 |
+
$event_name = self::START_OF_SESSION;
|
| 428 |
+
$observer_data = array();
|
| 429 |
+
$this->sendEvent($event_name, $observer_data);
|
| 430 |
+
Mage::helper('actions')->log("Send Start of session state - Success");
|
| 431 |
+
}
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
private function sendEvent($event_name, $observer_data) {
|
| 435 |
+
//setting the local request flag, which denotes PHP to PHP call within current server
|
| 436 |
+
$is_local_request = true;
|
| 437 |
+
$connect = $this->connectionConfigSetup();
|
| 438 |
+
$async_sender_api = $connect['api'];
|
| 439 |
+
$connection_scheme = $connect['scheme'];
|
| 440 |
+
$event_no = Mage::getSingleton('core/session')->getEventNo();
|
| 441 |
+
$event_no = empty($event_no) ? 0 : $event_no;
|
| 442 |
+
Mage::getSingleton('core/session')->setEventNo($event_no + 1);
|
| 443 |
+
$data_string =
|
| 444 |
+
$this->prepareBizEventData($event_name, $observer_data, $async_sender_api, $event_no);
|
| 445 |
+
$req = $this->createBizEventRequest($async_sender_api['path'], $async_sender_api['host'],
|
| 446 |
+
$event_no, $data_string, $is_local_request, self::$correlation_id);
|
| 447 |
+
$socket = @fsockopen($connection_scheme . $async_sender_api['host'], $async_sender_api['port'],
|
| 448 |
+
$errno, $errstr, 0.025); //25ms timeout
|
| 449 |
+
$success = @fwrite($socket, $req);
|
| 450 |
+
Mage::getSingleton('core/session')->setLastEventTime(time());
|
| 451 |
+
if ($success) {
|
| 452 |
+
Mage::helper('actions')->log("[Send Event] - Success - sent the full event:" . $data_string);
|
| 453 |
+
} else {
|
| 454 |
+
Mage::helper('actions')->log("[Send Event] - ERROR - number: " . $errno
|
| 455 |
+
. 'Error string: ' . $errstr
|
| 456 |
+
. " the full event:" . $data_string);
|
| 457 |
+
}
|
| 458 |
+
$success = @fclose($socket);
|
| 459 |
+
}
|
| 460 |
+
|
| 461 |
+
/**
|
| 462 |
+
* Checks if this is an external request as opposed to a local server call to avoid an
|
| 463 |
+
* endless loop. Also verify that it's not Admin area of the store and that module is enabled.
|
| 464 |
+
*/
|
| 465 |
+
private static function isCartDefenderEnabledAndIsRequestNonLocalAndIsRequestNonAdmin() {
|
| 466 |
+
$settings = Mage::helper('actions')->getSettings();
|
| 467 |
+
return empty($_POST['is_local_request'])
|
| 468 |
+
&& !Mage::app()->getStore()->isAdmin()
|
| 469 |
+
&& $settings['enabled'];
|
| 470 |
+
}
|
| 471 |
+
|
| 472 |
+
}
|
app/code/community/CartDefender/Actions/controllers/CartDefenderSenderController.php
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
/**
|
| 4 |
+
* A script sending business events asynchronously to Cart Defender servers.
|
| 5 |
+
*
|
| 6 |
+
* The main reason for this script is so that we can launch it not blocking the main
|
| 7 |
+
* PHP process rendering the page for the user. If we blocked, the page rendering or
|
| 8 |
+
* AJAX processing would be slowed down by the time it takes for the round-trips to
|
| 9 |
+
* our servers (at least 3 in case of SSL - about 250 milliseconds for any transatlantic
|
| 10 |
+
* connections).
|
| 11 |
+
*
|
| 12 |
+
* @link http://cartdefender.com
|
| 13 |
+
* @since 0.0.1
|
| 14 |
+
*
|
| 15 |
+
* @package CartDefender_Actions
|
| 16 |
+
* @author Heptium Ltd.
|
| 17 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 18 |
+
* @license Open Software License
|
| 19 |
+
*/
|
| 20 |
+
class CartDefender_Actions_CartDefenderSenderController extends Mage_Core_Controller_Front_Action {
|
| 21 |
+
|
| 22 |
+
public function sendEventsAction() {
|
| 23 |
+
$settings = Mage::helper('actions')->getSettings();
|
| 24 |
+
// works only if flag is set to denote local API call and data exists
|
| 25 |
+
if (!empty($_POST['is_local_request'])
|
| 26 |
+
&& $settings['send_key'] === $_POST['send_key']
|
| 27 |
+
&& !empty($_POST['data'])
|
| 28 |
+
&& $settings['enabled']) {
|
| 29 |
+
$millis_before = round(microtime(true) * 1000);
|
| 30 |
+
|
| 31 |
+
$data = $_POST['data'];
|
| 32 |
+
$options = array(
|
| 33 |
+
'http' => array(
|
| 34 |
+
'header' => "Content-type: application/json\r\n"
|
| 35 |
+
. "Authorization: Basic " . base64_encode($settings['api'] . ":") . "\r\n",
|
| 36 |
+
'method' => 'POST',
|
| 37 |
+
'content' => $data));
|
| 38 |
+
$context = stream_context_create($options);
|
| 39 |
+
$url = $this->getUrl($settings);
|
| 40 |
+
$success = file_get_contents($url, false, $context);
|
| 41 |
+
|
| 42 |
+
// Logging.
|
| 43 |
+
$millis_after = round(microtime(true) * 1000);
|
| 44 |
+
if (!$success) {
|
| 45 |
+
// These will appear in the general server logs.
|
| 46 |
+
Mage::helper('actions')->log('[Cart Defender biz event sender ERROR]'
|
| 47 |
+
. ' Event number: ' . $_POST['event_no']
|
| 48 |
+
. ' Url: ' . $url
|
| 49 |
+
. ' Request time: ' . $millis_before
|
| 50 |
+
. ' Request latency: ' . ($millis_after - $millis_before));
|
| 51 |
+
} else {
|
| 52 |
+
Mage::helper('actions')->log('[Cart Defender biz event sender success]'
|
| 53 |
+
. ' Event number: ' . $_POST['event_no']
|
| 54 |
+
. ' Url: ' . $url
|
| 55 |
+
. ' Request time: ' . $millis_before
|
| 56 |
+
. ' Request latency: ' . ($millis_after - $millis_before)
|
| 57 |
+
. ' Is local equest: ' . $_POST['is_local_request']);
|
| 58 |
+
}
|
| 59 |
+
} else {
|
| 60 |
+
Mage::helper('actions')->log('[Cart Defender biz event sender ERROR] '
|
| 61 |
+
. 'Not a local POST request with an event or disabled');
|
| 62 |
+
}
|
| 63 |
+
Mage::helper('actions')->log('[Cart Defender biz event sender] Work done, time to finish.');
|
| 64 |
+
echo 'Done';
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
/**
|
| 68 |
+
* Returns the URL to which business events should be sent.
|
| 69 |
+
*/
|
| 70 |
+
private function getUrl($settings) {
|
| 71 |
+
$path = CartDefender_Actions_Helper_Data::CD_PLUGIN_BIZ_API_PATH_START
|
| 72 |
+
. '/' . $_POST['correlation_id'] . '/'
|
| 73 |
+
. CartDefender_Actions_Helper_Data::CD_PLUGIN_BIZ_API_VERSION
|
| 74 |
+
. CartDefender_Actions_Helper_Data::CD_PLUGIN_BIZ_API_PATH_END;
|
| 75 |
+
$use_raw_test_url = $settings['use_raw_test_url_for_biz_api'];
|
| 76 |
+
return $settings['test']
|
| 77 |
+
? ($settings['test_server_url_start'] . ($use_raw_test_url ? '' : $path))
|
| 78 |
+
: (CartDefender_Actions_Helper_Data::CD_HOST . $path);
|
| 79 |
+
}
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
?>
|
app/code/community/CartDefender/Actions/etc/config.xml
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0"?>
|
| 2 |
+
<!--
|
| 3 |
+
/**
|
| 4 |
+
* Cart Defender Actions plugin for Magento
|
| 5 |
+
*
|
| 6 |
+
* @package CartDefender_Actions
|
| 7 |
+
* @author Heptium Ltd.
|
| 8 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 9 |
+
* @license Open Software License
|
| 10 |
+
*/
|
| 11 |
+
-->
|
| 12 |
+
<config>
|
| 13 |
+
<modules>
|
| 14 |
+
<CartDefender_Actions>
|
| 15 |
+
<version>1.1.0</version>
|
| 16 |
+
</CartDefender_Actions>
|
| 17 |
+
</modules>
|
| 18 |
+
|
| 19 |
+
<global>
|
| 20 |
+
<blocks>
|
| 21 |
+
<actions>
|
| 22 |
+
<class>CartDefender_Actions_Block</class>
|
| 23 |
+
</actions>
|
| 24 |
+
</blocks>
|
| 25 |
+
<helpers>
|
| 26 |
+
<actions>
|
| 27 |
+
<class>CartDefender_Actions_Helper</class>
|
| 28 |
+
</actions>
|
| 29 |
+
</helpers>
|
| 30 |
+
|
| 31 |
+
<events>
|
| 32 |
+
<controller_front_send_response_before>
|
| 33 |
+
<observers>
|
| 34 |
+
<cartdefender_controller_front_send_response_before>
|
| 35 |
+
<type>singleton</type>
|
| 36 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 37 |
+
<method>ensureCookieSetBeforeResponse</method>
|
| 38 |
+
</cartdefender_controller_front_send_response_before>
|
| 39 |
+
</observers>
|
| 40 |
+
</controller_front_send_response_before>
|
| 41 |
+
<catalog_controller_product_view>
|
| 42 |
+
<observers>
|
| 43 |
+
<cartdefender_catalog_controller_product_view>
|
| 44 |
+
<type>singleton</type>
|
| 45 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 46 |
+
<method>captureEvent</method>
|
| 47 |
+
</cartdefender_catalog_controller_product_view>
|
| 48 |
+
</observers>
|
| 49 |
+
</catalog_controller_product_view>
|
| 50 |
+
<checkout_cart_save_after>
|
| 51 |
+
<observers>
|
| 52 |
+
<cartdefender_checkout_cart_save_after>
|
| 53 |
+
<type>singleton</type>
|
| 54 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 55 |
+
<method>captureEvent</method>
|
| 56 |
+
</cartdefender_checkout_cart_save_after>
|
| 57 |
+
</observers>
|
| 58 |
+
</checkout_cart_save_after>
|
| 59 |
+
<checkout_controller_multishipping_shipping_post>
|
| 60 |
+
<observers>
|
| 61 |
+
<cartdefender_checkout_controller_multishipping_shipping_post>
|
| 62 |
+
<type>singleton</type>
|
| 63 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 64 |
+
<method>captureEvent</method>
|
| 65 |
+
</cartdefender_checkout_controller_multishipping_shipping_post>
|
| 66 |
+
</observers>
|
| 67 |
+
</checkout_controller_multishipping_shipping_post>
|
| 68 |
+
<checkout_controller_onepage_save_shipping_method>
|
| 69 |
+
<observers>
|
| 70 |
+
<cartdefender_checkout_controller_onepage_save_shipping_method>
|
| 71 |
+
<type>singleton</type>
|
| 72 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 73 |
+
<method>captureEvent</method>
|
| 74 |
+
</cartdefender_checkout_controller_onepage_save_shipping_method>
|
| 75 |
+
</observers>
|
| 76 |
+
</checkout_controller_onepage_save_shipping_method>
|
| 77 |
+
<checkout_multishipping_controller_success_action>
|
| 78 |
+
<observers>
|
| 79 |
+
<cartdefender_checkout_multishipping_controller_success_action>
|
| 80 |
+
<type>singleton</type>
|
| 81 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 82 |
+
<method>captureEvent</method>
|
| 83 |
+
</cartdefender_checkout_multishipping_controller_success_action>
|
| 84 |
+
</observers>
|
| 85 |
+
</checkout_multishipping_controller_success_action>
|
| 86 |
+
<checkout_onepage_controller_success_action>
|
| 87 |
+
<observers>
|
| 88 |
+
<cartdefender_checkout_onepage_controller_success_action>
|
| 89 |
+
<type>singleton</type>
|
| 90 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 91 |
+
<method>captureEvent</method>
|
| 92 |
+
</cartdefender_checkout_onepage_controller_success_action>
|
| 93 |
+
</observers>
|
| 94 |
+
</checkout_onepage_controller_success_action>
|
| 95 |
+
<customer_login>
|
| 96 |
+
<observers>
|
| 97 |
+
<cartdefender_customer_login>
|
| 98 |
+
<type>singleton</type>
|
| 99 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 100 |
+
<method>handleCustomerLogin</method>
|
| 101 |
+
</cartdefender_customer_login>
|
| 102 |
+
</observers>
|
| 103 |
+
</customer_login>
|
| 104 |
+
<customer_logout>
|
| 105 |
+
<observers>
|
| 106 |
+
<cartdefender_customer_logout>
|
| 107 |
+
<type>singleton</type>
|
| 108 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 109 |
+
<method>handleCustomerLogout</method>
|
| 110 |
+
</cartdefender_customer_logout>
|
| 111 |
+
</observers>
|
| 112 |
+
</customer_logout>
|
| 113 |
+
<googlecheckout_checkout_before>
|
| 114 |
+
<observers>
|
| 115 |
+
<cartdefender_googlecheckout_checkout_before>
|
| 116 |
+
<type>singleton</type>
|
| 117 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 118 |
+
<method>captureEvent</method>
|
| 119 |
+
</cartdefender_googlecheckout_checkout_before>
|
| 120 |
+
</observers>
|
| 121 |
+
</googlecheckout_checkout_before>
|
| 122 |
+
<googlecheckout_save_order_after>
|
| 123 |
+
<observers>
|
| 124 |
+
<cartdefender_googlecheckout_save_order_after>
|
| 125 |
+
<type>singleton</type>
|
| 126 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 127 |
+
<method>captureEvent</method>
|
| 128 |
+
</cartdefender_googlecheckout_save_order_after>
|
| 129 |
+
</observers>
|
| 130 |
+
</googlecheckout_save_order_after>
|
| 131 |
+
<order_cancel_after>
|
| 132 |
+
<observers>
|
| 133 |
+
<cartdefender_order_cancel_after>
|
| 134 |
+
<type>singleton</type>
|
| 135 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 136 |
+
<method>captureEvent</method>
|
| 137 |
+
</cartdefender_order_cancel_after>
|
| 138 |
+
</observers>
|
| 139 |
+
</order_cancel_after>
|
| 140 |
+
<sales_order_payment_cancel>
|
| 141 |
+
<observers>
|
| 142 |
+
<cartdefender_sales_order_payment_cancel>
|
| 143 |
+
<type>singleton</type>
|
| 144 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 145 |
+
<method>captureEvent</method>
|
| 146 |
+
</cartdefender_sales_order_payment_cancel>
|
| 147 |
+
</observers>
|
| 148 |
+
</sales_order_payment_cancel>
|
| 149 |
+
<sales_order_payment_capture>
|
| 150 |
+
<observers>
|
| 151 |
+
<cartdefender_sales_order_payment_capture>
|
| 152 |
+
<type>singleton</type>
|
| 153 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 154 |
+
<method>captureEvent</method>
|
| 155 |
+
</cartdefender_sales_order_payment_capture>
|
| 156 |
+
</observers>
|
| 157 |
+
</sales_order_payment_capture>
|
| 158 |
+
<sales_order_payment_pay>
|
| 159 |
+
<observers>
|
| 160 |
+
<cartdefender_sales_order_payment_pay>
|
| 161 |
+
<type>singleton</type>
|
| 162 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 163 |
+
<method>captureEvent</method>
|
| 164 |
+
</cartdefender_sales_order_payment_pay>
|
| 165 |
+
</observers>
|
| 166 |
+
</sales_order_payment_pay>
|
| 167 |
+
<sales_order_payment_place_end>
|
| 168 |
+
<observers>
|
| 169 |
+
<cartdefender_sales_order_payment_place_end>
|
| 170 |
+
<type>singleton</type>
|
| 171 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 172 |
+
<method>captureEvent</method>
|
| 173 |
+
</cartdefender_sales_order_payment_place_end>
|
| 174 |
+
</observers>
|
| 175 |
+
</sales_order_payment_place_end>
|
| 176 |
+
<sales_order_payment_place_start>
|
| 177 |
+
<observers>
|
| 178 |
+
<cartdefender_sales_order_payment_place_start>
|
| 179 |
+
<type>singleton</type>
|
| 180 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 181 |
+
<method>captureEvent</method>
|
| 182 |
+
</cartdefender_sales_order_payment_place_start>
|
| 183 |
+
</observers>
|
| 184 |
+
</sales_order_payment_place_start>
|
| 185 |
+
<sales_order_payment_refund>
|
| 186 |
+
<observers>
|
| 187 |
+
<cartdefender_sales_order_payment_refund>
|
| 188 |
+
<type>singleton</type>
|
| 189 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 190 |
+
<method>captureEvent</method>
|
| 191 |
+
</cartdefender_sales_order_payment_refund>
|
| 192 |
+
</observers>
|
| 193 |
+
</sales_order_payment_refund>
|
| 194 |
+
<sales_order_payment_void>
|
| 195 |
+
<observers>
|
| 196 |
+
<cartdefender_sales_order_payment_void>
|
| 197 |
+
<type>singleton</type>
|
| 198 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 199 |
+
<method>captureEvent</method>
|
| 200 |
+
</cartdefender_sales_order_payment_void>
|
| 201 |
+
</observers>
|
| 202 |
+
</sales_order_payment_void>
|
| 203 |
+
<wishlist_add_item>
|
| 204 |
+
<observers>
|
| 205 |
+
<cartdefender_wishlist_add_item>
|
| 206 |
+
<type>singleton</type>
|
| 207 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 208 |
+
<method>captureEvent</method>
|
| 209 |
+
</cartdefender_wishlist_add_item>
|
| 210 |
+
</observers>
|
| 211 |
+
</wishlist_add_item>
|
| 212 |
+
<wishlist_add_product>
|
| 213 |
+
<observers>
|
| 214 |
+
<cartdefender_wishlist_add_product>
|
| 215 |
+
<type>singleton</type>
|
| 216 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 217 |
+
<method>captureEvent</method>
|
| 218 |
+
</cartdefender_wishlist_add_product>
|
| 219 |
+
</observers>
|
| 220 |
+
</wishlist_add_product>
|
| 221 |
+
<wishlist_add_product>
|
| 222 |
+
<observers>
|
| 223 |
+
<cartdefender_wishlist_add_product>
|
| 224 |
+
<type>singleton</type>
|
| 225 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 226 |
+
<method>captureEvent</method>
|
| 227 |
+
</cartdefender_wishlist_add_product>
|
| 228 |
+
</observers>
|
| 229 |
+
</wishlist_add_product>
|
| 230 |
+
<wishlist_product_add_after>
|
| 231 |
+
<observers>
|
| 232 |
+
<cartdefender_wishlist_product_add_after>
|
| 233 |
+
<type>singleton</type>
|
| 234 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 235 |
+
<method>captureEvent</method>
|
| 236 |
+
</cartdefender_wishlist_product_add_after>
|
| 237 |
+
</observers>
|
| 238 |
+
</wishlist_product_add_after>
|
| 239 |
+
<wishlist_share>
|
| 240 |
+
<observers>
|
| 241 |
+
<cartdefender_wishlist_share>
|
| 242 |
+
<type>singleton</type>
|
| 243 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 244 |
+
<method>captureEvent</method>
|
| 245 |
+
</cartdefender_wishlist_share>
|
| 246 |
+
</observers>
|
| 247 |
+
</wishlist_share>
|
| 248 |
+
<wishlist_update_item>
|
| 249 |
+
<observers>
|
| 250 |
+
<cartdefender_wishlist_update_item>
|
| 251 |
+
<type>singleton</type>
|
| 252 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 253 |
+
<method>captureEvent</method>
|
| 254 |
+
</cartdefender_wishlist_update_item>
|
| 255 |
+
</observers>
|
| 256 |
+
</wishlist_update_item>
|
| 257 |
+
<controller_action_predispatch_checkout_onepage_index>
|
| 258 |
+
<observers>
|
| 259 |
+
<cartdefender_controller_action_predispatch_checkout_onepage_index>
|
| 260 |
+
<type>singleton</type>
|
| 261 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 262 |
+
<method>captureEvent</method>
|
| 263 |
+
</cartdefender_controller_action_predispatch_checkout_onepage_index>
|
| 264 |
+
</observers>
|
| 265 |
+
</controller_action_predispatch_checkout_onepage_index>
|
| 266 |
+
<controller_action_predispatch_checkout_multishipping_index>
|
| 267 |
+
<observers>
|
| 268 |
+
<cartdefender_controller_action_predispatch_checkout_multishipping_index>
|
| 269 |
+
<type>singleton</type>
|
| 270 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
| 271 |
+
<method>captureEvent</method>
|
| 272 |
+
</cartdefender_controller_action_predispatch_checkout_multishipping_index>
|
| 273 |
+
</observers>
|
| 274 |
+
</controller_action_predispatch_checkout_multishipping_index>
|
| 275 |
+
|
| 276 |
+
</events>
|
| 277 |
+
</global>
|
| 278 |
+
|
| 279 |
+
<frontend>
|
| 280 |
+
<layout>
|
| 281 |
+
<updates>
|
| 282 |
+
<actions>
|
| 283 |
+
<file>actions.xml</file>
|
| 284 |
+
</actions>
|
| 285 |
+
</updates>
|
| 286 |
+
</layout>
|
| 287 |
+
<routers>
|
| 288 |
+
<actions>
|
| 289 |
+
<use>standard</use>
|
| 290 |
+
<args>
|
| 291 |
+
<module>CartDefender_Actions</module>
|
| 292 |
+
<frontName>cartdefender</frontName>
|
| 293 |
+
</args>
|
| 294 |
+
</actions>
|
| 295 |
+
</routers>
|
| 296 |
+
</frontend>
|
| 297 |
+
|
| 298 |
+
<adminhtml>
|
| 299 |
+
<acl>
|
| 300 |
+
<resources>
|
| 301 |
+
<admin>
|
| 302 |
+
<children>
|
| 303 |
+
<system>
|
| 304 |
+
<children>
|
| 305 |
+
<config>
|
| 306 |
+
<children>
|
| 307 |
+
<actions translate="title" module="actions">
|
| 308 |
+
<title>Actions</title>
|
| 309 |
+
</actions>
|
| 310 |
+
</children>
|
| 311 |
+
</config>
|
| 312 |
+
</children>
|
| 313 |
+
</system>
|
| 314 |
+
</children>
|
| 315 |
+
</admin>
|
| 316 |
+
</resources>
|
| 317 |
+
</acl>
|
| 318 |
+
</adminhtml>
|
| 319 |
+
</config>
|
app/code/community/CartDefender/Actions/etc/system.xml
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0"?>
|
| 2 |
+
<!--
|
| 3 |
+
/**
|
| 4 |
+
* Cart Defender Actions plugin for Magento
|
| 5 |
+
*
|
| 6 |
+
* @package CartDefender_Actions
|
| 7 |
+
* @author Heptium Ltd.
|
| 8 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 9 |
+
* @license Open Software License
|
| 10 |
+
*/
|
| 11 |
+
-->
|
| 12 |
+
<config>
|
| 13 |
+
<sections>
|
| 14 |
+
<actions translate="label" module="actions">
|
| 15 |
+
<label>Cart Defender Popups</label>
|
| 16 |
+
<tab>sales</tab>
|
| 17 |
+
<frontend_type>text</frontend_type>
|
| 18 |
+
<sort_order>1</sort_order>
|
| 19 |
+
<show_in_default>1</show_in_default>
|
| 20 |
+
<show_in_website>1</show_in_website>
|
| 21 |
+
<show_in_store>1</show_in_store>
|
| 22 |
+
<groups>
|
| 23 |
+
<settings translate="label">
|
| 24 |
+
<label>Settings</label>
|
| 25 |
+
<frontend_type>text</frontend_type>
|
| 26 |
+
<sort_order>1</sort_order>
|
| 27 |
+
<show_in_default>1</show_in_default>
|
| 28 |
+
<show_in_website>1</show_in_website>
|
| 29 |
+
<show_in_store>1</show_in_store>
|
| 30 |
+
<fields>
|
| 31 |
+
<enabled translate="label">
|
| 32 |
+
<label>Enabled</label>
|
| 33 |
+
<frontend_type>select</frontend_type>
|
| 34 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 35 |
+
<sort_order>1</sort_order>
|
| 36 |
+
<show_in_default>1</show_in_default>
|
| 37 |
+
<show_in_website>1</show_in_website>
|
| 38 |
+
<show_in_store>1</show_in_store>
|
| 39 |
+
</enabled>
|
| 40 |
+
<api translate="label">
|
| 41 |
+
<label>API key</label>
|
| 42 |
+
<frontend_type>text</frontend_type>
|
| 43 |
+
<sort_order>2</sort_order>
|
| 44 |
+
<show_in_default>1</show_in_default>
|
| 45 |
+
<show_in_website>1</show_in_website>
|
| 46 |
+
<show_in_store>1</show_in_store>
|
| 47 |
+
</api>
|
| 48 |
+
<send_key translate="label">
|
| 49 |
+
<label>Generated internal request key</label>
|
| 50 |
+
<frontend_type>text</frontend_type>
|
| 51 |
+
<sort_order>3</sort_order>
|
| 52 |
+
<show_in_default>1</show_in_default>
|
| 53 |
+
<show_in_website>0</show_in_website>
|
| 54 |
+
<show_in_store>0</show_in_store>
|
| 55 |
+
</send_key>
|
| 56 |
+
<test translate="label">
|
| 57 |
+
<label>Test mode</label>
|
| 58 |
+
<frontend_type>select</frontend_type>
|
| 59 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 60 |
+
<sort_order>4</sort_order>
|
| 61 |
+
<show_in_default>1</show_in_default>
|
| 62 |
+
<show_in_website>1</show_in_website>
|
| 63 |
+
<show_in_store>1</show_in_store>
|
| 64 |
+
</test>
|
| 65 |
+
<!-- Don't use a trailing slash in test server URL.-->
|
| 66 |
+
<test_server_url_start>
|
| 67 |
+
<label>Test server URL protocol, domain, and path prefix (if any)</label>
|
| 68 |
+
<frontend_type>text</frontend_type>
|
| 69 |
+
<sort_order>5</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 |
+
<depends><test>1</test></depends>
|
| 74 |
+
</test_server_url_start>
|
| 75 |
+
<!-- This setting controls if the "Test server URL" value is used exactly
|
| 76 |
+
as provided for sending biz events - i.e. without appending things
|
| 77 |
+
like "/plugin/<correlation id>/v1-beta/bizEvent". This is useful for
|
| 78 |
+
inspecting biz event JSONs with something like RequestBin. -->
|
| 79 |
+
<use_raw_test_url_for_biz_api>
|
| 80 |
+
<label>Use unadorned test server URL for JSON API</label>
|
| 81 |
+
<frontend_type>select</frontend_type>
|
| 82 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 83 |
+
<sort_order>6</sort_order>
|
| 84 |
+
<show_in_default>1</show_in_default>
|
| 85 |
+
<show_in_website>1</show_in_website>
|
| 86 |
+
<show_in_store>1</show_in_store>
|
| 87 |
+
<depends><test>1</test></depends>
|
| 88 |
+
</use_raw_test_url_for_biz_api>
|
| 89 |
+
</fields>
|
| 90 |
+
</settings>
|
| 91 |
+
</groups>
|
| 92 |
+
</actions>
|
| 93 |
+
</sections>
|
| 94 |
+
</config>
|
app/design/frontend/base/default/layout/actions.xml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0"?>
|
| 2 |
+
<!--
|
| 3 |
+
/**
|
| 4 |
+
* Cart Defender Actions plugin for Magento
|
| 5 |
+
*
|
| 6 |
+
* @category design_default
|
| 7 |
+
* @package CartDefender_Actions
|
| 8 |
+
* @author Heptium Ltd.
|
| 9 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 10 |
+
* @license Open Software License
|
| 11 |
+
*/
|
| 12 |
+
-->
|
| 13 |
+
<layout>
|
| 14 |
+
<default>
|
| 15 |
+
<reference name="before_body_end">
|
| 16 |
+
<block type="actions/script" name="actions" as="actions" template="actions/script.phtml"/>
|
| 17 |
+
</reference>
|
| 18 |
+
</default>
|
| 19 |
+
</layout>
|
app/design/frontend/base/default/template/actions/script.phtml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Actions plugin for Magento
|
| 4 |
+
*
|
| 5 |
+
* @package CartDefender_Actions
|
| 6 |
+
* @author Heptium Ltd.
|
| 7 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 8 |
+
* @license Open Software License
|
| 9 |
+
*/
|
| 10 |
+
?>
|
| 11 |
+
|
| 12 |
+
<?php if ($this->getSetting('enabled')) { ?>
|
| 13 |
+
<?php if ($this->getSetting('test')) { ?>
|
| 14 |
+
<p> Cart Defender Actions module is running in TEST MODE. </p>
|
| 15 |
+
<?php } ?>
|
| 16 |
+
<script type='text/javascript'>
|
| 17 |
+
/* <![CDATA[ */
|
| 18 |
+
var cdsvar = <?php echo $this->getVariables(); ?>;
|
| 19 |
+
/* ]]> */
|
| 20 |
+
</script>
|
| 21 |
+
<script type="text/javascript" src=<?php echo $this->getJavaScriptUrl(); ?> >
|
| 22 |
+
</script>
|
| 23 |
+
<?php } ?>
|
app/etc/modules/CartDefender_Actions.xml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0"?>
|
| 2 |
+
<!--
|
| 3 |
+
/**
|
| 4 |
+
* Cart Defender Actions plugin for Magento
|
| 5 |
+
*
|
| 6 |
+
* @package CartDefender_Actions
|
| 7 |
+
* @author Heptium Ltd.
|
| 8 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
| 9 |
+
* @license Open Software License
|
| 10 |
+
*/
|
| 11 |
+
-->
|
| 12 |
+
<config>
|
| 13 |
+
<modules>
|
| 14 |
+
<CartDefender_Actions>
|
| 15 |
+
<active>true</active>
|
| 16 |
+
<codePool>community</codePool>
|
| 17 |
+
</CartDefender_Actions>
|
| 18 |
+
</modules>
|
| 19 |
+
</config>
|
package.xml
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0"?>
|
| 2 |
+
<package>
|
| 3 |
+
<name>cartdefender_actions</name>
|
| 4 |
+
<version>1.1.0</version>
|
| 5 |
+
<stability>stable</stability>
|
| 6 |
+
<license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
|
| 7 |
+
<channel>community</channel>
|
| 8 |
+
<extends/>
|
| 9 |
+
<summary>Increase sales with smart targeted popups and offers delivered to your visitors in real time.</summary>
|
| 10 |
+
<description>You can instantly use messages and offers which convert your visitors into customers. You focus on your business needs without A/B tests, as Cart Defender learns which popups covert the best and adjusts itself automatically.</description>
|
| 11 |
+
<notes>Initial stable release for Magento Connect. Covers integration with Cart Defender Service.</notes>
|
| 12 |
+
<authors><author><name>Radoslaw Gliniecki</name><user>Cart_Defender</user><email>radek@cartdefender.com</email></author><author><name>Jan Zankowski</name><user>janzankowski</user><email>jan@cartdefender.com</email></author><author><name>Przemyslaw Gliniecki</name><user>psgliniecki</user><email>psg@cartdefender.com</email></author></authors>
|
| 13 |
+
<date>2016-06-30</date>
|
| 14 |
+
<time>19:13:42</time>
|
| 15 |
+
<contents><target name="magecommunity"><dir name="CartDefender"><dir name="Actions"><dir name="Block"><file name="Script.php" hash="6879aeda8fa9d464124915992a761d00"/></dir><dir name="Helper"><file name="Data.php" hash="3b85a232191fa48f1487687c95c371fc"/></dir><dir name="Model"><file name="Observer.php" hash="545653986fc2fe4a4007011ec1429cf9"/></dir><dir name="controllers"><file name="CartDefenderSenderController.php" hash="aef1db479967b4cc35623dc34e3979b7"/></dir><dir name="etc"><file name="config.xml" hash="220f0ff171665eb589b24b389fd2787a"/><file name="system.xml" hash="7c2c60a71221a23990e37bb94041a50f"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="CartDefender_Actions.xml" hash="e0458c6a3a4e1ae4210d523e8fcdd6fb"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="actions"><file name="script.phtml" hash="c25ad0d5fcdec392e8a69dc489667a91"/></dir></dir><dir name="layout"><file name="actions.xml" hash="ec83d87d66ef40a87b00bd0851be610f"/></dir></dir></dir></dir></target></contents>
|
| 16 |
+
<compatible/>
|
| 17 |
+
<dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.7.0.2</min><max>1.9.2.4</max></package><extension><name>openssl</name><min>0.9.6</min><max>1.0.1</max></extension></required></dependencies>
|
| 18 |
+
</package>
|
