Version Notes
All required page templates and layout files are located in the default theme directory (app/design/frontend/base/default). You will need to copy these files into your site's installed theme directory to install this module. See installation instructions for more details.
Download this release
Release Info
Developer | Joe Mancini |
Extension | AgilOne_Recommendations_CE |
Version | 1.0.0.0 |
Comparing to | |
See all releases |
Version 1.0.0.0
- app/code/community/AgilOne/Recommendations/Block/Catalog/Product/List/Upsell.php +77 -0
- app/code/community/AgilOne/Recommendations/Block/Catalog/Product/List/Upsell/Item.php +31 -0
- app/code/community/AgilOne/Recommendations/Block/Iframe.php +18 -0
- app/code/community/AgilOne/Recommendations/Block/Webtag.php +113 -0
- app/code/community/AgilOne/Recommendations/Block/Widget/U2p.php +16 -0
- app/code/community/AgilOne/Recommendations/Block/Widget/U2p/Items.php +74 -0
- app/code/community/AgilOne/Recommendations/Block/Widget/U2p/Items/Item.php +38 -0
- app/code/community/AgilOne/Recommendations/Helper/Data.php +16 -0
- app/code/community/AgilOne/Recommendations/Model/Abstract.php +316 -0
- app/code/community/AgilOne/Recommendations/Model/Adminhtml/System/Config/Source/Brand.php +32 -0
- app/code/community/AgilOne/Recommendations/Model/Adminhtml/System/Config/Source/Log.php +28 -0
- app/code/community/AgilOne/Recommendations/Model/Feed.php +225 -0
- app/code/community/AgilOne/Recommendations/Model/Observer.php +37 -0
- app/code/community/AgilOne/Recommendations/Model/Webtag.php +132 -0
- app/code/community/AgilOne/Recommendations/controllers/AjaxController.php +23 -0
- app/code/community/AgilOne/Recommendations/etc/adminhtml.xml +23 -0
- app/code/community/AgilOne/Recommendations/etc/config.xml +125 -0
- app/code/community/AgilOne/Recommendations/etc/system.xml +204 -0
- app/code/community/AgilOne/Recommendations/etc/widget.xml +7 -0
- app/design/frontend/base/default/layout/recommendations.xml +30 -0
- app/design/frontend/base/default/template/recommendations/catalog/product/list/upsell.phtml +24 -0
- app/design/frontend/base/default/template/recommendations/catalog/product/list/upsell/item.phtml +14 -0
- app/design/frontend/base/default/template/recommendations/iframe.phtml +10 -0
- app/design/frontend/base/default/template/recommendations/webtag.phtml +53 -0
- app/design/frontend/base/default/template/recommendations/widget/u2p/items.phtml +23 -0
- app/design/frontend/base/default/template/recommendations/widget/u2p/items/item.phtml +13 -0
- app/etc/modules/AgilOne_Recommendations.xml +17 -0
- app/locale/en_US/AgileOne_Recommendations.csv +0 -0
- package.xml +33 -0
- skin/frontend/base/default/css/recommendations.css +21 -0
app/code/community/AgilOne/Recommendations/Block/Catalog/Product/List/Upsell.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category AgilOne
|
4 |
+
* @package AgilOne_Recommendations
|
5 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
6 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class AgilOne_Recommendations_Block_Catalog_Product_List_Upsell extends Mage_Catalog_Block_Product_Abstract
|
10 |
+
{
|
11 |
+
|
12 |
+
protected $_items = null;
|
13 |
+
|
14 |
+
protected $_title = null;
|
15 |
+
|
16 |
+
protected $_columnCount = null;
|
17 |
+
|
18 |
+
protected function _construct()
|
19 |
+
{
|
20 |
+
parent::_construct();
|
21 |
+
|
22 |
+
$this->setTemplate('recommendations/catalog/product/list/upsell.phtml');
|
23 |
+
|
24 |
+
if (!$this->_items = Mage::getModel('recommendations/feed')->getP2PItems($this->getProduct()->getId())) {
|
25 |
+
$this->_items = new Varien_Data_Collection();
|
26 |
+
}
|
27 |
+
|
28 |
+
$this->_title = Mage::getStoreConfig('agilone/pdp/title');
|
29 |
+
|
30 |
+
$this->_columnCount = Mage::getStoreConfig('agilone/pdp/limit');
|
31 |
+
|
32 |
+
$product = Mage::registry('product');
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getTitle()
|
36 |
+
{
|
37 |
+
return $this->__($this->_title);
|
38 |
+
}
|
39 |
+
|
40 |
+
public function hasItems()
|
41 |
+
{
|
42 |
+
return $this->getItemsCount() > 0;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function getItems()
|
46 |
+
{
|
47 |
+
return $this->getItemCollection();
|
48 |
+
}
|
49 |
+
|
50 |
+
public function getItemCollection()
|
51 |
+
{
|
52 |
+
return $this->_items;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function getItemsCount()
|
56 |
+
{
|
57 |
+
return count($this->getItemCollection());
|
58 |
+
}
|
59 |
+
|
60 |
+
public function getRowCount()
|
61 |
+
{
|
62 |
+
return ceil($this->getItemsCount()/$this->getColumnCount());
|
63 |
+
}
|
64 |
+
|
65 |
+
public function setColumnCount($columns)
|
66 |
+
{
|
67 |
+
if (intval($columns) > 0) {
|
68 |
+
$this->_columnCount = intval($columns);
|
69 |
+
}
|
70 |
+
return $this;
|
71 |
+
}
|
72 |
+
|
73 |
+
public function getColumnCount()
|
74 |
+
{
|
75 |
+
return $this->_columnCount;
|
76 |
+
}
|
77 |
+
}
|
app/code/community/AgilOne/Recommendations/Block/Catalog/Product/List/Upsell/Item.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category AgilOne
|
4 |
+
* @package AgilOne_Recommendations
|
5 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
6 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class AgilOne_Recommendations_Block_Catalog_Product_List_Upsell_Item extends Mage_Catalog_Block_Product_Abstract
|
10 |
+
{
|
11 |
+
protected $_item = null;
|
12 |
+
|
13 |
+
protected $_position = null;
|
14 |
+
|
15 |
+
public function getItem()
|
16 |
+
{
|
17 |
+
return $this->_item;
|
18 |
+
}
|
19 |
+
|
20 |
+
public function setItem($item)
|
21 |
+
{
|
22 |
+
$this->_item = $item;
|
23 |
+
return $this;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function setPosition($position)
|
27 |
+
{
|
28 |
+
$this->_position = $position;
|
29 |
+
return $this;
|
30 |
+
}
|
31 |
+
}
|
app/code/community/AgilOne/Recommendations/Block/Iframe.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Iframe Block
|
4 |
+
*
|
5 |
+
* @category AgilOne
|
6 |
+
* @package AgilOne_Recommendations
|
7 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
8 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
9 |
+
*/
|
10 |
+
|
11 |
+
class AgilOne_Recommendations_Block_Iframe extends Mage_Core_Block_Template
|
12 |
+
{
|
13 |
+
|
14 |
+
protected function _getUrl()
|
15 |
+
{
|
16 |
+
return Mage::getUrl('recommendations/ajax/webtag',array('_secure'=> Mage::app()->getStore()->isCurrentlySecure()));
|
17 |
+
}
|
18 |
+
}
|
app/code/community/AgilOne/Recommendations/Block/Webtag.php
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WebTab Block: Provides data for a1as.push javascript variables
|
4 |
+
*
|
5 |
+
* var _a1as = _a1as || [];
|
6 |
+
* _a1as.push(["init","1234567"]);
|
7 |
+
* _a1as.push(["setvar","userid","142"]);
|
8 |
+
* _a1as.push(["setvar","email","rloerzel@lyonscg.com"]);
|
9 |
+
* _a1as.push(["track"]);
|
10 |
+
*
|
11 |
+
* @category AgilOne
|
12 |
+
* @package AgilOne_Recommendations
|
13 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
14 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
15 |
+
*/
|
16 |
+
|
17 |
+
class AgilOne_Recommendations_Block_Webtag extends Mage_Core_Block_Template
|
18 |
+
{
|
19 |
+
|
20 |
+
protected $_webtagModel;
|
21 |
+
|
22 |
+
|
23 |
+
|
24 |
+
protected function _construct()
|
25 |
+
{
|
26 |
+
parent::_construct();
|
27 |
+
|
28 |
+
$this->_webtagModel = Mage::getModel('recommendations/webtag');
|
29 |
+
|
30 |
+
}
|
31 |
+
|
32 |
+
public function isEnabled()
|
33 |
+
{
|
34 |
+
return $this->_webtagModel->isEnabled();
|
35 |
+
}
|
36 |
+
|
37 |
+
public function getHandle()
|
38 |
+
{
|
39 |
+
return $this->_webtagModel->getHandle();
|
40 |
+
}
|
41 |
+
/**
|
42 |
+
* Get Website's WebTagId
|
43 |
+
*@return string|boolean
|
44 |
+
*/
|
45 |
+
public function getWebTagId()
|
46 |
+
{
|
47 |
+
return $this->_webtagModel->getWebTagId();
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Get Logged-In User's Magento ID
|
52 |
+
* @return string
|
53 |
+
*/
|
54 |
+
public function getUserId()
|
55 |
+
{
|
56 |
+
return $this->_webtagModel->getUserId();
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Get Logged-In User's Email Address
|
61 |
+
* @return string|boolean
|
62 |
+
*/
|
63 |
+
public function getEmail()
|
64 |
+
{
|
65 |
+
return $this->_webtagModel->getEmail();
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Get SKU and brand of product viewed
|
70 |
+
* @return string|boolean
|
71 |
+
*/
|
72 |
+
public function getProductView()
|
73 |
+
{
|
74 |
+
return $this->_webtagModel->getProductView();
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Get URL-Key of category viewed
|
79 |
+
* @return string|boolean
|
80 |
+
*/
|
81 |
+
public function getCategoryIdView()
|
82 |
+
{
|
83 |
+
return $this->_webtagModel->getCategoryIdView();
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Get contents of cart if item is added or removed
|
88 |
+
* @return string|boolean
|
89 |
+
*/
|
90 |
+
public function getProductIdCart()
|
91 |
+
{
|
92 |
+
return $this->_webtagModel->getProductIdCart();
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Get order information on success page
|
97 |
+
* @return Varien_Object|boolean
|
98 |
+
*/
|
99 |
+
public function getOrder()
|
100 |
+
{
|
101 |
+
return $this->_webtagModel->getOrder();
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Get search keywords
|
106 |
+
* @return string|boolean
|
107 |
+
*/
|
108 |
+
public function getOnsiteSearch()
|
109 |
+
{
|
110 |
+
return $this->_webtagModel->getOnsiteSearch();
|
111 |
+
}
|
112 |
+
|
113 |
+
}
|
app/code/community/AgilOne/Recommendations/Block/Widget/U2p.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category AgilOne
|
4 |
+
* @package AgilOne_Recommendations
|
5 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
6 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class AgilOne_Recommendations_Block_Widget_U2p extends Mage_Core_Block_Template implements Mage_Widget_Block_Interface
|
10 |
+
{
|
11 |
+
|
12 |
+
protected function _toHtml()
|
13 |
+
{
|
14 |
+
return $this->getLayout()->createBlock('recommendations/widget_u2p_items')->toHtml();
|
15 |
+
}
|
16 |
+
}
|
app/code/community/AgilOne/Recommendations/Block/Widget/U2p/Items.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category AgilOne
|
4 |
+
* @package AgilOne_Recommendations
|
5 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
6 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class AgilOne_Recommendations_Block_Widget_U2p_Items extends Mage_Core_Block_Template
|
10 |
+
{
|
11 |
+
protected $_items = null;
|
12 |
+
|
13 |
+
protected $_title = null;
|
14 |
+
|
15 |
+
protected $_columnCount = null;
|
16 |
+
|
17 |
+
protected function _construct()
|
18 |
+
{
|
19 |
+
parent::_construct();
|
20 |
+
|
21 |
+
$this->setLayout(Mage::getModel('core/layout'));
|
22 |
+
|
23 |
+
$this->setTemplate('recommendations/widget/u2p/items.phtml');
|
24 |
+
|
25 |
+
$this->setChild('widget.u2p.item',$this->getLayout()->createBlock('recommendations/widget_u2p_items_item'));
|
26 |
+
|
27 |
+
if (!$this->_items = Mage::getModel('recommendations/feed')->getU2PItems()) {
|
28 |
+
$this->_items = new Varien_Data_Collection();
|
29 |
+
}
|
30 |
+
|
31 |
+
$this->_title = Mage::getStoreConfig('agilone/widget/title');
|
32 |
+
|
33 |
+
$this->_columnCount = Mage::getStoreConfig('agilone/widget/limit');
|
34 |
+
}
|
35 |
+
|
36 |
+
public function getTitle()
|
37 |
+
{
|
38 |
+
return $this->__($this->_title);
|
39 |
+
}
|
40 |
+
|
41 |
+
public function hasItems()
|
42 |
+
{
|
43 |
+
return $this->getItemsCount() > 0;
|
44 |
+
}
|
45 |
+
|
46 |
+
public function getItemCollection()
|
47 |
+
{
|
48 |
+
return $this->_items;
|
49 |
+
}
|
50 |
+
|
51 |
+
public function getItemsCount()
|
52 |
+
{
|
53 |
+
return count($this->getItemCollection());
|
54 |
+
}
|
55 |
+
|
56 |
+
public function getRowCount()
|
57 |
+
{
|
58 |
+
return ceil($this->getItemsCount()/$this->getColumnCount());
|
59 |
+
}
|
60 |
+
|
61 |
+
public function setColumnCount($columns)
|
62 |
+
{
|
63 |
+
if (intval($columns) > 0) {
|
64 |
+
$this->_columnCount = intval($columns);
|
65 |
+
}
|
66 |
+
return $this;
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getColumnCount()
|
70 |
+
{
|
71 |
+
return $this->_columnCount;
|
72 |
+
}
|
73 |
+
|
74 |
+
}
|
app/code/community/AgilOne/Recommendations/Block/Widget/U2p/Items/Item.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category AgilOne
|
4 |
+
* @package AgilOne_Recommendations
|
5 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
6 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class AgilOne_Recommendations_Block_Widget_U2p_Items_Item extends Mage_Catalog_Block_Product_Abstract
|
10 |
+
{
|
11 |
+
protected $_item = null;
|
12 |
+
|
13 |
+
protected $_position = null;
|
14 |
+
|
15 |
+
protected function _construct()
|
16 |
+
{
|
17 |
+
parent::_construct();
|
18 |
+
|
19 |
+
$this->setTemplate('recommendations/widget/u2p/items/item.phtml');
|
20 |
+
}
|
21 |
+
|
22 |
+
public function getItem()
|
23 |
+
{
|
24 |
+
return $this->_item;
|
25 |
+
}
|
26 |
+
|
27 |
+
public function setItem($item)
|
28 |
+
{
|
29 |
+
$this->_item = $item;
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function setPosition($position)
|
34 |
+
{
|
35 |
+
$this->_position = $position;
|
36 |
+
return $this;
|
37 |
+
}
|
38 |
+
}
|
app/code/community/AgilOne/Recommendations/Helper/Data.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category AgilOne
|
4 |
+
* @package AgilOne_Recommendations
|
5 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
6 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class AgilOne_Recommendations_Helper_Data extends Mage_Core_Helper_Abstract
|
10 |
+
{
|
11 |
+
const LOG_LEVEL_NONE = 0;
|
12 |
+
|
13 |
+
const LOG_LEVEL_ERRORS = 1;
|
14 |
+
|
15 |
+
const LOG_LEVEL_ALL = 2;
|
16 |
+
}
|
app/code/community/AgilOne/Recommendations/Model/Abstract.php
ADDED
@@ -0,0 +1,316 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Abstract Model
|
4 |
+
*
|
5 |
+
* @category AgilOne
|
6 |
+
* @package AgilOne_Recommendations
|
7 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
8 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
9 |
+
*
|
10 |
+
* https://agilone.zendesk.com/hc/en-us/articles/201534597-OpenAPI-Recommendations
|
11 |
+
*/
|
12 |
+
|
13 |
+
abstract class AgilOne_Recommendations_Model_Abstract extends Mage_Core_Model_Abstract
|
14 |
+
{
|
15 |
+
/**
|
16 |
+
* @var string $_storeId
|
17 |
+
*
|
18 |
+
* Id of current active store
|
19 |
+
*/
|
20 |
+
protected $_storeId = null;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var Mage_Core_Model_Store $_store
|
24 |
+
*
|
25 |
+
* Current active store object
|
26 |
+
*/
|
27 |
+
protected $_store = null;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var boolean $_isEnabled
|
31 |
+
*
|
32 |
+
* Is module enabled?
|
33 |
+
*/
|
34 |
+
protected $_isEnabled = null;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var Mage_Checkout_Model_Session $_checkoutSession
|
38 |
+
*
|
39 |
+
* Checkout session singleton object
|
40 |
+
*/
|
41 |
+
protected $_checkoutSession = null;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @var Mage_Customer_Model_Session $_customerSession
|
45 |
+
*
|
46 |
+
* Customer session singleton object
|
47 |
+
*/
|
48 |
+
protected $_customerSession = null;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @var string $_sourceId
|
52 |
+
*
|
53 |
+
* The SourceID is an ID specific to your data sources. You may have several of them if
|
54 |
+
* AgilOne manage different customer or product databases for you. The {sourceid} parameter
|
55 |
+
* makes sure that the {customerkey} or {productkey} you're supplying is unique.
|
56 |
+
*/
|
57 |
+
protected $_sourceId = null;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @var string $_tenantId
|
61 |
+
*
|
62 |
+
* The TenantID is an ID specific to your workspace. If on app.agilone.com, you only have
|
63 |
+
* access to one workspace (the most common case) the tenant value is optional in API calls.
|
64 |
+
*/
|
65 |
+
protected $_tenantId = null;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @var string $_webtagId
|
69 |
+
*
|
70 |
+
* ID provided with AgilOne WebTag account
|
71 |
+
*/
|
72 |
+
protected $_webtagId = null;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @var string $_brandAttribute
|
76 |
+
*
|
77 |
+
* Magento product attribute to represent the AgilOne 'brand' attribute in API calls
|
78 |
+
*/
|
79 |
+
protected $_brandAttribute = null;
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @var string $_logLevel
|
83 |
+
*
|
84 |
+
* Debug Logging Level
|
85 |
+
*
|
86 |
+
* 0: None
|
87 |
+
* 1: Errors Only
|
88 |
+
* 2: All Traffic
|
89 |
+
*/
|
90 |
+
protected $_logLevel = null;
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @var string $_baseUrl
|
94 |
+
*
|
95 |
+
* Base AgilOne API URL (i.e. "api.agilone.com")
|
96 |
+
*/
|
97 |
+
protected $_baseUrl = null;
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @var string $_handle
|
101 |
+
*
|
102 |
+
* Layout Handle Identifier (i.e. "catalog_product_view")
|
103 |
+
*/
|
104 |
+
protected $_handle = null;
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @var string $_action
|
108 |
+
*
|
109 |
+
* Controller action
|
110 |
+
*/
|
111 |
+
protected $_action = null;
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @var string $_userId
|
115 |
+
*
|
116 |
+
* Logged-in customer user id
|
117 |
+
*/
|
118 |
+
protected $_userId = null;
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @var string $_email
|
122 |
+
*
|
123 |
+
* Logged-in customer user email address
|
124 |
+
*/
|
125 |
+
protected $_email = null;
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Constructor. Set variables.
|
129 |
+
*/
|
130 |
+
protected function _construct()
|
131 |
+
{
|
132 |
+
parent::_construct();
|
133 |
+
|
134 |
+
try {
|
135 |
+
$this->_storeId = Mage::app()->getStore()->getId();
|
136 |
+
|
137 |
+
$this->_store = $store = Mage::app()->getStore();
|
138 |
+
|
139 |
+
$this->_checkoutSession = Mage::getSingleton('checkout/session');
|
140 |
+
|
141 |
+
$this->_customerSession = Mage::getSingleton('customer/session');
|
142 |
+
|
143 |
+
$this->_isEnabled = Mage::getStoreConfig('agilone/general/enabled',$this->_storeId);
|
144 |
+
|
145 |
+
$this->_sourceId = Mage::getStoreConfig('agilone/general/source_id',$this->_storeId);
|
146 |
+
|
147 |
+
$this->_tenantId = Mage::getStoreConfig('agilone/general/tenant_id',$this->_storeId);
|
148 |
+
|
149 |
+
$this->_webtagId = Mage::getStoreConfig('agilone/general/webtag_id',$this->_storeId);
|
150 |
+
|
151 |
+
$this->_brandAttribute = Mage::getStoreConfig('agilone/general/brand_attribute',$this->_storeId);
|
152 |
+
|
153 |
+
$this->_logLevel = Mage::getStoreConfig('agilone/general/log_level',$this->_storeId);
|
154 |
+
|
155 |
+
if (Mage::getStoreConfig('agilone/general/force_https',$this->_storeId)) {
|
156 |
+
$protocol = 'https';
|
157 |
+
} else {
|
158 |
+
$protocol = 'http';
|
159 |
+
}
|
160 |
+
|
161 |
+
$this->_baseUrl = $protocol . '://' . Mage::getStoreConfig('agilone/general/base_url',$this->_storeId);
|
162 |
+
|
163 |
+
$req = Mage::app()->getRequest();
|
164 |
+
|
165 |
+
$this->_handle = $req->getRequestedRouteName() . '_' . $req->getRequestedControllerName() . '_' . $req->getRequestedActionName();
|
166 |
+
|
167 |
+
$this->_action = $req->getRequestedActionName();
|
168 |
+
|
169 |
+
if($this->_customerSession->isLoggedIn()){
|
170 |
+
$customer = $this->_customerSession->getCustomer();
|
171 |
+
$this->_userId = $customer->getId();
|
172 |
+
$this->_email = $customer->getEmail();
|
173 |
+
} else {
|
174 |
+
$this->_userId = null;
|
175 |
+
$this->_email = $this->_checkoutSession->getQuote()->getCustomerEmail();
|
176 |
+
}
|
177 |
+
|
178 |
+
} catch (Exception $e) {
|
179 |
+
Mage::logException($e);
|
180 |
+
}
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Is module enabled?
|
185 |
+
*
|
186 |
+
* @return boolean
|
187 |
+
*/
|
188 |
+
public function isEnabled()
|
189 |
+
{
|
190 |
+
return (boolean) $this->_isEnabled;
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Get A1 Api Key
|
195 |
+
*
|
196 |
+
*@return string
|
197 |
+
*/
|
198 |
+
protected function _getApiKey()
|
199 |
+
{
|
200 |
+
return $this->_apiKey;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Get A1 Api Secret Key
|
205 |
+
*
|
206 |
+
*@return string
|
207 |
+
*/
|
208 |
+
protected function _getApiSecret()
|
209 |
+
{
|
210 |
+
return $this->_apiSecret;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Get layout handle for current page
|
215 |
+
*
|
216 |
+
* @return string
|
217 |
+
*/
|
218 |
+
public function getHandle()
|
219 |
+
{
|
220 |
+
return $this->_handle;
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Get Website's WebTagId
|
225 |
+
*
|
226 |
+
*@return string|boolean
|
227 |
+
*/
|
228 |
+
public function getWebTagId()
|
229 |
+
{
|
230 |
+
return $this->_webtagId;
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Get Logged-In User's Magento ID
|
235 |
+
*
|
236 |
+
* @return string
|
237 |
+
*/
|
238 |
+
public function getUserId()
|
239 |
+
{
|
240 |
+
return $this->_userId;
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Get Logged-In User's Email Address
|
245 |
+
*
|
246 |
+
* @return string|boolean
|
247 |
+
*/
|
248 |
+
public function getEmail()
|
249 |
+
{
|
250 |
+
return $this->_email;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Get product viewed
|
255 |
+
*
|
256 |
+
* @return string|boolean
|
257 |
+
*/
|
258 |
+
public function getProduct()
|
259 |
+
{
|
260 |
+
try {
|
261 |
+
if ($this->_handle === 'catalog_product_view') {
|
262 |
+
if ($productId = Mage::registry('current_product')->getId()) {
|
263 |
+
return Mage::getModel('catalog/product')->load($productId);
|
264 |
+
}
|
265 |
+
}
|
266 |
+
} catch (Exception $e) {
|
267 |
+
Mage::logException($e);
|
268 |
+
}
|
269 |
+
|
270 |
+
return false;
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Get cache lifetime for P2P data
|
275 |
+
*
|
276 |
+
* @return string
|
277 |
+
*/
|
278 |
+
protected function _getCacheP2P()
|
279 |
+
{
|
280 |
+
return $this->_cacheP2P;
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Get cache lifetime for U2P data
|
285 |
+
*
|
286 |
+
* @return string
|
287 |
+
*/
|
288 |
+
protected function _getCacheU2P()
|
289 |
+
{
|
290 |
+
return $this->_cacheU2P;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Log debug information and errors
|
295 |
+
*
|
296 |
+
* @param string $message
|
297 |
+
* @param number $level
|
298 |
+
*/
|
299 |
+
|
300 |
+
public function log($message = '',$level = 7)
|
301 |
+
{
|
302 |
+
switch ($this->_logLevel) {
|
303 |
+
case AgilOne_Recommendations_Helper_Data::LOG_LEVEL_ALL:
|
304 |
+
Mage::log($message,$level,'agilone_recommendations.log');
|
305 |
+
break;
|
306 |
+
|
307 |
+
case AgilOne_Recommendations_Helper_Data::LOG_LEVEL_ERRORS:
|
308 |
+
case $level > 5:
|
309 |
+
Mage::log($message,$level,'agilone_recommendations.log');
|
310 |
+
|
311 |
+
break;
|
312 |
+
default:
|
313 |
+
break;
|
314 |
+
}
|
315 |
+
}
|
316 |
+
}
|
app/code/community/AgilOne/Recommendations/Model/Adminhtml/System/Config/Source/Brand.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category AgilOne
|
4 |
+
* @package AgilOne_Recommendations
|
5 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
6 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class AgilOne_Recommendations_Model_Adminhtml_System_Config_Source_Brand
|
10 |
+
{
|
11 |
+
protected $_options;
|
12 |
+
|
13 |
+
public function toOptionArray()
|
14 |
+
{
|
15 |
+
if (!$this->_options) {
|
16 |
+
$this->_options = array();
|
17 |
+
$attributes = Mage::getResourceModel('catalog/product_attribute_collection')
|
18 |
+
->addVisibleFilter()
|
19 |
+
->getSelect()
|
20 |
+
->order(array('frontend_label ASC'))
|
21 |
+
->query();
|
22 |
+
|
23 |
+
foreach($attributes as $attribute) {
|
24 |
+
$this->_options[] = array(
|
25 |
+
'value'=> $attribute['attribute_code'],
|
26 |
+
'label'=> $attribute['frontend_label'] . ' (' . $attribute['attribute_code'] . ')'
|
27 |
+
);
|
28 |
+
}
|
29 |
+
}
|
30 |
+
return $this->_options;
|
31 |
+
}
|
32 |
+
}
|
app/code/community/AgilOne/Recommendations/Model/Adminhtml/System/Config/Source/Log.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category AgilOne
|
4 |
+
* @package AgilOne_Recommendations
|
5 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
6 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class AgilOne_Recommendations_Model_Adminhtml_System_Config_Source_Log
|
10 |
+
{
|
11 |
+
public function toOptionArray()
|
12 |
+
{
|
13 |
+
return array(
|
14 |
+
array(
|
15 |
+
'value' => AgilOne_Recommendations_Helper_Data::LOG_LEVEL_NONE,
|
16 |
+
'label' => Mage::helper('recommendations')->__('None')
|
17 |
+
),
|
18 |
+
array(
|
19 |
+
'value' => AgilOne_Recommendations_Helper_Data::LOG_LEVEL_ERRORS,
|
20 |
+
'label' => Mage::helper('recommendations')->__('Errors Only')
|
21 |
+
),
|
22 |
+
array(
|
23 |
+
'value' => AgilOne_Recommendations_Helper_Data::LOG_LEVEL_ALL,
|
24 |
+
'label' => Mage::helper('recommendations')->__('All Traffic')
|
25 |
+
),
|
26 |
+
);
|
27 |
+
}
|
28 |
+
}
|
app/code/community/AgilOne/Recommendations/Model/Feed.php
ADDED
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Recommendation Feed Model
|
4 |
+
*
|
5 |
+
* @category AgilOne
|
6 |
+
* @package AgilOne_Recommendations
|
7 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
8 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
9 |
+
*
|
10 |
+
* https://agilone.zendesk.com/hc/en-us/articles/201534597-OpenAPI-Recommendations
|
11 |
+
*/
|
12 |
+
|
13 |
+
class AgilOne_Recommendations_Model_Feed extends AgilOne_Recommendations_Model_Abstract
|
14 |
+
{
|
15 |
+
/**
|
16 |
+
* @var string $_apiKey
|
17 |
+
*
|
18 |
+
* SHA256 (AES) Public Key
|
19 |
+
*/
|
20 |
+
protected $_apiKey = null;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var string $_apiSecret
|
24 |
+
*
|
25 |
+
* SHA256 (AES) Secret Key
|
26 |
+
*/
|
27 |
+
protected $_apiSecret = null;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var string $_limitP2P
|
31 |
+
*
|
32 |
+
* Number of product recommendations to return
|
33 |
+
*/
|
34 |
+
protected $_limitP2P = null;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var string $_cacheP2P
|
38 |
+
*
|
39 |
+
* Caching expiration seconds from current timestamp for product recommendations
|
40 |
+
*/
|
41 |
+
protected $_cacheP2P = null;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @var string $_limitU2P
|
45 |
+
*
|
46 |
+
* Number of customer recommendations to return
|
47 |
+
*/
|
48 |
+
protected $_limitU2P = null;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @var string $_cacheU2P
|
52 |
+
*
|
53 |
+
* Caching expiration seconds from current timestamp for customer recommendations
|
54 |
+
*/
|
55 |
+
protected $_cacheU2P = null;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @var string $_defaultEmail
|
59 |
+
*
|
60 |
+
* Default email address to use for customers who aren't logged in.
|
61 |
+
*/
|
62 |
+
protected $_defaultEmail = null;
|
63 |
+
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Constructor. Set variables.
|
67 |
+
*/
|
68 |
+
protected function _construct()
|
69 |
+
{
|
70 |
+
parent::_construct();
|
71 |
+
|
72 |
+
try {
|
73 |
+
$this->_apiKey = Mage::getStoreConfig('agilone/general/api_key',$this->_storeId);
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Secret key encoding for query string authentication
|
77 |
+
* https://agilone.zendesk.com/hc/en-us/articles/201534547-OpenAPI-Query-String-Authentication
|
78 |
+
*/
|
79 |
+
$this->_apiSecret = base64_decode(mb_convert_encoding(Mage::getStoreConfig('agilone/general/api_secret',$this->_storeId), "auto", "ASCII"));
|
80 |
+
|
81 |
+
$this->_limitP2P = Mage::getStoreConfig('agilone/pdp/limit',$this->_storeId);
|
82 |
+
|
83 |
+
$this->_cacheP2P = Mage::getStoreConfig('agilone/pdp/cache_lifetime',$this->_storeId);
|
84 |
+
|
85 |
+
$this->_limitU2P = Mage::getStoreConfig('agilone/widget/limit',$this->_storeId);
|
86 |
+
|
87 |
+
$this->_cacheU2P = Mage::getStoreConfig('agilone/widget/cache_lifetime',$this->_storeId);
|
88 |
+
|
89 |
+
/**
|
90 |
+
* if guest checkout use email from quote
|
91 |
+
*/
|
92 |
+
if (!$this->_defaultEmail = Mage::getSingleton('checkout/session')->getQuote()->getCustomerEmail()) {
|
93 |
+
$this->_defaultEmail = Mage::getStoreConfig('agilone/widget/default_email',$this->_storeId);
|
94 |
+
}
|
95 |
+
|
96 |
+
} catch (Exception $e) {
|
97 |
+
Mage::logException($e);
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Convert JSON from API into array for template page
|
103 |
+
*
|
104 |
+
* @param string $json
|
105 |
+
* @return multitype:array
|
106 |
+
*/
|
107 |
+
protected function _convertItemJson($json = null)
|
108 |
+
{
|
109 |
+
try {
|
110 |
+
$items = new Varien_Data_Collection();
|
111 |
+
|
112 |
+
if ($json) {
|
113 |
+
|
114 |
+
$obj = json_decode($json);
|
115 |
+
|
116 |
+
if ($obj && $obj->result && $obj->result->resultSet && $rows = $obj->result->resultSet->resultSetitem) {
|
117 |
+
|
118 |
+
foreach($rows as $row) {
|
119 |
+
$product = new Varien_Object();
|
120 |
+
$product->setName(htmlentities($row->product->name, ENT_QUOTES, 'UTF-8'));
|
121 |
+
$product->setDescription(htmlentities($row->product->name, ENT_QUOTES, 'UTF-8'));
|
122 |
+
$product->setBrand(htmlentities($row->product->brand, ENT_QUOTES, 'UTF-8'));
|
123 |
+
$product->setSku($row->product->id);
|
124 |
+
$product->setRank($row->rank);
|
125 |
+
$product->setImageUrl($row->product->imageUrl);
|
126 |
+
$product->setProductUrl($row->product->productUrl);
|
127 |
+
$product->setPrice($row->product->price);
|
128 |
+
$product->setSpecialPrice($row->product->salePrice);
|
129 |
+
$product->setAvailability($row->product->availability);
|
130 |
+
$product->setSaleCondition($row->product->saleCondition);
|
131 |
+
$product->setGtin($row->product->gtin);
|
132 |
+
$product->setMpn($row->product->mpn);
|
133 |
+
$items->addItem($product);
|
134 |
+
}
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
return $items;
|
139 |
+
} catch (Exception $e) {
|
140 |
+
Mage::logException($e);
|
141 |
+
}
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Send request for recommendations to AgilOne API
|
146 |
+
*
|
147 |
+
* @param string $path The URL-encoded path including the leading slash. E.g. '/1.0/account/1/2'.
|
148 |
+
* @param string $expires The time in seconds from the Epoch when the signature expires.
|
149 |
+
* @param string $limit Number of recommendations to return
|
150 |
+
*/
|
151 |
+
protected function _request($path,$expires,$limit = 4)
|
152 |
+
{
|
153 |
+
try {
|
154 |
+
$canonical = mb_convert_encoding("GET\n\n\n" . $expires . "\n" . $path, "auto", 'UTF-8');
|
155 |
+
$signature = urlencode(base64_encode(hash_hmac("sha256", $canonical, $this->_apiSecret, true)));
|
156 |
+
$url = $this->_baseUrl . $path . '?limit=' . $limit . '&a1accesskeyid=' . $this->_apiKey . '&expires=' . $expires . '&signature=' . $signature;
|
157 |
+
|
158 |
+
if ($data = @file_get_contents($url)) {
|
159 |
+
$items = $this->_convertItemJson($data);
|
160 |
+
$this->log(count($items) . " RECOMMENDATIONS: $url",Zend_Log::INFO);
|
161 |
+
return $items;
|
162 |
+
} else {
|
163 |
+
$this->log("NO RECOMMENDATIONS: $url",Zend_Log::WARN);
|
164 |
+
return false;
|
165 |
+
}
|
166 |
+
} catch (Exception $e) {
|
167 |
+
Mage::logException($e);
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Get JSON-formatted object of product recommendations
|
173 |
+
*
|
174 |
+
* @return string
|
175 |
+
*/
|
176 |
+
public function getU2PItems()
|
177 |
+
{
|
178 |
+
try {
|
179 |
+
|
180 |
+
if ($email = $this->_email ? $this->_email : $this->_defaultEmail) {
|
181 |
+
if (is_numeric($this->_tenantId)) {
|
182 |
+
$path = '/1.0/tenant/' . $this->_tenantId . '/customer/' . $email . '/recommendations/product';
|
183 |
+
} else {
|
184 |
+
$path = '/1.0/user/' . $email . '/recommendations/product';
|
185 |
+
}
|
186 |
+
|
187 |
+
$expires = time() + intval($this->_getCacheU2P());
|
188 |
+
return $this->_request($path,$expires,$this->_limitU2P);
|
189 |
+
} else {
|
190 |
+
throw new Exception("U2P default email not set.");
|
191 |
+
}
|
192 |
+
|
193 |
+
} catch (Exception $e) {
|
194 |
+
Mage::logException($e);
|
195 |
+
}
|
196 |
+
return false;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Get JSON-formatted object of user product recommendations
|
201 |
+
*
|
202 |
+
* @param string $productId
|
203 |
+
* @return string
|
204 |
+
*/
|
205 |
+
public function getP2PItems($productId = null)
|
206 |
+
{
|
207 |
+
try {
|
208 |
+
if (is_numeric($productId)) {
|
209 |
+
if (is_numeric($this->_tenantId)) {
|
210 |
+
$path = '/1.0/tenant/' . $this->_tenantId . '/product/' . $this->_sourceId . '/' . $productId . '/recommendations/product';
|
211 |
+
} else {
|
212 |
+
$path = '/1.0/product/' . $this->_sourceId . '/' . $productId. '/recommendations/product';
|
213 |
+
}
|
214 |
+
|
215 |
+
$expires = time() + intval($this->_getCacheP2P());
|
216 |
+
return $this->_request($path,$expires,$this->_limitP2P);
|
217 |
+
} else {
|
218 |
+
return;
|
219 |
+
}
|
220 |
+
} catch (Exception $e) {
|
221 |
+
Mage::logException($e);
|
222 |
+
return false;
|
223 |
+
}
|
224 |
+
}
|
225 |
+
}
|
app/code/community/AgilOne/Recommendations/Model/Observer.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Observer Model
|
4 |
+
*
|
5 |
+
* @category AgilOne
|
6 |
+
* @package AgilOne_Recommendations
|
7 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
8 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
9 |
+
*/
|
10 |
+
|
11 |
+
class AgilOne_Recommendations_Model_Observer extends Mage_Core_Model_Abstract
|
12 |
+
{
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Capture Add To Cart/Remove From Cart events as a session
|
16 |
+
* variable to limit output of cart contents in Webtag.php
|
17 |
+
*/
|
18 |
+
public function updateProductIdCart()
|
19 |
+
{
|
20 |
+
Mage::getSingleton('checkout/session')->setA1Cart(true);
|
21 |
+
}
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Capture search keywords
|
26 |
+
* @param Varien_Event_Observer $event
|
27 |
+
*/
|
28 |
+
public function captureSearch(Varien_Event_Observer $event)
|
29 |
+
{
|
30 |
+
try {
|
31 |
+
Mage::getSingleton('checkout/session')->setA1Search($event->getData('catalogsearch_query')->getData('query_text'));
|
32 |
+
} catch (Mage_Core_Exception $e) {
|
33 |
+
Mage::logException($e);
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
}
|
app/code/community/AgilOne/Recommendations/Model/Webtag.php
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WebTab Model: Provides data for a1as.push javascript variables
|
4 |
+
*
|
5 |
+
* var _a1as = _a1as || [];
|
6 |
+
* _a1as.push(["init","1234567"]);
|
7 |
+
* _a1as.push(["setvar","userid","142"]);
|
8 |
+
* _a1as.push(["setvar","email","rloerzel@lyonscg.com"]);
|
9 |
+
* _a1as.push(["track"]);
|
10 |
+
*
|
11 |
+
* @category AgilOne
|
12 |
+
* @package AgilOne_Recommendations
|
13 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
14 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
15 |
+
*/
|
16 |
+
|
17 |
+
class AgilOne_Recommendations_Model_Webtag extends AgilOne_Recommendations_Model_Abstract
|
18 |
+
{
|
19 |
+
/**
|
20 |
+
* Get SKU and brand of product viewed
|
21 |
+
* @return string|boolean
|
22 |
+
*/
|
23 |
+
public function getProductView()
|
24 |
+
{
|
25 |
+
try {
|
26 |
+
if ($product = $this->getProduct()) {
|
27 |
+
$a1Product = new Varien_Object();
|
28 |
+
$a1Product->setProductId($product->getId());
|
29 |
+
$a1Product->setBrandId($product->getAttributeText($this->_brandAttribute));
|
30 |
+
return $a1Product;
|
31 |
+
}
|
32 |
+
} catch (Exception $e) {
|
33 |
+
Mage::logException($e);
|
34 |
+
}
|
35 |
+
|
36 |
+
return false;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Get URL-Key of category viewed
|
41 |
+
* @return string|boolean
|
42 |
+
*/
|
43 |
+
public function getCategoryIdView()
|
44 |
+
{
|
45 |
+
try {
|
46 |
+
if ($this->_handle === 'catalog_category_view') {
|
47 |
+
return Mage::registry('current_category')->getId();
|
48 |
+
}
|
49 |
+
} catch (Exception $e) {
|
50 |
+
Mage::logException($e);
|
51 |
+
}
|
52 |
+
|
53 |
+
return false;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Get contents of cart if item is added or removed
|
58 |
+
* @return string|boolean
|
59 |
+
*/
|
60 |
+
public function getProductIdCart()
|
61 |
+
{
|
62 |
+
try {
|
63 |
+
if ( $this->_checkoutSession->getA1Cart()) {
|
64 |
+
$ids = array();
|
65 |
+
$quote = $this->_checkoutSession->getQuote();
|
66 |
+
|
67 |
+
foreach($quote->getAllVisibleItems() as $item) {
|
68 |
+
$ids[] = $item->getProductId();
|
69 |
+
}
|
70 |
+
|
71 |
+
$this->_checkoutSession->setA1Cart(false);
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Return " " if cart has been emptied.
|
75 |
+
* Trim on webtag.phtml will result in:
|
76 |
+
* _a1as.push(["setvar","productid_cart",""]);
|
77 |
+
*/
|
78 |
+
return $ids ? implode(',',$ids) : ' ';
|
79 |
+
}
|
80 |
+
} catch (Exception $e) {
|
81 |
+
Mage::logException($e);
|
82 |
+
}
|
83 |
+
|
84 |
+
return false;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Get order information on success page
|
89 |
+
* @return Varien_Object|boolean
|
90 |
+
*/
|
91 |
+
public function getOrder()
|
92 |
+
{
|
93 |
+
try {
|
94 |
+
$a1Order = new Varien_Object();
|
95 |
+
if ($this->_action == 'success') {
|
96 |
+
$_lastOrderId = Mage::getSingleton('checkout/session')->getLastOrderId();
|
97 |
+
if (is_numeric($_lastOrderId) && $order = Mage::getModel('sales/order')->load($_lastOrderId)) {
|
98 |
+
$a1Order->setOrderId($order->getIncrementId());
|
99 |
+
$a1Order->setOrderTotal($order->getGrandTotal());
|
100 |
+
$ids = array();
|
101 |
+
foreach($order->getAllVisibleItems() as $item) {
|
102 |
+
$ids[] = $item->getProductId();
|
103 |
+
}
|
104 |
+
$a1Order->setProductIdOrder(implode(',',$ids));
|
105 |
+
$a1Order->setCustomerEmail($order->getCustomerEmail());
|
106 |
+
$a1Order->setCustomerId($order->getCustomerId() ? $order->getCustomerId() : 0);
|
107 |
+
}
|
108 |
+
return $a1Order;
|
109 |
+
}
|
110 |
+
|
111 |
+
} catch (Exception $e) {
|
112 |
+
Mage::logException($e);
|
113 |
+
}
|
114 |
+
return false;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Get search keywords
|
119 |
+
* @return string|boolean
|
120 |
+
*/
|
121 |
+
public function getOnsiteSearch()
|
122 |
+
{
|
123 |
+
try {
|
124 |
+
$a1Search = Mage::getSingleton('checkout/session')->getA1Search();
|
125 |
+
Mage::getSingleton('checkout/session')->setA1Search();
|
126 |
+
return $a1Search;
|
127 |
+
} catch (Exception $e) {
|
128 |
+
Mage::logException($e);
|
129 |
+
}
|
130 |
+
return false;
|
131 |
+
}
|
132 |
+
}
|
app/code/community/AgilOne/Recommendations/controllers/AjaxController.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Ajax Controller
|
4 |
+
*
|
5 |
+
* @category AgilOne
|
6 |
+
* @package AgilOne_Recommendations
|
7 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
8 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
9 |
+
*/
|
10 |
+
|
11 |
+
class AgilOne_Recommendations_AjaxController extends Mage_Core_Controller_Front_Action
|
12 |
+
{
|
13 |
+
public function webtagAction()
|
14 |
+
{
|
15 |
+
$this->loadLayout();
|
16 |
+
$webtags = $this->getLayout()->createBlock('recommendations/webtag')->setTemplate('recommendations/webtag.phtml')->toHtml();
|
17 |
+
$content = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
|
18 |
+
$content .= '<html xmlns="http://www.w3.org/1999/xhtml">';
|
19 |
+
$content .= '<head><title>' . html_entity_decode(Mage::getStoreConfig('design/head/default_description')) . '</title>';
|
20 |
+
$content .= '</head><body>' . $webtags . '</body></html>';
|
21 |
+
$this->getResponse()->setBody($content);
|
22 |
+
}
|
23 |
+
}
|
app/code/community/AgilOne/Recommendations/etc/adminhtml.xml
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<acl>
|
4 |
+
<resources>
|
5 |
+
<admin>
|
6 |
+
<children>
|
7 |
+
<system>
|
8 |
+
<children>
|
9 |
+
<config>
|
10 |
+
<children>
|
11 |
+
<agilone translate="title" module="agilone">
|
12 |
+
<title>AgilOne Configuration</title>
|
13 |
+
<sort_order>10</sort_order>
|
14 |
+
</agilone>
|
15 |
+
</children>
|
16 |
+
</config>
|
17 |
+
</children>
|
18 |
+
</system>
|
19 |
+
</children>
|
20 |
+
</admin>
|
21 |
+
</resources>
|
22 |
+
</acl>
|
23 |
+
</config>
|
app/code/community/AgilOne/Recommendations/etc/config.xml
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* @category AgilOne
|
5 |
+
* @package AgilOne_Recommendations
|
6 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
7 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
8 |
+
*/
|
9 |
+
-->
|
10 |
+
<config>
|
11 |
+
<modules>
|
12 |
+
<AgilOne_Recommendations>
|
13 |
+
<version>1.0.0</version>
|
14 |
+
</AgilOne_Recommendations>
|
15 |
+
</modules>
|
16 |
+
<global>
|
17 |
+
<models>
|
18 |
+
<recommendations>
|
19 |
+
<class>AgilOne_Recommendations_Model</class>
|
20 |
+
</recommendations>
|
21 |
+
</models>
|
22 |
+
<helpers>
|
23 |
+
<recommendations>
|
24 |
+
<class>AgilOne_Recommendations_Helper</class>
|
25 |
+
</recommendations>
|
26 |
+
</helpers>
|
27 |
+
<resources>
|
28 |
+
<recommendations_setup>
|
29 |
+
<setup>
|
30 |
+
<module>AgilOne_Recommendations</module>
|
31 |
+
</setup>
|
32 |
+
</recommendations_setup>
|
33 |
+
</resources>
|
34 |
+
<blocks>
|
35 |
+
<recommendations>
|
36 |
+
<class>AgilOne_Recommendations_Block</class>
|
37 |
+
</recommendations>
|
38 |
+
</blocks>
|
39 |
+
</global>
|
40 |
+
<frontend>
|
41 |
+
<routers>
|
42 |
+
<recommendations>
|
43 |
+
<use>standard</use>
|
44 |
+
<args>
|
45 |
+
<module>AgilOne_Recommendations</module>
|
46 |
+
<frontName>recommendations</frontName>
|
47 |
+
</args>
|
48 |
+
</recommendations>
|
49 |
+
</routers>
|
50 |
+
<events>
|
51 |
+
<sales_quote_add_item>
|
52 |
+
<observers>
|
53 |
+
<recommendations_sales_quote_add_item>
|
54 |
+
<type>singleton</type>
|
55 |
+
<class>recommendations/observer</class>
|
56 |
+
<method>updateProductIdCart</method>
|
57 |
+
</recommendations_sales_quote_add_item>
|
58 |
+
</observers>
|
59 |
+
</sales_quote_add_item>
|
60 |
+
<sales_quote_item_delete_after>
|
61 |
+
<observers>
|
62 |
+
<recommendations_sales_quote_item_delete_after>
|
63 |
+
<type>singleton</type>
|
64 |
+
<class>recommendations/observer</class>
|
65 |
+
<method>updateProductIdCart</method>
|
66 |
+
</recommendations_sales_quote_item_delete_after>
|
67 |
+
</observers>
|
68 |
+
</sales_quote_item_delete_after>
|
69 |
+
<catalogsearch_query_save_after>
|
70 |
+
<observers>
|
71 |
+
<recommendations_catalogsearch_query_save_after>
|
72 |
+
<type>singleton</type>
|
73 |
+
<class>recommendations/observer</class>
|
74 |
+
<method>captureSearch</method>
|
75 |
+
</recommendations_catalogsearch_query_save_after>
|
76 |
+
</observers>
|
77 |
+
</catalogsearch_query_save_after>
|
78 |
+
</events>
|
79 |
+
<translate>
|
80 |
+
<modules>
|
81 |
+
<AgilOne_Recommendations>
|
82 |
+
<files>
|
83 |
+
<default>AgilOne_Recommendations.csv</default>
|
84 |
+
</files>
|
85 |
+
</AgilOne_Recommendations>
|
86 |
+
</modules>
|
87 |
+
</translate>
|
88 |
+
<layout>
|
89 |
+
<updates>
|
90 |
+
<recommendations>
|
91 |
+
<file>recommendations.xml</file>
|
92 |
+
</recommendations>
|
93 |
+
</updates>
|
94 |
+
</layout>
|
95 |
+
</frontend>
|
96 |
+
<default>
|
97 |
+
<agilone>
|
98 |
+
<general>
|
99 |
+
<enabled>1</enabled>
|
100 |
+
<base_url>api.agilone.com</base_url>
|
101 |
+
<api_key></api_key>
|
102 |
+
<api_secret></api_secret>
|
103 |
+
<tenant_id></tenant_id>
|
104 |
+
<source_id></source_id>
|
105 |
+
<webtag_id></webtag_id>
|
106 |
+
<force_https>1</force_https>
|
107 |
+
<brand_attribute>manufacturer</brand_attribute>
|
108 |
+
<log_level>0</log_level>
|
109 |
+
</general>
|
110 |
+
<pdp>
|
111 |
+
<title>You may also like . . .</title>
|
112 |
+
<limit>4</limit>
|
113 |
+
<cache_lifetime>3800</cache_lifetime>
|
114 |
+
<error_message>There are no recommendations to display.</error_message>
|
115 |
+
</pdp>
|
116 |
+
<widget>
|
117 |
+
<title>You may also like . . .</title>
|
118 |
+
<limit>4</limit>
|
119 |
+
<cache_lifetime>3800</cache_lifetime>
|
120 |
+
<error_message>There are no recommendations to display.</error_message>
|
121 |
+
<default_email>dummy@example.com</default_email>
|
122 |
+
</widget>
|
123 |
+
</agilone>
|
124 |
+
</default>
|
125 |
+
</config>
|
app/code/community/AgilOne/Recommendations/etc/system.xml
ADDED
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<sections>
|
4 |
+
<agilone translate="label" module="recommendations">
|
5 |
+
<label><![CDATA[<img src="https://app.agilone.com/images/logo-a1-60x60.png" alt="AgilOne Logo" style="width:20px;height:20px;padding-right:3px;position:relative;top:+4px;" />AgilOne Recommendations]]></label>
|
6 |
+
<tab>customer</tab>
|
7 |
+
<sort_order>1</sort_order>
|
8 |
+
<show_in_default>1</show_in_default>
|
9 |
+
<show_in_website>1</show_in_website>
|
10 |
+
<show_in_store>1</show_in_store>
|
11 |
+
<groups>
|
12 |
+
<general>
|
13 |
+
<label>Account Settings</label>
|
14 |
+
<comment><![CDATA[<h3>How does AgilOne work?</h3><p><strong>Now marketers, large and small, can boost revenues, improve marketing returns and transform their businesses without the need for in-house data scientists or ongoing IT involvement. AgilOne has been described as the perfect marriage between Machine Learning and Human Intelligence. When you sign up for AgilOne, you will also be supported by the best data scientists and marketing experts in the business. We are here to help!</strong><br/><br/><a href="https://app.agilone.com/metrics" target="_blank">Customer Login</a></span> | <a href="https://agilone.zendesk.com/hc/en-us" target="_blank">Knowledge Base</a></p><br/><br/>]]></comment>
|
15 |
+
<frontend_type>text</frontend_type>
|
16 |
+
<sort_order>10</sort_order>
|
17 |
+
<show_in_default>1</show_in_default>
|
18 |
+
<show_in_website>1</show_in_website>
|
19 |
+
<show_in_store>1</show_in_store>
|
20 |
+
<fields>
|
21 |
+
<enabled translate="label">
|
22 |
+
<label>Enable Module</label>
|
23 |
+
<frontend_type>select</frontend_type>
|
24 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
25 |
+
<sort_order>10</sort_order>
|
26 |
+
<show_in_default>1</show_in_default>
|
27 |
+
<show_in_website>1</show_in_website>
|
28 |
+
<show_in_store>1</show_in_store>
|
29 |
+
</enabled>
|
30 |
+
<base_url translate="label">
|
31 |
+
<label>Base URL</label>
|
32 |
+
<comment><![CDATA[Base URL for API (i.e. "api.agilone.com")]]></comment>
|
33 |
+
<frontend_type>text</frontend_type>
|
34 |
+
<sort_order>20</sort_order>
|
35 |
+
<show_in_default>1</show_in_default>
|
36 |
+
<show_in_website>1</show_in_website>
|
37 |
+
<show_in_store>1</show_in_store>
|
38 |
+
</base_url>
|
39 |
+
<api_key translate="label">
|
40 |
+
<label>A1 Access Key Id</label>
|
41 |
+
<comment><![CDATA[SHA256 (AES) Public Key.]]></comment>
|
42 |
+
<frontend_type>text</frontend_type>
|
43 |
+
<sort_order>30</sort_order>
|
44 |
+
<show_in_default>1</show_in_default>
|
45 |
+
<show_in_website>1</show_in_website>
|
46 |
+
<show_in_store>1</show_in_store>
|
47 |
+
</api_key>
|
48 |
+
<api_secret translate="label">
|
49 |
+
<label>A1 Secret Access Key</label>
|
50 |
+
<comment><![CDATA[SHA256 (AES) Secret Key.]]></comment>
|
51 |
+
<frontend_type>text</frontend_type>
|
52 |
+
<sort_order>40</sort_order>
|
53 |
+
<show_in_default>1</show_in_default>
|
54 |
+
<show_in_website>1</show_in_website>
|
55 |
+
<show_in_store>1</show_in_store>
|
56 |
+
</api_secret>
|
57 |
+
<tenant_id translate="label">
|
58 |
+
<label>Tenant ID (OPTIONAL)</label>
|
59 |
+
<comment><![CDATA[The TenantID is an ID specific to your workspace. If on app.agilone.com, you only have access to one workspace (the most common case) the tenant value is optional in API calls.]]></comment>
|
60 |
+
<frontend_type>text</frontend_type>
|
61 |
+
<sort_order>50</sort_order>
|
62 |
+
<show_in_default>1</show_in_default>
|
63 |
+
<show_in_website>1</show_in_website>
|
64 |
+
<show_in_store>1</show_in_store>
|
65 |
+
</tenant_id>
|
66 |
+
<source_id translate="label">
|
67 |
+
<label>Source ID</label>
|
68 |
+
<comment><![CDATA[The SourceID is an ID specific to your data sources. You may have several of them if AgilOne manage different customer or product databases for you. The {sourceid} parameter makes sure that the {customerkey} or {productkey} you're supplying is unique.]]></comment>
|
69 |
+
<frontend_type>text</frontend_type>
|
70 |
+
<sort_order>60</sort_order>
|
71 |
+
<show_in_default>1</show_in_default>
|
72 |
+
<show_in_website>1</show_in_website>
|
73 |
+
<show_in_store>1</show_in_store>
|
74 |
+
</source_id>
|
75 |
+
<webtag_id translate="label">
|
76 |
+
<label>WebTag ID</label>
|
77 |
+
<comment><![CDATA[ID provided with AgilOne WebTag account]]></comment>
|
78 |
+
<frontend_type>text</frontend_type>
|
79 |
+
<sort_order>70</sort_order>
|
80 |
+
<show_in_default>1</show_in_default>
|
81 |
+
<show_in_website>1</show_in_website>
|
82 |
+
<show_in_store>1</show_in_store>
|
83 |
+
</webtag_id>
|
84 |
+
<force_https translate="label">
|
85 |
+
<label>Force HTTPS</label>
|
86 |
+
<comment><![CDATA[Use HTTP or HTTPS for API access. NOTE: AgilOne's API enforces SSL on all connections by default. ]]></comment>
|
87 |
+
<frontend_type>select</frontend_type>
|
88 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
89 |
+
<sort_order>80</sort_order>
|
90 |
+
<show_in_default>1</show_in_default>
|
91 |
+
<show_in_website>1</show_in_website>
|
92 |
+
<show_in_store>1</show_in_store>
|
93 |
+
</force_https>
|
94 |
+
<brand_attribute translate="label">
|
95 |
+
<label>Brand Attribute</label>
|
96 |
+
<comment><![CDATA[Magento product attribute to represent the AgilOne 'brand' attribute in API calls.]]></comment>
|
97 |
+
<frontend_type>select</frontend_type>
|
98 |
+
<source_model>recommendations/adminhtml_system_config_source_brand</source_model>
|
99 |
+
<sort_order>90</sort_order>
|
100 |
+
<show_in_default>1</show_in_default>
|
101 |
+
<show_in_website>1</show_in_website>
|
102 |
+
<show_in_store>1</show_in_store>
|
103 |
+
</brand_attribute>
|
104 |
+
<log_level>
|
105 |
+
<label>Log Level</label>
|
106 |
+
<comment><![CDATA[Debug Logging Level.]]></comment>
|
107 |
+
<frontend_type>select</frontend_type>
|
108 |
+
<source_model>recommendations/adminhtml_system_config_source_log</source_model>
|
109 |
+
<sort_order>100</sort_order>
|
110 |
+
<show_in_default>1</show_in_default>
|
111 |
+
<show_in_website>1</show_in_website>
|
112 |
+
<show_in_store>1</show_in_store>
|
113 |
+
</log_level>
|
114 |
+
</fields>
|
115 |
+
</general>
|
116 |
+
<pdp>
|
117 |
+
<label>P2P Product Detail Page Recommendations</label>
|
118 |
+
<comment><![CDATA[<p><strong>Settings for P2P product recommendations block on PDP page (i.e. "catalog_product_view"). Replaces product upsell content block.</strong><br/><br/></p>]]></comment>
|
119 |
+
<frontend_type>text</frontend_type>
|
120 |
+
<sort_order>20</sort_order>
|
121 |
+
<show_in_default>1</show_in_default>
|
122 |
+
<show_in_website>1</show_in_website>
|
123 |
+
<show_in_store>1</show_in_store>
|
124 |
+
<fields>
|
125 |
+
<title translate="label">
|
126 |
+
<label>Title</label>
|
127 |
+
<comment><![CDATA[P2P block header title.]]></comment>
|
128 |
+
<frontend_type>text</frontend_type>
|
129 |
+
<sort_order>10</sort_order>
|
130 |
+
<show_in_default>1</show_in_default>
|
131 |
+
<show_in_website>1</show_in_website>
|
132 |
+
<show_in_store>1</show_in_store>
|
133 |
+
</title>
|
134 |
+
<limit translate="label">
|
135 |
+
<label>Number of Recommendations Returned</label>
|
136 |
+
<comment><![CDATA[Maximum number of P2P recommendations to return from API.]]></comment>
|
137 |
+
<frontend_type>text</frontend_type>
|
138 |
+
<sort_order>20</sort_order>
|
139 |
+
<show_in_default>1</show_in_default>
|
140 |
+
<show_in_website>1</show_in_website>
|
141 |
+
<show_in_store>1</show_in_store>
|
142 |
+
</limit>
|
143 |
+
<cache_lifetime translate="label">
|
144 |
+
<label>Cache Lifetime (seconds)</label>
|
145 |
+
<comment><![CDATA[Caching expiration seconds from current timestamp for P2P recommendations]]></comment>
|
146 |
+
<frontend_type>text</frontend_type>
|
147 |
+
<sort_order>30</sort_order>
|
148 |
+
<show_in_default>1</show_in_default>
|
149 |
+
<show_in_website>1</show_in_website>
|
150 |
+
<show_in_store>1</show_in_store>
|
151 |
+
</cache_lifetime>
|
152 |
+
</fields>
|
153 |
+
</pdp>
|
154 |
+
<widget>
|
155 |
+
<label>U2P Widget Recommendations</label>
|
156 |
+
<comment><![CDATA[<p><strong>Settings for the U2P user product recommendation widget.</strong><br/><br/></p>]]></comment>
|
157 |
+
<frontend_type>text</frontend_type>
|
158 |
+
<sort_order>30</sort_order>
|
159 |
+
<show_in_default>1</show_in_default>
|
160 |
+
<show_in_website>1</show_in_website>
|
161 |
+
<show_in_store>1</show_in_store>
|
162 |
+
<fields>
|
163 |
+
<title translate="label">
|
164 |
+
<label>Title</label>
|
165 |
+
<comment><![CDATA[U2P block header title.]]></comment>
|
166 |
+
<frontend_type>text</frontend_type>
|
167 |
+
<sort_order>10</sort_order>
|
168 |
+
<show_in_default>1</show_in_default>
|
169 |
+
<show_in_website>1</show_in_website>
|
170 |
+
<show_in_store>1</show_in_store>
|
171 |
+
</title>
|
172 |
+
<limit translate="label">
|
173 |
+
<label>Number of Recommendations Returned</label>
|
174 |
+
<comment><![CDATA[Maximum number of U2P recommendations to return from API.]]></comment>
|
175 |
+
<frontend_type>text</frontend_type>
|
176 |
+
<sort_order>20</sort_order>
|
177 |
+
<show_in_default>1</show_in_default>
|
178 |
+
<show_in_website>1</show_in_website>
|
179 |
+
<show_in_store>1</show_in_store>
|
180 |
+
</limit>
|
181 |
+
<cache_lifetime translate="label">
|
182 |
+
<label>Cache Lifetime (seconds)</label>
|
183 |
+
<comment><![CDATA[Caching expiration seconds from current timestamp for U2P recommendations]]></comment>
|
184 |
+
<frontend_type>text</frontend_type>
|
185 |
+
<sort_order>30</sort_order>
|
186 |
+
<show_in_default>1</show_in_default>
|
187 |
+
<show_in_website>1</show_in_website>
|
188 |
+
<show_in_store>1</show_in_store>
|
189 |
+
</cache_lifetime>
|
190 |
+
<default_email translate="label">
|
191 |
+
<label>Default Email for Guests</label>
|
192 |
+
<comment><![CDATA[Default email address to use for customers who aren't logged in.]]></comment>
|
193 |
+
<frontend_type>text</frontend_type>
|
194 |
+
<sort_order>40</sort_order>
|
195 |
+
<show_in_default>1</show_in_default>
|
196 |
+
<show_in_website>1</show_in_website>
|
197 |
+
<show_in_store>1</show_in_store>
|
198 |
+
</default_email>
|
199 |
+
</fields>
|
200 |
+
</widget>
|
201 |
+
</groups>
|
202 |
+
</agilone>
|
203 |
+
</sections>
|
204 |
+
</config>
|
app/code/community/AgilOne/Recommendations/etc/widget.xml
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<widgets>
|
3 |
+
<recommendations_u2p type="recommendations/widget_u2p">
|
4 |
+
<name>AgilOne U2P Recommendations</name>
|
5 |
+
<description type="desc">Customer product recommendations provided by AgilOne.</description>
|
6 |
+
</recommendations_u2p>
|
7 |
+
</widgets>
|
app/design/frontend/base/default/layout/recommendations.xml
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* @category AgileOne
|
5 |
+
* @package AgileOne_Recommendations
|
6 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
7 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
8 |
+
*/
|
9 |
+
-->
|
10 |
+
<layout version="1.0.0">
|
11 |
+
<default>
|
12 |
+
<reference name="head">
|
13 |
+
<action method="addItem">
|
14 |
+
<type>skin_css</type>
|
15 |
+
<name>css/recommendations.css</name>
|
16 |
+
</action>
|
17 |
+
</reference>
|
18 |
+
<reference name="before_body_end">
|
19 |
+
<block type="recommendations/webtag" name="agilone.recommendations.webtag" as="agilone.recommendations.webtag" template="recommendations/webtag.phtml" />
|
20 |
+
<block type="recommendations/iframe" name="agilone.recommendations.iframe" as="agilone.recommendations.iframe" template="recommendations/iframe.phtml" />
|
21 |
+
</reference>
|
22 |
+
</default>
|
23 |
+
<catalog_product_view>
|
24 |
+
<reference name="product.info">
|
25 |
+
<block type="recommendations/catalog_product_list_upsell" name="product.info.upsell" as="upsell_products" template="recommendations/catalog/product/list/upsell.phtml">
|
26 |
+
<action method="setColumnCount"><columns>4</columns></action>
|
27 |
+
<block type="recommendations/catalog_product_list_upsell_item" name="catalog.product.upsell.item" template="recommendations/catalog/product/list/upsell/item.phtml" />
|
28 |
+
</block>
|
29 |
+
</reference>
|
30 |
+
</catalog_product_view></layout>
|
app/design/frontend/base/default/template/recommendations/catalog/product/list/upsell.phtml
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ($this->hasItems()): ?>
|
2 |
+
<div id="ordergroove-upsell">
|
3 |
+
<div class="widget-box">
|
4 |
+
<div class="box-title">
|
5 |
+
<h2><?php echo $this->getTitle() ?></h2>
|
6 |
+
</div>
|
7 |
+
<?php $i=0; foreach ($this->getItemCollection() as $_item): ?>
|
8 |
+
<?php if ($i++ % $this->getColumnCount() == 0): ?>
|
9 |
+
<ul class="widget-grid">
|
10 |
+
<?php endif ?>
|
11 |
+
<li class="item<?php if (($i - 1) % $this->getColumnCount() == 0):?> first<?php elseif ($i % $this->getColumnCount() == 0):?> last<?php endif;?>">
|
12 |
+
<?php
|
13 |
+
$itemBlock = $this->getChild('catalog.product.upsell.item')->setItem($_item)->setPosition($i);
|
14 |
+
echo $itemBlock->toHtml();
|
15 |
+
?>
|
16 |
+
</li>
|
17 |
+
<?php if ($i % $this->getColumnCount() == 0 || $i == $this->getItemsCount()): ?>
|
18 |
+
</ul>
|
19 |
+
<?php endif ?>
|
20 |
+
<?php endforeach; ?>
|
21 |
+
|
22 |
+
</div>
|
23 |
+
</div>
|
24 |
+
<?php endif ?>
|
app/design/frontend/base/default/template/recommendations/catalog/product/list/upsell/item.phtml
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php $_item = $this->getItem();
|
2 |
+
if ($_item = $this->getItem()): ?>
|
3 |
+
<div class="item-info">
|
4 |
+
<a href="<?php echo $_item->getProductUrl() ?>" class="product-image"><img src="<?php echo $_item->getImageUrl() ?>" width="100" height="100" alt="<?php echo $this->escapeHtml($_item->getName()) ?>" title="<?php echo $this->escapeHtml($_item->getName()) ?>" /></a>
|
5 |
+
<div class="product-details">
|
6 |
+
<h3 class="product-name"><a href="<?php echo $_item->getProductUrl() ?>"><?php echo $this->escapeHtml($_item->getName()) ?></a></h3>
|
7 |
+
<div class="price-box">
|
8 |
+
<span class="regular-price">
|
9 |
+
<span class="price"><?php echo Mage::helper('core')->currency($_item->getSpecialPrice() ? $_item->getSpecialPrice() : $_item->getPrice(), true, false) ?></span>
|
10 |
+
</span>
|
11 |
+
</div>
|
12 |
+
</div>
|
13 |
+
</div>
|
14 |
+
<?php endif;?>
|
app/design/frontend/base/default/template/recommendations/iframe.phtml
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<iframe src="" id="a1iframe" width="1" height="1" frameborder="0" ></iframe>
|
2 |
+
<script type='text/javascript'>
|
3 |
+
document.observe("dom:loaded", function() {
|
4 |
+
if ($("billing-buttons-container") != undefined) {
|
5 |
+
$("billing-buttons-container").on("click", "button.validation-passed", function() {
|
6 |
+
$('a1iframe').src = "<?php echo $this->_getUrl() ?>";
|
7 |
+
});
|
8 |
+
}
|
9 |
+
});
|
10 |
+
</script>
|
app/design/frontend/base/default/template/recommendations/webtag.phtml
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ($this->isEnabled()): ?>
|
2 |
+
<script type='text/javascript'>
|
3 |
+
var _a1as = _a1as || [];
|
4 |
+
_a1as.push(["init","<?php echo $this->getWebTagId() ?>"]);
|
5 |
+
<?php $userId = $this->getUserId() ?>
|
6 |
+
<?php if (is_numeric($userId)):?>
|
7 |
+
_a1as.push(["setvar","userid","<?php echo $userId ?>"]);
|
8 |
+
<?php endif?>
|
9 |
+
<?php if ($email = $this->getEmail()):?>
|
10 |
+
_a1as.push(["setvar","email","<?php echo $email ?>"]);
|
11 |
+
<?php endif?>
|
12 |
+
<?php if ($product = $this->getProductView()):?>
|
13 |
+
_a1as.push(["setvar","productid_view","<?php echo $product->getProductId() ?>"]);
|
14 |
+
<?php if ($brandId = $product->getBrandId()): ?>
|
15 |
+
_a1as.push(["setvar","brandid_view","<?php echo $brandId ?>"]);
|
16 |
+
<?php endif?>
|
17 |
+
<?php endif?>
|
18 |
+
<?php if ($categoryId = $this->getCategoryIdView()):?>
|
19 |
+
_a1as.push(["setvar","categoryid_view","<?php echo $categoryId ?>"]);
|
20 |
+
<?php endif?>
|
21 |
+
<?php if ($productIds = $this->getProductIdCart()):?>
|
22 |
+
_a1as.push(["setvar","productid_cart","<?php echo trim($productIds) ?>"]);
|
23 |
+
<?php endif ?>
|
24 |
+
<?php if ($keyword = $this->getOnsiteSearch()):?>
|
25 |
+
_a1as.push(["setvar","onsitesearch","<?php echo $keyword ?>"]);
|
26 |
+
<?php endif ?>
|
27 |
+
<?php
|
28 |
+
if ($order = $this->getOrder()) {
|
29 |
+
if (!is_numeric($userId)) { ?>
|
30 |
+
_a1as.push(["setvar","userid","<?php echo $order->getCustomerId() ?>"]);
|
31 |
+
<?php }
|
32 |
+
if (!$email = $this->getEmail()) {?>
|
33 |
+
_a1as.push(["setvar","email","<?php echo $order->getCustomerEmail() ?>"]);
|
34 |
+
<?php }?>
|
35 |
+
_a1as.push(["setvar","orderid","<?php echo $order->getOrderId() ?>"]);
|
36 |
+
_a1as.push(["setvar","productid_order","<?php echo $order->getProductIdOrder() ?>"]);
|
37 |
+
_a1as.push(["setvar","ordertotal","<?php echo $order->getOrderTotal() ?>"]);
|
38 |
+
<?php } ?>
|
39 |
+
_a1as.push(["track"]);
|
40 |
+
</script>
|
41 |
+
<script type='text/javascript'>
|
42 |
+
(function() {
|
43 |
+
var a1s = document.createElement('script');
|
44 |
+
a1s.type = 'text/javascript';
|
45 |
+
a1s.async = true;
|
46 |
+
a1s.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'tr-1.agilone.com/tr-as.js';
|
47 |
+
var a1ss = document.getElementsByTagName('script')[0];
|
48 |
+
a1ss.parentNode.insertBefore(a1s, a1ss);
|
49 |
+
})();
|
50 |
+
</script>
|
51 |
+
<?php else:?>
|
52 |
+
<!-- AgilOne_Recommendations module has been disabled in the Magento admin -->
|
53 |
+
<?php endif?>
|
app/design/frontend/base/default/template/recommendations/widget/u2p/items.phtml
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ($this->hasItems()): ?>
|
2 |
+
<div id="ordergroove-widget">
|
3 |
+
<div class="widget-box">
|
4 |
+
<div class="box-title">
|
5 |
+
<h2><?php echo $this->getTitle() ?></h2>
|
6 |
+
</div>
|
7 |
+
<?php $i=0; foreach ($this->getItemCollection() as $_item): ?>
|
8 |
+
<?php if ($i++ % $this->getColumnCount() == 0): ?>
|
9 |
+
<ul class="widget-grid">
|
10 |
+
<?php endif ?>
|
11 |
+
<li class="item<?php if (($i - 1) % $this->getColumnCount() == 0):?> first<?php elseif ($i % $this->getColumnCount() == 0):?> last<?php endif;?>">
|
12 |
+
<?php
|
13 |
+
$itemBlock = $this->getChild('widget.u2p.item')->setItem($_item)->setPosition($i);
|
14 |
+
echo $itemBlock->toHtml();
|
15 |
+
?>
|
16 |
+
</li>
|
17 |
+
<?php if ($i % $this->getColumnCount() == 0 || $i == $this->getItemsCount()): ?>
|
18 |
+
</ul>
|
19 |
+
<?php endif ?>
|
20 |
+
<?php endforeach; ?>
|
21 |
+
</div>
|
22 |
+
</div>
|
23 |
+
<?php endif ?>
|
app/design/frontend/base/default/template/recommendations/widget/u2p/items/item.phtml
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ($_item = $this->getItem()): ?>
|
2 |
+
<div class="item-info">
|
3 |
+
<a href="<?php echo $_item->getProductUrl() ?>" class="product-image"><img src="<?php echo $_item->getImageUrl() ?>" width="100" height="100" alt="<?php echo $this->escapeHtml($_item->getName()) ?>" title="<?php echo $this->escapeHtml($_item->getName()) ?>" /></a>
|
4 |
+
<div class="product-details">
|
5 |
+
<h3 class="product-name"><a href="<?php echo $_item->getProductUrl() ?>"><?php echo $this->escapeHtml($_item->getName()) ?></a></h3>
|
6 |
+
<div class="price-box">
|
7 |
+
<span class="regular-price">
|
8 |
+
<span class="price"><?php echo Mage::helper('core')->currency($_item->getSpecialPrice() ? $_item->getSpecialPrice() : $_item->getPrice(), true, false) ?></span>
|
9 |
+
</span>
|
10 |
+
</div>
|
11 |
+
</div>
|
12 |
+
</div>
|
13 |
+
<?php endif;?>
|
app/etc/modules/AgilOne_Recommendations.xml
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* @category AgilOne
|
5 |
+
* @package AgilOne_Recommendations
|
6 |
+
* @copyright Copyright (c) 2014 AgilOne (http://www.agilone.com/)
|
7 |
+
* @author Richard Loerzel (rloerzel@lyonscg.com)
|
8 |
+
*/
|
9 |
+
-->
|
10 |
+
<config>
|
11 |
+
<modules>
|
12 |
+
<AgilOne_Recommendations>
|
13 |
+
<active>true</active>
|
14 |
+
<codePool>community</codePool>
|
15 |
+
</AgilOne_Recommendations>
|
16 |
+
</modules>
|
17 |
+
</config>
|
app/locale/en_US/AgileOne_Recommendations.csv
ADDED
File without changes
|
package.xml
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>AgilOne_Recommendations_CE</name>
|
4 |
+
<version>1.0.0.0</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>AgilOne Predictive Marketing Module for Magento Community Edition</summary>
|
10 |
+
<description>AgilOne provides out of the box predictive marketing programs that increase conversions and customer lifetime value. Whether you are looking to convert more browsers into buyers, grow one time buyers into repeat buyers or retain valuable customers, AgilOne Turnkey Actions can deliver. For each program hyper-target content and offers using likelihood to buy, lifetime value, behavioral, product and brand clusters. Add one-on-one upsell, cross-sell and next-sell recommendations to boost impact. Whichever AgilOne program you start with, you will see immediate lift. Start with one program today, then continue to add new programs, all powered by the same Predictive Marketing Cloud. 
|
11 |
+

|
12 |
+
What Gives AgilOne The Leading Edge?
|
13 |
+

|
14 |
+
Predictive Cart Recovery- Recover up to 45% of carts by providing the right incentive for each customer, taking into account likelihood to buy, lifetime value or cluster personas. Coordinate cart campaigns across channels to ensure you don’t remind customers who already bought.
|
15 |
+

|
16 |
+
Predictive Email Retargeting- Double site conversions by reminding customers to come back. Use one-on-one content such as abandoned search terms, items browsed, and recommendations. Then add the right incentive for each person based on likelihood to buy and lifetime value.
|
17 |
+

|
18 |
+
Repeat Purchase Program- Get customers to repeat buy and double sales with post-purchase offers and recommendations or by sending replenishment reminders for consumables. Use likelihood to buy predictions to add the right level of discount or incentive.
|
19 |
+

|
20 |
+
Cluster-Based Targeting- Triple conversions and increase lifetime value by targeted content using predictive product, brand or behavioral clusters. Also add personalized product recommendations to any of your programs – online and offline.
|
21 |
+

|
22 |
+
Loyalty Appreciation- Increase retention by showering your best customers with attention. Increase lifetime value by rewarding each customer with personalized loyalty rewards if they buy just a little more, or a little more often, than they usually would.
|
23 |
+

|
24 |
+
Customer Reactivation- Reactivate customers with content based on cluster personas, a personal recommendation and an incentive that is right-sized using likelihood to buy and lifetime value. Also reduce email opt-outs 40% by adjusting email frequency by segment.</description>
|
25 |
+
<notes>All required page templates and layout files are located in the default theme directory (app/design/frontend/base/default). You will need to copy these files into your site's installed theme directory to install this module. See installation instructions for more details.
|
26 |
+
</notes>
|
27 |
+
<authors><author><name>Joe Mancini</name><user>jmancini</user><email>joe.mancini@agilone.com</email></author></authors>
|
28 |
+
<date>2015-01-27</date>
|
29 |
+
<time>16:55:06</time>
|
30 |
+
<contents><target name="magecommunity"><dir><dir name="AgilOne"><dir name="Recommendations"><dir name="Block"><dir name="Catalog"><dir name="Product"><dir name="List"><dir name="Upsell"><file name="Item.php" hash="e4c027773238928af9785420dc5d0e7f"/></dir><file name="Upsell.php" hash="2417b4ef08b896c4644bf237df5d63b2"/></dir></dir></dir><file name="Iframe.php" hash="617872f6f4246bb4c2630c4960377864"/><file name="Webtag.php" hash="86805274691e6ef41686746bbb9f3945"/><dir name="Widget"><dir name="U2p"><dir name="Items"><file name="Item.php" hash="3e3cb709eea726ea7ddc436d71949c6d"/></dir><file name="Items.php" hash="706ab4ade9b7ab7c82311fb5e4a73df2"/></dir><file name="U2p.php" hash="94a58e321fcbe289238c7cc86a3e7c67"/></dir></dir><dir name="Helper"><file name="Data.php" hash="2d8cd6135b38e854755dc575b5b1df6b"/></dir><dir name="Model"><file name="Abstract.php" hash="7210e4b1c533da85ec86b58f37c3f2bb"/><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Source"><file name="Brand.php" hash="298072061fe5725ce6ff3636cecc7f02"/><file name="Log.php" hash="81841ae9aac08ee561e7f95f3f4e254c"/></dir></dir></dir></dir><file name="Feed.php" hash="9492859a2c00da4b5c330e442ca0f314"/><file name="Observer.php" hash="adcfae4929499f950dab60fad9129216"/><file name="Webtag.php" hash="11a8461f56a3b0b19794022121a65b4e"/></dir><dir name="controllers"><file name="AjaxController.php" hash="2919d6acab2a89459c9f0547316e59d2"/></dir><dir name="etc"><file name="adminhtml.xml" hash="b7ade3730ef0a58c10bbb504f7d59753"/><file name="config.xml" hash="1ed5137d00b1a638af221ebee18775aa"/><file name="system.xml" hash="d5eb10c4ebd05f04f8c380b081873fa9"/><file name="widget.xml" hash="1146942200e7eb109c683308f6eae7df"/></dir></dir></dir></dir></target><target name="magedesign"><dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="recommendations.xml" hash="49fb21c6005cf28d00ca3ff3e7dcd956"/></dir><dir name="template"><dir name="recommendations"><dir name="catalog"><dir name="product"><dir name="list"><dir name="upsell"><file name="item.phtml" hash="af1973e8a7e24ae3bcdbea2cad4a3348"/></dir><file name="upsell.phtml" hash="3f305c35bbb95aed702062b340965d22"/></dir></dir></dir><file name="iframe.phtml" hash="56b2e5cf2b01588910a91efa6ac5150e"/><file name="webtag.phtml" hash="95d86170a07bed708173f9e455dc6280"/><dir name="widget"><dir name="u2p"><dir name="items"><file name="item.phtml" hash="ef06bc8d5875ca4baa1d28fcd67ff255"/></dir><file name="items.phtml" hash="b01af5a56e889306eef45bbc1318f452"/></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir><dir name="modules"><file name="AgilOne_Recommendations.xml" hash="0c1e21985b9226bc310a56d249963212"/></dir></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="AgileOne_Recommendations.csv" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir></dir></target><target name="mageskin"><dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><file name="recommendations.css" hash="ef5656b647a3afd22d636c3a8b68af5c"/></dir></dir></dir></dir></dir></target></contents>
|
31 |
+
<compatible/>
|
32 |
+
<dependencies><required><php><min>5.3.3</min><max>5.3.29</max></php><package><name/><channel>connect.magentocommerce.com/core</channel><min/><max/></package><extension><name>mbstring</name><min/><max/></extension><extension><name>mcrypt</name><min/><max/></extension></required></dependencies>
|
33 |
+
</package>
|
skin/frontend/base/default/css/recommendations.css
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#ordergroove-upsell { background-color:#faf7ee; padding:0; margin:0; }
|
2 |
+
#ordergroove-upsell .widget-box .box-title h2 { font-weight:bold; font-size:15px; color:#e26703; padding:0 0 1px; margin:0 0 8px; }
|
3 |
+
#ordergroove-upsell .widget-box { min-height:260px; margin:0; }
|
4 |
+
#ordergroove-upsell .widget-box .widget-grid .item { background-color:#ffffff;float:left; width:138px;padding:4px;margin:4px;border: 1px solid #e5dcc3;}
|
5 |
+
#ordergroove-upsell .widget-box .widget-grid .product-image {width:100px;height:135px;display:block; margin-left:auto;margin-right:auto;margin-bottom:10px;}
|
6 |
+
#ordergroove-upsell .widget-box .widget-grid .product-name { /*min-height:2.7em;*/ margin:0 0 5px; font-weight:bold; font-size:13px; color:#203548; text-align:center;}
|
7 |
+
#ordergroove-upsell .widget-box .widget-grid .product-name a { color:#203548; }
|
8 |
+
#ordergroove-upsell .widget-box .widget-grid .price-box { margin:5px 0; text-align:center;}
|
9 |
+
#ordergroove-upsell .widget-box .widget-grid .availability { line-height:21px; }
|
10 |
+
#ordergroove-upsell .widget-box .widget-grid .actions { position:absolute; bottom:12px; }
|
11 |
+
|
12 |
+
#ordergroove-widget { display:inline-block; padding:25px;}
|
13 |
+
#ordergroove-widget .widget-box .box-title h2 { font-weight:bold; font-size:15px; color:#e26703; padding:0 0 1px; margin:0 0 8px; border-bottom: 1px solid #e5dcc3; }
|
14 |
+
#ordergroove-widget .widget-box { min-height:240px; margin:0; }
|
15 |
+
#ordergroove-widget .widget-box .widget-grid .item { background-color:#ffffff;float:left; width:138px;padding:4px;margin:4px;border: 1px solid #e5dcc3; }
|
16 |
+
#ordergroove-widget .widget-box .widget-grid .product-image {width:100px;height:135px;display:block; margin-left:auto;margin-right:auto;margin-bottom:10px;}
|
17 |
+
#ordergroove-widget .widget-box .widget-grid .product-name { /*min-height:2.7em;*/ margin:0 0 5px; font-weight:bold; font-size:13px; color:#203548; text-align:center;}
|
18 |
+
#ordergroove-widget .widget-box .widget-grid .product-name a { color:#203548; }
|
19 |
+
#ordergroove-widget .widget-box .widget-grid .price-box { margin:5px 0; text-align:center;}
|
20 |
+
#ordergroove-widget .widget-box .widget-grid .availability { line-height:21px; }
|
21 |
+
#ordergroove-widget .widget-box .widget-grid .actions { position:absolute; bottom:12px; }
|