VantageAnalytics_Analytics - Version 0.9.0

Version Notes

First release

Download this release

Release Info

Developer Brandon Kane
Extension VantageAnalytics_Analytics
Version 0.9.0
Comparing to
See all releases


Version 0.9.0

Files changed (86) hide show
  1. app/code/community/VantageAnalytics/Analytics/Block/Adminhtml/Analyticsbackend.php +9 -0
  2. app/code/community/VantageAnalytics/Analytics/Block/Adminhtml/Reset.php +17 -0
  3. app/code/community/VantageAnalytics/Analytics/Helper/Account.php +65 -0
  4. app/code/community/VantageAnalytics/Analytics/Helper/Data.php +6 -0
  5. app/code/community/VantageAnalytics/Analytics/Helper/DateFormatter.php +40 -0
  6. app/code/community/VantageAnalytics/Analytics/Helper/Extension/Lister.php +38 -0
  7. app/code/community/VantageAnalytics/Analytics/Helper/Extension/Pool.php +44 -0
  8. app/code/community/VantageAnalytics/Analytics/Helper/Log.php +39 -0
  9. app/code/community/VantageAnalytics/Analytics/Helper/Queue.php +74 -0
  10. app/code/community/VantageAnalytics/Analytics/Helper/Statuses.php +102 -0
  11. app/code/community/VantageAnalytics/Analytics/Helper/Tracking.php +43 -0
  12. app/code/community/VantageAnalytics/Analytics/Model/AddressRetriever.php +25 -0
  13. app/code/community/VantageAnalytics/Analytics/Model/Api/Exceptions/BadRequest.php +6 -0
  14. app/code/community/VantageAnalytics/Analytics/Model/Api/Exceptions/CurlError.php +6 -0
  15. app/code/community/VantageAnalytics/Analytics/Model/Api/Exceptions/MaxRetries.php +6 -0
  16. app/code/community/VantageAnalytics/Analytics/Model/Api/Exceptions/ServerError.php +6 -0
  17. app/code/community/VantageAnalytics/Analytics/Model/Api/Request.php +109 -0
  18. app/code/community/VantageAnalytics/Analytics/Model/Api/RequestQueue.php +14 -0
  19. app/code/community/VantageAnalytics/Analytics/Model/Api/Secret.php +46 -0
  20. app/code/community/VantageAnalytics/Analytics/Model/Api/Signature.php +25 -0
  21. app/code/community/VantageAnalytics/Analytics/Model/Api/Username.php +13 -0
  22. app/code/community/VantageAnalytics/Analytics/Model/Api/Webhook.php +52 -0
  23. app/code/community/VantageAnalytics/Analytics/Model/Cron.php +79 -0
  24. app/code/community/VantageAnalytics/Analytics/Model/Debug.php +103 -0
  25. app/code/community/VantageAnalytics/Analytics/Model/Export/Base.php +55 -0
  26. app/code/community/VantageAnalytics/Analytics/Model/Export/Customer.php +17 -0
  27. app/code/community/VantageAnalytics/Analytics/Model/Export/Order.php +21 -0
  28. app/code/community/VantageAnalytics/Analytics/Model/Export/Product.php +17 -0
  29. app/code/community/VantageAnalytics/Analytics/Model/Export/Runner.php +68 -0
  30. app/code/community/VantageAnalytics/Analytics/Model/Export/Store.php +20 -0
  31. app/code/community/VantageAnalytics/Analytics/Model/Heartbeat.php +16 -0
  32. app/code/community/VantageAnalytics/Analytics/Model/Observer/Base.php +47 -0
  33. app/code/community/VantageAnalytics/Analytics/Model/Observer/CatalogProduct.php +23 -0
  34. app/code/community/VantageAnalytics/Analytics/Model/Observer/Customer.php +29 -0
  35. app/code/community/VantageAnalytics/Analytics/Model/Observer/SalesOrder.php +43 -0
  36. app/code/community/VantageAnalytics/Analytics/Model/Observer/SalesQuote.php +30 -0
  37. app/code/community/VantageAnalytics/Analytics/Model/Observer/Tracking.php +24 -0
  38. app/code/community/VantageAnalytics/Analytics/Model/ParentProduct.php +70 -0
  39. app/code/community/VantageAnalytics/Analytics/Model/ProductCategories.php +37 -0
  40. app/code/community/VantageAnalytics/Analytics/Model/ProductImages.php +44 -0
  41. app/code/community/VantageAnalytics/Analytics/Model/ProductOptions.php +50 -0
  42. app/code/community/VantageAnalytics/Analytics/Model/Queue/Adapter/Db.php +19 -0
  43. app/code/community/VantageAnalytics/Analytics/Model/Resource/Mysql4/Setup.php +9 -0
  44. app/code/community/VantageAnalytics/Analytics/Model/SubscriberInformation.php +42 -0
  45. app/code/community/VantageAnalytics/Analytics/Model/Transformer/Address.php +122 -0
  46. app/code/community/VantageAnalytics/Analytics/Model/Transformer/Base.php +44 -0
  47. app/code/community/VantageAnalytics/Analytics/Model/Transformer/BaseSales.php +159 -0
  48. app/code/community/VantageAnalytics/Analytics/Model/Transformer/BaseSalesItem.php +67 -0
  49. app/code/community/VantageAnalytics/Analytics/Model/Transformer/Customer.php +101 -0
  50. app/code/community/VantageAnalytics/Analytics/Model/Transformer/Product.php +127 -0
  51. app/code/community/VantageAnalytics/Analytics/Model/Transformer/SalesOrder.php +106 -0
  52. app/code/community/VantageAnalytics/Analytics/Model/Transformer/SalesOrderLineItem.php +67 -0
  53. app/code/community/VantageAnalytics/Analytics/Model/Transformer/SalesQuote.php +85 -0
  54. app/code/community/VantageAnalytics/Analytics/Model/Transformer/SalesQuoteLineItem.php +27 -0
  55. app/code/community/VantageAnalytics/Analytics/Model/Transformer/Store.php +150 -0
  56. app/code/community/VantageAnalytics/Analytics/Test/Model/Api/Signature.php +28 -0
  57. app/code/community/VantageAnalytics/Analytics/Test/Model/Base.php +12 -0
  58. app/code/community/VantageAnalytics/Analytics/Test/Model/Config.php +14 -0
  59. app/code/community/VantageAnalytics/Analytics/Test/Model/Customer.php +40 -0
  60. app/code/community/VantageAnalytics/Analytics/Test/Model/Customer/fixtures/simpleCustomer.yaml +34 -0
  61. app/code/community/VantageAnalytics/Analytics/Test/Model/DateFormatterTest.php +28 -0
  62. app/code/community/VantageAnalytics/Analytics/Test/Model/LineItem.php +31 -0
  63. app/code/community/VantageAnalytics/Analytics/Test/Model/LineItem/fixtures/simpleOrder.yaml +87 -0
  64. app/code/community/VantageAnalytics/Analytics/Test/Model/Order.php +72 -0
  65. app/code/community/VantageAnalytics/Analytics/Test/Model/Order/fixtures/orderStatus.yaml +61 -0
  66. app/code/community/VantageAnalytics/Analytics/Test/Model/Order/fixtures/orderStatusCanceled.yaml +5 -0
  67. app/code/community/VantageAnalytics/Analytics/Test/Model/Order/fixtures/orderStatusComplete.yaml +44 -0
  68. app/code/community/VantageAnalytics/Analytics/Test/Model/Order/fixtures/paymentStatusUnpaid.yaml +22 -0
  69. app/code/community/VantageAnalytics/Analytics/Test/Model/Order/providers/orderStatus.yaml +15 -0
  70. app/code/community/VantageAnalytics/Analytics/Test/Model/Product.php +54 -0
  71. app/code/community/VantageAnalytics/Analytics/Test/Model/Product/fixtures/parentProduct.yaml +62 -0
  72. app/code/community/VantageAnalytics/Analytics/Test/Model/Product/fixtures/simpleProduct.yaml +45 -0
  73. app/code/community/VantageAnalytics/Analytics/Test/Model/Webhook.php +17 -0
  74. app/code/community/VantageAnalytics/Analytics/controllers/Adminhtml/AnalyticsbackendController.php +127 -0
  75. app/code/community/VantageAnalytics/Analytics/controllers/Adminhtml/ResetController.php +30 -0
  76. app/code/community/VantageAnalytics/Analytics/etc/adminhtml.xml +27 -0
  77. app/code/community/VantageAnalytics/Analytics/etc/config.xml +219 -0
  78. app/code/community/VantageAnalytics/Analytics/etc/system.xml +84 -0
  79. app/code/community/VantageAnalytics/Analytics/sql/vantageanalytics_analytics_setup/install-0.1.0.php +40 -0
  80. app/code/community/VantageAnalytics/Analytics/sql/vantageanalytics_analytics_setup/mysql4-upgrade-0.1.0-0.2.0.php +7 -0
  81. app/design/adminhtml/default/default/layout/analytics.xml +19 -0
  82. app/design/adminhtml/default/default/template/analytics/analyticsbackend.phtml +37 -0
  83. app/etc/modules/VantageAnalytics_Analytics.xml +9 -0
  84. package.xml +19 -0
  85. skin/adminhtml/base/default/images/vantage-for-magento.png +0 -0
  86. skin/adminhtml/default/default/css/register.css +41 -0
app/code/community/VantageAnalytics/Analytics/Block/Adminhtml/Analyticsbackend.php ADDED
@@ -0,0 +1,9 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Block_Adminhtml_Analyticsbackend extends Mage_Adminhtml_Block_Template {
4
+
5
+ public function isAccountVerified()
6
+ {
7
+ return Mage::helper('analytics/account')->isVerified();
8
+ }
9
+ }
app/code/community/VantageAnalytics/Analytics/Block/Adminhtml/Reset.php ADDED
@@ -0,0 +1,17 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Block_Adminhtml_Reset extends Mage_Adminhtml_Block_System_Config_Form_Field
4
+ {
5
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
6
+ {
7
+ $resetUrl = $this->getUrl('analytics/adminhtml_reset/reset');
8
+ $this->setElement($element);
9
+ return $this->getLayout()
10
+ ->createBlock('adminhtml/widget_button')
11
+ ->setType('button')
12
+ ->setClass('scalable')
13
+ ->setLabel('Reset')
14
+ ->setOnClick("setLocation('{$resetUrl}')")
15
+ ->toHtml();
16
+ }
17
+ }
app/code/community/VantageAnalytics/Analytics/Helper/Account.php ADDED
@@ -0,0 +1,65 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Helper_Account extends Mage_Core_Helper_Abstract
4
+ {
5
+ public function username()
6
+ {
7
+ return Mage::getStoreConfig('vantageanalytics/accountoptions/accountid', Mage::app()->getStore());
8
+ }
9
+
10
+ public function setUsername($username)
11
+ {
12
+ Mage::getConfig()->saveConfig('vantageanalytics/accountoptions/accountid', $username);
13
+ Mage::getConfig()->reinit();
14
+ }
15
+
16
+ public function secret()
17
+ {
18
+ return Mage::getStoreConfig('vantageanalytics/accountoptions/accountpwd', Mage::app()->getStore());
19
+ }
20
+
21
+ public function setSecret($secret)
22
+ {
23
+ Mage::getConfig()->saveConfig('vantageanalytics/accountoptions/accountpwd', $secret);
24
+ Mage::getConfig()->reinit();
25
+ }
26
+
27
+ public function vantageUrl()
28
+ {
29
+ return Mage::getStoreConfig('vantageanalytics/accountoptions/vantageurl', Mage::app()->getStore());
30
+ }
31
+
32
+ public function registerAccountUrl()
33
+ {
34
+ return dirname($this->vantageUrl()) . '/register/';
35
+ }
36
+
37
+ public function setVantageUrl($url)
38
+ {
39
+ Mage::getConfig()->saveConfig('vantageanalytics/accountoptions/vantageurl', $url);
40
+ Mage::getConfig()->reinit();
41
+ }
42
+
43
+ public function isVerified()
44
+ {
45
+ return Mage::getStoreConfig('vantageanalytics/accountoptions/verified', Mage::app()->getStore());
46
+ }
47
+
48
+ public function setIsVerified($isVerified)
49
+ {
50
+ Mage::getConfig()->saveConfig('vantageanalytics/accountoptions/verified', $isVerified);
51
+ Mage::getConfig()->reinit();
52
+ }
53
+
54
+ public function isExportDone()
55
+ {
56
+ return Mage::getStoreConfig('vantageanalytics/export/done', Mage::app()->getStore());
57
+ }
58
+
59
+ public function setExportDone($done)
60
+ {
61
+ Mage::getConfig()->saveConfig('vantageanalytics/export/done', $done);
62
+ Mage::getConfig()->reinit();
63
+ }
64
+
65
+ }
app/code/community/VantageAnalytics/Analytics/Helper/Data.php ADDED
@@ -0,0 +1,6 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+
6
+ }
app/code/community/VantageAnalytics/Analytics/Helper/DateFormatter.php ADDED
@@ -0,0 +1,40 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Helper_DateFormatter
3
+ {
4
+ public static function factory($dateString)
5
+ {
6
+ return new self($dateString);
7
+ }
8
+
9
+ public function __construct($dateString)
10
+ {
11
+ $this->dateString = $dateString;
12
+ }
13
+
14
+ public function defaultTimezone()
15
+ {
16
+ return new DateTimeZone("UTC");
17
+ }
18
+
19
+ public function dateFormat()
20
+ {
21
+ return "c";
22
+ }
23
+
24
+ public function toDate()
25
+ {
26
+ $datetime = new DateTime($this->dateString);
27
+
28
+ return $datetime->format($this->dateFormat());
29
+ }
30
+
31
+ public function toUtcDate()
32
+ {
33
+ $datetime = new DateTime($this->dateString);
34
+
35
+ $datetime->setTimeZone($this->defaultTimezone());
36
+
37
+ return $datetime->format($this->dateFormat());
38
+ }
39
+
40
+ }
app/code/community/VantageAnalytics/Analytics/Helper/Extension/Lister.php ADDED
@@ -0,0 +1,38 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Helper_Extension_Lister
3
+ {
4
+ public static function factory()
5
+ {
6
+ return new self();
7
+ }
8
+
9
+ public function __construct()
10
+ {
11
+ $this->config = Mage::getConfig();
12
+ }
13
+
14
+ public function extensions()
15
+ {
16
+ return array_map("basename", $this->filePaths());
17
+ }
18
+
19
+ public function pools()
20
+ {
21
+ return array('core','community','local');
22
+ }
23
+
24
+ private function filePaths()
25
+ {
26
+ $extensions = array();
27
+
28
+ foreach($this->pools() as $pool)
29
+ {
30
+ $extensions[] =
31
+ VantageAnalytics_Analytics_Helper_Extension_Pool::factory($pool)
32
+ ->files();
33
+ }
34
+
35
+ return call_user_func_array('array_merge', $extensions);
36
+ }
37
+
38
+ }
app/code/community/VantageAnalytics/Analytics/Helper/Extension/Pool.php ADDED
@@ -0,0 +1,44 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Helper_Extension_Pool
3
+ {
4
+ public static function factory($poolName)
5
+ {
6
+ return new self($poolName);
7
+ }
8
+
9
+ public function __construct($poolName)
10
+ {
11
+ $this->poolName = $poolName;
12
+ $this->config = Mage::getConfig();
13
+ }
14
+
15
+ public function files()
16
+ {
17
+ $final = array();
18
+
19
+ foreach($this->_files() as $file)
20
+ {
21
+ if(is_dir($file))
22
+ {
23
+ $final[] = $file;
24
+ }
25
+ }
26
+ return $final;
27
+ }
28
+
29
+ private function _files()
30
+ {
31
+ return glob($this->_poolPath($this->poolName) . DS . '*');
32
+ }
33
+
34
+ private function _basePath()
35
+ {
36
+ return $this->config->getOptions()->getCodeDir();
37
+ }
38
+
39
+ private function _poolPath($pool)
40
+ {
41
+ return $this->_basePath() . DS . $pool;
42
+ }
43
+ }
44
+
app/code/community/VantageAnalytics/Analytics/Helper/Log.php ADDED
@@ -0,0 +1,39 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Helper_Log extends Mage_Core_Helper_Abstract
4
+ {
5
+ const LOGFILE = 'vantage-analytics.log';
6
+ const MARKER = '[VantageAnalytics] ';
7
+
8
+ protected function format($message, $findCaller=false)
9
+ {
10
+ if ($findCaller) {
11
+ $callerInfo = debug_backtrace();
12
+ $callerLine = $callerInfo[1]['line'];
13
+ $callerFile = $callerInfo[1]['file'];
14
+ return self::MARKER . " ({$callerFile}:{$callerLine}) {$message}";
15
+ }
16
+ return self::MARKER . " {$message}";
17
+ }
18
+
19
+ public function logInfo($msg)
20
+ {
21
+ Mage::log($this->format($msg), Zend_Log::INFO, self::LOGFILE);
22
+ }
23
+
24
+ public function logWarn($msg)
25
+ {
26
+ Mage::log($this->format($msg), Zend_Log::WARN, self::LOGFILE);
27
+ }
28
+
29
+ public function logError($msg)
30
+ {
31
+ Mage::log($this->format($msg, true), Zend_Log::ERR, self::LOGFILE, true);
32
+ }
33
+
34
+ public function logException($e)
35
+ {
36
+ Mage::log($this->format("\n" . $e->__toString(), true), Zend_Log::ERR, self::LOGFILE, true);
37
+ Mage::logException($e); // These always make it to a file named exception.log
38
+ }
39
+ }
app/code/community/VantageAnalytics/Analytics/Helper/Queue.php ADDED
@@ -0,0 +1,74 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Helper_Queue extends Mage_Core_Helper_Abstract
4
+ {
5
+ protected $queueName = "vantage";
6
+ protected $registry = array();
7
+ protected $maxBatchSize = 1000;
8
+
9
+ protected function getQueue()
10
+ {
11
+ if (!isset($this->registry[$this->queueName]))
12
+ {
13
+ $config = Mage::getConfig()->getResourceConnectionConfig("default_setup");
14
+ $queueOptions = array(
15
+ Zend_Queue::NAME => $this->queueName,
16
+ 'messageTableName' => 'vantage_message',
17
+ 'queueTableName' => 'vantage_queue',
18
+ 'driverOptions' => array(
19
+ 'host' => $config->host,
20
+ 'port' => $config->port,
21
+ 'username' => $config->username,
22
+ 'password' => $config->password,
23
+ 'dbname' => $config->dbname,
24
+ 'type' => 'pdo_mysql',
25
+ Zend_Queue::TIMEOUT => 1,
26
+ Zend_Queue::VISIBILITY_TIMEOUT => 1
27
+ )
28
+ );
29
+ $zendDb = new VantageAnalytics_Analytics_Model_Queue_Adapter_Db($queueOptions);
30
+ $this->registry[$this->queueName] = new Zend_Queue($zendDb, $queueOptions);
31
+ }
32
+ return $this->registry[$this->queueName];
33
+ }
34
+
35
+ protected function buildJob($msg)
36
+ {
37
+ $jobclass = $msg['class'];
38
+ $classname = "VantageAnalytics_Analytics_Model_{$jobclass}";
39
+ return new $classname;
40
+ }
41
+
42
+ protected function runJob($message)
43
+ {
44
+ $msg = json_decode($message->body, true);
45
+ $job = $this->buildJob($msg);
46
+ $method = $msg['method'];
47
+ return call_user_func_array(array($job, $method), $msg['args']);
48
+ }
49
+
50
+ public function processQueue()
51
+ {
52
+ try
53
+ {
54
+ $queue = $this->getQueue();
55
+ foreach ($queue->receive($this->maxBatchSize) as $message) {
56
+ $this->runJob($message);
57
+ $queue->deleteMessage($message);
58
+ }
59
+ }
60
+ catch (Exception $e)
61
+ {
62
+ Mage::helper('analytics/log')->logException($e);
63
+ return false;
64
+ }
65
+ return true;
66
+ }
67
+
68
+ public function enqueue($task)
69
+ {
70
+ $msg = json_encode($task);
71
+ $this->getQueue()->send($msg);
72
+ return true;
73
+ }
74
+ }
app/code/community/VantageAnalytics/Analytics/Helper/Statuses.php ADDED
@@ -0,0 +1,102 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Helper_Statuses
4
+ {
5
+ /*
6
+ * see: https://github.com/OpenMage/magento-mirror/blob/magento-1.7/app/code/core/Mage/Sales/Model/Order/Item.php#L194
7
+ * see: https://github.com/OpenMage/magento-mirror/blob/magento-1.7/app/code/core/Mage/Sales/Model/Order.php#L334
8
+ * see: http://www.magentocommerce.com/wiki/2_-_magento_concepts_and_architecture/order_management
9
+ */
10
+
11
+ public static function factory($salesEntity)
12
+ {
13
+ return new self($salesEntity);
14
+ }
15
+
16
+ public function __construct($salesEntity)
17
+ {
18
+ $this->salesEntity = $salesEntity;
19
+ }
20
+
21
+ public function paymentStatus()
22
+ {
23
+ $state = $this->_getOrderState();
24
+
25
+ if($state == Mage_Sales_Model_Order::STATUS_FRAUD) {
26
+ return 'paid';
27
+ }
28
+
29
+ $due = $this->salesEntity->getTotalDue();
30
+
31
+ if ($due == 0) {
32
+ return 'paid';
33
+ }
34
+
35
+ return 'unpaid';
36
+ }
37
+
38
+ public function fulfillmentStatus()
39
+ {
40
+ $statuses = array();
41
+
42
+ foreach ($this->salesEntity->getAllVisibleItems() as $item) {
43
+ $statuses[] = $item->getStatusId();
44
+ }
45
+
46
+ if ($this->_allItemsShipped($statuses)) {
47
+ return 'fulfilled';
48
+ }
49
+
50
+ if ($this->_partiallyFulfilled($statuses)) {
51
+ return 'partial-fulfilled';
52
+ }
53
+
54
+ return 'unfulfilled';
55
+ }
56
+
57
+ private function _allItemsShipped($statuses)
58
+ {
59
+ $unique_statuses = array_unique($statuses);
60
+
61
+ return (count($unique_statuses) == 1 && ($unique_statuses[0] == Mage_Sales_Model_Order_Item::STATUS_SHIPPED));
62
+ }
63
+
64
+ private function _partiallyFulfilled($statuses)
65
+ {
66
+ $unique_statuses = array_unique($statuses);
67
+
68
+ /* If one line item is fully fulfilled, while others are not
69
+ * then the order is also only partially fulfilled
70
+ */
71
+ return in_array(Mage_Sales_Model_Order_Item::STATUS_PARTIAL, $unique_statuses) ||
72
+ (in_array(Mage_Sales_Model_Order_Item::STATUS_SHIPPED, $unique_statuses) && (count($unique_statuses) > 1));
73
+ }
74
+
75
+ public function orderStatus()
76
+ {
77
+ $state = $this->_getOrderState();
78
+ switch ($state)
79
+ {
80
+ case Mage_Sales_Model_Order::STATE_CLOSED:
81
+ case Mage_Sales_Model_Order::STATE_COMPLETE:
82
+ return 'closed';
83
+ case Mage_Sales_Model_Order::STATE_CANCELED:
84
+ case Mage_Sales_Model_Order::STATUS_FRAUD:
85
+ return 'canceled';
86
+ case Mage_Sales_Model_Order::STATE_NEW:
87
+ case Mage_Sales_Model_Order::STATE_HOLDED:
88
+ case Mage_Sales_Model_Order::STATE_PENDING_PAYMENT:
89
+ case Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW:
90
+ case Mage_Sales_Model_Order::STATE_PENDING_PAYMENT:
91
+ case Mage_Sales_Model_Order::STATE_PROCESSING:
92
+ return 'placed';
93
+ default:
94
+ return 'open';
95
+ }
96
+ }
97
+
98
+ private function _getOrderState()
99
+ {
100
+ return $this->salesEntity->getState();
101
+ }
102
+ }
app/code/community/VantageAnalytics/Analytics/Helper/Tracking.php ADDED
@@ -0,0 +1,43 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Helper_Tracking extends Mage_Core_Helper_Abstract
4
+ {
5
+ const COOKIE_NAME = '__vantage';
6
+
7
+ public function gatherTrackingData($request)
8
+ {
9
+ $tracking = array(
10
+ 'landing_site' => $request->getRequestUri(),
11
+ 'referral_site' => $request->getServer('HTTP_REFERER')
12
+ );
13
+ return $tracking;
14
+ }
15
+
16
+ public function setInitialCookie($request)
17
+ {
18
+ if ($this->hasTrackingCookie()) {
19
+ return;
20
+ }
21
+ $tracking = $this->gatherTrackingData($request);
22
+ $cookie = json_encode($tracking);
23
+ $sixtyDays = 86400 * 60;
24
+ Mage::getModel('core/cookie')->set(self::COOKIE_NAME, $cookie, $sixtyDays);
25
+ }
26
+
27
+ public function hasTrackingCookie()
28
+ {
29
+ $currentCookie = $this->getTrackingFromCookie();
30
+ return (count($currentCookie) > 0);
31
+ }
32
+
33
+ public function getTrackingFromCookie()
34
+ {
35
+ $cookie = Mage::getModel('core/cookie')->get(self::COOKIE_NAME);
36
+ $tracking = json_decode($cookie, true);
37
+ if (!is_null($tracking)) {
38
+ return $tracking;
39
+ }
40
+ return array();
41
+ }
42
+
43
+ }
app/code/community/VantageAnalytics/Analytics/Model/AddressRetriever.php ADDED
@@ -0,0 +1,25 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_AddressRetriever
4
+ {
5
+ public function __construct($customer)
6
+ {
7
+ $this->customer = $customer;
8
+ }
9
+
10
+ public static function factory($customer)
11
+ {
12
+ return new self($customer);
13
+ }
14
+
15
+ protected function addressId()
16
+ {
17
+ return $this->customer->getDefaultBilling();
18
+ }
19
+
20
+ public function address()
21
+ {
22
+ return Mage::getModel('customer/address')->load($this->addressId());
23
+ }
24
+
25
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/Exceptions/BadRequest.php ADDED
@@ -0,0 +1,6 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Exceptions_BadRequest extends Exception
4
+ {
5
+
6
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/Exceptions/CurlError.php ADDED
@@ -0,0 +1,6 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Exceptions_CurlError extends Exception
4
+ {
5
+
6
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/Exceptions/MaxRetries.php ADDED
@@ -0,0 +1,6 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Exceptions_MaxRetries extends Exception
4
+ {
5
+
6
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/Exceptions/ServerError.php ADDED
@@ -0,0 +1,6 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Exceptions_ServerError extends Exception
4
+ {
5
+
6
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/Request.php ADDED
@@ -0,0 +1,109 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Request
4
+ {
5
+ public function __construct($vantageUrl=null, $username=null, $secret=null)
6
+ {
7
+ $this->vantageUrl = $vantageUrl ? $vantageUrl : Mage::helper("analytics/account")->vantageUrl();
8
+ $this->apiUsername = $username ? $username : Mage::helper("analytics/account")->username();
9
+ $this->apiSecret = $secret ? $secret : Mage::helper("analytics/account")->secret();
10
+ }
11
+
12
+ protected function makeSignatureHeader($body)
13
+ {
14
+ $signer = new VantageAnalytics_Analytics_Model_Api_Signature($body, $this->apiSecret);
15
+ return $signer->signatureHeader();
16
+ }
17
+
18
+
19
+ protected function setupCurl($method, $entityData)
20
+ {
21
+ $uri = "{$this->vantageUrl}/";
22
+ $channel = curl_init("$uri");
23
+ if (!$channel) {
24
+ $errorDesc = curl_error($channel);
25
+ throw new VantageAnalytics_Analytics_Model_Api_Exceptions_CurlError(
26
+ $errorDesc
27
+ );
28
+ }
29
+ curl_setopt($channel, CURLOPT_SSL_VERIFYHOST, 2);
30
+ curl_setopt($channel, CURLOPT_CUSTOMREQUEST, $method);
31
+ curl_setopt($channel, CURLOPT_RETURNTRANSFER, true);
32
+
33
+ $entityData['username'] = $this->apiUsername;
34
+ $body = json_encode($entityData);
35
+ curl_setopt($channel, CURLOPT_POSTFIELDS, $body);
36
+ $headers = array(
37
+ 'Content-type: application/json',
38
+ 'Content-length: ' . strlen($body),
39
+ $this->makeSignatureHeader($body)
40
+ );
41
+ curl_setopt($channel, CURLOPT_HTTPHEADER, $headers);
42
+
43
+ return $channel;
44
+ }
45
+
46
+ protected function raiseOnError($channel)
47
+ {
48
+ $status = curl_getinfo($channel, CURLINFO_HTTP_CODE);
49
+
50
+ if ($status >= 400 && $status < 500) {
51
+ throw new VantageAnalytics_Analytics_Model_Api_Exceptions_BadRequest;
52
+ }
53
+ if ($status >= 500) {
54
+ throw new VantageAnalytics_Analytics_Model_Api_Exceptions_ServerError;
55
+ }
56
+
57
+ if (curl_errno($channel)) {
58
+ $errorDesc = curl_error($channel);
59
+ curl_close($channel);
60
+ throw new VantageAnalytics_Analytics_Model_Api_Exceptions_CurlError(
61
+ $errorDesc
62
+ );
63
+ }
64
+ }
65
+
66
+ protected function wait($attempt)
67
+ {
68
+ if ($attempt == 10) {
69
+ Mage::helper('analytics/log')->logError("Tried $attempt times, giving up");
70
+ throw new VantageAnalytics_Analytics_Model_Api_Exceptions_MaxRetries("Maximum retries exceeded");
71
+ }
72
+ $waitTimes = array(30, 60, 5*60, 10*60, 30*60, 60*60,
73
+ 2*60*60, 5*60*60, 12*60*60, 24*60*60);
74
+ $seconds = $waitTimes[$attempt];
75
+ Mage::helper('analytics/log')->logWarn("Waiting for {$seconds} seconds.");
76
+ sleep($seconds);
77
+ }
78
+
79
+ protected function execCurl($method, $entityData)
80
+ {
81
+ $attempts = 0;
82
+ $success = false;
83
+ while ($attempts < 10 && !$success) {
84
+ try {
85
+ $channel = $this->setupCurl($method, $entityData);
86
+ $response = curl_exec($channel);
87
+ $this->raiseOnError($channel);
88
+ curl_close($channel);
89
+ $success = true;
90
+ } catch (VantageAnalytics_Analytics_Model_Api_Exceptions_ServerError $e) {
91
+ $this->wait($attempts);
92
+ } catch (VantageAnalytics_Analytics_Model_Api_Exceptions_CurlError $e) {
93
+ $this->wait($attempts);
94
+ } catch (VantageAnalytics_Analytics_Model_Api_Exceptions_BadRequest $e) {
95
+ $this->wait($attempts);
96
+ }
97
+ $attempts += 1;
98
+ }
99
+ return $response;
100
+ }
101
+
102
+ public function send($method, $entity)
103
+ {
104
+ $postData = VantageAnalytics_Analytics_Model_Api_Webhook::factory(
105
+ $entity, $method
106
+ )->getPostData();
107
+ $this->execCurl("POST", $postData);
108
+ }
109
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/RequestQueue.php ADDED
@@ -0,0 +1,14 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_RequestQueue
4
+ {
5
+ public function enqueue($method, $resource)
6
+ {
7
+ $queue = Mage::helper('analytics/queue');
8
+ $queue->enqueue(array(
9
+ 'class' => 'Api_Request',
10
+ 'method' => 'send',
11
+ 'args' => array($method, $resource)
12
+ ));
13
+ }
14
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/Secret.php ADDED
@@ -0,0 +1,46 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Secret extends Mage_Core_Model_Config_Data
4
+ {
5
+ public function save()
6
+ {
7
+ $secret = $this->getValue();
8
+ if (strlen($secret) == 0) {
9
+ Mage::throwException("The VantageAnalytics Secret is required.");
10
+ }
11
+ if (strlen($secret) < 32) {
12
+ Mage::throwException(
13
+ "Double check the VantageAnalytics Secret, it " .
14
+ " should be 32 characters long."
15
+ );
16
+ }
17
+
18
+ $username = Mage::helper('analytics/account')->username();
19
+ $post = Mage::app()->getRequest()->getPost();
20
+ $username = $post['groups']['accountoptions']['fields']
21
+ ['accountid']['value'];
22
+
23
+ $vantageUrl = Mage::helper('analytics/account')->vantageUrl();
24
+
25
+ $api = new VantageAnalytics_Analytics_Model_Api_Request(
26
+ $vantageUrl, $username, $secret
27
+ );
28
+ $verifiyEntity = array('entity_type' => 'verification');
29
+
30
+ try {
31
+ $api->send('create', $verifiyEntity);
32
+ Mage::helper('analytics/account')->setIsVerified(1);
33
+ Mage::getSingleton('core/session')->addSuccess("Your VantageAnalytics "
34
+ . "username and secret were verified."
35
+ );
36
+ } catch (VantageAnalytics_Analytics_Model_Api_Exception_BadRequest $e) {
37
+ Mage::helper('analytics/account')->setIsVerified(0);
38
+ Mage::throwException(
39
+ "Verfication with VantageAnalytics.com failed! " .
40
+ "Re-enter the VantageAnalytics username and secret. "
41
+ );
42
+ }
43
+
44
+ return parent::save();
45
+ }
46
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/Signature.php ADDED
@@ -0,0 +1,25 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Signature
4
+ {
5
+ const HEADER = 'X-Vantage-Hmac-SHA256';
6
+
7
+ public function __construct($message, $secret)
8
+ {
9
+ $this->message = $message;
10
+ $this->secret = $secret;
11
+ }
12
+
13
+ public function sign()
14
+ {
15
+ return hash_hmac('sha256', $this->message, $this->secret);
16
+ }
17
+
18
+ public function signatureHeader()
19
+ {
20
+ $header = self::HEADER;
21
+ $signature = $this->sign();
22
+ return "{$header}: {$signature}";
23
+ }
24
+ }
25
+
app/code/community/VantageAnalytics/Analytics/Model/Api/Username.php ADDED
@@ -0,0 +1,13 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Username extends Mage_Core_Model_Config_Data
4
+ {
5
+ public function save()
6
+ {
7
+ $username = $this->getValue();
8
+ if (strlen($username) == 0) {
9
+ Mage::throwException("Your VantageAnalytics username is required");
10
+ }
11
+ return parent::save();
12
+ }
13
+ }
app/code/community/VantageAnalytics/Analytics/Model/Api/Webhook.php ADDED
@@ -0,0 +1,52 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Api_Webhook
4
+ {
5
+ public function __construct($resource, $method)
6
+ {
7
+ $this->resource = $resource;
8
+ $this->method = $method;
9
+ }
10
+
11
+ public static function factory($resource, $method)
12
+ {
13
+ return new self($resource, $method);
14
+ }
15
+
16
+ public function getPostData()
17
+ {
18
+ return array_merge($this->preamble(), $this->body());
19
+ }
20
+
21
+ public function preamble()
22
+ {
23
+ return array(
24
+ "webhook" => array(
25
+ "created" => $this->createdAt(),
26
+ "type" => $this->type()
27
+ ),
28
+ );
29
+ }
30
+
31
+ public function body()
32
+ {
33
+ return array("body" => $this->resource);
34
+ }
35
+
36
+ private function type()
37
+ {
38
+ return $this->_name() . "." . $this->method;
39
+ }
40
+
41
+ private function createdAt()
42
+ {
43
+ $date = gmdate('Y-m-d H:i:s');
44
+
45
+ return VantageAnalytics_Analytics_Helper_DateFormatter::factory($date)->toDate();
46
+ }
47
+
48
+ private function _name()
49
+ {
50
+ return array_key_exists('entity_type', $this->resource) ? $this->resource['entity_type'] : "object";
51
+ }
52
+ }
app/code/community/VantageAnalytics/Analytics/Model/Cron.php ADDED
@@ -0,0 +1,79 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Cron
4
+ {
5
+ public function __construct()
6
+ {
7
+ $this->lockfile = null;
8
+ }
9
+
10
+ protected function log($msg)
11
+ {
12
+ Mage::helper('analytics/log')->logInfo('Cron ' . $msg);
13
+ }
14
+
15
+ protected function jitter()
16
+ {
17
+ $seconds = rand(0, 5*60);
18
+ $this->log("Sleeping for {$seconds} seconds");
19
+ sleep($seconds);
20
+ }
21
+
22
+ protected function getCronLockfile()
23
+ {
24
+ if (is_null($this->lockfile)) {
25
+ $this->log('lock file opened');
26
+ $this->lockfile = fopen(Mage::getBaseDir('var').DS.'locks'.DS.'vantage_cron_lock', 'w');
27
+ }
28
+ return $this->lockfile;
29
+ }
30
+
31
+ public function acquireCronLock()
32
+ {
33
+ $this->log('attempting to acquire the lock');
34
+ $file = $this->getCronLockfile();
35
+ return flock($file, LOCK_EX | LOCK_NB);
36
+ }
37
+
38
+ public function releaseCronLock()
39
+ {
40
+ // Not strictly necessary because the process will close the handle on exit anyway
41
+ $this->log('lock file closed');
42
+ fclose($this->lockfile);
43
+ }
44
+
45
+ public function runHistoricalExport()
46
+ {
47
+ $export = Mage::getModel('analytics/Export_Runner');
48
+ $export->run();
49
+ }
50
+
51
+ protected function accountIsVerified()
52
+ {
53
+ return Mage::helper('analytics/account')->isVerified();
54
+ }
55
+
56
+ public function run()
57
+ {
58
+ $this->jitter();
59
+
60
+ if (!$this->acquireCronLock()) {
61
+ $this->log('lock not acquired - cron is already running');
62
+ return;
63
+ }
64
+
65
+ $this->runHistoricalExport();
66
+
67
+ if (!$this->accountIsVerified()) {
68
+ $this->log('account verification required or failed. Not running.');
69
+ return;
70
+ }
71
+
72
+ $this->log('processing the queue');
73
+ $queue = Mage::helper('analytics/queue');
74
+ $queue->processQueue();
75
+
76
+ $this->log('the queue is empty');
77
+ $this->releaseCronLock();
78
+ }
79
+ }
app/code/community/VantageAnalytics/Analytics/Model/Debug.php ADDED
@@ -0,0 +1,103 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Debug
4
+ {
5
+
6
+ public static function factory()
7
+ {
8
+ return new self();
9
+ }
10
+
11
+ // Makes it simpler to accept the
12
+ // debug information in the inbound-api
13
+ public function storeIds()
14
+ {
15
+ return array_values(Mage::app()->getWebsite()->getStoreIds());
16
+ }
17
+
18
+ public function entityType()
19
+ {
20
+ return 'heartbeat';
21
+ }
22
+
23
+ public function php()
24
+ {
25
+ return phpversion();
26
+ }
27
+
28
+ public function magentoVersion()
29
+ {
30
+ $version = Mage::getVersion();
31
+ $edition = Mage::getEdition();
32
+
33
+ return $version . "/" . $edition;
34
+ }
35
+
36
+ public function machine()
37
+ {
38
+ return php_uname();
39
+ }
40
+
41
+ public function installDate()
42
+ {
43
+ $config = Mage::app()->getConfig();
44
+
45
+ return VantageAnalytics_Analytics_Helper_DateFormatter::factory(
46
+ $config->getNode('global/install/date')
47
+ )->toDate();
48
+ }
49
+
50
+ public function stores()
51
+ {
52
+ $stores = array();
53
+
54
+ foreach (Mage::app()->getStores() as $store) {
55
+ $stores[$store->getId()] = $store->getCode();
56
+ }
57
+
58
+ return $stores;
59
+ }
60
+
61
+ public function websites()
62
+ {
63
+ $websites = array();
64
+
65
+ $sites = Mage::app()->getWebsites(true);
66
+
67
+ foreach($sites as $website) {
68
+ $websites[$website->getId()] = $website->getCode();
69
+ }
70
+
71
+
72
+ return $websites;
73
+ }
74
+
75
+ public function extensions()
76
+ {
77
+ return VantageAnalytics_Analytics_Helper_Extension_Lister::factory()->extensions();
78
+ }
79
+
80
+ public function verified()
81
+ {
82
+ return Mage::helper('analytics/account')->isVerified();
83
+ }
84
+
85
+ public function toVantage()
86
+ {
87
+ $methods = array_diff(
88
+ get_class_methods($this),
89
+ array('toVantage', '__construct', 'factory')
90
+ );
91
+
92
+ $data = array();
93
+
94
+ foreach ($methods as $method) {
95
+ $attr = strtolower(preg_replace(
96
+ '/(?<=\\w)(?=[A-Z])/',"_$1", $method));
97
+ $data[$attr] = call_user_func(array($this, $method));
98
+ }
99
+
100
+ return $data;
101
+ }
102
+
103
+ }
app/code/community/VantageAnalytics/Analytics/Model/Export/Base.php ADDED
@@ -0,0 +1,55 @@
1
+ <?php
2
+
3
+ abstract class VantageAnalytics_Analytics_Model_Export_Base
4
+ {
5
+ const PAGE_SIZE = 500;
6
+
7
+ abstract protected function createCollection($website);
8
+
9
+ public function __construct($pageSize = null, $api=null, $transformer='')
10
+ {
11
+ $this->transformer = $transformer;
12
+ $this->pageSize = !is_null($pageSize) ? $pageSize : self::PAGE_SIZE;
13
+ $this->api = (!is_null($api) ? $api :
14
+ new VantageAnalytics_Analytics_Model_Api_RequestQueue());
15
+ }
16
+
17
+ protected function makeTransformer($entity)
18
+ {
19
+ return Mage::getModel("analytics/Transformer_{$this->transformer}", $entity);
20
+ }
21
+
22
+ protected function enqueue($data)
23
+ {
24
+ $this->api->enqueue('create', $data);
25
+ }
26
+
27
+ protected function exportEntity($entity)
28
+ {
29
+ $transformer = $this->makeTransformer($entity);
30
+ $data = $transformer->toVantage();
31
+ $this->enqueue($data);
32
+ }
33
+
34
+ protected function exportWebsite($website)
35
+ {
36
+ $collection = $this->createCollection($website);
37
+ $totalPages = $collection->getLastPageNumber();
38
+ $currentPage = 1;
39
+ while ($currentPage <= $totalPages) {
40
+ foreach ($collection as $entity) {
41
+ $this->exportEntity($entity);
42
+ }
43
+ $currentPage++;
44
+ $collection->clear();
45
+ }
46
+ }
47
+
48
+ public function run()
49
+ {
50
+ $websites = Mage::app()->getWebsites();
51
+ foreach ($websites as $website) {
52
+ $this->exportWebsite($website);
53
+ }
54
+ }
55
+ }
app/code/community/VantageAnalytics/Analytics/Model/Export/Customer.php ADDED
@@ -0,0 +1,17 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Export_Customer extends VantageAnalytics_Analytics_Model_Export_Base
4
+ {
5
+ public function __construct($pageSize=null, $api=null)
6
+ {
7
+ parent::__construct($pageSize, $api, 'Customer');
8
+ }
9
+
10
+ protected function createCollection($website)
11
+ {
12
+ return Mage::getModel('customer/customer')->getCollection()
13
+ ->addAttributeToSelect('*')
14
+ ->addFieldToFilter('website_id', $website->getId())
15
+ ->setPageSize(self::PAGE_SIZE);
16
+ }
17
+ }
app/code/community/VantageAnalytics/Analytics/Model/Export/Order.php ADDED
@@ -0,0 +1,21 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Export_Order extends VantageAnalytics_Analytics_Model_Export_Base
4
+ {
5
+ public function __construct($pageSize=null, $api=null)
6
+ {
7
+ parent::__construct($pageSize, $api, 'SalesOrder');
8
+ }
9
+
10
+ protected function createCollection($website)
11
+ {
12
+ $filter = array();
13
+ foreach ($website->getStoreIds() as $storeId) {
14
+ $filter[] = array('eq', $storeId);
15
+ }
16
+ return Mage::getModel('sales/order')->getCollection()
17
+ ->addAttributeToSelect('*')
18
+ ->addFieldToFilter('store_id', $filter)
19
+ ->setPageSize($this->pageSize);
20
+ }
21
+ }
app/code/community/VantageAnalytics/Analytics/Model/Export/Product.php ADDED
@@ -0,0 +1,17 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Export_Product extends VantageAnalytics_Analytics_Model_Export_Base
4
+ {
5
+ public function __construct($pageSize=null, $api=null)
6
+ {
7
+ parent::__construct($pageSize, $api, 'Product');
8
+ }
9
+
10
+ protected function createCollection($website)
11
+ {
12
+ return Mage::getModel('catalog/product')->getCollection()
13
+ ->addWebsiteFilter($website->getId())
14
+ ->addAttributeToSelect('*');
15
+ }
16
+ }
17
+
app/code/community/VantageAnalytics/Analytics/Model/Export/Runner.php ADDED
@@ -0,0 +1,68 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Export_Runner
4
+ {
5
+
6
+
7
+ protected function enqueue($method, $resource)
8
+ {
9
+ $api = new VantageAnalytics_Analytics_Model_Api_RequestQueue();
10
+ $api->enqueue($method, $resource);
11
+ }
12
+
13
+ public function run()
14
+ {
15
+ if ($this->isExportDone()) {
16
+ return;
17
+ }
18
+
19
+ $this->notifyExportStart();
20
+ $this->setExportDone(); // Hope for the best
21
+
22
+ $entities = array('Store', 'Customer', 'Product', 'Order');
23
+ Mage::helper('analytics/log')->logInfo("Start exporting all entities");
24
+ foreach ($entities as $entity) {
25
+ $exporter = Mage::getModel('analytics/Export_' . $entity);
26
+ $exporter->run();
27
+ }
28
+
29
+ $this->notifyExportComplete();
30
+ Mage::helper('analytics/log')->logInfo("Done exporting all entities");
31
+ }
32
+
33
+ public function isExportDone()
34
+ {
35
+ return Mage::helper('analytics/account')->isExportDone();
36
+ }
37
+
38
+ public function setExportDone($done=1)
39
+ {
40
+ return Mage::helper('analytics/account')->setExportDone($done);
41
+ }
42
+
43
+ protected function websiteIds()
44
+ {
45
+ $websites = Mage::app()->getWebsites();
46
+ $websiteIds = array();
47
+ foreach ($websites as $website) {
48
+ $websiteIds[] = $website->getId();
49
+ }
50
+ return $websiteIds;
51
+ }
52
+
53
+ public function notifyExportStart()
54
+ {
55
+ foreach ($this->websiteIds() as $websiteId) {
56
+ $exportStarting = array('entity_type' => 'export', 'store_ids' => array($websiteId));
57
+ $this->enqueue('start', $exportStarting);
58
+ }
59
+ }
60
+
61
+ public function notifyExportComplete()
62
+ {
63
+ foreach ($this->websiteIds() as $websiteId) {
64
+ $exportComplete = array('entity_type' => 'export', 'store_ids' => array($websiteId));
65
+ $this->enqueue('complete', $exportComplete);
66
+ }
67
+ }
68
+ }
app/code/community/VantageAnalytics/Analytics/Model/Export/Store.php ADDED
@@ -0,0 +1,20 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Export_Store extends VantageAnalytics_Analytics_Model_Export_Base
4
+ {
5
+ public function __construct($pageSize=null, $api=null)
6
+ {
7
+ parent::__construct($pageSize, $api, 'Store');
8
+ }
9
+
10
+ protected function createCollection($website)
11
+ {
12
+ // stub out abstract function from base class
13
+ }
14
+
15
+ public function exportWebsite($website)
16
+ {
17
+ $this->exportEntity($website);
18
+ }
19
+ }
20
+
app/code/community/VantageAnalytics/Analytics/Model/Heartbeat.php ADDED
@@ -0,0 +1,16 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Heartbeat
4
+ {
5
+ public function __construct()
6
+ {
7
+ $this->api = new VantageAnalytics_Analytics_Model_Api_Request();
8
+ }
9
+
10
+ public function send()
11
+ {
12
+ $data = VantageAnalytics_Analytics_Model_Debug::factory()->toVantage();
13
+
14
+ $this->api->send('create', $data);
15
+ }
16
+ }
app/code/community/VantageAnalytics/Analytics/Model/Observer/Base.php ADDED
@@ -0,0 +1,47 @@
1
+ <?php
2
+ abstract class VantageAnalytics_Analytics_Model_Observer_Base
3
+ {
4
+ public function __construct($transformer='')
5
+ {
6
+ $this->api = new VantageAnalytics_Analytics_Model_Api_RequestQueue();
7
+ $this->transformer = $transformer;
8
+ }
9
+
10
+ // abstract protected function
11
+ abstract protected function getEntity($event);
12
+
13
+ protected function collectData($entity)
14
+ {
15
+ $transform = Mage::getModel("analytics/Transformer_{$this->transformer}", $entity);
16
+ return $transform->toVantage();
17
+ }
18
+
19
+ public function isAdmin()
20
+ {
21
+ return (Mage::app()->getStore()->isAdmin() ||
22
+ Mage::getDesign()->getArea() == 'adminhtml');
23
+ }
24
+
25
+ public function performSave($observer)
26
+ {
27
+ try {
28
+ $entity = $this->getEntity($observer->getEvent());
29
+ $data = $this->collectData($entity);
30
+ $this->api->enqueue('create', $data);
31
+ } catch (Exception $e) {
32
+ Mage::helper('analytics/log')->logException($e);
33
+ }
34
+ }
35
+
36
+ public function performDelete($observer)
37
+ {
38
+ try {
39
+ $entity = $this->getEntity($observer->getEvent());
40
+ $data = $this->collectData($entity);
41
+ $this->api->enqueue('delete', $data);
42
+ } catch (Exception $e) {
43
+ Mage::helper('analytics/log')->logException($e);
44
+ }
45
+ }
46
+
47
+ }
app/code/community/VantageAnalytics/Analytics/Model/Observer/CatalogProduct.php ADDED
@@ -0,0 +1,23 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_Observer_CatalogProduct extends VantageAnalytics_Analytics_Model_Observer_Base
3
+ {
4
+ public function __construct()
5
+ {
6
+ parent::__construct("Product");
7
+ }
8
+
9
+ protected function getEntity($event)
10
+ {
11
+ return $event->getProduct();
12
+ }
13
+
14
+ public function catalogProductSaveAfter($observer)
15
+ {
16
+ $this->performSave($observer);
17
+ }
18
+
19
+ public function catalogProductDeleteAfter($observer)
20
+ {
21
+ $this->performDelete($observer);
22
+ }
23
+ }
app/code/community/VantageAnalytics/Analytics/Model/Observer/Customer.php ADDED
@@ -0,0 +1,29 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_Observer_Customer extends VantageAnalytics_Analytics_Model_Observer_Base
3
+ {
4
+ public function __construct()
5
+ {
6
+ parent::__construct('Customer');
7
+ }
8
+
9
+ protected function getEntity($event)
10
+ {
11
+ return $event->getCustomer();
12
+ }
13
+
14
+ public function customerRegisterSuccess($observer)
15
+ {
16
+ $this->performSave($observer);
17
+ }
18
+
19
+ public function customerSaveAfter($observer)
20
+ {
21
+ $this->performSave($observer);
22
+ }
23
+
24
+ public function customerDeleteAfter($observer)
25
+ {
26
+ $this->performDelete($observer);
27
+ }
28
+ }
29
+
app/code/community/VantageAnalytics/Analytics/Model/Observer/SalesOrder.php ADDED
@@ -0,0 +1,43 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_Observer_SalesOrder extends VantageAnalytics_Analytics_Model_Observer_Base
3
+ {
4
+ public function __construct()
5
+ {
6
+ parent::__construct('SalesOrder');
7
+ }
8
+
9
+ protected function getEntity($event)
10
+ {
11
+ return $event->getOrder();
12
+ }
13
+
14
+ protected function collectData($entity)
15
+ {
16
+ $data = parent::collectData($entity);
17
+
18
+ // Collect cookies from real shoppers and not site admins.
19
+ if (!$this->isAdmin()) {
20
+ $tracking = Mage::helper('analytics/tracking')->getTrackingFromCookie();
21
+ if ($tracking) {
22
+ $data = array_merge($data, $tracking);
23
+ }
24
+ }
25
+
26
+ return $data;
27
+ }
28
+
29
+ public function salesOrderSaveAfter($observer)
30
+ {
31
+ $this->performSave($observer);
32
+ }
33
+
34
+ public function salesOrderPlaceAfter($observer)
35
+ {
36
+ $this->performSave($observer);
37
+ }
38
+
39
+ public function salesOrderDeleteAfter($observer)
40
+ {
41
+ $this->performDelete($observer);
42
+ }
43
+ }
app/code/community/VantageAnalytics/Analytics/Model/Observer/SalesQuote.php ADDED
@@ -0,0 +1,30 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_Observer_SalesQuote extends VantageAnalytics_Analytics_Model_Observer_Base
3
+ {
4
+ public function __construct()
5
+ {
6
+ parent::__construct('SalesQuote');
7
+ }
8
+
9
+ protected function getEntity($event)
10
+ {
11
+ return $event->getQuote();
12
+ }
13
+
14
+ protected function collectData($entity)
15
+ {
16
+ $data = parent::collectData($entity);
17
+ if (!$this->isAdmin()) { // Get cookies from real shoppers, not site admins
18
+ $tracking = Mage::helper('analytics/tracking')->getTrackingFromCookie();
19
+ if ($tracking) {
20
+ $data = array_merge($data, $tracking);
21
+ }
22
+ }
23
+ return $data;
24
+ }
25
+
26
+ public function salesQuoteSaveAfter($observer)
27
+ {
28
+ $this->performSave($observer);
29
+ }
30
+ }
app/code/community/VantageAnalytics/Analytics/Model/Observer/Tracking.php ADDED
@@ -0,0 +1,24 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Observer_Tracking
4
+ {
5
+ protected function isAdmin()
6
+ {
7
+ return (Mage::app()->getStore()->isAdmin() ||
8
+ Mage::getDesign()->getArea() == 'adminhtml');
9
+ }
10
+
11
+ public function controllerFrontInitBefore($observer)
12
+ {
13
+ try {
14
+ if ($this->isAdmin()) {
15
+ return;
16
+ }
17
+ $frontController = $observer->getEvent()->getFront();
18
+ $request = $frontController->getRequest();
19
+ Mage::helper('analytics/tracking')->setInitialCookie($request);
20
+ } catch (Exception $e) {
21
+ Mage::helper('analytics/log')->logException($e);
22
+ }
23
+ }
24
+ }
app/code/community/VantageAnalytics/Analytics/Model/ParentProduct.php ADDED
@@ -0,0 +1,70 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_ParentProduct
3
+ {
4
+ public static function factory($product)
5
+ {
6
+ return new self($product);
7
+ }
8
+
9
+ public function __construct($product)
10
+ {
11
+ $this->product = $product;
12
+ }
13
+
14
+ public function id()
15
+ {
16
+ // Configurable products do not have parent products
17
+ // hence, there's no ParentProduct->id()
18
+ if ($this->_configurableProduct($this->product)) {
19
+ return NULL;
20
+ }
21
+
22
+ $parentProduct = $this->parent();
23
+
24
+ return $parentProduct ? $parentProduct->getId() : NULL;
25
+ }
26
+
27
+ public function parent()
28
+ {
29
+ // A parent is the configurable product related to a simple product
30
+ // A simple product can have multiple parents
31
+ // Parents can be "grouped products" or "configurable products"
32
+ // Only one of those parents can be a "configurable product"
33
+ // An example of a grouped product "Buy a phone and a car charger"
34
+ $parents = $this->_parents();
35
+
36
+ foreach($parents as $parent)
37
+ {
38
+ if ($this->_configurableProduct($parent))
39
+ {
40
+ return $parent;
41
+ }
42
+ }
43
+
44
+ return NULL;
45
+ }
46
+
47
+ private function _parents()
48
+ {
49
+ $parents = array();
50
+
51
+ $parentIds = $this->_parentIds();
52
+
53
+ foreach($parentIds as $parentId) {
54
+ $parents[] = Mage::getModel('catalog/product')->load($parentId);
55
+ }
56
+
57
+ return $parents;
58
+ }
59
+
60
+ private function _parentIds()
61
+ {
62
+ return Mage::getModel('catalog/product_type_configurable')
63
+ ->getParentIdsByChild($this->product->getId());
64
+ }
65
+
66
+ private function _configurableProduct($product)
67
+ {
68
+ return ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE);
69
+ }
70
+ }
app/code/community/VantageAnalytics/Analytics/Model/ProductCategories.php ADDED
@@ -0,0 +1,37 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_ProductCategories
3
+ {
4
+ public static function factory($product)
5
+ {
6
+ return new self($product);
7
+ }
8
+
9
+ public function __construct($product)
10
+ {
11
+ $this->product = $product;
12
+ }
13
+
14
+ public function categories()
15
+ {
16
+ $categories = array();
17
+
18
+ foreach ($this->_categoryIds() as $catId) {
19
+ $categories[$catId] = $this->_getCategoryName($catId);
20
+ }
21
+
22
+ return $categories;
23
+ }
24
+
25
+ private function _categoryIds()
26
+ {
27
+ return $this->product->getCategoryIds();
28
+ }
29
+
30
+ private function _getCategoryName($categoryId)
31
+ {
32
+ $category = Mage::getModel('catalog/category')->load($categoryId);
33
+
34
+ return $category->getName();
35
+ }
36
+
37
+ }
app/code/community/VantageAnalytics/Analytics/Model/ProductImages.php ADDED
@@ -0,0 +1,44 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_ProductImages
3
+ {
4
+ public static function factory($product)
5
+ {
6
+ return new self($product);
7
+ }
8
+
9
+ public function __construct($product)
10
+ {
11
+ $this->product = $product;
12
+ $this->config = $product->getMediaConfig();
13
+ }
14
+
15
+ public function urls()
16
+ {
17
+ return array(
18
+ "base" => $this->_imageUrl($this->_baseImage()),
19
+ "small" => $this->_imageUrl($this->_smallImage()),
20
+ "thumbnail" => $this->_imageUrl($this->_thumbnail())
21
+ );
22
+ }
23
+
24
+ private function _imageUrl($image)
25
+ {
26
+ return $image ? $this->config->getMediaUrl($image) : NULL;
27
+ }
28
+
29
+ private function _baseImage()
30
+ {
31
+ return $this->product->getImage();
32
+ }
33
+
34
+ private function _smallImage()
35
+ {
36
+ return $this->product->getSmallImage();
37
+ }
38
+
39
+ private function _thumbnail()
40
+ {
41
+ return $this->product->getThumbnail();
42
+ }
43
+
44
+ }
app/code/community/VantageAnalytics/Analytics/Model/ProductOptions.php ADDED
@@ -0,0 +1,50 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_ProductOptions
3
+ {
4
+ public static function factory($lineItem)
5
+ {
6
+ return new self($lineItem);
7
+ }
8
+
9
+ public function __construct($lineItem)
10
+ {
11
+ $this->lineItem = $lineItem;
12
+ $this->product = $this->lineItem->getProduct();
13
+ }
14
+
15
+ public function _configurableProduct()
16
+ {
17
+ $type = $this->product->getTypeID();
18
+ return ($type == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE);
19
+ }
20
+
21
+ public function options()
22
+ {
23
+ // Only configurable products have options
24
+ // If we dont have product options, send NULL
25
+ // PHP converts empty dictionaries to arrays
26
+ // and with forceObject set, it breaks other things
27
+ if (!$this->_configurableProduct()) {
28
+ return NULL;
29
+ }
30
+
31
+ $attributes = $this->_attributes();
32
+ $options = array();
33
+ foreach ($attributes as $option) {
34
+ $options += $this->_buildSelection($option);
35
+ }
36
+
37
+ return empty($options) ? NULL : $options;
38
+ }
39
+
40
+ private function _attributes() {
41
+ $attributes = $this->lineItem->getProductOptions();
42
+ return $attributes['attributes_info'];
43
+ }
44
+
45
+ private function _buildSelection($option) {
46
+ $values = array_map("strtolower", array_values($option));
47
+ return array($values[0] => $values[1]);
48
+ }
49
+
50
+ }
app/code/community/VantageAnalytics/Analytics/Model/Queue/Adapter/Db.php ADDED
@@ -0,0 +1,19 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Queue_Adapter_Db extends Zend_Queue_Adapter_Db
4
+ {
5
+ public function __construct($options, Zend_Queue $queue = null)
6
+ {
7
+ parent::__construct($options, $queue);
8
+ if (isset($options['queueTableName'])) {
9
+ $this->_queueTable->setOptions(
10
+ array(Zend_Db_Table_Abstract::NAME => $options['queueTableName'])
11
+ );
12
+ }
13
+ if (isset($options['messageTableName'])) {
14
+ $this->_messageTable->setOptions(
15
+ array(Zend_Db_Table_Abstract::NAME => $options['messageTableName'])
16
+ );
17
+ }
18
+ }
19
+ }
app/code/community/VantageAnalytics/Analytics/Model/Resource/Mysql4/Setup.php ADDED
@@ -0,0 +1,9 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Resource_Mysql4_Setup extends Mage_Core_Model_Resource_Setup
4
+ {
5
+ public function resetConfig()
6
+ {
7
+ Mage::helper('analytics/account')->setIsVerified(0);
8
+ }
9
+ }
app/code/community/VantageAnalytics/Analytics/Model/SubscriberInformation.php ADDED
@@ -0,0 +1,42 @@
1
+ <?php
2
+ class VantageAnalytics_Analytics_Model_SubscriberInformation
3
+ {
4
+ public static function factory($email)
5
+ {
6
+ return new self($email);
7
+ }
8
+
9
+ public function __construct($email)
10
+ {
11
+ $this->email = $email;
12
+ }
13
+
14
+ private function _subscribedStatus()
15
+ {
16
+ // http://docs.magentocommerce.com/Mage_Newsletter/Mage_Newsletter_Model_Subscriber.html
17
+ // STATUS_NOT_ACTIVE = 2
18
+ // STATUS_SUBSCRIBED = 1
19
+ // STATUS_UNCONFIRMED = 4
20
+ // STATUS_UNSUBSCRIBED = 3
21
+
22
+ return 1;
23
+ }
24
+
25
+ public function subscriber()
26
+ {
27
+ return Mage::getModel('newsletter/subscriber')
28
+ ->loadByEmail($this->email);
29
+ }
30
+
31
+ public function status()
32
+ {
33
+ return $this->subscriber()->getStatus();
34
+
35
+ }
36
+
37
+ public function acceptsMarketing()
38
+ {
39
+ return $this->status() == $this->_subscribedStatus();
40
+ }
41
+
42
+ }
app/code/community/VantageAnalytics/Analytics/Model/Transformer/Address.php ADDED
@@ -0,0 +1,122 @@
1
+ <?php
2
+
3
+ class VantageAnalytics_Analytics_Model_Transformer_Address
4
+ {
5
+ public function __construct($magentoAddress, $addressType='')
6
+ {
7
+ $this->address = $magentoAddress;
8
+ $this->addressType = $addressType;
9
+ }
10
+
11
+ public static function factory($magentoAddress, $addressType='')
12
+ {
13
+ return new self($magentoAddress, $addressType);
14
+ }
15
+
16
+ public function externalIdentifier()
17
+ {
18
+ return $this->address->getId();
19
+ }
20
+
21
+ public function addressLine1()
22
+ {
23
+ return $this->address ? $this->address->getStreet1() : '';
24
+ }
25
+
26
+ public function addressLine2()
27
+ {
28
+ return $this->address ? $this->address->getStreet2() : '';
29
+ }
30
+
31
+ public function city()
32
+ {
33
+ return $this->address ? $this->address->getCity() : '';
34
+ }
35
+
36
+ public function province()
37
+ {
38
+ // Note to self, get region returns the name
39
+ // when called on a customer/address model.
40
+ return $this->address ? $this->address->getRegion() : '';
41
+ }
42
+
43
+ public function provinceCode()
44
+ {
45
+ return $this->address ? $this->address->getRegionCode() : '';
46
+ }
47
+
48
+ protected function countryModel()
49
+ {
50
+ if($this->address) {
51
+ return $this->address->getCountryModel();
52
+ }
53
+
54
+ return '';
55
+ }
56
+
57
+ public function country()
58
+ {
59
+ if($this->address) {
60
+ return $this->countryModel()->getName();
61
+ }
62
+
63
+ return '';
64
+
65
+ }
66
+
67
+ public function countryCode()
68
+ {
69
+ if($this->address) {
70
+ return $this->countryModel()->getCountryId();
71
+ }
72
+
73
+ return '';
74
+ }
75
+
76
+ public function telephone()
77
+ {
78
+ return $this->address ? $this->address->getTelephone() :'';
79
+ }
80
+
81
+ public function postalCode()
82
+ {
83
+ return $this->address ? $this->address->getPostcode() : '';
84
+ }
85
+
86
+ public function company()
87
+ {
88
+ return $this->address ? $this->address->getCompany() : '';
89
+ }
90
+
91
+ public function type()
92
+ {
93
+ return $this->addressType;
94
+ }
95
+
96
+ public function entityType()
97
+ {
98
+ return "address";
99
+ }
100
+
101
+ public function toVantage()
102
+ {
103
+ $prefix = '';
104
+ if ($this->type()) {
105
+ $prefix = $this->type() . "_";
106
+ }
107
+
108
+ $data = array(
109
+ "{$prefix}address_line_1" => $this->addressLine1(),
110
+ "{$prefix}address_line_2" => $this->addressLine2(),
111
+ "{$prefix}city" => $this->city(),
112
+ "{$prefix}province" => $this->province(),
113
+ "{$prefix}country" => $this->country(),
114
+ "{$prefix}postal_code" => $this->postalCode(),
115
+ "{$prefix}province_code" => $this->provinceCode(),
116
+ "{$prefix}country_code" => $this->countryCode(),
117
+ "{$prefix}company" => $this->company(),
118
+ );
119
+
120
+ return $data;
121
+ }
122
+ }
app/code/community/VantageAnalytics/Analytics/Model/Transformer/Base.php ADDED
@@ -0,0 +1,44 @@
1
+ <?php
2
+
3
+ abstract class VantageAnalytics_Analytics_Model_Transformer_Base
4
+ {
5
+ /* Magento returns the "created_at" in the store's
6
+ * timezone thus, it needs to be converted to UTC.
7
+ * 'updated_at' is already in UTC, and does not
8
+ * require conversion. Neither are formatted correctly.
9
+ */
10
+ public function __construct($magentoEntity)
11
+ {
12
+ $this->entity = $magentoEntity;
13
+ $this->data = $this->entity->getData();
14
+ }
15
+
16
+ public function sourceCreatedAt()
17
+ {
18
+ $name = 'created_at';
19
+
20
+ if (isset($this->data[$name])) {
21
+ return VantageAnalytics_Analytics_Helper_DateFormatter::factory(
22
+ $this->data[$name]
23