YOOCHOOSE_Recommender_Engine - Version 1.1.1

Version Notes

Added configuration options for the used scenarios

Download this release

Release Info

Developer Magento Core Team
Extension YOOCHOOSE_Recommender_Engine
Version 1.1.1
Comparing to
See all releases


Version 1.1.1

Files changed (25) hide show
  1. app/code/community/AvS/Yoochoose/Block/Crosssell.php +48 -0
  2. app/code/community/AvS/Yoochoose/Block/Recommendation.php +88 -0
  3. app/code/community/AvS/Yoochoose/Block/Related.php +48 -0
  4. app/code/community/AvS/Yoochoose/Block/Tracking.php +108 -0
  5. app/code/community/AvS/Yoochoose/Block/Upsell.php +53 -0
  6. app/code/community/AvS/Yoochoose/Helper/Data.php +248 -0
  7. app/code/community/AvS/Yoochoose/Model/Api.php +47 -0
  8. app/code/community/AvS/Yoochoose/Model/Api/Event.php +232 -0
  9. app/code/community/AvS/Yoochoose/Model/Api/Recommendation.php +165 -0
  10. app/code/community/AvS/Yoochoose/Model/Api/Recommendation/Crossselling.php +95 -0
  11. app/code/community/AvS/Yoochoose/Model/Api/Recommendation/Related.php +43 -0
  12. app/code/community/AvS/Yoochoose/Model/Api/Recommendation/Upselling.php +43 -0
  13. app/code/community/AvS/Yoochoose/Model/Observer.php +194 -0
  14. app/code/community/AvS/Yoochoose/etc/config.xml +188 -0
  15. app/code/community/AvS/Yoochoose/etc/system.xml +222 -0
  16. app/code/community/AvS/Yoochoose/sql/yoochoose_setup/mysql4-install-0.1.0.php +14 -0
  17. app/design/frontend/base/default/layout/yoochoose.xml +38 -0
  18. app/design/frontend/base/default/template/yoochoose/crosssell.phtml +34 -0
  19. app/design/frontend/base/default/template/yoochoose/recommendation.phtml +50 -0
  20. app/design/frontend/base/default/template/yoochoose/related.phtml +69 -0
  21. app/design/frontend/base/default/template/yoochoose/tracking.phtml +46 -0
  22. app/design/frontend/base/default/template/yoochoose/upsell.phtml +37 -0
  23. app/etc/modules/AvS_Yoochoose.xml +9 -0
  24. app/locale/de_DE/AvS_Yoochoose.csv +36 -0
  25. package.xml +70 -0
app/code/community/AvS/Yoochoose/Block/Crosssell.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Block_Crosssell extends Mage_Checkout_Block_Cart_Crosssell
10
+ {
11
+ protected $_itemArray = false;
12
+
13
+ /**
14
+ * Request Recommendations from Yoochoose Api and transform them to an array
15
+ * of products
16
+ *
17
+ * @return array
18
+ */
19
+ public function getItemArray()
20
+ {
21
+ if ($this->_itemArray === false) {
22
+
23
+ /** @var $api AvS_Yoochoose_Model_Api_Recommendation_Crossselling */
24
+ $api = Mage::getSingleton('yoochoose/api_recommendation_crossselling');
25
+
26
+ $this->_itemArray = array();
27
+ if (Mage::getStoreConfig('yoochoose/crossselling/prefer_manual_connections')) {
28
+
29
+ // load manual set upselling products first
30
+ $this->_itemArray = $api->getArrayFromItemCollection($this->getItems());
31
+ }
32
+
33
+ if (!Mage::helper('yoochoose')->isActive()) {
34
+ return $this->_itemArray;
35
+ }
36
+
37
+ if (count($this->_itemArray) < $api->getMaxNumberProducts()) {
38
+ $scenario = Mage::getStoreConfig('yoochoose/crossselling/scenario');
39
+ $this->_itemArray = $api->mergeItemArrays(
40
+ $this->_itemArray,
41
+ $api->getRecommendedProducts($scenario)
42
+ );
43
+ }
44
+ }
45
+
46
+ return $this->_itemArray;
47
+ }
48
+ }
app/code/community/AvS/Yoochoose/Block/Recommendation.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Block_Recommendation extends Mage_Catalog_Block_Product_List
10
+ {
11
+ protected $_itemArray = false;
12
+
13
+ protected $_columnCount = 4;
14
+
15
+ protected $_maxItems = 0;
16
+
17
+ protected $_scenario = AvS_Yoochoose_Model_Api_Recommendation::SCENARIO_TOP_SELLING;
18
+
19
+ /**
20
+ * Request Recommendations from Yoochoose Api and transform them to an array
21
+ * of products
22
+ *
23
+ * @return array
24
+ */
25
+ public function getItemArray()
26
+ {
27
+ if ($this->_itemArray === false) {
28
+
29
+ if (!Mage::helper('yoochoose')->isActive()) {
30
+ return array();
31
+ }
32
+
33
+ /** @var $api AvS_Yoochoose_Model_Api_Recommendation $api */
34
+ $api = Mage::getSingleton('yoochoose/api_recommendation');
35
+ if ($this->getMaxItems() > 0) {
36
+ $api->setMaxNumberProducts($this->getMaxItems());
37
+ }
38
+
39
+ if ($api->getMaxNumberProducts() > 0) {
40
+
41
+ $this->_itemArray = $api->mergeItemArrays(
42
+ $this->_itemArray,
43
+ $api->getRecommendedProducts($this->getScenario())
44
+ );
45
+ }
46
+ }
47
+
48
+ return $this->_itemArray;
49
+ }
50
+
51
+ public function getRowCount()
52
+ {
53
+ return ceil(count($this->_itemArray)/$this->getColumnCount());
54
+ }
55
+
56
+ public function getColumnCount()
57
+ {
58
+ return $this->_columnCount;
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 getMaxItems()
70
+ {
71
+ return $this->_maxItems;
72
+ }
73
+
74
+ public function setMaxItems($maxItems)
75
+ {
76
+ $this->_maxItems = intval($maxItems);
77
+ }
78
+
79
+ public function getScenario()
80
+ {
81
+ return $this->_scenario;
82
+ }
83
+
84
+ public function setScenario($scenario)
85
+ {
86
+ $this->_scenario = $scenario;
87
+ }
88
+ }
app/code/community/AvS/Yoochoose/Block/Related.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Block_Related extends Mage_Catalog_Block_Product_List_Related
10
+ {
11
+ protected $_itemArray = false;
12
+
13
+ /**
14
+ * Request Recommendations from Yoochoose Api and transform them to an array
15
+ * of products
16
+ *
17
+ * @return array
18
+ */
19
+ public function getItemArray()
20
+ {
21
+ if ($this->_itemArray === false) {
22
+
23
+ /** @var $api AvS_Yoochoose_Model_Api_Recommendation_Related */
24
+ $api = Mage::getSingleton('yoochoose/api_recommendation_related');
25
+
26
+ $this->_itemArray = array();
27
+ if (Mage::getStoreConfig('yoochoose/related/prefer_manual_connections')) {
28
+
29
+ // load manual set upselling products first
30
+ $this->_itemArray = $api->getArrayFromItemCollection($this->getItems());
31
+ }
32
+
33
+ if (!Mage::helper('yoochoose')->isActive()) {
34
+ return $this->_itemArray;
35
+ }
36
+
37
+ if (count($this->_itemArray) < $api->getMaxNumberProducts()) {
38
+ $scenario = Mage::getStoreConfig('yoochoose/related/scenario');
39
+ $this->_itemArray = $api->mergeItemArrays(
40
+ $this->_itemArray,
41
+ $api->getRecommendedProducts($scenario)
42
+ );
43
+ }
44
+ }
45
+
46
+ return $this->_itemArray;
47
+ }
48
+ }
app/code/community/AvS/Yoochoose/Block/Tracking.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Block_Tracking extends Mage_Core_Block_Template
10
+ {
11
+ /**
12
+ * Request object
13
+ *
14
+ * @var Zend_Controller_Request_Abstract
15
+ */
16
+ protected $_request;
17
+
18
+ protected $_trackingPixelData = null;
19
+
20
+ /**
21
+ * Constructor
22
+ */
23
+ public function __construct()
24
+ {
25
+ $this->_request = Mage::app()->getRequest();
26
+ }
27
+
28
+ /**
29
+ * Generate Yoochoose Tracking Pixel(s) Data depending on request
30
+ *
31
+ * @return array
32
+ */
33
+ public function getTrackingPixelData()
34
+ {
35
+ if (!is_array($this->_trackingPixelData)) {
36
+
37
+ $this->_trackingPixelData = array();
38
+
39
+ switch($this->_getFullActionName()) {
40
+
41
+ case 'catalog_category_view':
42
+
43
+ $this->_trackingPixelData = Mage::getSingleton('yoochoose/api_event')->getCategoryViewTrackingPixelData();
44
+ break;
45
+
46
+ case 'catalog_product_view':
47
+
48
+ $isRecommended = $this->_isRecommended();
49
+ $this->_trackingPixelData = Mage::getSingleton('yoochoose/api_event')->getProductViewTrackingPixelData($isRecommended);
50
+ break;
51
+
52
+ case 'checkout_onepage_success':
53
+ case 'checkout_multishipping_success':
54
+
55
+ $this->_trackingPixelData = Mage::getSingleton('yoochoose/api_event')->getCheckoutSuccessTrackingPixelData();
56
+ break;
57
+ }
58
+
59
+ if (is_array(Mage::getSingleton('customer/session')->getTransferEventInfo())) {
60
+
61
+ $this->_trackingPixelData[] = Mage::getSingleton('yoochoose/api_event')->getTransferTrackingPixelData();
62
+ }
63
+ }
64
+
65
+ return $this->_trackingPixelData;
66
+ }
67
+
68
+ protected function _isRecommended() {
69
+
70
+ return $this->_getRequest()->getParam('recommended') == 1;
71
+ }
72
+
73
+ /**
74
+ * Generate Url from given Params and Generic Data
75
+ *
76
+ * @param array $trackingPixelData
77
+ * @return string
78
+ */
79
+ public function generateTrackingPixelUrl($trackingPixelData)
80
+ {
81
+ return Mage::getSingleton('yoochoose/api_event')->generateTrackingPixelUrl($trackingPixelData);
82
+ }
83
+
84
+ /**
85
+ * Retrieve full bane of current action current controller and
86
+ * current module
87
+ *
88
+ * @param string $delimiter
89
+ * @return string
90
+ */
91
+ protected function _getFullActionName($delimiter='_')
92
+ {
93
+ return $this->_getRequest()->getRequestedRouteName().$delimiter.
94
+ $this->_getRequest()->getRequestedControllerName().$delimiter.
95
+ $this->_getRequest()->getRequestedActionName();
96
+ }
97
+
98
+ /**
99
+ * Retrieve request object
100
+ *
101
+ * @return Mage_Core_Controller_Request_Http
102
+ */
103
+ protected function _getRequest()
104
+ {
105
+ return $this->_request;
106
+ }
107
+
108
+ }
app/code/community/AvS/Yoochoose/Block/Upsell.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Block_Upsell extends Mage_Catalog_Block_Product_List_Upsell
10
+ {
11
+ protected $_itemArray = false;
12
+
13
+ /**
14
+ * Request Recommendations from Yoochoose Api and transform them to an array
15
+ * of products
16
+ *
17
+ * @return array
18
+ */
19
+ public function getItemArray()
20
+ {
21
+ if ($this->_itemArray === false) {
22
+
23
+ /** @var $api AvS_Yoochoose_Model_Api_Recommendation_Upselling */
24
+ $api = Mage::getSingleton('yoochoose/api_recommendation_upselling');
25
+
26
+ $this->_itemArray = array();
27
+ if (Mage::getStoreConfig('yoochoose/upselling/prefer_manual_connections')) {
28
+
29
+ // load manual set upselling products first
30
+ $this->_itemArray = $api->getArrayFromItemCollection($this->getItems());
31
+ }
32
+
33
+ if (!Mage::helper('yoochoose')->isActive()) {
34
+ return $this->_itemArray;
35
+ }
36
+
37
+ if (count($this->_itemArray) < $api->getMaxNumberProducts()) {
38
+ $scenario = Mage::getStoreConfig('yoochoose/upselling/scenario');
39
+ $this->_itemArray = $api->mergeItemArrays(
40
+ $this->_itemArray,
41
+ $api->getRecommendedProducts($scenario)
42
+ );
43
+ }
44
+ }
45
+
46
+ return $this->_itemArray;
47
+ }
48
+
49
+ public function getRowCount()
50
+ {
51
+ return ceil(count($this->_itemArray)/$this->getColumnCount());
52
+ }
53
+ }
app/code/community/AvS/Yoochoose/Helper/Data.php ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Helper_Data extends Mage_Core_Helper_Abstract
10
+ {
11
+ const COOKIE_NAME = 'yoochoose_tracking';
12
+
13
+ public function isActive()
14
+ {
15
+ return
16
+ !Mage::getStoreConfig('yoochoose/general/disabled')
17
+ && Mage::getStoreConfig('yoochoose/api/license_type');
18
+ }
19
+
20
+ /**
21
+ * Return Customer Session
22
+ *
23
+ * @return Mage_Customer_Model_Session
24
+ */
25
+ protected function _getSession()
26
+ {
27
+ return Mage::getSingleton('customer/session');
28
+ }
29
+
30
+ /**
31
+ * Get User Id from Cookie, Session or Customer Object (if logged in)
32
+ *
33
+ * @return string
34
+ */
35
+ public function getUserId()
36
+ {
37
+ // get from session
38
+ if ($userId = $this->_getSession()->getYoochooseUserId()) {
39
+
40
+ return $userId;
41
+ }
42
+
43
+ // get from customer object
44
+ if ($this->_getSession()->isLoggedIn()) {
45
+
46
+ $customer = $this->_getSession()->getCustomer();
47
+ if ($userId = $customer->getYoochooseUserId()) {
48
+
49
+ $this->_storeUserIdInSession($userId);
50
+ return $userId;
51
+ }
52
+ }
53
+
54
+ // get from cookie
55
+ $cookie = Mage::app()->getCookie();
56
+ if ($userId = $cookie->get(self::COOKIE_NAME)) {
57
+
58
+ $this->_storeUserId($userId);
59
+ return $userId;
60
+ }
61
+
62
+ // generate new
63
+ $userId = $this->_generateNewUserId();
64
+ $this->_storeUserId($userId);
65
+
66
+ return $userId;
67
+ }
68
+
69
+ /**
70
+ * On Login: Update User ID which is stored in customer object and cookie
71
+ */
72
+ public function mergeUserIdOnLogin()
73
+ {
74
+ if ($this->_getSession()->isLoggedIn()) {
75
+
76
+ $sessionUserId = $this->getUserId();
77
+
78
+ $customer = $this->_getSession()->getCustomer();
79
+ $customerUserId = $customer->getYoochooseUserId();
80
+
81
+ if ($sessionUserId != $customerUserId) {
82
+
83
+ if ($customerUserId) {
84
+
85
+ // transfer from customer to session if exists already
86
+ $this->_generateTransferEventInfo($sessionUserId, $customerUserId);
87
+ $this->_storeUserIdInSession($customerUserId);
88
+ $this->_storeUserIdInCookie($customerUserId);
89
+ } else {
90
+
91
+ // transfer from session to customer if none at customer exists
92
+ $this->_storeUserIdInCustomerObject($sessionUserId);
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Generate new user id
100
+ *
101
+ * @return string
102
+ */
103
+ protected function _generateNewUserId() {
104
+
105
+ srand(intval(microtime(true) * 1000));
106
+ $salt = (string) Mage::getConfig()->getNode('global/crypt/key');
107
+ return md5($salt . rand());
108
+ }
109
+
110
+ /**
111
+ * Store a newly generated User Id
112
+ *
113
+ * @param string $userId
114
+ */
115
+ protected function _storeUserId($userId)
116
+ {
117
+ $this->_storeUserIdInSession($userId);
118
+ $this->_storeUserIdInCustomerObject($userId);
119
+ $this->_storeUserIdInCookie($userId);
120
+
121
+ }
122
+
123
+ /**
124
+ * Store a newly generated User Id in Customer Session
125
+ *
126
+ * @param string $userId
127
+ */
128
+ protected function _storeUserIdInSession($userId)
129
+ {
130
+ $this->_getSession()->setYoochooseUserId($userId);
131
+ }
132
+
133
+ /**
134
+ * Store a User Id in Customer Object (database)
135
+ *
136
+ * @param string $userId
137
+ */
138
+ protected function _storeUserIdInCustomerObject($userId)
139
+ {
140
+ if ($this->_getSession()->isLoggedIn()) {
141
+
142
+ $customer = $this->_getSession()->getCustomer();
143
+ $customer->setYoochooseUserId($userId);
144
+ $customer->getResource()->saveAttribute($customer, 'yoochoose_user_id');
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Store a User Id in Customer Object (database)
150
+ *
151
+ * @param string $userId
152
+ */
153
+ protected function _storeUserIdInCookie($userId)
154
+ {
155
+ $cookie = Mage::app()->getCookie();
156
+
157
+ $cookie->set(self::COOKIE_NAME, $userId, true);
158
+ }
159
+
160
+ /**
161
+ *
162
+ * @param string $oldUserId
163
+ * @param string $newUserId
164
+ */
165
+ protected function _generateTransferEventInfo($oldUserId, $newUserId)
166
+ {
167
+ $this->_getSession()->setTransferEventInfo(array('old' => $oldUserId, 'new' => $newUserId));
168
+ }
169
+
170
+ /**
171
+ * Reading a page via HTTPS and returning its content.
172
+ *
173
+ * @param string $host
174
+ * @param string $username
175
+ * @param string $password
176
+ */
177
+ public function _getHttpsPage($host, $username, $password)
178
+ {
179
+ $client = new Varien_Http_Client();
180
+ $client->setUri($host)
181
+ ->setConfig(array('timeout' => 30))
182
+ ->setHeaders('accept-encoding', '')
183
+ ->setParameterGet(array())
184
+ ->setMethod(Zend_Http_Client::GET)
185
+ ->setAuth($username, $password);
186
+ $request = $client->request();
187
+ // Workaround for pseudo chunked messages which are yet too short, so
188
+ // only an exception is is thrown instead of returning raw body
189
+ if (!preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $request->getRawBody(), $m))
190
+ return $request->getRawBody();
191
+
192
+ return $request->getBody();
193
+ }
194
+
195
+ /**
196
+ * Reading a page via HTTP and returning its content.
197
+ *
198
+ * @param string $host
199
+ * @param array $params
200
+ */
201
+ public function _getHttpPage($host, $params)
202
+ {
203
+ $client = new Varien_Http_Client();
204
+ $client->setUri($host)
205
+ ->setConfig(array('timeout' => 30))
206
+ ->setHeaders('accept-encoding', '')
207
+ ->setParameterGet($params)
208
+ ->setMethod(Zend_Http_Client::GET);
209
+ $request = $client->request();
210
+ // Workaround for pseudo chunked messages which are yet too short, so
211
+ // only an exception is is thrown instead of returning raw body
212
+ if (!preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $request->getRawBody(), $m))
213
+ return $request->getRawBody();
214
+
215
+ return $request->getBody();
216
+ }
217
+
218
+ /**
219
+ * Sort Array by subkey
220
+ *
221
+ * @param array $inputArray
222
+ * @param string $subkey
223
+ * @return array
224
+ */
225
+ public function getArraySortedBySubkey($inputArray, $subkey)
226
+ {
227
+ $sortArray = array();
228
+
229
+ foreach ($inputArray as $key => $row) {
230
+ $sortArray[$key] = $row[$subkey];
231
+ }
232
+
233
+ array_multisort($sortArray, SORT_DESC, $inputArray);
234
+ return $inputArray;
235
+ }
236
+
237
+ /**
238
+ * Generates Product URLs with "recommended" param
239
+ *
240
+ * @param Mage_Catalog_Model_Product $product
241
+ * @return string
242
+ */
243
+ public function getProductUrl($product)
244
+ {
245
+ $params = array('_query' => array('recommended' => 1));
246
+ return $product->getUrlModel()->getUrl($product, $params);
247
+ }
248
+ }
app/code/community/AvS/Yoochoose/Model/Api.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Model_Api
10
+ {
11
+ const YOOCHOOSE_RECOMMENDATION_URL = 'http://reco.yoochoose.net/';
12
+ const YOOCHOOSE_EVENT_URL = 'http://event.yoochoose.net/';
13
+
14
+ const ITEM_TYPE_CATEGORY = 0;
15
+ const ITEM_TYPE_PRODUCT = 1;
16
+
17
+ const EVENT_TYPE_CLICK = 'click';
18
+ const EVENT_TYPE_BUY = 'buy';
19
+ const EVENT_TYPE_RECOMMENDATION = 'recommendation';
20
+ const EVENT_TYPE_TRANSFER = 'transfer';
21
+
22
+ const PRODUCT_ID = 'ebl';
23
+
24
+ /**
25
+ * Get User Id from Cookie, Session or Customer Object (if logged in)
26
+ *
27
+ * @return string
28
+ */
29
+ protected function _getUserId()
30
+ {
31
+ return Mage::helper('yoochoose')->getUserId();
32
+ }
33
+
34
+ /**
35
+ * return comma seperated category ids of current item (category or product)
36
+ *
37
+ * @return string
38
+ */
39
+ protected function _getCategoryPath() {
40
+
41
+ $category = Mage::registry('current_category');
42
+ if (!$category) return '';
43
+
44
+ $categoryPath = $category->getPathInStore();
45
+ return implode(',', array_reverse(explode(',', $categoryPath)));
46
+ }
47
+ }
app/code/community/AvS/Yoochoose/Model/Api/Event.php ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Model_Api_Event extends AvS_Yoochoose_Model_Api
10
+ {
11
+
12
+ /**
13
+ * On Category View Page: Generate Tracking Pixel Data
14
+ *
15
+ * @return array
16
+ */
17
+ public function getCategoryViewTrackingPixelData() {
18
+
19
+ $category = Mage::registry('current_category');
20
+ $categoryId = $category->getId();
21
+
22
+ $trackingPixelData = array(
23
+ 'ItemId' => $categoryId,
24
+ 'ItemTypeId' => self::ITEM_TYPE_CATEGORY,
25
+ 'CategoryPath' => $this->_getCategoryPath(),
26
+ 'Recommended' => 0, // only products get recommended
27
+ 'EventType' => self::EVENT_TYPE_CLICK,
28
+ );
29
+
30
+ return array($trackingPixelData);
31
+ }
32
+
33
+ /**
34
+ * On Product View Page: Generate Tracking Pixel Data
35
+ *
36
+ * @param boolean $isRecommended
37
+ * @return array
38
+ */
39
+ public function getProductViewTrackingPixelData($isRecommended = false) {
40
+
41
+ $product = Mage::registry('product');
42
+ $productId = $product->getId();
43
+
44
+ $trackingPixelData = array(
45
+ 'ItemId' => $productId,
46
+ 'ItemTypeId' => self::ITEM_TYPE_PRODUCT,
47
+ 'CategoryPath' => $this->_getCategoryPath(),
48
+ 'Recommended' => intval($isRecommended),
49
+ 'EventType' => self::EVENT_TYPE_CLICK,
50
+ );
51
+
52
+ return array($trackingPixelData);
53
+ }
54
+
55
+ /**
56
+ * On Checkout Success Page: Generate Tracking Pixel Data, one for each item
57
+ *
58
+ * @return array
59
+ */
60
+ public function getCheckoutSuccessTrackingPixelData() {
61
+
62
+ $orderId = Mage::getSingleton('checkout/session')->getLastOrderId();
63
+ $order = Mage::getModel('sales/order')->load($orderId);
64
+ $items = $order->getAllItems();
65
+
66
+ $timestamp = time();
67
+
68
+ $trackingPixelData = array();
69
+
70
+ foreach($items as $item) {
71
+
72
+ if ($item->getParentItem()) {
73
+
74
+ continue;
75
+ }
76
+
77
+ $trackingPixelData[] = $this->_generateItemData($item, $timestamp);
78
+ }
79
+
80
+ return $trackingPixelData;
81
+ }
82
+
83
+ /**
84
+ * After Login: Generate Tracking Pixel Data for switching UserIds
85
+ *
86
+ * @return array
87
+ */
88
+ public function getTransferTrackingPixelData() {
89
+
90
+ $transferInfoData = Mage::getSingleton('customer/session')->getTransferEventInfo();
91
+ if (!is_array($transferInfoData)) return array();
92
+
93
+ $trackingPixelData = array(
94
+ 'EventType' => self::EVENT_TYPE_TRANSFER,
95
+ 'userId' => $transferInfoData['old'],
96
+ 'newUserId' => $transferInfoData['new'],
97
+ );
98
+
99
+ Mage::getSingleton('customer/session')->unsetData('transfer_event_info');
100
+
101
+ return $trackingPixelData;
102
+ }
103
+
104
+ /**
105
+ * Generate order item data for tracking pixel
106
+ *
107
+ * @param Mage_Sales_Model_Order_Item $item
108
+ * @param int $timestamp
109
+ * @return array
110
+ */
111
+ protected function _generateItemData($item, $timestamp)
112
+ {
113
+ $productId = $item->getProductId();
114
+
115
+ return array(
116
+ 'ItemId' => $productId,
117
+ 'ItemTypeId' => self::ITEM_TYPE_PRODUCT,
118
+ 'Quantity' => intval($item->getQtyOrdered()),
119
+ 'Price' => intval($item->getBasePrice() * 100),
120
+ 'Currency' => $item->getOrder()->getBaseCurrency()->getCode(),
121
+ 'Timestamp' => $timestamp,
122
+ 'EventType' => self::EVENT_TYPE_BUY,
123
+ );
124
+ }
125
+
126
+ /**
127
+ * Generate Url from given Params and Generic Data
128
+ *
129
+ * @param array $trackingPixelData
130
+ * @return string
131
+ */
132
+ public function generateTrackingPixelUrl($trackingPixelData)
133
+ {
134
+ $baseUrl = self::YOOCHOOSE_EVENT_URL;
135
+
136
+ $primaryParams = $this->_getPrimaryParamsString($trackingPixelData);
137
+ $secondaryParams = $this->_getSecondaryParamsString($trackingPixelData);
138
+
139
+ $url = $baseUrl . $primaryParams . $secondaryParams;
140
+
141
+ return $url;
142
+ }
143
+
144
+ /**
145
+ * Generate String of primary params (as directories, divided by slash
146
+ *
147
+ * @param array $trackingPixelData
148
+ * @return string
149
+ */
150
+ protected function _getPrimaryParamsString($trackingPixelData)
151
+ {
152
+ $productId = self::PRODUCT_ID;
153
+ $clientId = Mage::getStoreConfig('yoochoose/api/client_id');
154
+ $eventType = $trackingPixelData['EventType'];
155
+
156
+ $primaryAttributesArray = array(
157
+ $productId,
158
+ $clientId,
159
+ $eventType,
160
+ );
161
+
162
+ if (isset($trackingPixelData['ItemTypeId']) && isset($trackingPixelData['ItemId'])) {
163
+
164
+ $userId = $this->_getUserId();
165
+ $itemType = $trackingPixelData['ItemTypeId'];
166
+ $itemId = urlencode($trackingPixelData['ItemId']);
167
+
168
+ $primaryAttributesArray[] = $userId;
169
+ $primaryAttributesArray[] = $itemType;
170
+ $primaryAttributesArray[] = $itemId;
171
+ }
172
+
173
+ if (isset($trackingPixelData['userId']) && isset($trackingPixelData['newUserId'])) {
174
+
175
+ $userId = $trackingPixelData['userId'];
176
+ $newUserId = $trackingPixelData['newUserId'];
177
+
178
+ $primaryAttributesArray[] = $userId;
179
+ $primaryAttributesArray[] = $newUserId;
180
+ }
181
+
182
+ $primaryAttributes = implode('/', $primaryAttributesArray);
183
+
184
+ return $primaryAttributes;
185
+ }
186
+
187
+ /**
188
+ * Generate String of secondary params (as default http params)
189
+ *
190
+ * @param array $trackingPixelData
191
+ * @return string
192
+ */
193
+ protected function _getSecondaryParamsString($trackingPixelData)
194
+ {
195
+ $secondaryParams = $this->_getSecondaryParams($trackingPixelData);
196
+ if (empty($secondaryParams)) {
197
+
198
+ return '';
199
+ }
200
+
201
+ $secondaryParamsString = '?';
202
+ $i = 0;
203
+ foreach($secondaryParams as $key => $value) {
204
+
205
+ if ($i > 0) {
206
+ $secondaryParamsString .= '&';
207
+ }
208
+ $secondaryParamsString .= $key . '=' . urlencode($value);
209
+ $i++;
210
+ }
211
+
212
+ return $secondaryParamsString;
213
+ }
214
+
215
+ /**
216
+ * Extract secondary params from all params; they are all params which have
217
+ * not been used yet
218
+ *
219
+ * @param array $trackingPixelData
220
+ * @return array
221
+ */
222
+ protected function _getSecondaryParams($trackingPixelData)
223
+ {
224
+ unset($trackingPixelData['EventType']);
225
+ unset($trackingPixelData['ItemTypeId']);
226
+ unset($trackingPixelData['ItemId']);
227
+ unset($trackingPixelData['userId']);
228
+ unset($trackingPixelData['newUserId']);
229
+
230
+ return $trackingPixelData;
231
+ }
232
+ }
app/code/community/AvS/Yoochoose/Model/Api/Recommendation.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Model_Api_Recommendation extends AvS_Yoochoose_Model_Api
10
+ {
11
+ const SCENARIO_ALSO_CLICKED = 'also_clicked';
12
+ const SCENARIO_ALSO_PURCHASED = 'also_purchased';
13
+ const SCENARIO_TOP_SELLING = 'top_selling';
14
+
15
+ protected $_recommendedProductIds = array();
16
+ protected $_numberProducts = 10;
17
+
18
+ /**
19
+ * Get Product Recommendations based on Client Id and License Key
20
+ *
21
+ * @param int $maxCount
22
+ * @return array
23
+ */
24
+ public function getRecommendedProducts($scenario, $maxCount = 10)
25
+ {
26
+
27
+ $url = $this->_getRecommendationBaseUrl($scenario);
28
+ $params = $this->_getRecommendationUrlParams($maxCount);
29
+
30
+ try {
31
+ $rawResponse = Mage::helper('yoochoose')->_getHttpPage($url, $params);
32
+ $response = Zend_Json::decode($rawResponse);
33
+
34
+ return $this->_getRecommendedProductsArray($response);
35
+ }
36
+ catch(Exception $e) {
37
+
38
+ Mage::logException($e);
39
+ // authentication failed
40
+ return array();
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Transform Response Array to Array of Products
46
+ *
47
+ * @param array $response
48
+ * @return array
49
+ */
50
+ protected function _getRecommendedProductsArray($response)
51
+ {
52
+ $responseArray = $response['recommendationResponseList'];
53
+ $responseArray = Mage::helper('yoochoose')->getArraySortedBySubkey($responseArray, 'relevance');
54
+
55
+ $recommendedProductsArray = array();
56
+ foreach($responseArray as $singleRecommendation) {
57
+
58
+ if ($singleRecommendation['itemType'] == 1) {
59
+
60
+ $product = Mage::getModel('catalog/product')->load($singleRecommendation['itemId']);
61
+ if ($product->getId()) {
62
+
63
+ $recommendedProductsArray[] = $product;
64
+ }
65
+ }
66
+ }
67
+
68
+ return $recommendedProductsArray;
69
+ }
70
+
71
+ /**
72
+ * Generate Base Url for Recommendation Request
73
+ *
74
+ * @param string $scenario
75
+ * @return string
76
+ */
77
+ protected function _getRecommendationBaseUrl($scenario)
78
+ {
79
+ $url = self::YOOCHOOSE_RECOMMENDATION_URL;
80
+ $path = array(
81
+ self::PRODUCT_ID,
82
+ self::EVENT_TYPE_RECOMMENDATION,
83
+ Mage::getStoreConfig('yoochoose/api/client_id'),
84
+ $this->_getUserId(),
85
+ $scenario . '.json',
86
+ );
87
+
88
+ return $url . implode('/', $path);
89
+ }
90
+
91
+ /**
92
+ * Generate Parameters for Recommendation URL
93
+ *
94
+ * @param int $maxCount
95
+ * @return array
96
+ */
97
+ protected function _getRecommendationUrlParams($maxCount)
98
+ {
99
+ return array(
100
+ 'categoryPath' => $this->_getCategoryPath(),
101
+ 'recnum' => min(10, $maxCount),
102
+ );
103
+ }
104
+
105
+ /**
106
+ * Merge two array of products; don't add duplicates
107
+ *
108
+ * @param array $itemArray1
109
+ * @param array $itemArray2
110
+ * @return array
111
+ */
112
+ public function mergeItemArrays($itemArray1, $itemArray2)
113
+ {
114
+ foreach($itemArray2 as $item) {
115
+
116
+ if (!in_array($item->getId(), $this->_recommendedProductIds)) {
117
+
118
+ $itemArray1[] = $item;
119
+
120
+ if (count($itemArray1) >= $this->getMaxNumberProducts()) {
121
+ break;
122
+ }
123
+ }
124
+ }
125
+
126
+ return $itemArray1;
127
+ }
128
+
129
+ /**
130
+ * Gets configured maximum number of recommended products
131
+ *
132
+ * @return int
133
+ */
134
+ public function getMaxNumberProducts()
135
+ {
136
+ return $this->_numberProducts;
137
+ }
138
+
139
+ /**
140
+ * Gets configured maximum number of recommended products
141
+ *
142
+ * @return int
143
+ */
144
+ public function setMaxNumberProducts($numberProducts)
145
+ {
146
+ $this->_numberProducts = $numberProducts;
147
+ }
148
+
149
+ /**
150
+ * Converts item collection to array
151
+ *
152
+ * @return array
153
+ */
154
+ public function getArrayFromItemCollection($itemCollection)
155
+ {
156
+ $itemArray = array();
157
+ foreach($itemCollection as $item) {
158
+
159
+ $itemArray[] = $item;
160
+ $this->_recommendedProductIds[] = $item->getId();
161
+ }
162
+
163
+ return $itemArray;
164
+ }
165
+ }
app/code/community/AvS/Yoochoose/Model/Api/Recommendation/Crossselling.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Model_Api_Recommendation_Crossselling extends AvS_Yoochoose_Model_Api_Recommendation
10
+ {
11
+ protected $_cartProductIds = array();
12
+
13
+ /**
14
+ * Gets configured maximum number of recommended products
15
+ *
16
+ * @return int
17
+ */
18
+ public function getMaxNumberProducts()
19
+ {
20
+ $maxNumberProducts = intval(Mage::getStoreConfig('yoochoose/crossselling/max_count'));
21
+
22
+ if ($maxNumberProducts > 0) {
23
+ return $maxNumberProducts;
24
+ } else {
25
+ return parent::getMaxNumberProducts();
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Generate Parameters for Recommendation URL
31
+ *
32
+ * @param int $maxCount
33
+ * @return array
34
+ */
35
+ protected function _getRecommendationUrlParams($maxCount)
36
+ {
37
+ $cartProductIds = $this->_getCartProductIds();
38
+
39
+ return array(
40
+ 'contextItems' => implode(',', $cartProductIds),
41
+ 'recnum' => min(10, $maxCount),
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Get all Product Ids of customer cart
47
+ *
48
+ * @return array
49
+ */
50
+ protected function _getCartProductIds()
51
+ {
52
+ if (empty($this->_cartProductIds)) {
53
+
54
+ /** @var $checkoutSession Mage_Checkout_Model_Session */
55
+ $checkoutSession = Mage::getSingleton('checkout/session');
56
+ $cartItems = $checkoutSession->getQuote()->getAllItems();
57
+
58
+ foreach($cartItems as $item) {
59
+
60
+ if ($item->getParentItem()) {
61
+
62
+ continue;
63
+ }
64
+
65
+ $this->_cartProductIds[] = $item->getProductId();
66
+ }
67
+ }
68
+
69
+ return $this->_cartProductIds;
70
+ }
71
+
72
+ /**
73
+ * Merge two array of products; don't add duplicates
74
+ *
75
+ * @param array $itemArray1
76
+ * @param array $itemArray2
77
+ * @return array
78
+ */
79
+ public function mergeItemArrays($itemArray1, $itemArray2)
80
+ {
81
+ foreach($itemArray2 as $item) {
82
+
83
+ if (!in_array($item->getId(), $this->_recommendedProductIds) && !in_array($item->getId(), $this->_getCartProductIds())) {
84
+
85
+ $itemArray1[] = $item;
86
+
87
+ if (count($itemArray1) >= $this->getMaxNumberProducts()) {
88
+ break;
89
+ }
90
+ }
91
+ }
92
+
93
+ return $itemArray1;
94
+ }
95
+ }
app/code/community/AvS/Yoochoose/Model/Api/Recommendation/Related.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Model_Api_Recommendation_Related extends AvS_Yoochoose_Model_Api_Recommendation
10
+ {
11
+ /**
12
+ * Gets configured maximum number of recommended products
13
+ *
14
+ * @return int
15
+ */
16
+ public function getMaxNumberProducts()
17
+ {
18
+ $maxNumberProducts = intval(Mage::getStoreConfig('yoochoose/related/max_count'));
19
+
20
+ if ($maxNumberProducts > 0) {
21
+ return $maxNumberProducts;
22
+ } else {
23
+ return parent::getMaxNumberProducts();
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Generate Parameters for Recommendation URL
29
+ *
30
+ * @param int $maxCount
31
+ * @return array
32
+ */
33
+ protected function _getRecommendationUrlParams($maxCount)
34
+ {
35
+ $product = Mage::registry('product');
36
+
37
+ return array(
38
+ 'itemId' => $product->getId(),
39
+ 'categoryPath' => $this->_getCategoryPath(),
40
+ 'recnum' => min(10, $maxCount),
41
+ );
42
+ }
43
+ }
app/code/community/AvS/Yoochoose/Model/Api/Recommendation/Upselling.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Model_Api_Recommendation_Upselling extends AvS_Yoochoose_Model_Api_Recommendation
10
+ {
11
+ /**
12
+ * Gets configured maximum number of recommended products
13
+ *
14
+ * @return int
15
+ */
16
+ public function getMaxNumberProducts()
17
+ {
18
+ $maxNumberProducts = intval(Mage::getStoreConfig('yoochoose/upselling/max_count'));
19
+
20
+ if ($maxNumberProducts > 0) {
21
+ return $maxNumberProducts;
22
+ } else {
23
+ return parent::getMaxNumberProducts();
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Generate Parameters for Recommendation URL
29
+ *
30
+ * @param int $maxCount
31
+ * @return array
32
+ */
33
+ protected function _getRecommendationUrlParams($maxCount)
34
+ {
35
+ $product = Mage::registry('product');
36
+
37
+ return array(
38
+ 'itemId' => $product->getId(),
39
+ 'categoryPath' => $this->_getCategoryPath(),
40
+ 'recnum' => min(10, $maxCount),
41
+ );
42
+ }
43
+ }
app/code/community/AvS/Yoochoose/Model/Observer.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category AvS
5
+ * @package AvS_Yoochoose
6
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
7
+ */
8
+
9
+ class AvS_Yoochoose_Model_Observer
10
+ {
11
+ const YOOCHOOSE_LICENSE_URL = 'https://config.yoochoose.net/ebl/%customer_id%/license.json';
12
+ const YOOCHOOSE_SUMMARY_URL = 'https://config.yoochoose.net/rest/%customer_id%/counter/summary.json';
13
+
14
+ /**
15
+ * Update field "yoochoose_user_id" from session to
16
+ * customer object (database) or vice verse, if customer info already exists
17
+ *
18
+ * @param Varien_Event_Observer $observer
19
+ */
20
+ public function onCustomerLogin($observer)
21
+ {
22
+ $customer = $observer->getEvent()->getCustomer();
23
+ Mage::helper('yoochoose')->mergeUserIdOnLogin();
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @param Varien_Event_Observer $observer
29
+ */
30
+ public function adminSystemConfigChangedSectionYoochoose($observer)
31
+ {
32
+ $clientId = Mage::getStoreConfig('yoochoose/api/client_id');
33
+ $licenseKey = Mage::getStoreConfig('yoochoose/api/license_key');
34
+
35
+ if (!$clientId && !$licenseKey) return;
36
+
37
+ $licenseType = $this->_getLicenseType($clientId, $licenseKey);
38
+
39
+ $this->_displayMessage($licenseType);
40
+
41
+ if ($licenseType != Mage::getStoreConfig('yoochoose/api/license_type')) {
42
+ Mage::getSingleton('core/resource_setup')->setConfigData('yoochoose/api/license_type', $licenseType);
43
+ Mage::getSingleton('core/config')->reinit();
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Display success or error message, depending on license type
49
+ *
50
+ * @param string $licenseType
51
+ */
52
+ protected function _displayMessage($licenseType)
53
+ {
54
+ if ($licenseType && $licenseType != Mage::getStoreConfig('yoochoose/api/license_type')) {
55
+ Mage::getSingleton('adminhtml/session')->addSuccess(
56
+ Mage::helper('yoochoose')->__('License successfully verified.')
57
+ );
58
+ } else if (!$licenseType) {
59
+ Mage::getSingleton('adminhtml/session')->addError(
60
+ Mage::helper('yoochoose')->__('License could not be verified.')
61
+ );
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Get License Type base on Client Id and License Key
67
+ *
68
+ * @param string $clientId
69
+ * @param string $licenseKey
70
+ * @return string
71
+ */
72
+ protected function _getLicenseType($clientId, $licenseKey)
73
+ {
74
+ $url = str_replace('%customer_id%', $clientId, self::YOOCHOOSE_LICENSE_URL);
75
+ try {
76
+ $rawResponse = Mage::helper('yoochoose')->_getHttpsPage($url, $clientId, $licenseKey);
77
+ $response = Zend_Json::decode($rawResponse);
78
+ return $response['license']['type'];
79
+ }
80
+ catch(Exception $e) {
81
+
82
+ // authentication failed
83
+ return '';
84
+ }
85
+ }
86
+
87
+ public function updateStats()
88
+ {
89
+ $clientId = Mage::getStoreConfig('yoochoose/api/client_id');
90
+ $licenseKey = Mage::getStoreConfig('yoochoose/api/license_key');
91
+
92
+ if (!$clientId && !$licenseKey) return;
93
+
94
+ $stats = $this->_getStats($clientId, $licenseKey);
95
+
96
+ $statsHtml = $this->_generateStatsHtml($stats);
97
+ if ($statsHtml) {
98
+
99
+ Mage::getSingleton('core/resource_setup')->setConfigData('yoochoose/general/stats', $statsHtml);
100
+ Mage::getSingleton('core/config')->reinit();
101
+ }
102
+
103
+ return $statsHtml;
104
+ }
105
+
106
+ /**
107
+ * Get Statistics bases on Client Id and License Key
108
+ *
109
+ * @param string $clientId
110
+ * @param string $licenseKey
111
+ * @return array
112
+ */
113
+ protected function _getStats($clientId, $licenseKey)
114
+ {
115
+ $url = str_replace('%customer_id%', $clientId, self::YOOCHOOSE_SUMMARY_URL);
116
+ try {
117
+ $rawResponse = Mage::helper('yoochoose')->_getHttpsPage($url, $clientId, $licenseKey);
118
+ $response = Zend_Json::decode($rawResponse);
119
+ return $response;
120
+ }
121
+ catch(Exception $e) {
122
+
123
+ // authentication failed
124
+ return array();
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Generate Statistics HTML for display in configuration
130
+ *
131
+ * @param array $stats
132
+ * @return string
133
+ */
134
+ protected function _generateStatsHtml($stats)
135
+ {
136
+ $statsHtml = '<table>';
137
+ $statsLines = array();
138
+ $baseSorting = 6;
139
+
140
+ foreach($stats as $key => $singleStat) {
141
+
142
+ switch ($key) {
143
+
144
+ case 'EVENT_1':
145
+
146
+ $label = Mage::helper('yoochoose')->__('Registered Clicks');
147
+ $sorting = 0;
148
+ break;
149
+
150
+ case 'EVENT_2':
151
+
152
+ $label = Mage::helper('yoochoose')->__('Registered Buys');
153
+ $sorting = 1;
154
+ break;
155
+
156
+ case 'RECO_also_purchased':
157
+
158
+ $label = Mage::helper('yoochoose')->__('"Also purchased" recommendations');
159
+ $sorting = 3;
160
+ break;
161
+
162
+ case 'RECO_also_clicked':
163
+
164
+ $label = Mage::helper('yoochoose')->__('"Also clicked" recommendations');
165
+ $sorting = 4;
166
+ break;
167
+
168
+ case 'RECO_top_selling':
169
+
170
+ $label = Mage::helper('yoochoose')->__('"Top selling" recommendations');
171
+ $sorting = 5;
172
+ break;
173
+
174
+ default:
175
+
176
+ $label = $key;
177
+ $sorting = $baseSorting;
178
+ $baseSorting++;
179
+ break;
180
+ }
181
+
182
+ $statsLines[$sorting] = '<tr><td>' . $label . ':&nbsp;</td><td>' . $singleStat['count'] . '</td></tr>';
183
+ }
184
+
185
+ $statsLines[2] = '<tr><td>----------</td><td>&nbsp;</td></tr>';
186
+
187
+ ksort($statsLines);
188
+ $statsHtml .= implode("\n", $statsLines);
189
+
190
+ $statsHtml .= '</table>';
191
+
192
+ return $statsHtml;
193
+ }
194
+ }
app/code/community/AvS/Yoochoose/etc/config.xml ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+
4
+ <modules>
5
+ <AvS_Yoochoose>
6
+ <version>1.1.0</version>
7
+ </AvS_Yoochoose>
8
+ </modules>
9
+
10
+ <global>
11
+
12
+ <resources>
13
+ <yoochoose_setup>
14
+ <setup>
15
+ <module>AvS_Yoochoose</module>
16
+ <class>Mage_Customer_Model_Entity_Setup</class>
17
+ </setup>
18
+ <connection>
19
+ <use>core_setup</use>
20
+ </connection>
21
+ </yoochoose_setup>
22
+ </resources>
23
+
24
+ <models>
25
+ <yoochoose>
26
+ <class>AvS_Yoochoose_Model</class>
27
+ </yoochoose>
28
+ </models>
29
+
30
+ <helpers>
31
+ <yoochoose>
32
+ <class>AvS_Yoochoose_Helper</class>
33
+ </yoochoose>
34
+ </helpers>
35
+
36
+ <blocks>
37
+ <yoochoose>
38
+ <class>AvS_Yoochoose_Block</class>
39
+ </yoochoose>
40
+ <catalog>
41
+ <rewrite>
42
+ <product_list_upsell>AvS_Yoochoose_Block_Upsell</product_list_upsell>
43
+ <product_list_related>AvS_Yoochoose_Block_Related</product_list_related>
44
+ </rewrite>
45
+ </catalog>
46
+ <checkout>
47
+ <rewrite>
48
+ <cart_crosssell>AvS_Yoochoose_Block_Crosssell</cart_crosssell>
49
+ </rewrite>
50
+ </checkout>
51
+ </blocks>
52
+
53
+ </global>
54
+
55
+ <frontend>
56
+
57
+ <events>
58
+ <customer_login>
59
+ <observers>
60
+ <yoochoose>
61
+ <type>singleton</type>
62
+ <class>yoochoose/observer</class>
63
+ <method>onCustomerLogin</method>
64
+ </yoochoose>
65
+ </observers>
66
+ </customer_login>
67
+ </events>
68
+
69
+ <layout>
70
+ <updates>
71
+ <yoochoose>
72
+ <file>yoochoose.xml</file>
73
+ </yoochoose>
74
+ </updates>
75
+ </layout>
76
+
77
+ <translate>
78
+ <modules>
79
+ <AvS_Yoochoose>
80
+ <files>
81
+ <default>AvS_Yoochoose.csv</default>
82
+ </files>
83
+ </AvS_Yoochoose>
84
+ </modules>
85
+ </translate>
86
+
87
+ </frontend>
88
+
89
+ <adminhtml>
90
+
91
+ <events>
92
+ <admin_system_config_changed_section_yoochoose>
93
+ <observers>
94
+ <yoochoose>
95
+ <type>singleton</type>
96
+ <class>yoochoose/observer</class>
97
+ <method>adminSystemConfigChangedSectionYoochoose</method>
98
+ </yoochoose>
99
+ </observers>
100
+ </admin_system_config_changed_section_yoochoose>
101
+ <admin_user_authenticate_after>
102
+ <observers>
103
+ <yoochoose>
104
+ <type>singleton</type>
105
+ <class>yoochoose/observer</class>
106
+ <method>updateStats</method>
107
+ </yoochoose>
108
+ </observers>
109
+ </admin_user_authenticate_after>
110
+ </events>
111
+
112
+ <acl>
113
+ <resources>
114
+ <admin>
115
+ <children>
116
+ <system>
117
+ <children>
118
+ <config>
119
+ <children>
120
+ <yoochoose translate="title" module="yoochoose">
121
+ <title>Yoochoose</title>
122
+ </yoochoose>
123
+ </children>
124
+ </config>
125
+ </children>
126
+ </system>
127
+ </children>
128
+ </admin>
129
+ </resources>
130
+ </acl>
131
+
132
+ <translate>
133
+ <modules>
134
+ <AvS_Yoochoose>
135
+ <files>
136
+ <default>AvS_Yoochoose.csv</default>
137
+ </files>
138
+ </AvS_Yoochoose>
139
+ </modules>
140
+ </translate>
141
+
142
+ </adminhtml>
143
+
144
+ <default>
145
+ <yoochoose>
146
+ <general>
147
+ <disabled>0</disabled>
148
+ </general>
149
+ <crossselling>
150
+ <display_yoochoose_recommendations>0</display_yoochoose_recommendations>
151
+ <scenario>also_purchased</scenario>
152
+ <prefer_manual_connections>1</prefer_manual_connections>
153
+ <max_count>4</max_count>
154
+ </crossselling>
155
+ <upselling>
156
+ <display_yoochoose_recommendations>0</display_yoochoose_recommendations>
157
+ <scenario>also_clicked</scenario>
158
+ <prefer_manual_connections>1</prefer_manual_connections>
159
+ <max_count>4</max_count>
160
+ </upselling>
161
+ <related>
162
+ <display_yoochoose_recommendations>0</display_yoochoose_recommendations>
163
+ <scenario>top_selling</scenario>
164
+ <prefer_manual_connections>1</prefer_manual_connections>
165
+ <max_count>4</max_count>
166
+ </related>
167
+ </yoochoose>
168
+ </default>
169
+
170
+ <crontab>
171
+ <translate>
172
+ <modules>
173
+ <AvS_Yoochoose>
174
+ <files>
175
+ <default>AvS_Yoochoose.csv</default>
176
+ </files>
177
+ </AvS_Yoochoose>
178
+ </modules>
179
+ </translate>
180
+
181
+ <jobs>
182
+ <yoochoose_update_stats>
183
+ <schedule><cron_expr>0 * * * *</cron_expr></schedule>
184
+ <run><model>yoochoose/observer::updateStats</model></run>
185
+ </yoochoose_update_stats>
186
+ </jobs>
187
+ </crontab>
188
+ </config>
app/code/community/AvS/Yoochoose/etc/system.xml ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <yoochoose translate="label" module="yoochoose">
5
+ <label>Yoochoose</label>
6
+ <tab>catalog</tab>
7
+ <sort_order>990</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 translate="label">
13
+ <label>General Settings</label>
14
+ <sort_order>10</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>1</show_in_store>
18
+ <comment><![CDATA[
19
+ <script type="text/javascript">
20
+ document.observe("dom:loaded", function() {
21
+ $('yoochoose_general_stats').replace($('yoochoose_general_stats').value);
22
+ });
23
+ </script>
24
+ ]]></comment>
25
+ <fields>
26
+ <disabled translate="label">
27
+ <label>Disabled</label>
28
+ <frontend_type>select</frontend_type>
29
+ <source_model>adminhtml/system_config_source_yesno</source_model>
30
+ <sort_order>10</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>1</show_in_website>
33
+ <show_in_store>1</show_in_store>
34
+ </disabled>
35
+ <stats translate="label">
36
+ <label>Statistics</label>
37
+ <frontend_type>textarea</frontend_type>
38
+ <sort_order>20</sort_order>
39
+ <show_in_default>1</show_in_default>
40
+ <show_in_website>1</show_in_website>
41
+ <show_in_store>1</show_in_store>
42
+ </stats>
43
+ </fields>
44
+ </general>
45
+ <api translate="label">
46
+ <label>API Settings</label>
47
+ <sort_order>20</sort_order>
48
+ <show_in_default>1</show_in_default>
49
+ <show_in_website>1</show_in_website>
50
+ <show_in_store>1</show_in_store>
51
+ <comment><![CDATA[
52
+ <script type="text/javascript">
53
+ document.observe("dom:loaded", function() {
54
+ $('yoochoose_api_license_type').disabled = true;
55
+ });
56
+ </script>
57
+ ]]></comment>
58
+ <fields>
59
+ <client_id translate="label,comment">
60
+ <label>Yoochoose Client ID</label>
61
+ <comment><![CDATA[If you don't have a Client ID yet, <a href="http://config.yoochoose.net" target="_blank">click here</a>.]]></comment>
62
+ <frontend_type>text</frontend_type>
63
+ <sort_order>10</sort_order>
64
+ <show_in_default>1</show_in_default>
65
+ <show_in_website>1</show_in_website>
66
+ <show_in_store>1</show_in_store>
67
+ </client_id>
68
+ <license_key translate="label">
69
+ <label>Yoochoose License Key</label>
70
+ <frontend_type>text</frontend_type>
71
+ <sort_order>20</sort_order>
72
+ <show_in_default>1</show_in_default>
73
+ <show_in_website>1</show_in_website>
74
+ <show_in_store>1</show_in_store>
75
+ </license_key>
76
+ <license_type translate="label,comment">
77
+ <label>Yoochoose License Type</label>
78
+ <comment>Will be filled automatically after saving with correct license data</comment>
79
+ <frontend_type>text</frontend_type>
80
+ <sort_order>30</sort_order>
81
+ <show_in_default>1</show_in_default>
82
+ <show_in_website>1</show_in_website>
83
+ <show_in_store>1</show_in_store>
84
+ </license_type>
85
+ </fields>
86
+ </api>
87
+ <crossselling translate="label">
88
+ <label>Cross Selling</label>
89
+ <sort_order>40</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
+ <fields>
94
+ <display_yoochoose_recommendations translate="label">
95
+ <label>Display Yoochoose Recommendations in Crossselling Block</label>
96
+ <frontend_type>select</frontend_type>
97
+ <source_model>adminhtml/system_config_source_yesno</source_model>
98
+ <sort_order>10</sort_order>
99
+ <show_in_default>1</show_in_default>
100
+ <show_in_website>1</show_in_website>
101
+ <show_in_store>1</show_in_store>
102
+ </display_yoochoose_recommendations>
103
+ <scenario translate="label">
104
+ <label>Scenario used</label>
105
+ <frontend_type>text</frontend_type>
106
+ <sort_order>15</sort_order>
107
+ <show_in_default>1</show_in_default>
108
+ <show_in_website>1</show_in_website>
109
+ <show_in_store>1</show_in_store>
110
+ </scenario>
111
+ <prefer_manual_connections translate="label,comment">
112
+ <label>Prefer manually entered Connections</label>
113
+ <frontend_type>select</frontend_type>
114
+ <source_model>adminhtml/system_config_source_yesno</source_model>
115
+ <sort_order>20</sort_order>
116
+ <show_in_default>1</show_in_default>
117
+ <show_in_website>1</show_in_website>
118
+ <show_in_store>1</show_in_store>
119
+ <comment>Don't display otherwise</comment>
120
+ </prefer_manual_connections>
121
+ <max_count translate="label">
122
+ <label>Max count of recommendations</label>
123
+ <frontend_type>text</frontend_type>
124
+ <sort_order>30</sort_order>
125
+ <show_in_default>1</show_in_default>
126
+ <show_in_website>1</show_in_website>
127
+ <show_in_store>1</show_in_store>
128
+ </max_count>
129
+ </fields>
130
+ </crossselling>
131
+ <upselling translate="label">
132
+ <label>Up Selling</label>
133
+ <sort_order>50</sort_order>
134
+ <show_in_default>1</show_in_default>
135
+ <show_in_website>1</show_in_website>
136
+ <show_in_store>1</show_in_store>
137
+ <fields>
138
+ <display_yoochoose_recommendations translate="label">
139
+ <label>Display Yoochoose Recommendations in Upselling Block</label>
140
+ <frontend_type>select</frontend_type>
141
+ <source_model>adminhtml/system_config_source_yesno</source_model>
142
+ <sort_order>10</sort_order>
143
+ <show_in_default>1</show_in_default>
144
+ <show_in_website>1</show_in_website>
145
+ <show_in_store>1</show_in_store>
146
+ </display_yoochoose_recommendations>
147
+ <scenario translate="label">
148
+ <label>Scenario used</label>
149
+ <frontend_type>text</frontend_type>
150
+ <sort_order>15</sort_order>
151
+ <show_in_default>1</show_in_default>
152
+ <show_in_website>1</show_in_website>
153
+ <show_in_store>1</show_in_store>
154
+ </scenario>
155
+ <prefer_manual_connections translate="label,comment">
156
+ <label>Prefer manually entered Connections</label>
157
+ <frontend_type>select</frontend_type>
158
+ <source_model>adminhtml/system_config_source_yesno</source_model>
159
+ <sort_order>20</sort_order>
160
+ <show_in_default>1</show_in_default>
161
+ <show_in_website>1</show_in_website>
162
+ <show_in_store>1</show_in_store>
163
+ <comment>Don't display otherwise</comment>
164
+ </prefer_manual_connections>
165
+ <max_count translate="label">
166
+ <label>Max count of recommendations</label>
167
+ <frontend_type>text</frontend_type>
168
+ <sort_order>30</sort_order>
169
+ <show_in_default>1</show_in_default>
170
+ <show_in_website>1</show_in_website>
171
+ <show_in_store>1</show_in_store>
172
+ </max_count>
173
+ </fields>
174
+ </upselling>
175
+ <related translate="label">
176
+ <label>Related Products</label>
177
+ <sort_order>60</sort_order>
178
+ <show_in_default>1</show_in_default>
179
+ <show_in_website>1</show_in_website>
180
+ <show_in_store>1</show_in_store>
181
+ <fields>
182
+ <display_yoochoose_recommendations translate="label">
183
+ <label>Display Yoochoose Recommendations in Related Products Block</label>
184
+ <frontend_type>select</frontend_type>
185
+ <source_model>adminhtml/system_config_source_yesno</source_model>
186
+ <sort_order>10</sort_order>
187
+ <show_in_default>1</show_in_default>
188
+ <show_in_website>1</show_in_website>
189
+ <show_in_store>1</show_in_store>
190
+ </display_yoochoose_recommendations>
191
+ <scenario translate="label">
192
+ <label>Scenario used</label>
193
+ <frontend_type>text</frontend_type>
194
+ <sort_order>15</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
+ </scenario>
199
+ <prefer_manual_connections translate="label,comment">
200
+ <label>Prefer manually entered Connections</label>
201
+ <frontend_type>select</frontend_type>
202
+ <source_model>adminhtml/system_config_source_yesno</source_model>
203
+ <sort_order>20</sort_order>
204
+ <show_in_default>1</show_in_default>
205
+ <show_in_website>1</show_in_website>
206
+ <show_in_store>1</show_in_store>
207
+ <comment>Don't display otherwise</comment>
208
+ </prefer_manual_connections>
209
+ <max_count translate="label">
210
+ <label>Max count of recommendations</label>
211
+ <frontend_type>text</frontend_type>
212
+ <sort_order>30</sort_order>
213
+ <show_in_default>1</show_in_default>
214
+ <show_in_website>1</show_in_website>
215
+ <show_in_store>1</show_in_store>
216
+ </max_count>
217
+ </fields>
218
+ </related>
219
+ </groups>
220
+ </yoochoose>
221
+ </sections>
222
+ </config>
app/code/community/AvS/Yoochoose/sql/yoochoose_setup/mysql4-install-0.1.0.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+
6
+ $installer->addAttribute('customer', 'yoochoose_user_id', array(
7
+ 'label' => Mage::helper('yoochoose')->__('Yoochoose User Id'),
8
+ 'type' => 'varchar',
9
+ 'visible' => false,
10
+ 'required' => false,
11
+ 'input' => 'hidden',
12
+ ));
13
+
14
+ $installer->endSetup();
app/design/frontend/base/default/layout/yoochoose.xml ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+
4
+ <default>
5
+
6
+ <!-- Yoochoose Tracking -->
7
+ <reference name="before_body_end">
8
+ <block type="yoochoose/tracking" name="yoochoose.tracking" template="yoochoose/tracking.phtml" />
9
+ <!-- disable again if necessary -->
10
+ <action method="unsetChild" ifconfig="yoochoose/general/disabled">
11
+ <name>yoochoose.tracking</name>
12
+ </action>
13
+ </reference>
14
+
15
+ </default>
16
+
17
+ <catalog_product_view>
18
+ <reference name="product.info.upsell">
19
+ <action method="setTemplate" ifconfig="yoochoose/upselling/display_yoochoose_recommendations">
20
+ <template>yoochoose/upsell.phtml</template>
21
+ </action>
22
+ </reference>
23
+ <reference name="catalog.product.related">
24
+ <action method="setTemplate" ifconfig="yoochoose/related/display_yoochoose_recommendations">
25
+ <template>yoochoose/related.phtml</template>
26
+ </action>
27
+ </reference>
28
+ </catalog_product_view>
29
+
30
+ <checkout_cart_index>
31
+ <reference name="checkout.cart.crosssell">
32
+ <action method="setTemplate" ifconfig="yoochoose/crossselling/display_yoochoose_recommendations">
33
+ <template>yoochoose/crosssell.phtml</template>
34
+ </action>
35
+ </reference>
36
+ </checkout_cart_index>
37
+
38
+ </layout>
app/design/frontend/base/default/template/yoochoose/crosssell.phtml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cart cross sell items template
4
+ *
5
+ * @see Mage_Checkout_Block_Cart_Crosssell
6
+ */
7
+ ?>
8
+ <?php $itemArray = $this->getItemArray() ?>
9
+ <?php if(count($itemArray)): ?>
10
+ <div class="crosssell">
11
+ <h2><?php echo $this->__('Based on your selection, you may be interested in the following items:') ?></h2>
12
+ <ul id="crosssell-products-list">
13
+ <?php foreach ($itemArray as $_item): ?>
14
+ <li class="item">
15
+ <a class="product-image" href="<?php echo Mage::helper('yoochoose')->getProductUrl($_item) ?>" title="<?php echo $this->htmlEscape($_item->getName()) ?>"><img src="<?php echo $this->helper('catalog/image')->init($_item, 'thumbnail')->resize(75); ?>" width="75" height="75" alt="<?php echo $this->htmlEscape($_item->getName()) ?>" /></a>
16
+ <div class="product-details">
17
+ <h3 class="product-name"><a href="<?php echo Mage::helper('yoochoose')->getProductUrl($_item) ?>"><?php echo $this->htmlEscape($_item->getName()) ?></a></h3>
18
+ <?php echo $this->getPriceHtml($_item, true) ?>
19
+ <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_item) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
20
+ <ul class="add-to-links">
21
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
22
+ <li><a href="<?php echo $this->getAddToWishlistUrl($_item) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
23
+ <?php endif; ?>
24
+ <?php if($_compareUrl=$this->getAddToCompareUrl($_item)): ?>
25
+ <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
26
+ <?php endif; ?>
27
+ </ul>
28
+ </div>
29
+ </li>
30
+ <?php endforeach; ?>
31
+ </ul>
32
+ <script type="text/javascript">decorateList('crosssell-products-list', 'none-recursive')</script>
33
+ </div>
34
+ <?php endif; ?>
app/design/frontend/base/default/template/yoochoose/recommendation.phtml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @category AvS
4
+ * @package AvS_Yoochoose
5
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
6
+ */
7
+ ?>
8
+ <?php $_helper = $this->helper('catalog/output') ?>
9
+
10
+ <?php $itemArray = $this->getItemArray() ?>
11
+ <?php if(count($itemArray)): ?>
12
+ <div class="category-products">
13
+
14
+ <?php $_collectionSize = count($itemArray) ?>
15
+ <?php $_columnCount = $this->getColumnCount(); ?>
16
+ <?php $i=0; foreach ($itemArray as $_product): ?>
17
+ <?php if ($i++%$_columnCount==0): ?>
18
+ <ul class="products-grid">
19
+ <?php endif ?>
20
+ <li class="item<?php if(($i-1)%$_columnCount==0): ?> first<?php elseif($i%$_columnCount==0): ?> last<?php endif; ?>">
21
+ <a href="<?php echo Mage::helper('yoochoose')->getProductUrl($_product) ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" /></a>
22
+ <h2 class="product-name"><a href="<?php echo Mage::helper('yoochoose')->getProductUrl($_product) ?>" title="<?php echo $this->stripTags($_product->getName(), null, true) ?>"><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></a></h2>
23
+ <?php if($_product->getRatingSummary()): ?>
24
+ <?php echo $this->getReviewsSummaryHtml($_product, 'short') ?>
25
+ <?php endif; ?>
26
+ <?php echo $this->getPriceHtml($_product, true) ?>
27
+ <div class="actions">
28
+ <?php if($_product->isSaleable()): ?>
29
+ <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
30
+ <?php else: ?>
31
+ <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
32
+ <?php endif; ?>
33
+ <ul class="add-to-links">
34
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
35
+ <li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
36
+ <?php endif; ?>
37
+ <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
38
+ <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
39
+ <?php endif; ?>
40
+ </ul>
41
+ </div>
42
+ </li>
43
+ <?php if ($i%$_columnCount==0 || $i==$_collectionSize): ?>
44
+ </ul>
45
+ <?php endif ?>
46
+ <?php endforeach ?>
47
+ <script type="text/javascript">decorateGeneric($$('ul.products-grid'), ['odd','even','first','last'])</script>
48
+
49
+ </div>
50
+ <?php endif ?>
app/design/frontend/base/default/template/yoochoose/related.phtml ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $itemArray = $this->getItemArray() ?>
2
+ <?php if(count($itemArray)): ?>
3
+ <div class="block block-related">
4
+ <div class="block-title">
5
+ <strong><span><?php echo $this->__('Related Products') ?></span></strong>
6
+ </div>
7
+ <div class="block-content">
8
+ <p class="block-subtitle"><?php echo $this->__('Check items to add to the cart or') ?>&nbsp;<a href="#" onclick="selectAllRelated(this); return false;"><?php echo $this->__('select all') ?></a></p>
9
+ <ol class="mini-products-list" id="block-related">
10
+ <?php foreach($itemArray as $_item): ?>
11
+ <li class="item">
12
+ <?php if(!$_item->isComposite() && $_item->isSaleable()): ?>
13
+ <?php if (!$_item->getRequiredOptions()): ?>
14
+ <input type="checkbox" class="checkbox related-checkbox" id="related-checkbox<?php echo $_item->getId() ?>" name="related_products[]" value="<?php echo $_item->getId() ?>" />
15
+ <?php endif; ?>
16
+ <?php endif; ?>
17
+ <div class="product">
18
+ <a href="<?php echo Mage::helper('yoochoose')->getProductUrl($_item) ?>" title="<?php echo $this->htmlEscape($_item->getName()) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_item, 'thumbnail')->resize(50) ?>" width="50" height="50" alt="<?php echo $this->htmlEscape($_item->getName()) ?>" /></a>
19
+ <div class="product-details">
20
+ <p class="product-name"><a href="<?php echo Mage::helper('yoochoose')->getProductUrl($_item) ?>"><?php echo $this->htmlEscape($_item->getName()) ?></a></p>
21
+ <?php echo $this->getPriceHtml($_item, true, '-related') ?>
22
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
23
+ <a href="<?php echo $this->getAddToWishlistUrl($_item) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a>
24
+ <?php endif; ?>
25
+ </div>
26
+ </div>
27
+ </li>
28
+ <?php endforeach ?>
29
+ </ol>
30
+ <script type="text/javascript">decorateList('block-related', 'none-recursive')</script>
31
+ </div>
32
+ <script type="text/javascript">
33
+ //<![CDATA[
34
+ $$('.related-checkbox').each(function(elem){
35
+ Event.observe(elem, 'click', addRelatedToProduct)
36
+ });
37
+
38
+ var relatedProductsCheckFlag = false;
39
+ function selectAllRelated(txt){
40
+ if (relatedProductsCheckFlag == false) {
41
+ $$('.related-checkbox').each(function(elem){
42
+ elem.checked = true;
43
+ });
44
+ relatedProductsCheckFlag = true;
45
+ txt.innerHTML="<?php echo $this->__('unselect all') ?>";
46
+ } else {
47
+ $$('.related-checkbox').each(function(elem){
48
+ elem.checked = false;
49
+ });
50
+ relatedProductsCheckFlag = false;
51
+ txt.innerHTML="<?php echo $this->__('select all') ?>";
52
+ }
53
+ addRelatedToProduct();
54
+ }
55
+
56
+ function addRelatedToProduct(){
57
+ var checkboxes = $$('.related-checkbox');
58
+ var values = [];
59
+ for(var i=0;i<checkboxes.length;i++){
60
+ if(checkboxes[i].checked) values.push(checkboxes[i].value);
61
+ }
62
+ if($('related-products-field')){
63
+ $('related-products-field').value = values.join(',');
64
+ }
65
+ }
66
+ //]]>
67
+ </script>
68
+ </div>
69
+ <?php endif ?>
app/design/frontend/base/default/template/yoochoose/tracking.phtml ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @category AvS
4
+ * @package AvS_Yoochoose
5
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
6
+ */
7
+
8
+ /** @var $this AvS_Yoochoose_Block_Tracking */
9
+ ?>
10
+
11
+ <?php if (Mage::helper('yoochoose')->isActive() && sizeof($this->getTrackingPixelData()) > 0): ?>
12
+
13
+ <div id="yoochoose_tracking">
14
+ <script type="text/javascript">
15
+ // <![CDATA[
16
+ Event.observe(window, 'load', function() {
17
+
18
+ <?php foreach ($this->getTrackingPixelData() as $trackingPixelData): ?>
19
+
20
+ var newImage = new Element('img', {
21
+ 'src' : '<?php echo $this->generateTrackingPixelUrl($trackingPixelData) ?>',
22
+ 'alt' : '',
23
+ 'width' : '0',
24
+ 'height' : '0'
25
+ });
26
+
27
+ var contentElement = $('yoochoose_tracking');
28
+
29
+ Element.insert(contentElement, {'bottom': newImage});
30
+
31
+ <?php endforeach ?>
32
+
33
+ });
34
+ // ]]>
35
+ </script>
36
+ <noscript>
37
+ <?php foreach ($this->getTrackingPixelData() as $trackingPixelData): ?>
38
+
39
+ <img src="<?php echo $this->generateTrackingPixelUrl($trackingPixelData) ?>" alt="<?php echo $this->__('Yoochoose Tracking') ?>" width="0" height="0" />
40
+
41
+ <?php endforeach ?>
42
+ </noscript>
43
+ </div>
44
+
45
+ <?php endif ?>
46
+
app/design/frontend/base/default/template/yoochoose/upsell.phtml ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @category AvS
4
+ * @package AvS_Yoochoose
5
+ * @author Andreas von Studnitz <avs@avs-webentwicklung.de>
6
+ */
7
+ ?>
8
+
9
+ <?php $itemArray = $this->getItemArray() ?>
10
+ <?php if(count($itemArray)): ?>
11
+ <?php $i = 0 ?>
12
+ <div class="box-collateral box-up-sell">
13
+ <h2><?php echo $this->__('You may also be interested in the following product(s)') ?></h2>
14
+ <table class="products-grid" id="upsell-product-table">
15
+ <?php // $this->setColumnCount(5); // uncomment this line if you want to have another number of columns. also can be changed in layout ?>
16
+ <?php for($row=0;$row<$this->getRowCount();$row++): ?>
17
+ <tr>
18
+ <?php for($column=0;$column<$this->getColumnCount();$column++): ?>
19
+ <?php if(isset($itemArray[$i])): ?>
20
+ <?php $_item=$itemArray[$i] ?>
21
+ <?php $i++ ?>
22
+ <td>
23
+ <a href="<?php echo Mage::helper('yoochoose')->getProductUrl($_item) ?>" title="<?php echo $this->htmlEscape($_item->getName()) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_item, 'small_image')->resize(125) ?>" width="125" height="125" alt="<?php echo $this->htmlEscape($_item->getName()) ?>" /></a>
24
+ <h3 class="product-name"><a href="<?php echo Mage::helper('yoochoose')->getProductUrl($_item) ?>" title="<?php echo $this->htmlEscape($_item->getName()) ?>"><?php echo $this->htmlEscape($_item->getName()) ?></a></h3>
25
+ <?php echo $this->getPriceHtml($_item, true, '-upsell') ?>
26
+ <?php echo $this->getReviewsSummaryHtml($_item) ?>
27
+ </td>
28
+ <?php else: ?>
29
+ <td class="empty">&nbsp;</td>
30
+ <?php endif; ?>
31
+ <?php endfor; ?>
32
+ </tr>
33
+ <?php endfor; ?>
34
+ </table>
35
+ <script type="text/javascript">decorateTable('upsell-product-table')</script>
36
+ </div>
37
+ <?php endif ?>
app/etc/modules/AvS_Yoochoose.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <AvS_Yoochoose>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </AvS_Yoochoose>
8
+ </modules>
9
+ </config>
app/locale/de_DE/AvS_Yoochoose.csv ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Yoochoose","Yoochoose"
2
+ "General Settings","Allgemeine Einstellungen"
3
+ "Disabled","Deaktiviert"
4
+ "API Settings","API-Benutzerdaten"
5
+ "Yoochoose Client ID","Yoochoose Kundennummer"
6
+ "If you don't have a Client ID yet, <a href=""http://config.yoochoose.net"" target=""_blank"">click here</a>.","Wenn Sie noch keine Kundennummer haben, <a href=""http://config.yoochoose.net"" target=""_blank"">klicken Sie hier</a>."
7
+ "Yoochoose License Key","Yoochoose Lizenzschlüssel"
8
+ "Yoochoose License Type","Yoochoose Lizenztyp"
9
+ "Will be filled automatically after saving with correct license data","Wird nach dem Speichern mit korrekten Lizenz-Informationen automatisch befüllt."
10
+ "License successfully verified.","Ihre Lizenz wurde bestätigt."
11
+ "License could not be verified.","Ihre Lizenz konnte nicht bestätigt werden."
12
+ "Events","Events"
13
+ "Display Tracking Pixel with help of Javascript","Javascript benutzen, um Trackingpixel darzustellen"
14
+ "Yoochoose Base URL","Yoochoose Basis-URL"
15
+ "Tracking Pixel will be rendered after the rest of the page; recommended for performance reasons","Tracking-Pixel wird erst nach dem Rest der Seite erstellt; aus Performance-Gründen empfohlen."
16
+ "Cross Selling","Cross-Selling"
17
+ "Up Selling","Up-Selling"
18
+ "Related Products","Ähnliche Produkte"
19
+ "Display Yoochoose Recommendations in Crossselling Block","Yoochoose-Empfehlungen im Cross-Selling-Block anzeigen"
20
+ "Display Yoochoose Recommendations in Upselling Block","Yoochoose-Empfehlungen im Up-Selling-Block anzeigen"
21
+ "Display Yoochoose Recommendations in Related Products Block","Yoochoose-Empfehlungen im Ähnliche-Produkte-Block anzeigen"
22
+ "Scenario used","Verwendetes Szenario"
23
+ "Prefer manually entered Connections","Manuell angelegte Verknüpfungen bevorzugt darstellen"
24
+ "Don't display otherwise","Andernfalls nicht darstellen"
25
+ "Max count of recommendations","Maximale Anzahl Verknüpfungen"
26
+ "Registered Clicks","Registrierte Klicks"
27
+ "Registered Buys","Registrierte Käufe"
28
+ """Also purchased"" recommendations","Anzahl der Abrufe von Empfehlungen ""Kunden kauften auch …"""
29
+ """Also clicked"" recommendations","Anzahl der Abrufe von Empfehlungen ""Kunden interessierten sich auch …"""
30
+ """Top selling"" recommendations","Anzahl der Abrufe von Empfehlungen ""Meistverkaufte Artikel …"""
31
+ "Statistics","Statistiken"
32
+
33
+ "Item Type %s unknown.","Item Type %s unbekannt."
34
+ "Yoochoose Tracking","Yoochoose Tracking"
35
+
36
+ "Yoochoose User Id","Yoochoose Kunden-ID"
package.xml ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>YOOCHOOSE_Recommender_Engine</name>
4
+ <version>1.1.1</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>Use our superior and patented recommender engine to boost your online sales with personalized and self-learning recommendations.</summary>
10
+ <description>Use our superior and patented recommender engine to boost your online sales with personalized and self-learning recommendations.&#xD;
11
+ &#xD;
12
+ YOOCHOOSE Recommender Engine&#xD;
13
+ &#xD;
14
+ Personalized and self-learning recommendations enable you to &#xD;
15
+ &#x2022; Sell more products online&#xD;
16
+ &#x2022; Lower costs for service and support&#xD;
17
+ &#x2022; Enhance usability of your website&#xD;
18
+ Introduce recommendations &#x2013; increase sales&#xD;
19
+ With the YOOCHOOSE Recommender Engine, you can combine the knowledge of your products and media content with the users' usage behavior in order to offer optimal individualized recommendations.&#xD;
20
+ This enables all kinds of professional recommendations from simple Amazon&#xAE;-like &#x201C;Other people also bought &#x2026;&#x201D; to fully personalized and self-learning recommendations for your online shoppers.&#xD;
21
+ &#xD;
22
+ Example (schematic representation): Just a few weeks after introduction of the recommender engine, purchases that have been proven to be based on personalized recommendations lead to a significant sales increase &#xD;
23
+ YOOCHOOSE Recommendations will become the best sales person in your online shop and increases revenue typically by 5- 30 % depending on our specific business and the goods you sell.&#xD;
24
+ &#xD;
25
+ &#xD;
26
+ Start with the plugin &#x2013; risk free pricing&#xD;
27
+ Using this free of charge plugin for Magento enables you to send events from your online shop to the YOOCHOOSE recommender engine. In addition the plugin offer you to enrich your cross- and up-selling functions with high quality recommendations. You access the configuration through the administration panel (sub-menu at System/Configuration).&#xD;
28
+ &#xD;
29
+ Data privacy &#x2013; we act responsible &#xD;
30
+ As a German based company we are obliged to act on base of the highest data privacy and security standards in the world. Our data centers are certified according to ISO 27001 and have accomplished SAS70 Type II security audits. If you are a European-based company you don&#x2019;t have to fear that your data will be stored or forwarded to a location outside the European Community. If you operate from elsewhere in the world you can profit from this high security standards and express your responsibility for the privacy of your customers by choosing our service.&#xD;
31
+ Try us for free! We offer the recommender engine with no upfront costs and a 30 day free trial period*.&#xD;
32
+ *Limited trial version in regards of number of products and number of recommendations. Write us an e-mail to receive more information: info@yoochoose.com. &#xD;
33
+ &#xD;
34
+ &#xD;
35
+ &#x2003;&#xD;
36
+ &#x2022; &#xDC;berblick&#xD;
37
+ Steigern Sie Ihren Online-Umsatz durch personalisierte und selbstlernende Empfehlungen mit unserer innovativen &#x201E;Recommender-Engine&#x201C;&#xD;
38
+ &#xD;
39
+ YOOCHOOSE Empfehlungen&#xD;
40
+ Personalisierte und selbstlernende Empfehlungen machen es m&#xF6;glich:&#xD;
41
+ &#xD;
42
+ &#x2022; Verkaufen Sie deutlich mehr Produkte in Ihrem Online Shop&#xD;
43
+ &#x2022; Senken Sie Ihre Kosten f&#xFC;r Wartung und Support&#xD;
44
+ &#x2022; Erh&#xF6;hen Sie die Attraktivit&#xE4;t Ihres Online-Auftritts&#xD;
45
+ &#xD;
46
+ Empfehlungen einf&#xFC;hren &#x2013; Umsatz steigern&#xD;
47
+ Mit YOOCHOOSE Empfehlungen ist es erstmals m&#xF6;glich, das Wissen &#xFC;ber Ihre Produkte und Medien mit dem Benutzerverhalten ihrer Anwender zu kombinieren. Damit k&#xF6;nnen Sie Ihren K&#xE4;ufern optimal individualisierte Empfehlungen anbieten.&#xD;
48
+ &#xD;
49
+ Es gibt verschiedene M&#xF6;glichkeiten, um Empfehlungen effizient in Ihrem Online Shop einzusetzen. Wir bieten Ihnen das gesamte Spektrum vom einfachen &#x201E;Kunden kauften auch &#x2026;..&#x201C;-Empfehlungen a la Amazon&#xAE; bis hin zu vollst&#xE4;ndig personalisierten und selbstlernenden Empfehlungsverfahren.&#xD;
50
+ &#xD;
51
+ Beispiel: Schon wenige Wochen nach der Einf&#xFC;hrung der Recommender Engine f&#xFC;hren Eink&#xE4;ufe, die eindeutig auf personalisierten Empfehlungen beruhen, zu einer signifikanten Steigerung des Umsatzes (Quelle: Schematische Darstellung der Daten von YOOCHOOSE Kunden)&#xD;
52
+ Lassen Sie die YOOCHOOSE Recommender Engine zu ihrem besten Vertriebsmitarbeiter werden. Umsatzsteigerungen zwischen 5% und 25% k&#xF6;nnen je nach Gr&#xF6;&#xDF;e des Produktportfolio und Marktsegment erwartet werden.&#xD;
53
+ Starten Sie mit dem unserem Magento-Plugin &#x2013; es ist kostenfrei&#xD;
54
+ &#xDC;ber unser kostenfreies Magento-Shop Plugin ist es Ihnen m&#xF6;glich die verschiedenen Kauf- und Klick-Events aus Ihrem Shop an uns zu &#xFC;bermitteln. Dar&#xFC;ber hinaus passt das Plugin Ihre Cross- und Up-Selling Funktionen so an, dass Sie qualitativ hochwertige Empfehlungen neben den eigenen Empfehlungen ausspielen k&#xF6;nnen. Die Konfiguration erreichen Sie einfach &#xFC;ber das Admin-Panel (Untermenu von System/Configuration).&#xD;
55
+ &#xD;
56
+ &#xD;
57
+ &#xD;
58
+ Datenschutz &#x2013; wir handeln verantwortungsbewusst&#xD;
59
+ Wir legen hohen Wert auf die Einhaltung der Datenschutzverordnungen und Gesetze. Unsere Rechenzentren sind ISO27001-zertifiziert und wurden erfolgreich einer SAS70 Typ II Sicherheits&#xFC;berpr&#xFC;fung unterzogen. Bevor wir Daten f&#xFC;r Sie verarbeiten schlie&#xDF;en wir einen Vertrag zur Auftragsdatenverarbeitung mit Ihnen ab und helfen Ihnen die datenschutzrechtlichen Hinweise auf Ihrer Webseite entsprechend anzupassen.&#xD;
60
+ Sollten Sie Ihren Firmensitz au&#xDF;erhalb der EU haben, dann profitieren Sie ebenfalls automatisch von unseren hohen Sicherheitsstandards. So wird stets die Privatsph&#xE4;re Ihrer Kunden gewahrt.&#xD;
61
+ Nutzen Sie unsere kostenlose Testphase! Wir bieten Ihnen den Empfehlungsdienst ohne Bereitstellungsgeb&#xFC;hr kostenlos f&#xFC;r 30-Tage* an.&#xD;
62
+ *Eingeschr&#xE4;nkte Test Version &#x2013; Beschr&#xE4;nkung des Produktumfangs und der Empfehlungsabrufe. Bei Fragen stehen wir Ihnen gerne telefonisch unter der Rufnummer 0221/16800762 sowie unter info@yoochoose.com zur Verf&#xFC;gung.</description>
63
+ <notes>Added configuration options for the used scenarios</notes>
64
+ <authors><author><name>Andreas von Studnitz</name><user>auto-converted</user><email>avs@avs-webentwicklung.de</email></author></authors>
65
+ <date>2011-04-08</date>
66
+ <time>09:17:31</time>
67
+ <contents><target name="mageetc"><dir name="modules"><file name="AvS_Yoochoose.xml" hash="695d97ac588c41c8478b74cf27e24f56"/></dir></target><target name="magecommunity"><dir name="AvS"><dir name="Yoochoose"><dir name="Block"><file name="Crosssell.php" hash="19f6e22fb73a78ba7be2ed3986370943"/><file name="Recommendation.php" hash="476f5590d2613509f6fd3c3781801c57"/><file name="Related.php" hash="84d84555b6fa7ee79f56d75df752d00d"/><file name="Tracking.php" hash="0cee2eac736623c8d7ffdb400c126084"/><file name="Upsell.php" hash="d8f2b4597c96d54e7567e09223841a5b"/></dir><dir name="Helper"><file name="Data.php" hash="88e28453703452bb2b3a1c7fb0822915"/></dir><dir name="Model"><dir name="Api"><dir name="Recommendation"><file name="Crossselling.php" hash="a975b28acc8fb6fe5ef9bdae1ede7c09"/><file name="Related.php" hash="343feb6af7e8cdc2030819437b2c195d"/><file name="Upselling.php" hash="032a35a019762174ef1e1ea569ee61cb"/></dir><file name="Event.php" hash="e8a3294c4ee5cb7eec68d90621cf4774"/><file name="Recommendation.php" hash="840d90c0706a27718549c223c5a480c4"/></dir><file name="Api.php" hash="2ffa2e06e9b745b6759c4f3d0fce6853"/><file name="Observer.php" hash="ee46ff843b0a961f579b29b671a6dc4e"/></dir><dir name="etc"><file name="config.xml" hash="fdef729426792a59c9d856a8af221aa3"/><file name="system.xml" hash="b0c065dd22b27fa2034462bc8076b75e"/></dir><dir name="sql"><dir name="yoochoose_setup"><file name="mysql4-install-0.1.0.php" hash="d5c03520d481885434e75819007701a0"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="yoochoose"><file name="crosssell.phtml" hash="ed022f89202e2f41536a4f71bc3c491f"/><file name="recommendation.phtml" hash="8f6024432a96168f276670135fbe371d"/><file name="related.phtml" hash="060be5346b8b6c360c24ee7081370858"/><file name="tracking.phtml" hash="b981947607bfcb8d0cf15eaec70cb380"/><file name="upsell.phtml" hash="5b39cafe647f645c080420b50299c5ba"/></dir></dir><dir name="layout"><file name="yoochoose.xml" hash="56b7ed57066f29e412e75cf55d3a0d21"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="de_DE"><file name="AvS_Yoochoose.csv" hash="33c25b1743602613c850a9e50642ab15"/></dir></target></contents>
68
+ <compatible/>
69
+ <dependencies/>
70
+ </package>