Version Notes
No-op refactors and minor bugfixes.
Download this release
Release Info
Developer | Radoslaw Gliniecki |
Extension | cartdefender_actions |
Version | 1.1.3 |
Comparing to | |
See all releases |
Code changes from version 1.1.1 to 1.1.3
- app/code/community/CartDefender/Actions/Block/Script.php +101 -82
- app/code/community/CartDefender/Actions/Helper/Data.php +219 -101
- app/code/community/CartDefender/Actions/Helper/Logger.php +35 -0
- app/code/community/CartDefender/Actions/Model/AsyncLocalSender.php +156 -0
- app/code/community/CartDefender/Actions/Model/CorrelationIdManager.php +163 -0
- app/code/community/CartDefender/Actions/Model/EventAsyncLocalSender.php +51 -0
- app/code/community/CartDefender/Actions/Model/EventBuilder.php +214 -0
- app/code/community/CartDefender/Actions/Model/Observer.php +126 -469
- app/code/community/CartDefender/Actions/controllers/CartDefenderSenderController.php +114 -69
- app/code/community/CartDefender/Actions/etc/config.xml +308 -305
- app/code/community/CartDefender/Actions/etc/system.xml +8 -8
- app/design/frontend/base/default/layout/actions.xml +2 -2
- app/design/frontend/base/default/template/actions/script.phtml +12 -12
- app/etc/modules/CartDefender_Actions.xml +2 -2
- package.xml +6 -8
app/code/community/CartDefender/Actions/Block/Script.php
CHANGED
@@ -1,7 +1,9 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
/**
|
4 |
-
* Cart Defender
|
5 |
*
|
6 |
* @category design_default
|
7 |
* @package CartDefender_Actions
|
@@ -9,93 +11,110 @@
|
|
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 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
$this->setTemplate('actions/script.phtml');
|
20 |
-
}
|
21 |
-
}
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
? $
|
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 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
use CartDefender_Actions_Helper_Data as CDData;
|
4 |
+
|
5 |
/**
|
6 |
+
* Cart Defender main Block.
|
7 |
*
|
8 |
* @category design_default
|
9 |
* @package CartDefender_Actions
|
11 |
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
12 |
* @license Open Software License
|
13 |
*/
|
14 |
+
class CartDefender_Actions_Block_Script extends Mage_Core_Block_Template
|
15 |
+
{
|
16 |
|
17 |
+
/**
|
18 |
+
* @var CartDefender_Actions_Helper_Logger $logger Logger of Cart Defender
|
19 |
+
* specific messages.
|
20 |
+
*/
|
21 |
+
private $logger;
|
|
|
|
|
|
|
22 |
|
23 |
+
/** Initializes this class, particularly the logger and its Template. */
|
24 |
+
public function _construct()
|
25 |
+
{
|
26 |
+
parent::_construct();
|
27 |
+
$this->logger = Mage::helper('actions/logger');
|
28 |
+
$this->logger->log('Script->_construct');
|
29 |
+
$api = Mage::helper('actions')->getApi();
|
30 |
+
if (Mage::helper('actions')->enabled() == true && !empty($api)) {
|
31 |
+
$this->setTemplate('actions/script.phtml');
|
32 |
+
}
|
33 |
+
}
|
34 |
|
35 |
+
/**
|
36 |
+
* Returns a named Cart Defender configuration setting value.
|
37 |
+
*
|
38 |
+
* @param string $key the name of the setting.
|
39 |
+
* @return string|null the value of the setting or null if key is invalid.
|
40 |
+
*/
|
41 |
+
public function getSetting($key)
|
42 |
+
{
|
43 |
+
$data = Mage::helper('actions')->getSettings();
|
44 |
+
return isset($data[$key]) ? $data[$key] : null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
+
/**
|
48 |
+
* Returns the CartDefender JavaScript URL.
|
49 |
+
*
|
50 |
+
* @return string the CartDefender JavaScript URL.
|
51 |
+
*/
|
52 |
+
public function getJavaScriptUrl()
|
53 |
+
{
|
54 |
+
return $this->getHost() . CDData::CD_SCRIPT_PATH;
|
55 |
+
}
|
56 |
|
57 |
+
/**
|
58 |
+
* Returns the hostname of Cart Defender server.
|
59 |
+
*
|
60 |
+
* @return string the hostname of Cart Defender server.
|
61 |
+
*/
|
62 |
+
private function getHost()
|
63 |
+
{
|
64 |
+
return $this->getSetting('test')
|
65 |
+
? $this->getSetting('test_server_url_start') : CDData::CD_HOST;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
}
|
|
|
|
|
|
|
67 |
|
68 |
+
/**
|
69 |
+
* Returns a JSON-encoded list of values to be (invisibly) rendered
|
70 |
+
* on the page, for use of Cart Defender JavaScript.
|
71 |
+
*
|
72 |
+
* @return string JSON-encoded list of values of interest to our JS.
|
73 |
+
*/
|
74 |
+
public function getVariables()
|
75 |
+
{
|
76 |
+
// "static" to compute only once and return cached value later.
|
77 |
+
static $cdsvarData = null;
|
78 |
+
if ($cdsvarData === null) {
|
79 |
+
$store = Mage::app()->getStore();
|
80 |
+
$storeGroup = $store->getGroup();
|
81 |
+
$storeId = $store->getId();
|
82 |
+
$website = Mage::app()->getWebsite();
|
83 |
+
Mage::getSingleton('actions/correlationIdManager')
|
84 |
+
->ensureCorrelationIdSet();
|
85 |
+
|
86 |
+
$cdsvarData = array(
|
87 |
+
'website_url' =>
|
88 |
+
Mage::getStoreConfig('web/unsecure/base_url', 0),
|
89 |
+
'app_software_name' => 'Magento ' . Mage::getEdition(),
|
90 |
+
'app_software_version' => Mage::getVersion(),
|
91 |
+
'website_code' => $website->getCode(),
|
92 |
+
'website_name' => $website->getName(),
|
93 |
+
'website_default_shop_id' => $website->getDefaultGroupId(),
|
94 |
+
'website_is_default' => $website->getIsDefault(),
|
95 |
+
'shop_id' => $storeGroup->getGroupId(),
|
96 |
+
'shop_name' => $storeGroup->getName(),
|
97 |
+
'shop_root_category_id' => $storeGroup->getRootCategoryId(),
|
98 |
+
'shop_default_shop_view_id' =>
|
99 |
+
$storeGroup->getDefaultStoreId(),
|
100 |
+
'shop_view_id' => $store->getStoreId(),
|
101 |
+
'shop_view_code' => $store->getCode(),
|
102 |
+
'shop_view_name' => $store->getName(),
|
103 |
+
'shop_view_locale_code' =>
|
104 |
+
Mage::getStoreConfig('general/locale/code', $storeId),
|
105 |
+
'shop_view_url' => $store->getBaseUrl(),
|
106 |
+
'shop_view_home_url' => $store->getHomeUrl(),
|
107 |
+
'checkout_link' =>
|
108 |
+
Mage::helper('checkout/url')->getCheckoutUrl(),
|
109 |
+
'multishipping_checkout_link' =>
|
110 |
+
Mage::helper('checkout/url')->getMSCheckoutUrl(),
|
111 |
+
'request_route_name' =>
|
112 |
+
Mage::app()->getRequest()->getRouteName(),
|
113 |
+
'page_identifier' =>
|
114 |
+
Mage::getSingleton('cms/page')->getIdentifier()
|
115 |
+
);
|
116 |
+
}
|
117 |
+
$serializedData = Zend_Json::encode($cdsvarData, true);
|
118 |
+
return $serializedData;
|
119 |
+
}
|
120 |
}
|
app/code/community/CartDefender/Actions/Helper/Data.php
CHANGED
@@ -1,114 +1,232 @@
|
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
-
* Cart Defender
|
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 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
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 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
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 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
}
|
113 |
-
}
|
114 |
}
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
+
* Cart Defender extension helper, with miscellaneous utility functions.
|
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_Helper_Data extends Mage_Core_Helper_Abstract
|
12 |
+
{
|
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
|
26 |
+
* API for shop platform plugins (e.g. WooCommerce, Magento, etc),
|
27 |
+
* as opposed to JSON REST API for custom shops.
|
28 |
+
*/
|
29 |
+
|
30 |
+
/**
|
31 |
+
* The start of the path part of the biz API URL.
|
32 |
+
*/
|
33 |
+
const CD_PLUGIN_BIZ_API_PATH_START = '/plugin';
|
34 |
+
|
35 |
+
/**
|
36 |
+
* The version of the biz API.
|
37 |
+
*/
|
38 |
+
const CD_PLUGIN_BIZ_API_VERSION = 'v1-beta';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* The end of the path part of the biz API URL.
|
42 |
+
*/
|
43 |
+
const CD_PLUGIN_BIZ_API_PATH_END = '/magentoBizEvent';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* The path part of the URL to Cart Defender JavaScript file.
|
47 |
+
*/
|
48 |
+
const CD_SCRIPT_PATH = '/script/cartdefender.js';
|
49 |
+
|
50 |
+
/**
|
51 |
+
* The name of the start of session biz event.
|
52 |
+
*/
|
53 |
+
const START_OF_SESSION = 'start_of_session';
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Returns the API setting.
|
57 |
+
*
|
58 |
+
* @return string the API setting.
|
59 |
+
*/
|
60 |
+
public function getApi()
|
61 |
+
{
|
62 |
+
return Mage::getStoreConfig('actions/settings/api');
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Returns whether the Cart Defender extension is enabled.
|
67 |
+
*
|
68 |
+
* @return bool whether the Cart Defender extension is enabled.
|
69 |
+
*/
|
70 |
+
public function enabled()
|
71 |
+
{
|
72 |
+
return (bool) Mage::getStoreConfig('actions/settings/enabled');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Returns whether the Cart Defender extension is running in test mode.
|
77 |
+
*
|
78 |
+
* @return bool whether the Cart Defender extension is running in test mode.
|
79 |
+
*/
|
80 |
+
private function test()
|
81 |
+
{
|
82 |
+
return (bool) Mage::getStoreConfig('actions/settings/test');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* For cases when Cart Defender extension is running in test mode, returns
|
87 |
+
* the test server URL protocol, domain, and path prefix (if any).
|
88 |
+
*
|
89 |
+
* @return string the test server URL protocol, domain,
|
90 |
+
* and path prefix (if any).
|
91 |
+
*/
|
92 |
+
private function getTestServerUrlStart()
|
93 |
+
{
|
94 |
+
return Mage::getStoreConfig('actions/settings/test_server_url_start');
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Returns whether the value returned by getTestServerUrlStart() is used
|
99 |
+
* exactly as provided for sending biz events - i.e. without appending
|
100 |
+
* things like "/plugin/[correlation id]/v1-beta/bizEvent". This is useful
|
101 |
+
* for inspecting biz event JSONs with something like RequestBin.
|
102 |
+
*
|
103 |
+
* @return bool whether the value returned by getTestServerUrlStart()
|
104 |
+
* is used exactly as provided for sending biz events.
|
105 |
+
*/
|
106 |
+
private function getUseRawTestUrlForBizApi()
|
107 |
+
{
|
108 |
+
return (bool) Mage::getStoreConfig(
|
109 |
+
'actions/settings/use_raw_test_url_for_biz_api'
|
110 |
+
);
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Obtains an internal shared key to access the synchronous remote
|
115 |
+
* sender PHP script, used e.g. to send business events to Cart Defender
|
116 |
+
* servers.
|
117 |
+
*
|
118 |
+
* @return string shared key needed to access the remote sender script.
|
119 |
+
*/
|
120 |
+
public function getSendKey()
|
121 |
+
{
|
122 |
+
$sendKey = Mage::getStoreConfig('actions/settings/send_key');
|
123 |
+
if (empty($sendKey)) {
|
124 |
+
$sendKey = hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
125 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
126 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
127 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)));
|
128 |
+
Mage::getConfig()->saveConfig(
|
129 |
+
'actions/settings/send_key',
|
130 |
+
$sendKey,
|
131 |
+
'default',
|
132 |
+
0
|
133 |
+
);
|
134 |
+
}
|
135 |
+
return $sendKey;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Returns an array containing Cart Defender configuration settings.
|
140 |
+
*
|
141 |
+
* @return array Cart Defender configuration settings.
|
142 |
+
*/
|
143 |
+
public function getSettings()
|
144 |
+
{
|
145 |
+
// "static" to compute only once and return cached value later.
|
146 |
+
static $data = null;
|
147 |
+
if ($data === null) {
|
148 |
+
// Settings
|
149 |
+
$data = array(
|
150 |
+
'api' => $this->getApi(),
|
151 |
+
'enabled' => $this->enabled(),
|
152 |
+
'test' => $this->test(),
|
153 |
+
'test_server_url_start' => $this->getTestServerUrlStart(),
|
154 |
+
'use_raw_test_url_for_biz_api' =>
|
155 |
+
$this->getUseRawTestUrlForBizApi(),
|
156 |
+
'send_key' => $this->getSendKey()
|
157 |
+
);
|
158 |
+
}
|
159 |
+
return $data;
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Recursively converts to UTF-8 all the strings contained in an array,
|
164 |
+
* an object, or just a single string.
|
165 |
+
*
|
166 |
+
* @param mixed $input the variable whose string entries are
|
167 |
+
* to be converted to UTF-8. If it's not an array, object,
|
168 |
+
* or string, the function exits immediately and does nothing.
|
169 |
+
* @param array $objectsDone helper array storing what has already
|
170 |
+
* been seen in the recursion. Pass in an empty array when
|
171 |
+
* using this function.
|
172 |
+
* @return mixed input, but with string entries converted to UTF-8.
|
173 |
+
*/
|
174 |
+
public function utf8ize($input, &$objectsDone)
|
175 |
+
{
|
176 |
+
if (!in_array($input, $objectsDone, true)) {
|
177 |
+
if (is_array($input)) {
|
178 |
+
$objectsDone[] = $input;
|
179 |
+
foreach ($input as $key => $value) {
|
180 |
+
$input[$key] = $this->utf8ize($value, $objectsDone);
|
181 |
+
}
|
182 |
+
} elseif (is_string($input)) {
|
183 |
+
if (!mb_detect_encoding($input, 'utf-8', true)) {
|
184 |
+
$input = utf8_encode($input);
|
185 |
+
return $input;
|
186 |
+
} else {
|
187 |
+
return $input;
|
188 |
+
}
|
189 |
+
} elseif (is_object($input)) {
|
190 |
+
$objectsDone[] = $input;
|
191 |
+
foreach ($input as $key => $value) {
|
192 |
+
$input->$key = $this->utf8ize($value, $objectsDone);
|
193 |
+
}
|
194 |
+
}
|
195 |
+
return $input;
|
196 |
+
} else {
|
197 |
+
return $input;
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* First call to this function in a given Magento session returns 0.
|
203 |
+
* Each following call returns the previous number incremened by 1.
|
204 |
+
*
|
205 |
+
* @return int the next sequence number in this Magento session.
|
206 |
+
*/
|
207 |
+
public function getSequenceNo()
|
208 |
+
{
|
209 |
+
$session = Mage::getSingleton('core/session');
|
210 |
+
$number = $session->getSequenceNo() ? : 0;
|
211 |
+
$session->setSequenceNo($number + 1);
|
212 |
+
return $number;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Checks that:
|
217 |
+
* (1) Cart Defender extension is enabled,
|
218 |
+
* (2) this is an external request as opposed to a local server call,
|
219 |
+
* to avoid an endless loop,
|
220 |
+
* (3) we're not in the Admin area of the store.
|
221 |
+
*
|
222 |
+
* @return bool whether extension is enabled, and current request is
|
223 |
+
* non local & non admin.
|
224 |
+
*/
|
225 |
+
public function isCDEnabledAndRequestNonLocalNonAdmin()
|
226 |
+
{
|
227 |
+
$settings = $this->getSettings();
|
228 |
+
return !Mage::app()->getRequest()->getPost('is_local_request')
|
229 |
+
&& !Mage::app()->getStore()->isAdmin()
|
230 |
+
&& $settings['enabled'];
|
231 |
}
|
|
|
232 |
}
|
app/code/community/CartDefender/Actions/Helper/Logger.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Cart Defender logging helper. Currently, our logging is enabled if
|
5 |
+
* the extension is running in test mode.
|
6 |
+
*
|
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_Logger extends Mage_Core_Helper_Abstract
|
13 |
+
{
|
14 |
+
|
15 |
+
/** @var mixed $enabled Whether Cart Defender specific logging is enabled. */
|
16 |
+
private $enabled = null;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Logs a message if Cart Defender logging is enabled.
|
20 |
+
*
|
21 |
+
* @param string $function the function name calling the logger.
|
22 |
+
* @param string $message the message to log.
|
23 |
+
* @return void
|
24 |
+
*/
|
25 |
+
public function log($function, $message = '')
|
26 |
+
{
|
27 |
+
if ($this->enabled === null) {
|
28 |
+
$settings = Mage::helper('actions')->getSettings();
|
29 |
+
$this->enabled = ($settings ? $settings['test'] : null);
|
30 |
+
}
|
31 |
+
if ($this->enabled) {
|
32 |
+
Mage::log('[CD] [' . $function . '] ' . $message);
|
33 |
+
}
|
34 |
+
}
|
35 |
+
}
|
app/code/community/CartDefender/Actions/Model/AsyncLocalSender.php
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Asynchronous sender of text data to "synchronous remote sender" (another
|
5 |
+
* Cart Defender PHP script available on localhost), which then sends the
|
6 |
+
* data synchronously to Cart Defender servers.
|
7 |
+
*
|
8 |
+
* @package CartDefender_Actions
|
9 |
+
* @author Heptium Ltd.
|
10 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
11 |
+
* @license Open Software License
|
12 |
+
*/
|
13 |
+
class CartDefender_Actions_Model_AsyncLocalSender extends Varien_Object
|
14 |
+
{
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var CartDefender_Actions_Helper_Logger $logger Logger of Cart Defender
|
18 |
+
* specific messages.
|
19 |
+
*/
|
20 |
+
protected $logger;
|
21 |
+
|
22 |
+
/** Initializes this class, particularly the logger. */
|
23 |
+
public function _construct()
|
24 |
+
{
|
25 |
+
parent::_construct();
|
26 |
+
$this->logger = Mage::helper('actions/logger');
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Asynchronously sends the data passed to "synchronous remote sender"
|
31 |
+
* (another Cart Defender PHP script available on localhost),
|
32 |
+
* which then sends the data synchronously to Cart Defender servers.
|
33 |
+
*
|
34 |
+
* See https://segment.com/blog/how-to-make-async-requests-in-php/
|
35 |
+
* for background on using fsockopen/pfsockopen. See however
|
36 |
+
* http://stackoverflow.com/questions/34769361 for the problem with
|
37 |
+
* pfsockopen. For this reason we use fsockopen, but to circumvent
|
38 |
+
* the fact that the connection opening is blocking, which can be
|
39 |
+
* very costly with remote servers, we connect to the same server
|
40 |
+
* (or group of servers) that the PHP process executing this runs on.
|
41 |
+
* Thus, we get blocking, but very fast connection opening, and then
|
42 |
+
* we send the request asynchronously, without waiting for response -
|
43 |
+
* using fclose() immediately.
|
44 |
+
*
|
45 |
+
* @param string $data the data to send.
|
46 |
+
* @param int $sequenceNo sequence number of the data being sent,
|
47 |
+
* used for logging purposes.
|
48 |
+
* @param string $correlationId the correlation identifier needed
|
49 |
+
* by Cart Defender backend.
|
50 |
+
* @return void
|
51 |
+
*/
|
52 |
+
public function send($data, $sequenceNo, $correlationId)
|
53 |
+
{
|
54 |
+
$remoteSenderConf = $this->getRemoteSenderConf();
|
55 |
+
$request = $this->createRequest(
|
56 |
+
$remoteSenderConf['path'],
|
57 |
+
$remoteSenderConf['host'],
|
58 |
+
$data,
|
59 |
+
$sequenceNo,
|
60 |
+
$correlationId
|
61 |
+
);
|
62 |
+
$socket = fsockopen(
|
63 |
+
$remoteSenderConf['protocol'] . $remoteSenderConf['host'],
|
64 |
+
$remoteSenderConf['port'],
|
65 |
+
$errno,
|
66 |
+
$errstr,
|
67 |
+
0.025 /*timeout*/
|
68 |
+
);
|
69 |
+
$success = fwrite($socket, $request);
|
70 |
+
Mage::getSingleton('core/session')->setLastEventTime(time());
|
71 |
+
$this->logger->log('AsyncLocalSender->send', ($success ? 'Success.'
|
72 |
+
: ('Error (num: [' . $errno . '], msg: [' . $errstr . '])'))
|
73 |
+
. ' Data: [' . $data . ']');
|
74 |
+
fclose($socket);
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Retrieves the configuration of synchronous remote sender,
|
79 |
+
* specifically its URL parts.
|
80 |
+
*
|
81 |
+
* @return array the configuration of synchronous remote sender, with
|
82 |
+
* entries such as 'protocol', 'host', 'port', 'path'.
|
83 |
+
*/
|
84 |
+
private function getRemoteSenderConf()
|
85 |
+
{
|
86 |
+
// "static" to compute only once and return cached value later.
|
87 |
+
static $remoteSenderConf = null;
|
88 |
+
if ($remoteSenderConf === null) {
|
89 |
+
$remoteSenderConf = parse_url(Mage::getUrl(
|
90 |
+
'cartdefender/CartDefenderSender/send',
|
91 |
+
array('_secure' => true)
|
92 |
+
));
|
93 |
+
if (empty($remoteSenderConf['port'])) {
|
94 |
+
$remoteSenderConf['port'] =
|
95 |
+
($remoteSenderConf['scheme'] == 'http') ? 80 : 443;
|
96 |
+
}
|
97 |
+
$remoteSenderConf['protocol'] =
|
98 |
+
($remoteSenderConf['scheme'] == 'http') ? 'tcp://' : 'ssl://';
|
99 |
+
}
|
100 |
+
return $remoteSenderConf;
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Creates the text of a POST request (headers & contents)
|
105 |
+
* carrying some data, targeting the synchronous remote sender
|
106 |
+
* PHP script on localhost.
|
107 |
+
*
|
108 |
+
* Note that we can't use Magento's Varien_Http_Client to construct
|
109 |
+
* the request because it doesn't allow for extracting the request
|
110 |
+
* text without sending it too, synchronously.
|
111 |
+
*
|
112 |
+
* @param string $remoteSenderUrlPath the URL path
|
113 |
+
* of the synchronous remote sender.
|
114 |
+
* @param string $remoteSenderHost the hostname of localhost.
|
115 |
+
* We can't use "localhost" or "127.0.0.1" in case request
|
116 |
+
* is sent via SSL and the certificate doesn't include these two.
|
117 |
+
* @param string $data the data to send.
|
118 |
+
* @param int $sequenceNo sequence number of the data being sent,
|
119 |
+
* used for logging purposes.
|
120 |
+
* @param string $correlationId the correlation identifier
|
121 |
+
* needed by Cart Defender backend.
|
122 |
+
* @return string the text of a POST request, which can be passed to fwrite.
|
123 |
+
*/
|
124 |
+
private function createRequest(
|
125 |
+
$remoteSenderUrlPath,
|
126 |
+
$remoteSenderHost,
|
127 |
+
$data,
|
128 |
+
$sequenceNo,
|
129 |
+
$correlationId
|
130 |
+
) {
|
131 |
+
$settings = Mage::helper('actions')->getSettings();
|
132 |
+
$queryParams = array(
|
133 |
+
'sequence_no' => $sequenceNo,
|
134 |
+
'data' => $data,
|
135 |
+
'is_local_request' => true, // PHP to PHP call within current server
|
136 |
+
'correlation_id' => $correlationId,
|
137 |
+
'send_key' => $settings['send_key']
|
138 |
+
);
|
139 |
+
$postdata = http_build_query($queryParams);
|
140 |
+
|
141 |
+
// Note that Carriage Return (\r) characters below are in accordance
|
142 |
+
// with RFC 2616. See http://stackoverflow.com/questions/5757290 Also,
|
143 |
+
// note that double quotes let \r & \n be interpreted correctly.
|
144 |
+
|
145 |
+
$request = "";
|
146 |
+
$request.= "POST " . $remoteSenderUrlPath . " HTTP/1.1\r\n";
|
147 |
+
$request.= "Host: " . $remoteSenderHost . "\r\n";
|
148 |
+
$request.= "Content-type: application/x-www-form-urlencoded\r\n";
|
149 |
+
$request.= "Content-length: " . strlen($postdata) . "\r\n";
|
150 |
+
$request.= "\r\n";
|
151 |
+
$request.= $postdata;
|
152 |
+
$request.= "\r\n\r\n";
|
153 |
+
|
154 |
+
return $request;
|
155 |
+
}
|
156 |
+
}
|
app/code/community/CartDefender/Actions/Model/CorrelationIdManager.php
ADDED
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use CartDefender_Actions_Helper_Data as CDData;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Cart Defender business logic for managing "correlation id", i.e. a number
|
7 |
+
* used by our backend servers to match events.
|
8 |
+
*
|
9 |
+
* @package CartDefender_Actions
|
10 |
+
* @author Heptium Ltd.
|
11 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
12 |
+
* @license Open Software License
|
13 |
+
*/
|
14 |
+
class CartDefender_Actions_Model_CorrelationIdManager extends Varien_Object
|
15 |
+
{
|
16 |
+
|
17 |
+
/**
|
18 |
+
* The name of the cookie storing the CartDefender correlation id.
|
19 |
+
*/
|
20 |
+
const CD_CORRELATION_COOKIE_NAME = "__cd_732655870348746856";
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var string|null $correlationId The CartDefender id used for correlating
|
24 |
+
* web and business events.
|
25 |
+
*/
|
26 |
+
private $correlationId = null;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var bool $responseStarted Whether the event
|
30 |
+
* "controller_front_send_response_before" was fired.
|
31 |
+
*/
|
32 |
+
private $responseStarted = false;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var CartDefender_Actions_Model_EventAsyncLocalSender $sender
|
36 |
+
* Asynchronous sender of data to "synchronous remote sender"
|
37 |
+
* (another Cart Defender PHP script available on localhost),
|
38 |
+
* which then sends the data synchronously to Cart Defender servers.
|
39 |
+
*/
|
40 |
+
private $sender;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var CartDefender_Actions_Helper_Logger $logger Logger of Cart Defender
|
44 |
+
* specific messages.
|
45 |
+
*/
|
46 |
+
private $logger;
|
47 |
+
|
48 |
+
/** Initializes this class, particularly the utility objects it uses. */
|
49 |
+
public function _construct()
|
50 |
+
{
|
51 |
+
parent::_construct();
|
52 |
+
$this->sender = Mage::getSingleton('actions/eventAsyncLocalSender');
|
53 |
+
$this->logger = Mage::helper('actions/logger');
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Returns the correlation id variable value.
|
58 |
+
*
|
59 |
+
* @return string|null the correlation id variable value.
|
60 |
+
*/
|
61 |
+
public function getCorrelationId()
|
62 |
+
{
|
63 |
+
return $this->correlationId;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Indicates that the response to the browser has begun, therefore not
|
68 |
+
* permitting setting cookies anymore.
|
69 |
+
*
|
70 |
+
* @return void
|
71 |
+
*/
|
72 |
+
public function setResponseStartedTrue()
|
73 |
+
{
|
74 |
+
$this->responseStarted = true;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* If correlation id variable is not yet set for the current request,
|
79 |
+
* tries to set it.
|
80 |
+
*
|
81 |
+
* Setting it means either taking it from existing correlation id cookie,
|
82 |
+
* or if no such cookie exists and we can still create cookies
|
83 |
+
* (before response to the browser starts), trying to do that.
|
84 |
+
*
|
85 |
+
* @return string|null the correlation id (whether setting it was successful
|
86 |
+
* or not).
|
87 |
+
*/
|
88 |
+
public function ensureCorrelationIdSet()
|
89 |
+
{
|
90 |
+
if (!Mage::helper('actions')->isCDEnabledAndRequestNonLocalNonAdmin()) {
|
91 |
+
return $this->correlationId;
|
92 |
+
}
|
93 |
+
|
94 |
+
$this->logger->log(
|
95 |
+
'CorrelationIdManager->ensureCorrelationIdSet',
|
96 |
+
'Response started: ' . ($this->responseStarted ? 'Y' : 'N')
|
97 |
+
);
|
98 |
+
|
99 |
+
if (($this->correlationId !== null) || $this->responseStarted) {
|
100 |
+
return $this->correlationId;
|
101 |
+
}
|
102 |
+
|
103 |
+
$cookie = Mage::getSingleton('core/cookie');
|
104 |
+
$corrCookie = $cookie->get(self::CD_CORRELATION_COOKIE_NAME);
|
105 |
+
$this->correlationId = $corrCookie ?: $this->generateCorrelationId();
|
106 |
+
if (!$corrCookie) {
|
107 |
+
$this->setCorrelationIdCookie();
|
108 |
+
// Notify CD servers of new correlation id.
|
109 |
+
$this->sender->sendEvent(
|
110 |
+
CDData::START_OF_SESSION,
|
111 |
+
$this->correlationId
|
112 |
+
);
|
113 |
+
}
|
114 |
+
|
115 |
+
$this->logger->log(
|
116 |
+
'CorrelationIdManager->ensureCorrelationIdSet',
|
117 |
+
'Correlation id [' . $this->correlationId . '] '
|
118 |
+
. ($corrCookie ? 'taken from' : 'created, set on new') . ' cookie.'
|
119 |
+
);
|
120 |
+
|
121 |
+
return $this->correlationId;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Generates a 64-bit random decimal string.
|
126 |
+
*
|
127 |
+
* @return string 64-bit random decimal string.
|
128 |
+
*/
|
129 |
+
private function generateCorrelationId()
|
130 |
+
{
|
131 |
+
// Don't use 4 as param b/c hexdec() has a limit of 7fffffff.
|
132 |
+
return hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
133 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
134 |
+
. hexdec(bin2hex(openssl_random_pseudo_bytes(2)));
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Sets a correlation id cookie on the HTTP response with the value
|
139 |
+
* of the correlation_id variable.
|
140 |
+
*
|
141 |
+
* @return void
|
142 |
+
*/
|
143 |
+
private function setCorrelationIdCookie()
|
144 |
+
{
|
145 |
+
// This sets an HTTP response header. But if client browser has
|
146 |
+
// 1-st party cookies disabled, the value won't be saved and
|
147 |
+
// returned to PHP engine on next call. We'll try to regenerate it
|
148 |
+
// in the same way, again failing to make it permanent. However,
|
149 |
+
// the web sensor will detect cookies disabled in JS and not load
|
150 |
+
// itself. The eventual outcome will be no web events, and biz
|
151 |
+
// events with CD correlation ids varying with each PHP request.
|
152 |
+
// Also, the nulls set corresponding settings to shop defaults.
|
153 |
+
Mage::getSingleton('core/cookie')->set(
|
154 |
+
self::CD_CORRELATION_COOKIE_NAME,
|
155 |
+
$this->correlationId,
|
156 |
+
0,
|
157 |
+
'/',
|
158 |
+
null /*domain*/,
|
159 |
+
null /*secure*/,
|
160 |
+
false /*HttpOnly*/
|
161 |
+
);
|
162 |
+
}
|
163 |
+
}
|
app/code/community/CartDefender/Actions/Model/EventAsyncLocalSender.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Specialization of AsyncLocalSender, for sending business events.
|
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_EventAsyncLocalSender
|
12 |
+
extends CartDefender_Actions_Model_AsyncLocalSender
|
13 |
+
{
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var CartDefender_Actions_Model_EventBuilder $eventBuilder Builder of
|
17 |
+
* Cart Defender business events to be sent to Cart Defender servers.
|
18 |
+
*/
|
19 |
+
private $eventBuilder;
|
20 |
+
|
21 |
+
/** Initializes this class, particularly the logger. */
|
22 |
+
public function _construct()
|
23 |
+
{
|
24 |
+
parent::_construct();
|
25 |
+
$this->eventBuilder = Mage::getSingleton('actions/eventBuilder');
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Asynchronously sends a biz event to Cart Defender servers.
|
30 |
+
*
|
31 |
+
* @param string $eventName name of the event.
|
32 |
+
* @param string|null $correlationId id used for correlating
|
33 |
+
* web and business events.
|
34 |
+
* @param array $data event data.
|
35 |
+
* @return void
|
36 |
+
*/
|
37 |
+
public function sendEvent($eventName, $correlationId, $data = array())
|
38 |
+
{
|
39 |
+
$sequenceNo = Mage::helper('actions')->getSequenceNo();
|
40 |
+
$event = $this->eventBuilder->buildEvent(
|
41 |
+
$eventName,
|
42 |
+
$data,
|
43 |
+
$sequenceNo
|
44 |
+
);
|
45 |
+
$this->send($event, $sequenceNo, $correlationId);
|
46 |
+
$this->logger->log(
|
47 |
+
'EventAsyncLocalSender->sendEvent',
|
48 |
+
'Sent event: ' . $eventName
|
49 |
+
);
|
50 |
+
}
|
51 |
+
}
|
app/code/community/CartDefender/Actions/Model/EventBuilder.php
ADDED
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use CartDefender_Actions_Helper_Data as CDData;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Cart Defender business event builder.
|
7 |
+
*
|
8 |
+
* @package CartDefender_Actions
|
9 |
+
* @author Heptium Ltd.
|
10 |
+
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
11 |
+
* @license Open Software License
|
12 |
+
*/
|
13 |
+
class CartDefender_Actions_Model_EventBuilder
|
14 |
+
{
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Builds a Cart Defender business event in JSON-encoded form.
|
18 |
+
*
|
19 |
+
* @param string $eventName name of the event to create.
|
20 |
+
* @param array $observerData data coming from the event hook.
|
21 |
+
* @param int $eventNo sequence number used for logging.
|
22 |
+
* @return string the built event in JSON-encoded form.
|
23 |
+
*/
|
24 |
+
public function buildEvent($eventName, $observerData, $eventNo)
|
25 |
+
{
|
26 |
+
$website = Mage::app()->getWebsite();
|
27 |
+
$store = Mage::app()->getStore();
|
28 |
+
|
29 |
+
$sessionData = $this->captureSessionData();
|
30 |
+
$cart = $this->captureCartData();
|
31 |
+
$fullOrders = $this->captureOrderData($observerData);
|
32 |
+
$visitorData = $sessionData['visitor_data'];
|
33 |
+
$event = array(
|
34 |
+
'api' => Mage::helper('actions')->getApi(),
|
35 |
+
'appSoftwareName' => 'Magento ' . Mage::getEdition(),
|
36 |
+
'appSoftwareVersion' => Mage::getVersion(),
|
37 |
+
'eventType' => $eventName,
|
38 |
+
'timestamp' => time(),
|
39 |
+
'shopCurrentCurrency' => $store->getCurrentCurrencyCode(),
|
40 |
+
'cart' => $cart,
|
41 |
+
'orders' => $fullOrders,
|
42 |
+
'eventNumber' => $eventNo,
|
43 |
+
'websiteId' => $website->getId(),
|
44 |
+
'websiteCode' => $website->getCode(),
|
45 |
+
'websiteName' => $website->getName(),
|
46 |
+
'websiteData' => $website->getData(),
|
47 |
+
'shopData' => $store->getGroup()->getData(),
|
48 |
+
'shopViewData' => $store->getData(),
|
49 |
+
'shopViewLocaleCode' => Mage::getStoreConfig(
|
50 |
+
'general/locale/code',
|
51 |
+
$store->getStoreId()
|
52 |
+
),
|
53 |
+
'shopViewBaseUrl' => $store->getBaseUrl(),
|
54 |
+
'shopViewHomeUrl' => $store->getHomeUrl(),
|
55 |
+
'checkoutLink' => Mage::helper('checkout/url')->getCheckoutUrl(),
|
56 |
+
'multishippingCheckoutLink' =>
|
57 |
+
Mage::helper('checkout/url')->getMSCheckoutUrl(),
|
58 |
+
'visitorId' => isset($visitorData['visitor_id'])
|
59 |
+
? $visitorData['visitor_id'] : CDData::MISSING_VALUE,
|
60 |
+
'visitorData' => $visitorData,
|
61 |
+
'isLoggedIn' => $sessionData['is_logged_in'],
|
62 |
+
'customerId' => $sessionData['customer_id'],
|
63 |
+
'customerData' => $sessionData['customer_data'],
|
64 |
+
'previousBizEventLatency' => CDData::MISSING_VALUE
|
65 |
+
);
|
66 |
+
$done = array();
|
67 |
+
$utf8izedEvent = Mage::helper('actions')->utf8ize($event, $done);
|
68 |
+
return Zend_Json::encode($utf8izedEvent, true);
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Returns various bits of data to be sent on each event,
|
73 |
+
* obtained from Magento session.
|
74 |
+
*
|
75 |
+
* @return array various bits of data to be sent on each event,
|
76 |
+
* obtained from Magento session.
|
77 |
+
*/
|
78 |
+
private function captureSessionData()
|
79 |
+
{
|
80 |
+
if (!session_id()) {
|
81 |
+
return array(
|
82 |
+
'visitor_data' => CDData::MISSING_VALUE,
|
83 |
+
'customer_id' => CDData::MISSING_VALUE,
|
84 |
+
'customer_data' => CDData::MISSING_VALUE,
|
85 |
+
'is_logged_in' => CDData::MISSING_VALUE);
|
86 |
+
}
|
87 |
+
|
88 |
+
$sessionCore = Mage::getSingleton('core/session');
|
89 |
+
$sessionCustomer = Mage::getSingleton('customer/session');
|
90 |
+
return array(
|
91 |
+
'visitor_data' => $sessionCore['visitor_data'],
|
92 |
+
'customer_id' => isset($sessionCustomer)
|
93 |
+
? $sessionCustomer->getCustomerId() : CDData::MISSING_VALUE,
|
94 |
+
'customer_data' => isset($sessionCustomer)
|
95 |
+
? $this->removePersonalData(
|
96 |
+
$sessionCustomer->getCustomer()->getData()
|
97 |
+
)
|
98 |
+
: CDData::MISSING_VALUE,
|
99 |
+
'is_logged_in' => isset($sessionCustomer)
|
100 |
+
&& $sessionCustomer->isLoggedIn());
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Returns various bits of data to be sent on each event,
|
105 |
+
* obtained from the Magento cart.
|
106 |
+
*
|
107 |
+
* @return array various bits of data to be sent on each event,
|
108 |
+
* obtained from the Magento cart.
|
109 |
+
*/
|
110 |
+
private function captureCartData()
|
111 |
+
{
|
112 |
+
return session_id()
|
113 |
+
? $this->getCartFromQuote(
|
114 |
+
Mage::getSingleton('checkout/session')->getQuote()
|
115 |
+
)
|
116 |
+
: array(CDData::MISSING_VALUE);
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Returns various bits of data to be sent on each event,
|
121 |
+
* obtained from the Magento cart.
|
122 |
+
*
|
123 |
+
* @param object $quote the Magento cart.
|
124 |
+
* @return array various bits of data to be sent on each event,
|
125 |
+
* obtained from the Magento cart.
|
126 |
+
*/
|
127 |
+
private function getCartFromQuote($quote)
|
128 |
+
{
|
129 |
+
$cartItems = array();
|
130 |
+
$cartData = array();
|
131 |
+
if (isset($quote)) {
|
132 |
+
$cartData = $this->removePersonalData($quote->getData());
|
133 |
+
$items = $quote->getAllVisibleItems();
|
134 |
+
foreach ($items as $item) {
|
135 |
+
$itemData = $item->getData();
|
136 |
+
$cartItems[] = $itemData;
|
137 |
+
}
|
138 |
+
} else {
|
139 |
+
$quote = CDData::MISSING_VALUE;
|
140 |
+
$cartData[] = CDData::MISSING_VALUE;
|
141 |
+
$cartItems[] = CDData::MISSING_VALUE;
|
142 |
+
}
|
143 |
+
return array('cart_data' => $cartData, 'cart_items' => $cartItems);
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Returns various bits of data to be sent on each event,
|
148 |
+
* obtained from the Magento orders.
|
149 |
+
*
|
150 |
+
* @param array $observerData data coming from the event hook.
|
151 |
+
* @return array various bits of data to be sent on each event,
|
152 |
+
* obtained from the Magento orders.
|
153 |
+
*/
|
154 |
+
private function captureOrderData($observerData)
|
155 |
+
{
|
156 |
+
$fullOrders = array(CDData::MISSING_VALUE);
|
157 |
+
if (!session_id() || !isset($observerData['order_ids'])) {
|
158 |
+
return $fullOrders;
|
159 |
+
}
|
160 |
+
|
161 |
+
$orderIds = $observerData['order_ids'];
|
162 |
+
foreach ($orderIds as $orderId) {
|
163 |
+
$oneFullOrder = array();
|
164 |
+
$oneFullOrder['order_id'] = $orderId;
|
165 |
+
|
166 |
+
$order = Mage::getModel('sales/order')->load($orderId);
|
167 |
+
$orderData = $this->removePersonalData($order->getData());
|
168 |
+
$oneFullOrder['order_data'] = $orderData;
|
169 |
+
|
170 |
+
$quoteId = $orderData['quote_id'];
|
171 |
+
$cartFromOrder = Mage::getModel('sales/quote')->load($quoteId);
|
172 |
+
$oneFullOrder['cart'] = $this->getCartFromQuote($cartFromOrder);
|
173 |
+
|
174 |
+
$items = $order->getAllVisibleItems();
|
175 |
+
$orderItems = array();
|
176 |
+
foreach ($items as $item) {
|
177 |
+
$itemData = $item->getData();
|
178 |
+
$orderItems[] = $itemData;
|
179 |
+
}
|
180 |
+
$oneFullOrder['order_items'] = $orderItems;
|
181 |
+
|
182 |
+
$fullOrders[] = $oneFullOrder;
|
183 |
+
}
|
184 |
+
return $fullOrders;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Removes sensitive data from the input array and returns it.
|
189 |
+
*
|
190 |
+
* @param array $input some data.
|
191 |
+
* @return array $input with sensitive data removed.
|
192 |
+
*/
|
193 |
+
private function removePersonalData($input)
|
194 |
+
{
|
195 |
+
unset($input['email']);
|
196 |
+
unset($input['prefix']);
|
197 |
+
unset($input['firstname']);
|
198 |
+
unset($input['middlename']);
|
199 |
+
unset($input['lastname']);
|
200 |
+
unset($input['suffix']);
|
201 |
+
unset($input['taxvat']);
|
202 |
+
unset($input['password_hash']);
|
203 |
+
unset($input['customer_tax_class_id']);
|
204 |
+
unset($input['customer_email']);
|
205 |
+
unset($input['customer_prefix']);
|
206 |
+
unset($input['customer_firstname']);
|
207 |
+
unset($input['customer_middlename']);
|
208 |
+
unset($input['customer_lastname']);
|
209 |
+
unset($input['customer_suffix']);
|
210 |
+
unset($input['customer_note']);
|
211 |
+
unset($input['customer_taxvat']);
|
212 |
+
return $input;
|
213 |
+
}
|
214 |
+
}
|
app/code/community/CartDefender/Actions/Model/Observer.php
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
/**
|
4 |
* Cart Defender business event capture for Magento
|
5 |
*
|
@@ -8,492 +10,147 @@
|
|
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 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
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 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
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 |
-
$
|
205 |
|
206 |
-
$
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
$objects_done[] = $mixed;
|
216 |
-
foreach ($mixed as $key => $value) {
|
217 |
-
$mixed[$key] = $this->utf8ize($value, $objects_done);
|
218 |
}
|
219 |
-
} else if (is_string($mixed)) {
|
220 |
-
if (!mb_detect_encoding($mixed, 'utf-8', true)) {
|
221 |
-
$mixed = utf8_encode($mixed);
|
222 |
-
return $mixed;
|
223 |
-
} else {
|
224 |
-
return $mixed;
|
225 |
-
}
|
226 |
-
} else if (is_object($mixed)) {
|
227 |
-
$objects_done[] = $mixed;
|
228 |
-
foreach ($mixed as $key => $value) {
|
229 |
-
$mixed->$key = $this->utf8ize($value, $objects_done);
|
230 |
-
}
|
231 |
-
}
|
232 |
-
return $mixed;
|
233 |
-
} else {
|
234 |
-
return $mixed;
|
235 |
}
|
236 |
-
}
|
237 |
-
|
238 |
-
private function prepareBizEventData($event_name, $observer_data, $async_sender_api, $event_no) {
|
239 |
-
$website = Mage::app()->getWebsite(); // Gets the current website details
|
240 |
-
$store = Mage::app()->getStore(); // Gets the current store's details
|
241 |
-
$storeId = $store->getStoreId();
|
242 |
-
$storeGroup = $store->getGroup();
|
243 |
-
|
244 |
-
$app_software_name = "Magento " . Mage::getEdition();
|
245 |
-
$app_software_version = Mage::getVersion();
|
246 |
-
$this->captureSessionData($sessionId, $visitorData, $customer_id, $customerData, $is_logged_in);
|
247 |
-
$cart = $this->captureCartData();
|
248 |
-
$full_orders = $this->captureOrderData($observer_data);
|
249 |
-
$event = array(
|
250 |
-
'api' => Mage::helper('actions')->getApi(),
|
251 |
-
'appSoftwareName' => $app_software_name,
|
252 |
-
'appSoftwareVersion' => $app_software_version,
|
253 |
-
'eventType' => $event_name,
|
254 |
-
'timestamp' => time(),
|
255 |
-
'shop_current_currency' => $store->getCurrentCurrencyCode(),
|
256 |
-
'cart' => $cart,
|
257 |
-
'orders' => $full_orders,
|
258 |
-
'eventNumber' => $event_no,
|
259 |
-
'website_id' => $website->getId(),
|
260 |
-
'website_code' => $website->getCode(),
|
261 |
-
'website_name' => $website->getName(),
|
262 |
-
'websiteData' => $website->getData(),
|
263 |
-
'shopData' => $storeGroup->getData(),
|
264 |
-
'shopViewData' => $store->getData(),
|
265 |
-
'shopViewLocaleCode' => Mage::getStoreConfig('general/locale/code', $storeId),
|
266 |
-
'shopViewBaseUrl' => $store->getBaseUrl(),
|
267 |
-
'shopViewHomeUrl' => $store->getHomeUrl(),
|
268 |
-
'checkout_link' => Mage::helper('checkout/url')->getCheckoutUrl(),
|
269 |
-
'multishipping_checkout_link' => Mage::helper('checkout/url')->getMSCheckoutUrl(),
|
270 |
-
'correlationId' => self::$correlation_id,
|
271 |
-
'visitorId' => isset($visitorData['visitor_id'])
|
272 |
-
? $visitorData['visitor_id'] : $this->MISSING_VALUE,
|
273 |
-
'visitorData' => $visitorData,
|
274 |
-
'isLoggedIn' => $is_logged_in,
|
275 |
-
'customerId' => $customer_id,
|
276 |
-
'customerData' => $customerData,
|
277 |
-
'previousBizEventLatency' => $this->MISSING_VALUE
|
278 |
-
);
|
279 |
-
$objects_done = array();
|
280 |
-
return Zend_Json::encode($this->utf8ize($event, $objects_done), true);
|
281 |
-
}
|
282 |
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
return $result;
|
294 |
-
}
|
295 |
-
return false;
|
296 |
-
}
|
297 |
-
|
298 |
-
/**
|
299 |
-
* Main event observer function. See ../etc/config.xml for observer configuration.
|
300 |
-
*
|
301 |
-
* List of events: http://www.nicksays.co.uk/magento-events-cheat-sheet-1-7/
|
302 |
-
*/
|
303 |
-
public function captureEvent($observer) {
|
304 |
-
if (self::isCartDefenderEnabledAndIsRequestNonLocalAndIsRequestNonAdmin()) {
|
305 |
-
if (!isset(self::$response_started) && !isset(self::$correlation_id)) {
|
306 |
-
Mage::helper('actions')->log("Capture Event - Response not started yet, and no correlation "
|
307 |
-
. "ID so we set correlation ID - Event: " . $observer->getEvent()->getName());
|
308 |
-
self::setCorrelationId();
|
309 |
-
}
|
310 |
-
if (isset(self::$correlation_id)) { //do not send an event without correlation id
|
311 |
-
if ($this->shouldSendSessionState()) {
|
312 |
-
$this->sendStartOfSessionState();
|
313 |
-
Mage::helper('actions')->log("Capture Event - Sent Session State Update. Event: "
|
314 |
-
. $observer->getEvent()->getName());
|
315 |
}
|
316 |
-
$
|
317 |
-
$observer_data = $observer->getData();
|
318 |
-
$this->sendEvent($event_name, $observer_data);
|
319 |
-
Mage::helper('actions')->log("Capture Event - Success - got the event name: ". $event_name);
|
320 |
-
}
|
321 |
-
}
|
322 |
-
}
|
323 |
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
$this->captureEvent($observer);
|
331 |
-
// This isn't cleared on login automatically even though Magento "frontend" cookie changes.
|
332 |
-
Mage::getSingleton('core/session')->unsLastEventTime();
|
333 |
-
}
|
334 |
-
|
335 |
-
/**
|
336 |
-
* Event observer function which should be called whenever a customer logs out.
|
337 |
-
* See ../etc/config.xml for observer configuration.
|
338 |
-
*/
|
339 |
-
public function handleCustomerLogout($observer) {
|
340 |
-
$this->captureEvent($observer);
|
341 |
-
// This isn't cleared on logout automatically even though Magento "frontend" cookie changes.
|
342 |
-
Mage::getSingleton('core/session')->unsLastEventTime();
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Creates the text of a POST request (headers & contents) carrying a biz event, targeting
|
347 |
-
* the biz event sender script on localhost.
|
348 |
-
*
|
349 |
-
* @param string $biz_event_sender_url_path the URL path of the event sender
|
350 |
-
* @param string $biz_event_sender_host the hostname of localhost. We can't use "localhost" or
|
351 |
-
* "127.0.0.1" in case request is sent via SSL and the certificate doesn't include these two.
|
352 |
-
* @param int $event_no sequence number of the event, used for logging purposes.
|
353 |
-
* @param string $data_string the biz event data to send.
|
354 |
-
* @param bool $is_local_request is the request local for the same server ("PHP to PHP")
|
355 |
-
* @param string $correlation_id the correlation identifier for events
|
356 |
-
*/
|
357 |
-
private function createBizEventRequest($biz_event_sender_url_path, $biz_event_sender_host,
|
358 |
-
$event_no, $data_string, $is_local_request, $correlation_id) {
|
359 |
-
$settings = Mage::helper('actions')->getSettings();
|
360 |
-
$query_params = array(
|
361 |
-
'event_no' => $event_no,
|
362 |
-
'data' => $data_string,
|
363 |
-
'is_local_request' => $is_local_request,
|
364 |
-
'correlation_id' => $correlation_id,
|
365 |
-
'send_key' => $settings['send_key']
|
366 |
-
);
|
367 |
-
$postdata = http_build_query($query_params);
|
368 |
|
369 |
-
|
370 |
-
|
371 |
-
$req.= "Host: " . $biz_event_sender_host . "\r\n";
|
372 |
-
$req.= "Content-type: application/x-www-form-urlencoded\r\n";
|
373 |
-
$req.= "Content-length: " . strlen($postdata) . "\r\n";
|
374 |
-
$req.= "\r\n";
|
375 |
-
$req.= $postdata;
|
376 |
-
$req.= "\r\n\r\n";
|
377 |
|
378 |
-
|
379 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
380 |
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
Mage::
|
394 |
-
$cookie = Mage::getSingleton('core/cookie');
|
395 |
-
if (method_exists($cookie, 'get')) {
|
396 |
-
$correlation_cookie = $cookie->get(self::CD_CORRELATION_COOKIE_NAME);
|
397 |
-
if (!empty($correlation_cookie)) {
|
398 |
-
self::$correlation_id = $correlation_cookie;
|
399 |
-
Mage::helper('actions')->log("--->>>> Taking id from cookie: " . self::$correlation_id);
|
400 |
-
} else {
|
401 |
-
// Don't use 4 as param b/c hexdec() has a limit of 7fffffff.
|
402 |
-
self::$correlation_id = hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
403 |
-
. hexdec(bin2hex(openssl_random_pseudo_bytes(3)))
|
404 |
-
. hexdec(bin2hex(openssl_random_pseudo_bytes(2)));
|
405 |
-
/* This sets an HTTP response header. But if client browser has 1-st party cookies
|
406 |
-
disabled, the value won't be saved and returned to PHP engine on next call. We'll
|
407 |
-
try to regenerate it in the same way, again failing to make it permanent. However,
|
408 |
-
the web sensor will detect cookies disabled in JS and not load itself. The
|
409 |
-
eventual outcome will be no web events, and biz events with CD correlation ids varying
|
410 |
-
with each PHP request. Also, the nulls set corresponding settings to shop defaults. */
|
411 |
-
Mage::getSingleton('core/cookie')->set(self::CD_CORRELATION_COOKIE_NAME,
|
412 |
-
self::$correlation_id, 0, '/', null /* domain */,
|
413 |
-
null /* secure */, false /* HttpOnly */);
|
414 |
-
Mage::helper('actions')->log("--->>>> Cookie was empty, now: " . self::$correlation_id);
|
415 |
-
}
|
416 |
-
} else {
|
417 |
-
Mage::helper('actions')->log("--->>>> Could not get the correlation cookie from the "
|
418 |
-
. "browser. Server variable is: " . self::$correlation_id);
|
419 |
-
}
|
420 |
-
}
|
421 |
}
|
422 |
-
}
|
423 |
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
if (
|
434 |
-
|
435 |
-
Mage::helper('actions')->log("Ensure cookie set - Sent Session State Update. Event: "
|
436 |
-
. $observer->getEvent()->getName());
|
437 |
}
|
438 |
-
Mage::helper('actions')->log("Ensure cookie set - Response has not started yet - Event: "
|
439 |
-
. $observer->getEvent()->getName() . " Correlation ID: " . self::$correlation_id);
|
440 |
-
} else {
|
441 |
-
Mage::helper('actions')->log("Ensure cookie set - Response started, don't set id - Event: "
|
442 |
-
. $observer->getEvent()->getName() . " Correlation ID: " . $self::$correlation_id);
|
443 |
-
}
|
444 |
-
} else {
|
445 |
-
Mage::helper('actions')->log("Ensure cookie set - local/admin/disabled, don't set id - Event:"
|
446 |
-
. $observer->getEvent()->getName() . " Correlation ID: " . self::$correlation_id
|
447 |
-
. " is Admin: " . Mage::app()->getStore()->isAdmin());
|
448 |
-
}
|
449 |
-
}
|
450 |
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
$observer_data = array();
|
456 |
-
$this->sendEvent($event_name, $observer_data);
|
457 |
-
Mage::helper('actions')->log("Send Start of session state - Success");
|
458 |
-
}
|
459 |
-
}
|
460 |
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
$async_sender_api = $connect['api'];
|
466 |
-
$connection_scheme = $connect['scheme'];
|
467 |
-
$event_no = Mage::getSingleton('core/session')->getEventNo();
|
468 |
-
$event_no = empty($event_no) ? 0 : $event_no;
|
469 |
-
Mage::getSingleton('core/session')->setEventNo($event_no + 1);
|
470 |
-
$data_string =
|
471 |
-
$this->prepareBizEventData($event_name, $observer_data, $async_sender_api, $event_no);
|
472 |
-
$req = $this->createBizEventRequest($async_sender_api['path'], $async_sender_api['host'],
|
473 |
-
$event_no, $data_string, $is_local_request, self::$correlation_id);
|
474 |
-
$socket = @fsockopen($connection_scheme . $async_sender_api['host'], $async_sender_api['port'],
|
475 |
-
$errno, $errstr, 0.025); //25ms timeout
|
476 |
-
$success = @fwrite($socket, $req);
|
477 |
-
Mage::getSingleton('core/session')->setLastEventTime(time());
|
478 |
-
if ($success) {
|
479 |
-
Mage::helper('actions')->log("[Send Event] - Success - sent the full event:" . $data_string);
|
480 |
-
} else {
|
481 |
-
Mage::helper('actions')->log("[Send Event] - ERROR - number: " . $errno
|
482 |
-
. 'Error string: ' . $errstr
|
483 |
-
. " the full event:" . $data_string);
|
484 |
}
|
485 |
-
$success = @fclose($socket);
|
486 |
-
}
|
487 |
-
|
488 |
-
/**
|
489 |
-
* Checks if this is an external request as opposed to a local server call to avoid an
|
490 |
-
* endless loop. Also verify that it's not Admin area of the store and that module is enabled.
|
491 |
-
*/
|
492 |
-
private static function isCartDefenderEnabledAndIsRequestNonLocalAndIsRequestNonAdmin() {
|
493 |
-
$settings = Mage::helper('actions')->getSettings();
|
494 |
-
return empty($_POST['is_local_request'])
|
495 |
-
&& !Mage::app()->getStore()->isAdmin()
|
496 |
-
&& $settings['enabled'];
|
497 |
-
}
|
498 |
-
|
499 |
}
|
1 |
<?php
|
2 |
|
3 |
+
use CartDefender_Actions_Helper_Data as CDData;
|
4 |
+
|
5 |
/**
|
6 |
* Cart Defender business event capture for Magento
|
7 |
*
|
10 |
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
11 |
* @license Open Software License
|
12 |
*/
|
13 |
+
class CartDefender_Actions_Model_Observer extends Varien_Event_Observer
|
14 |
+
{
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Threshold since last event was sent in seconds.
|
18 |
+
*/
|
19 |
+
const EVENT_TIME_THRESHOLD = 7200;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var CartDefender_Actions_Model_CorrelationIdManager
|
23 |
+
* $correlationIdMgr Container for business logic related
|
24 |
+
* to correlation id, used to match business events and web events.
|
25 |
+
*/
|
26 |
+
private $correlationIdMgr;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var CartDefender_Actions_Model_EventAsyncLocalSender $sender
|
30 |
+
* Asynchronous sender of data to "synchronous remote sender"
|
31 |
+
* (another Cart Defender PHP script available on localhost),
|
32 |
+
* which then sends the data synchronously to Cart Defender servers.
|
33 |
+
*/
|
34 |
+
private $sender;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var CartDefender_Actions_Helper_Logger $logger Logger of Cart Defender
|
38 |
+
* specific messages.
|
39 |
+
*/
|
40 |
+
private $logger;
|
41 |
+
|
42 |
+
/** Initializes this class, particularly the utility objects it uses. */
|
43 |
+
public function _construct()
|
44 |
+
{
|
45 |
+
parent::_construct();
|
46 |
+
$this->correlationIdMgr =
|
47 |
+
Mage::getSingleton('actions/correlationIdManager');
|
48 |
+
$this->sender = Mage::getSingleton('actions/eventAsyncLocalSender');
|
49 |
+
$this->logger = Mage::helper('actions/logger');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
+
/**
|
53 |
+
* Main event observer function.
|
54 |
+
*
|
55 |
+
* List of events: http://www.nicksays.co.uk/magento-events-cheat-sheet-1-7/
|
56 |
+
*
|
57 |
+
* @param object $observer event data.
|
58 |
+
* @return void
|
59 |
+
*/
|
60 |
+
public function captureEvent($observer)
|
61 |
+
{
|
62 |
+
if (!Mage::helper('actions')->isCDEnabledAndRequestNonLocalNonAdmin()) {
|
63 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
}
|
65 |
+
$this->logger->log('Observer->captureEvent');
|
66 |
|
67 |
+
$corrId = $this->correlationIdMgr->ensureCorrelationIdSet();
|
68 |
+
if ($corrId !== null) {
|
69 |
+
if ($this->isLongSinceLastEvent()) {
|
70 |
+
$this->sender->sendEvent(CDData::START_OF_SESSION, $corrId);
|
71 |
+
}
|
72 |
|
73 |
+
$eventName = $observer->getEvent()->getName();
|
74 |
+
$eventData = $observer->getData();
|
75 |
+
$this->sender->sendEvent($eventName, $corrId, $eventData);
|
|
|
|
|
|
|
76 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
+
/**
|
80 |
+
* Event observer function for event "controller_front_send_response_before"
|
81 |
+
*
|
82 |
+
* @param object $observer event data.
|
83 |
+
* @return void
|
84 |
+
*/
|
85 |
+
public function handleControllerFrontSendResponseBefore($observer)
|
86 |
+
{
|
87 |
+
if (!Mage::helper('actions')->isCDEnabledAndRequestNonLocalNonAdmin()) {
|
88 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
90 |
+
$this->logger->log('Observer->handleControllerFrontSendResponseBefore');
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
|
92 |
+
$corrId = $this->correlationIdMgr->ensureCorrelationIdSet();
|
93 |
+
if ($corrId !== null) {
|
94 |
+
if ($this->isLongSinceLastEvent()) {
|
95 |
+
$this->sender->sendEvent(CDData::START_OF_SESSION, $corrId);
|
96 |
+
}
|
97 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
|
99 |
+
$this->correlationIdMgr->setResponseStartedTrue();
|
100 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
+
/**
|
103 |
+
* Event observer function for event "customer_login"
|
104 |
+
* (when a customer logs in.)
|
105 |
+
*
|
106 |
+
* @param object $observer event data.
|
107 |
+
* @return void
|
108 |
+
*/
|
109 |
+
public function handleCustomerLogin($observer)
|
110 |
+
{
|
111 |
+
// Note that the customer_login event carries the pre-login cart.
|
112 |
+
$this->captureEvent($observer);
|
113 |
+
// This isn't cleared on login automatically
|
114 |
+
// even though Magento "frontend" cookie changes.
|
115 |
+
Mage::getSingleton('core/session')->unsLastEventTime();
|
116 |
+
}
|
117 |
|
118 |
+
/**
|
119 |
+
* Event observer function for event "customer_logout"
|
120 |
+
* (when a customer logs out.)
|
121 |
+
*
|
122 |
+
* @param object $observer event data.
|
123 |
+
* @return void
|
124 |
+
*/
|
125 |
+
public function handleCustomerLogout($observer)
|
126 |
+
{
|
127 |
+
$this->captureEvent($observer);
|
128 |
+
// This isn't cleared on logout automatically
|
129 |
+
// even though Magento "frontend" cookie changes.
|
130 |
+
Mage::getSingleton('core/session')->unsLastEventTime();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
}
|
|
|
132 |
|
133 |
+
/**
|
134 |
+
* Returns whether last biz event sent to Cart Defender servers happened a
|
135 |
+
* long time ago (EVENT_TIME_THRESHOLD). It's intended use is to determine
|
136 |
+
* whether we should now send session state biz event.
|
137 |
+
*
|
138 |
+
* @return bool whether last biz event was sent long ago.
|
139 |
+
*/
|
140 |
+
private function isLongSinceLastEvent()
|
141 |
+
{
|
142 |
+
if (!session_id()) {
|
143 |
+
return false;
|
|
|
|
|
144 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
|
146 |
+
$now = time();
|
147 |
+
$lastEventAt = Mage::getSingleton('core/session')->getLastEventTime();
|
148 |
+
$result = empty($lastEventAt)
|
149 |
+
|| (($now - $lastEventAt) > self::EVENT_TIME_THRESHOLD);
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
+
$this->logger->log('Observer->isLongSinceLastEvent', 'Result: '
|
152 |
+
. ($result ? 'Y' : 'N') . ' Time diff: '
|
153 |
+
. ($lastEventAt ? ($now - $lastEventAt): 'N/A'));
|
154 |
+
return $result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
}
|
app/code/community/CartDefender/Actions/controllers/CartDefenderSenderController.php
CHANGED
@@ -1,82 +1,127 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
/**
|
4 |
-
* A script sending
|
5 |
-
*
|
6 |
-
*
|
7 |
-
*
|
8 |
-
*
|
9 |
-
* our servers (at least 3 in case of SSL - about 250 milliseconds for any transatlantic
|
10 |
-
* connections).
|
11 |
*
|
12 |
-
*
|
13 |
-
*
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
|
3 |
+
use CartDefender_Actions_Helper_Data as CDData;
|
4 |
+
|
5 |
/**
|
6 |
+
* A script sending text data to Cart Defender servers. While it sends
|
7 |
+
* the data synchronously, it's meant to be used indirectly, via
|
8 |
+
* AsyncLocalSender. This other utility does pass the data to this script
|
9 |
+
* asynchronously, thus achieving non blocking behavior as far as
|
10 |
+
* the PHP process from which we wanted to send the data is concerned.
|
|
|
|
|
11 |
*
|
12 |
+
* The reason for this setup is not blocking the PHP process rendering
|
13 |
+
* the page for the user. If we blocked, the page rendering or AJAX
|
14 |
+
* processing would be slowed down by the time it takes for the round-trips
|
15 |
+
* to our servers (at least 3 in case of SSL - about 250 milliseconds for
|
16 |
+
* transatlantic connections).
|
17 |
*
|
18 |
* @package CartDefender_Actions
|
19 |
* @author Heptium Ltd.
|
20 |
* @copyright Copyright (c) 2016 Heptium Ltd. (http://www.cartdefender.com/)
|
21 |
* @license Open Software License
|
22 |
*/
|
23 |
+
class CartDefender_Actions_CartDefenderSenderController
|
24 |
+
extends Mage_Core_Controller_Front_Action
|
25 |
+
{
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var CartDefender_Actions_Helper_Logger $logger Logger of Cart Defender
|
29 |
+
* specific messages.
|
30 |
+
*/
|
31 |
+
private $logger;
|
32 |
|
33 |
+
/** Initializes this class, particularly the logger. */
|
34 |
+
public function _construct()
|
35 |
+
{
|
36 |
+
parent::_construct();
|
37 |
+
$this->logger = Mage::helper('actions/logger');
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Synchronously sends the text data contained in the POST request
|
42 |
+
* invoking this controller to the Cart Defender servers.
|
43 |
+
*
|
44 |
+
* @return void
|
45 |
+
*/
|
46 |
+
public function sendAction()
|
47 |
+
{
|
48 |
+
$settings = Mage::helper('actions')->getSettings();
|
49 |
+
$request = $this->getRequest();
|
50 |
+
if ($this->isRequestAllowed($request, $settings)) {
|
51 |
+
$millisBefore = round(microtime(true) * 1000);
|
52 |
+
|
53 |
+
// This is where the biz event is actually sent.
|
54 |
+
$response = $this->sendRequest($request, $settings);
|
55 |
+
|
56 |
+
// Logging.
|
57 |
+
$millisAfter = round(microtime(true) * 1000);
|
58 |
+
$this->logger->log(
|
59 |
+
'CartDefenderSenderController->sendAction',
|
60 |
+
(($response->getStatus() == 200) ? 'Success' : 'Error')
|
61 |
+
. ' Sequence number: ' . $request->getPost('sequence_no')
|
62 |
+
. ' Url: ' . $this->getUrl($settings)
|
63 |
+
. ' Request time: ' . $millisBefore
|
64 |
+
. ' Request latency: ' . ($millisAfter - $millisBefore)
|
65 |
+
);
|
66 |
+
} else {
|
67 |
+
$this->logger->log(
|
68 |
+
'CartDefenderSenderController->sendAction',
|
69 |
+
'Error - request not allowed.'
|
70 |
+
);
|
71 |
+
}
|
72 |
+
$this->logger->log('CartDefenderSenderController->sendAction', 'Done');
|
73 |
+
echo 'Done';
|
74 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
|
76 |
+
/**
|
77 |
+
* Returns whether the request is allowed for processing.
|
78 |
+
*
|
79 |
+
* @param object $request the request to check.
|
80 |
+
* @param array $settings Cart Defender configuration settings.
|
81 |
+
* @return bool whether the request is allowed for processing.
|
82 |
+
*/
|
83 |
+
private function isRequestAllowed($request, $settings)
|
84 |
+
{
|
85 |
+
$isLocalRequest = $request->getPost('is_local_request');
|
86 |
+
$data = $request->getPost('data');
|
87 |
+
return $settings['enabled'] // CD plugin enabled?
|
88 |
+
&& !empty($isLocalRequest) // Is local request?
|
89 |
+
// Send key matches?
|
90 |
+
&& ($settings['send_key'] === $request->getPost('send_key'))
|
91 |
+
&& !empty($data); // Data non-empty?
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Returns the URL to which the data should be sent by this script.
|
96 |
+
*
|
97 |
+
* @param array $settings Cart Defender configuration settings.
|
98 |
+
* @return string URL to which the data should be sent by this script.
|
99 |
+
*/
|
100 |
+
private function getUrl($settings)
|
101 |
+
{
|
102 |
+
$path = CDData::CD_PLUGIN_BIZ_API_PATH_START
|
103 |
+
. '/' . $this->getRequest()->getPost('correlation_id') . '/'
|
104 |
+
. CDData::CD_PLUGIN_BIZ_API_VERSION
|
105 |
+
. CDData::CD_PLUGIN_BIZ_API_PATH_END;
|
106 |
+
$useRawTestUrl = $settings['use_raw_test_url_for_biz_api'];
|
107 |
+
return $settings['test'] ? ($settings['test_server_url_start']
|
108 |
+
. ($useRawTestUrl ? '' : $path)) : (CDData::CD_HOST . $path);
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Sends a POST request to Cart Defender servers.
|
113 |
+
*
|
114 |
+
* @param object $request the request to send.
|
115 |
+
* @param array $settings Cart Defender configuration settings.
|
116 |
+
* @return void
|
117 |
+
*/
|
118 |
+
private function sendRequest($request, $settings)
|
119 |
+
{
|
120 |
+
$client = new Varien_Http_Client($this->getUrl($settings));
|
121 |
+
$client->setMethod(Varien_Http_Client::POST);
|
122 |
+
$client->setAuth($settings['api'], '', Zend_Http_Client::AUTH_BASIC);
|
123 |
+
$client->setRawData($request->getPost('data'));
|
124 |
+
$client->setEncType('application/json');
|
125 |
+
return $client->request();
|
126 |
+
}
|
127 |
+
}
|
app/code/community/CartDefender/Actions/etc/config.xml
CHANGED
@@ -1,319 +1,322 @@
|
|
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 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
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 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
</config>
|
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.3</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 |
+
<models>
|
31 |
+
<actions>
|
32 |
+
<class>CartDefender_Actions_Model</class>
|
33 |
+
</actions>
|
34 |
+
</models>
|
35 |
+
</global>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
|
37 |
+
<frontend>
|
38 |
+
<events>
|
39 |
+
<controller_front_send_response_before>
|
40 |
+
<observers>
|
41 |
+
<cartdefender_controller_front_send_response_before>
|
42 |
+
<type>singleton</type>
|
43 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
44 |
+
<method>handleControllerFrontSendResponseBefore</method>
|
45 |
+
</cartdefender_controller_front_send_response_before>
|
46 |
+
</observers>
|
47 |
+
</controller_front_send_response_before>
|
48 |
+
<catalog_controller_product_view>
|
49 |
+
<observers>
|
50 |
+
<cartdefender_catalog_controller_product_view>
|
51 |
+
<type>singleton</type>
|
52 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
53 |
+
<method>captureEvent</method>
|
54 |
+
</cartdefender_catalog_controller_product_view>
|
55 |
+
</observers>
|
56 |
+
</catalog_controller_product_view>
|
57 |
+
<checkout_cart_save_after>
|
58 |
+
<observers>
|
59 |
+
<cartdefender_checkout_cart_save_after>
|
60 |
+
<type>singleton</type>
|
61 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
62 |
+
<method>captureEvent</method>
|
63 |
+
</cartdefender_checkout_cart_save_after>
|
64 |
+
</observers>
|
65 |
+
</checkout_cart_save_after>
|
66 |
+
<checkout_controller_multishipping_shipping_post>
|
67 |
+
<observers>
|
68 |
+
<cartdefender_checkout_controller_multishipping_shipping_post>
|
69 |
+
<type>singleton</type>
|
70 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
71 |
+
<method>captureEvent</method>
|
72 |
+
</cartdefender_checkout_controller_multishipping_shipping_post>
|
73 |
+
</observers>
|
74 |
+
</checkout_controller_multishipping_shipping_post>
|
75 |
+
<checkout_controller_onepage_save_shipping_method>
|
76 |
+
<observers>
|
77 |
+
<cartdefender_checkout_controller_onepage_save_shipping_method>
|
78 |
+
<type>singleton</type>
|
79 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
80 |
+
<method>captureEvent</method>
|
81 |
+
</cartdefender_checkout_controller_onepage_save_shipping_method>
|
82 |
+
</observers>
|
83 |
+
</checkout_controller_onepage_save_shipping_method>
|
84 |
+
<checkout_multishipping_controller_success_action>
|
85 |
+
<observers>
|
86 |
+
<cartdefender_checkout_multishipping_controller_success_action>
|
87 |
+
<type>singleton</type>
|
88 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
89 |
+
<method>captureEvent</method>
|
90 |
+
</cartdefender_checkout_multishipping_controller_success_action>
|
91 |
+
</observers>
|
92 |
+
</checkout_multishipping_controller_success_action>
|
93 |
+
<checkout_onepage_controller_success_action>
|
94 |
+
<observers>
|
95 |
+
<cartdefender_checkout_onepage_controller_success_action>
|
96 |
+
<type>singleton</type>
|
97 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
98 |
+
<method>captureEvent</method>
|
99 |
+
</cartdefender_checkout_onepage_controller_success_action>
|
100 |
+
</observers>
|
101 |
+
</checkout_onepage_controller_success_action>
|
102 |
+
<customer_login>
|
103 |
+
<observers>
|
104 |
+
<cartdefender_customer_login>
|
105 |
+
<type>singleton</type>
|
106 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
107 |
+
<method>handleCustomerLogin</method>
|
108 |
+
</cartdefender_customer_login>
|
109 |
+
</observers>
|
110 |
+
</customer_login>
|
111 |
+
<customer_logout>
|
112 |
+
<observers>
|
113 |
+
<cartdefender_customer_logout>
|
114 |
+
<type>singleton</type>
|
115 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
116 |
+
<method>handleCustomerLogout</method>
|
117 |
+
</cartdefender_customer_logout>
|
118 |
+
</observers>
|
119 |
+
</customer_logout>
|
120 |
+
<googlecheckout_checkout_before>
|
121 |
+
<observers>
|
122 |
+
<cartdefender_googlecheckout_checkout_before>
|
123 |
+
<type>singleton</type>
|
124 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
125 |
+
<method>captureEvent</method>
|
126 |
+
</cartdefender_googlecheckout_checkout_before>
|
127 |
+
</observers>
|
128 |
+
</googlecheckout_checkout_before>
|
129 |
+
<googlecheckout_save_order_after>
|
130 |
+
<observers>
|
131 |
+
<cartdefender_googlecheckout_save_order_after>
|
132 |
+
<type>singleton</type>
|
133 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
134 |
+
<method>captureEvent</method>
|
135 |
+
</cartdefender_googlecheckout_save_order_after>
|
136 |
+
</observers>
|
137 |
+
</googlecheckout_save_order_after>
|
138 |
+
<order_cancel_after>
|
139 |
+
<observers>
|
140 |
+
<cartdefender_order_cancel_after>
|
141 |
+
<type>singleton</type>
|
142 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
143 |
+
<method>captureEvent</method>
|
144 |
+
</cartdefender_order_cancel_after>
|
145 |
+
</observers>
|
146 |
+
</order_cancel_after>
|
147 |
+
<sales_order_payment_cancel>
|
148 |
+
<observers>
|
149 |
+
<cartdefender_sales_order_payment_cancel>
|
150 |
+
<type>singleton</type>
|
151 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
152 |
+
<method>captureEvent</method>
|
153 |
+
</cartdefender_sales_order_payment_cancel>
|
154 |
+
</observers>
|
155 |
+
</sales_order_payment_cancel>
|
156 |
+
<sales_order_payment_capture>
|
157 |
+
<observers>
|
158 |
+
<cartdefender_sales_order_payment_capture>
|
159 |
+
<type>singleton</type>
|
160 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
161 |
+
<method>captureEvent</method>
|
162 |
+
</cartdefender_sales_order_payment_capture>
|
163 |
+
</observers>
|
164 |
+
</sales_order_payment_capture>
|
165 |
+
<sales_order_payment_pay>
|
166 |
+
<observers>
|
167 |
+
<cartdefender_sales_order_payment_pay>
|
168 |
+
<type>singleton</type>
|
169 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
170 |
+
<method>captureEvent</method>
|
171 |
+
</cartdefender_sales_order_payment_pay>
|
172 |
+
</observers>
|
173 |
+
</sales_order_payment_pay>
|
174 |
+
<sales_order_payment_place_end>
|
175 |
+
<observers>
|
176 |
+
<cartdefender_sales_order_payment_place_end>
|
177 |
+
<type>singleton</type>
|
178 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
179 |
+
<method>captureEvent</method>
|
180 |
+
</cartdefender_sales_order_payment_place_end>
|
181 |
+
</observers>
|
182 |
+
</sales_order_payment_place_end>
|
183 |
+
<sales_order_payment_place_start>
|
184 |
+
<observers>
|
185 |
+
<cartdefender_sales_order_payment_place_start>
|
186 |
+
<type>singleton</type>
|
187 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
188 |
+
<method>captureEvent</method>
|
189 |
+
</cartdefender_sales_order_payment_place_start>
|
190 |
+
</observers>
|
191 |
+
</sales_order_payment_place_start>
|
192 |
+
<sales_order_payment_refund>
|
193 |
+
<observers>
|
194 |
+
<cartdefender_sales_order_payment_refund>
|
195 |
+
<type>singleton</type>
|
196 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
197 |
+
<method>captureEvent</method>
|
198 |
+
</cartdefender_sales_order_payment_refund>
|
199 |
+
</observers>
|
200 |
+
</sales_order_payment_refund>
|
201 |
+
<sales_order_payment_void>
|
202 |
+
<observers>
|
203 |
+
<cartdefender_sales_order_payment_void>
|
204 |
+
<type>singleton</type>
|
205 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
206 |
+
<method>captureEvent</method>
|
207 |
+
</cartdefender_sales_order_payment_void>
|
208 |
+
</observers>
|
209 |
+
</sales_order_payment_void>
|
210 |
+
<wishlist_add_item>
|
211 |
+
<observers>
|
212 |
+
<cartdefender_wishlist_add_item>
|
213 |
+
<type>singleton</type>
|
214 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
215 |
+
<method>captureEvent</method>
|
216 |
+
</cartdefender_wishlist_add_item>
|
217 |
+
</observers>
|
218 |
+
</wishlist_add_item>
|
219 |
+
<wishlist_add_product>
|
220 |
+
<observers>
|
221 |
+
<cartdefender_wishlist_add_product>
|
222 |
+
<type>singleton</type>
|
223 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
224 |
+
<method>captureEvent</method>
|
225 |
+
</cartdefender_wishlist_add_product>
|
226 |
+
</observers>
|
227 |
+
</wishlist_add_product>
|
228 |
+
<wishlist_add_product>
|
229 |
+
<observers>
|
230 |
+
<cartdefender_wishlist_add_product>
|
231 |
+
<type>singleton</type>
|
232 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
233 |
+
<method>captureEvent</method>
|
234 |
+
</cartdefender_wishlist_add_product>
|
235 |
+
</observers>
|
236 |
+
</wishlist_add_product>
|
237 |
+
<wishlist_product_add_after>
|
238 |
+
<observers>
|
239 |
+
<cartdefender_wishlist_product_add_after>
|
240 |
+
<type>singleton</type>
|
241 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
242 |
+
<method>captureEvent</method>
|
243 |
+
</cartdefender_wishlist_product_add_after>
|
244 |
+
</observers>
|
245 |
+
</wishlist_product_add_after>
|
246 |
+
<wishlist_share>
|
247 |
+
<observers>
|
248 |
+
<cartdefender_wishlist_share>
|
249 |
+
<type>singleton</type>
|
250 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
251 |
+
<method>captureEvent</method>
|
252 |
+
</cartdefender_wishlist_share>
|
253 |
+
</observers>
|
254 |
+
</wishlist_share>
|
255 |
+
<wishlist_update_item>
|
256 |
+
<observers>
|
257 |
+
<cartdefender_wishlist_update_item>
|
258 |
+
<type>singleton</type>
|
259 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
260 |
+
<method>captureEvent</method>
|
261 |
+
</cartdefender_wishlist_update_item>
|
262 |
+
</observers>
|
263 |
+
</wishlist_update_item>
|
264 |
+
<controller_action_predispatch_checkout_onepage_index>
|
265 |
+
<observers>
|
266 |
+
<cartdefender_controller_action_predispatch_checkout_onepage_index>
|
267 |
+
<type>singleton</type>
|
268 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
269 |
+
<method>captureEvent</method>
|
270 |
+
</cartdefender_controller_action_predispatch_checkout_onepage_index>
|
271 |
+
</observers>
|
272 |
+
</controller_action_predispatch_checkout_onepage_index>
|
273 |
+
<controller_action_predispatch_checkout_multishipping_index>
|
274 |
+
<observers>
|
275 |
+
<cartdefender_controller_action_predispatch_checkout_multishipping_index>
|
276 |
+
<type>singleton</type>
|
277 |
+
<class>CartDefender_Actions_Model_Observer</class>
|
278 |
+
<method>captureEvent</method>
|
279 |
+
</cartdefender_controller_action_predispatch_checkout_multishipping_index>
|
280 |
+
</observers>
|
281 |
+
</controller_action_predispatch_checkout_multishipping_index>
|
282 |
+
</events>
|
283 |
+
<layout>
|
284 |
+
<updates>
|
285 |
+
<actions>
|
286 |
+
<file>actions.xml</file>
|
287 |
+
</actions>
|
288 |
+
</updates>
|
289 |
+
</layout>
|
290 |
+
<routers>
|
291 |
+
<actions>
|
292 |
+
<use>standard</use>
|
293 |
+
<args>
|
294 |
+
<module>CartDefender_Actions</module>
|
295 |
+
<frontName>cartdefender</frontName>
|
296 |
+
</args>
|
297 |
+
</actions>
|
298 |
+
</routers>
|
299 |
+
</frontend>
|
300 |
|
301 |
+
<adminhtml>
|
302 |
+
<acl>
|
303 |
+
<resources>
|
304 |
+
<admin>
|
305 |
+
<children>
|
306 |
+
<system>
|
307 |
+
<children>
|
308 |
+
<config>
|
309 |
+
<children>
|
310 |
+
<actions translate="title" module="actions">
|
311 |
+
<title>Actions</title>
|
312 |
+
</actions>
|
313 |
+
</children>
|
314 |
+
</config>
|
315 |
+
</children>
|
316 |
+
</system>
|
317 |
+
</children>
|
318 |
+
</admin>
|
319 |
+
</resources>
|
320 |
+
</acl>
|
321 |
+
</adminhtml>
|
322 |
</config>
|
app/code/community/CartDefender/Actions/etc/system.xml
CHANGED
@@ -1,10 +1,10 @@
|
|
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 |
*/
|
@@ -27,12 +27,12 @@
|
|
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 |
-
<comment><![CDATA[ <p>You can configure the Cart Defender's Magento Extension settings
|
31 |
-
in this section. </p>
|
32 |
-
<p>To register for Cart Defender's service and enable the Bot on your website
|
33 |
-
<a href="https://portal.cartdefender.com/#!register"
|
34 |
-
target="_blank">go to the registration page</a>.</p>
|
35 |
-
<p> To configure your Bot's messages <a href="https://portal.cartdefender.com"
|
36 |
target="_blank">go to the Cart Defender Portal</a>.</p>
|
37 |
]]>
|
38 |
</comment>
|
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 |
*/
|
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 |
+
<comment><![CDATA[ <p>You can configure the Cart Defender's Magento Extension settings
|
31 |
+
in this section. </p>
|
32 |
+
<p>To register for Cart Defender's service and enable the Bot on your website
|
33 |
+
<a href="https://portal.cartdefender.com/#!register"
|
34 |
+
target="_blank">go to the registration page</a>.</p>
|
35 |
+
<p> To configure your Bot's messages <a href="https://portal.cartdefender.com"
|
36 |
target="_blank">go to the Cart Defender Portal</a>.</p>
|
37 |
]]>
|
38 |
</comment>
|
app/design/frontend/base/default/layout/actions.xml
CHANGED
@@ -1,11 +1,11 @@
|
|
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 |
*/
|
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 |
*/
|
app/design/frontend/base/default/template/actions/script.phtml
CHANGED
@@ -1,23 +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 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
<?php } ?>
|
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
CHANGED
@@ -1,10 +1,10 @@
|
|
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 |
*/
|
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 |
*/
|
package.xml
CHANGED
@@ -1,20 +1,18 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>cartdefender_actions</name>
|
4 |
-
<version>1.1.
|
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
|
11 |
-
<notes>
|
12 |
-
Enhance configuration page with links to Cart Defender Portal and registration page
|
13 |
-
</notes>
|
14 |
<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>
|
15 |
-
<date>2016-
|
16 |
-
<time>
|
17 |
-
<contents><target name="magecommunity"><dir name="CartDefender"><dir name="Actions"><dir name="Block"><file name="Script.php" hash="
|
18 |
<compatible/>
|
19 |
<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>
|
20 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>cartdefender_actions</name>
|
4 |
+
<version>1.1.3</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 convert the best and adjusts itself automatically.</description>
|
11 |
+
<notes>No-op refactors and minor bugfixes.</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-10-27</date>
|
14 |
+
<time>20:04:27</time>
|
15 |
+
<contents><target name="magecommunity"><dir name="CartDefender"><dir name="Actions"><dir name="Block"><file name="Script.php" hash="b234814d8cd363bcb22c3f9ed33bb80b"/></dir><dir name="Helper"><file name="Data.php" hash="dd4057deaaa8b0bdcfcc3e6f7c31091c"/><file name="Logger.php" hash="f21b3aed521b3761a890b22ba0f247a9"/></dir><dir name="Model"><file name="AsyncLocalSender.php" hash="f4df465d8bba0799a5381b50e7fe244f"/><file name="CorrelationIdManager.php" hash="427b1999971c28ee4a5dc39d6c158be1"/><file name="EventAsyncLocalSender.php" hash="cd9a25e21225cb1966da47fbbc8f9854"/><file name="EventBuilder.php" hash="d814e3b3c947e5a4815b43ba268a9b87"/><file name="Observer.php" hash="b6e3237c696a417557fa7a3a98b75358"/></dir><dir name="controllers"><file name="CartDefenderSenderController.php" hash="2932402af887cac75255758c7fd4da34"/></dir><dir name="etc"><file name="config.xml" hash="b6332ca2c6038b906edb525d1cf4df71"/><file name="system.xml" hash="3a0ef9f8ca4414d7714e717a64816a33"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="CartDefender_Actions.xml" hash="f9e77235e41f79ac086160ef2e494837"/></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="aa322fad9cd04ae7c910936e043fa8f1"/></dir></dir><dir name="layout"><file name="actions.xml" hash="e6a4b2f6d8132a833a1b5f8b9fce7166"/></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>
|