ntoklo_recommendations - Version 1.0.0

Version Notes

initial release

Download this release

Release Info

Developer nToklo
Extension ntoklo_recommendations
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

Files changed (40) hide show
  1. LICENSE.txt +169 -0
  2. app/code/community/Ntoklo/Recommendations/Block/Adminhtml/Widget/Date/Helper.php +50 -0
  3. app/code/community/Ntoklo/Recommendations/Block/Adminhtml/Widget/Type/Helper.php +37 -0
  4. app/code/community/Ntoklo/Recommendations/Block/Chart.php +164 -0
  5. app/code/community/Ntoklo/Recommendations/Block/UniversalVariable.php +101 -0
  6. app/code/community/Ntoklo/Recommendations/Helper/Data.php +560 -0
  7. app/code/community/Ntoklo/Recommendations/Model/Cache/UniversalVariable.php +52 -0
  8. app/code/community/Ntoklo/Recommendations/Model/Observer.php +58 -0
  9. app/code/community/Ntoklo/Recommendations/Model/Service.php +248 -0
  10. app/code/community/Ntoklo/Recommendations/Model/UniversalVariable.php +39 -0
  11. app/code/community/Ntoklo/Recommendations/Model/Widget/Type.php +44 -0
  12. app/code/community/Ntoklo/Recommendations/etc/adminhtml.xml +41 -0
  13. app/code/community/Ntoklo/Recommendations/etc/cache.xml +29 -0
  14. app/code/community/Ntoklo/Recommendations/etc/config.xml +95 -0
  15. app/code/community/Ntoklo/Recommendations/etc/system.xml +120 -0
  16. app/code/community/Ntoklo/Recommendations/etc/widget.xml +163 -0
  17. app/design/frontend/base/default/layout/ntoklo_recommendations.xml +27 -0
  18. app/design/frontend/base/default/template/ntoklo/recommendations/universal_variable.phtml +35 -0
  19. app/design/frontend/base/default/template/ntoklo/recommendations/widget/chart_horisontal.phtml +62 -0
  20. app/design/frontend/base/default/template/ntoklo/recommendations/widget/chart_review_short.phtml +31 -0
  21. app/design/frontend/base/default/template/ntoklo/recommendations/widget/chart_vertical.phtml +49 -0
  22. app/etc/modules/Ntoklo_Recommendations.xml +30 -0
  23. app/locale/en_US/ntoklo_recommendations.csv +16 -0
  24. documentation/.DS_Store +0 -0
  25. documentation/readme.html +133 -0
  26. documentation/skin/.DS_Store +0 -0
  27. documentation/skin/img/.DS_Store +0 -0
  28. documentation/skin/img/cc.png +0 -0
  29. documentation/skin/img/config.png +0 -0
  30. documentation/skin/img/disablec1.png +0 -0
  31. documentation/skin/img/disablec2.png +0 -0
  32. documentation/skin/img/logo.png +0 -0
  33. documentation/skin/img/widgets_1.png +0 -0
  34. documentation/skin/img/widgets_2.png +0 -0
  35. documentation/skin/img/widgets_3.png +0 -0
  36. documentation/skin/img/widgets_4.png +0 -0
  37. documentation/skin/style.css +11 -0
  38. js/ntoklo/util.js +140 -0
  39. package.xml +23 -0
  40. skin/frontend/base/default/css/ntoklo/widgets.css +26 -0
LICENSE.txt ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Open Software License ("OSL") v. 3.0
2
+
3
+ This Open Software License (the "License") applies to any original work of
4
+ authorship (the "Original Work") whose owner (the "Licensor") has placed the
5
+ following licensing notice adjacent to the copyright notice for the Original
6
+ Work:
7
+
8
+ Licensed under the Open Software License version 3.0
9
+
10
+ 1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free,
11
+ non-exclusive, sublicensable license, for the duration of the copyright, to do
12
+ the following:
13
+
14
+ a) to reproduce the Original Work in copies, either alone or as part of a
15
+ collective work;
16
+
17
+ b) to translate, adapt, alter, transform, modify, or arrange the Original Work,
18
+ thereby creating derivative works ("Derivative Works") based upon the Original
19
+ Work;
20
+
21
+ c) to distribute or communicate copies of the Original Work and Derivative Works
22
+ to the public, with the proviso that copies of Original Work or Derivative Works
23
+ that You distribute or communicate shall be licensed under this Open Software
24
+ License;
25
+
26
+ d) to perform the Original Work publicly; and
27
+
28
+ e) to display the Original Work publicly.
29
+
30
+ 2) Grant of Patent License. Licensor grants You a worldwide, royalty-free,
31
+ non-exclusive, sublicensable license, under patent claims owned or controlled by
32
+ the Licensor that are embodied in the Original Work as furnished by the
33
+ Licensor, for the duration of the patents, to make, use, sell, offer for sale,
34
+ have made, and import the Original Work and Derivative Works.
35
+
36
+ 3) Grant of Source Code License. The term "Source Code" means the preferred form
37
+ of the Original Work for making modifications to it and all available
38
+ documentation describing how to modify the Original Work. Licensor agrees to
39
+ provide a machine-readable copy of the Source Code of the Original Work along
40
+ with each copy of the Original Work that Licensor distributes. Licensor reserves
41
+ the right to satisfy this obligation by placing a machine-readable copy of the
42
+ Source Code in an information repository reasonably calculated to permit
43
+ inexpensive and convenient access by You for as long as Licensor continues to
44
+ distribute the Original Work.
45
+
46
+ 4) Exclusions From License Grant. Neither the names of Licensor, nor the names
47
+ of any contributors to the Original Work, nor any of their trademarks or service
48
+ marks, may be used to endorse or promote products derived from this Original
49
+ Work without express prior permission of the Licensor. Except as expressly
50
+ stated herein, nothing in this License grants any license to Licensor's
51
+ trademarks, copyrights, patents, trade secrets or any other intellectual
52
+ property. No patent license is granted to make, use, sell, offer for sale, have
53
+ made, or import embodiments of any patent claims other than the licensed claims
54
+ defined in Section 2. No license is granted to the trademarks of Licensor even
55
+ if such marks are included in the Original Work. Nothing in this License shall
56
+ be interpreted to prohibit Licensor from licensing under terms different from
57
+ this License any Original Work that Licensor otherwise would have a right to
58
+ license.
59
+
60
+ 5) External Deployment. The term "External Deployment" means the use,
61
+ distribution, or communication of the Original Work or Derivative Works in any
62
+ way such that the Original Work or Derivative Works may be used by anyone other
63
+ than You, whether those works are distributed or communicated to those persons
64
+ or made available as an application intended for use over a network. As an
65
+ express condition for the grants of license hereunder, You must treat any
66
+ External Deployment by You of the Original Work or a Derivative Work as a
67
+ distribution under section 1(c).
68
+
69
+ 6) Attribution Rights. You must retain, in the Source Code of any Derivative
70
+ Works that You create, all copyright, patent, or trademark notices from the
71
+ Source Code of the Original Work, as well as any notices of licensing and any
72
+ descriptive text identified therein as an "Attribution Notice." You must cause
73
+ the Source Code for any Derivative Works that You create to carry a prominent
74
+ Attribution Notice reasonably calculated to inform recipients that You have
75
+ modified the Original Work.
76
+
77
+ 7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the
78
+ copyright in and to the Original Work and the patent rights granted herein by
79
+ Licensor are owned by the Licensor or are sublicensed to You under the terms of
80
+ this License with the permission of the contributor(s) of those copyrights and
81
+ patent rights. Except as expressly stated in the immediately preceding sentence,
82
+ the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT
83
+ WARRANTY, either express or implied, including, without limitation, the
84
+ warranties of non-infringement, merchantability or fitness for a particular
85
+ purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
86
+ This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
87
+ license to the Original Work is granted by this License except under this
88
+ disclaimer.
89
+
90
+ 8) Limitation of Liability. Under no circumstances and under no legal theory,
91
+ whether in tort (including negligence), contract, or otherwise, shall the
92
+ Licensor be liable to anyone for any indirect, special, incidental, or
93
+ consequential damages of any character arising as a result of this License or
94
+ the use of the Original Work including, without limitation, damages for loss of
95
+ goodwill, work stoppage, computer failure or malfunction, or any and all other
96
+ commercial damages or losses. This limitation of liability shall not apply to
97
+ the extent applicable law prohibits such limitation.
98
+
99
+ 9) Acceptance and Termination. If, at any time, You expressly assented to this
100
+ License, that assent indicates your clear and irrevocable acceptance of this
101
+ License and all of its terms and conditions. If You distribute or communicate
102
+ copies of the Original Work or a Derivative Work, You must make a reasonable
103
+ effort under the circumstances to obtain the express assent of recipients to the
104
+ terms of this License. This License conditions your rights to undertake the
105
+ activities listed in Section 1, including your right to create Derivative Works
106
+ based upon the Original Work, and doing so without honoring these terms and
107
+ conditions is prohibited by copyright law and international treaty. Nothing in
108
+ this License is intended to affect copyright exceptions and limitations
109
+ (including "fair use" or "fair dealing"). This License shall terminate
110
+ immediately and You may no longer exercise any of the rights granted to You by
111
+ this License upon your failure to honor the conditions in Section 1(c).
112
+
113
+ 10) Termination for Patent Action. This License shall terminate automatically
114
+ and You may no longer exercise any of the rights granted to You by this License
115
+ as of the date You commence an action, including a cross-claim or counterclaim,
116
+ against Licensor or any licensee alleging that the Original Work infringes a
117
+ patent. This termination provision shall not apply for an action alleging patent
118
+ infringement by combinations of the Original Work with other software or
119
+ hardware.
120
+
121
+ 11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
122
+ License may be brought only in the courts of a jurisdiction wherein the Licensor
123
+ resides or in which Licensor conducts its primary business, and under the laws
124
+ of that jurisdiction excluding its conflict-of-law provisions. The application
125
+ of the United Nations Convention on Contracts for the International Sale of
126
+ Goods is expressly excluded. Any use of the Original Work outside the scope of
127
+ this License or after its termination shall be subject to the requirements and
128
+ penalties of copyright or patent law in the appropriate jurisdiction. This
129
+ section shall survive the termination of this License.
130
+
131
+ 12) Attorneys' Fees. In any action to enforce the terms of this License or
132
+ seeking damages relating thereto, the prevailing party shall be entitled to
133
+ recover its costs and expenses, including, without limitation, reasonable
134
+ attorneys' fees and costs incurred in connection with such action, including any
135
+ appeal of such action. This section shall survive the termination of this
136
+ License.
137
+
138
+ 13) Miscellaneous. If any provision of this License is held to be unenforceable,
139
+ such provision shall be reformed only to the extent necessary to make it
140
+ enforceable.
141
+
142
+ 14) Definition of "You" in This License. "You" throughout this License, whether
143
+ in upper or lower case, means an individual or a legal entity exercising rights
144
+ under, and complying with all of the terms of, this License. For legal entities,
145
+ "You" includes any entity that controls, is controlled by, or is under common
146
+ control with you. For purposes of this definition, "control" means (i) the
147
+ power, direct or indirect, to cause the direction or management of such entity,
148
+ whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or
149
+ more of the outstanding shares, or (iii) beneficial ownership of such entity.
150
+
151
+ 15) Right to Use. You may use the Original Work in all ways not otherwise
152
+ restricted or conditioned by this License or by law, and Licensor promises not
153
+ to interfere with or be responsible for such uses by You.
154
+
155
+ 16) Modification of This License. This License is Copyright (c) 2005 Lawrence
156
+ Rosen. Permission is granted to copy, distribute, or communicate this License
157
+ without modification. Nothing in this License permits You to modify this License
158
+ as applied to the Original Work or to Derivative Works. However, You may modify
159
+ the text of this License and copy, distribute or communicate your modified
160
+ version (the "Modified License") and apply it to other original works of
161
+ authorship subject to the following conditions: (i) You may not indicate in any
162
+ way that your Modified License is the "Open Software License" or "OSL" and you
163
+ may not use those names in the name of your Modified License; (ii) You must
164
+ replace the notice specified in the first paragraph above with the notice
165
+ "Licensed under <insert your license name here>" or with a notice of your own
166
+ that is not confusingly similar to the notice in this License; and (iii) You may
167
+ not claim that your original works are open source software unless your Modified
168
+ License has been approved by Open Source Initiative (OSI) and You comply with
169
+ its license review and certification process.
app/code/community/Ntoklo/Recommendations/Block/Adminhtml/Widget/Date/Helper.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+ class Ntoklo_Recommendations_Block_Adminhtml_Widget_Date_Helper extends Mage_Adminhtml_Block_Widget {
20
+
21
+ protected $_element;
22
+
23
+ public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) {
24
+
25
+ $this->_element = $element;
26
+ $this->_elementValueId = "{$element->getId()}";
27
+ $element->setData('after_element_html', $this->toHtml());
28
+ $element->setValue('');
29
+ return $element;
30
+ }
31
+
32
+ protected function _toHtml() {
33
+
34
+ $date = new Varien_Data_Form_Element_Date;
35
+ $format = Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT);
36
+
37
+ $data = array(
38
+ 'name' => $this->_element->getName(),
39
+ 'html_id' => $this->_element->getId(),
40
+ 'image' => $this->getSkinUrl('images/grid-cal.gif'),
41
+ );
42
+
43
+ $date->setData($data);
44
+ $date->setValue($this->_element->getValue(), $format);
45
+ $date->setFormat(Mage::app()->getLocale()->getDateFormatWithLongYear(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT));
46
+ $date->setForm($this->_element->getForm());
47
+ return $date->getElementHtml();
48
+ }
49
+ }
50
+
app/code/community/Ntoklo/Recommendations/Block/Adminhtml/Widget/Type/Helper.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+
20
+ class Ntoklo_Recommendations_Block_Adminhtml_Widget_Type_Helper extends Mage_Adminhtml_Block_Widget {
21
+
22
+ public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) {
23
+ $this->_elementValueId = "{$element->getId()}";
24
+ $hidden = new Varien_Data_Form_Element_Hidden($element->getData());
25
+ $hidden->setId($this->_elementValueId)->setForm($element->getForm());
26
+ $hiddenHtml = $hidden->getElementHtml();
27
+
28
+ $element->setValue('')->setValueClass('value2');
29
+ $element->setData('after_element_html', $hiddenHtml . $this->toHtml());
30
+ return $element;
31
+ }
32
+
33
+ protected function _toHtml() {
34
+ return Mage::helper('ntoklo_recommendations')->__('<b style="color:red">Note:</b> A chart is non-personalised. If you place the chart on a Category based page then the chart will reflect the trending products for that category. However, if you put a chart widget on a non-category based page, like the Home page for example, then the chart will show trending products from your whole product catalogue.');
35
+ }
36
+
37
+ }
app/code/community/Ntoklo/Recommendations/Block/Chart.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+
20
+ class Ntoklo_Recommendations_Block_Chart extends Mage_Catalog_Block_Product_Abstract implements Mage_Widget_Block_Interface {
21
+
22
+ /** @var $_items */
23
+ protected $_items = null;
24
+
25
+ /**
26
+ * Initialize block's cache
27
+ */
28
+ protected function _construct() {
29
+ parent::_construct();
30
+ $this->addData(array(
31
+ 'cache_lifetime' => 86400,
32
+ 'cache_tags' => array(Mage_Catalog_Model_Product::CACHE_TAG),
33
+ ));
34
+ }
35
+
36
+ /**
37
+ * Get Key pieces for caching block content
38
+ * TODO: check whether we need to add a collection hash or some cookie
39
+ *
40
+ * @return array
41
+ */
42
+ public function getCacheKeyInfo() {
43
+ return array(
44
+ 'CATALOG_PRODUCT_NTOKLO_RECOMMENDATIONS',
45
+ Mage::app()->getStore()->getId(),
46
+ Mage::getDesign()->getPackageName(),
47
+ Mage::getDesign()->getTheme('template'),
48
+ Mage::getSingleton('customer/session')->getCustomerGroupId(),
49
+ 'template' => $this->getTemplate(),
50
+ Mage::getSingleton('customer/session')->getID()
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Calls Ntoklo API to get recommendations and loads the products
56
+ *
57
+ * @return $this
58
+ */
59
+ private function _prepareData() {
60
+ // Check if feature is enabled
61
+ if (!Mage::getStoreConfig(Ntoklo_Recommendations_Helper_Data::CONFIG_XPATH_IS_ENABLED)) {
62
+ return $this;
63
+ }
64
+
65
+ $recommendedIds = Mage::getSingleton('ntoklo_recommendations/service')
66
+ ->setDebug($this->getData('debug'))
67
+ ->getRecommendedIds($this);
68
+ if (!count($recommendedIds)) {
69
+ return $this;
70
+ }
71
+
72
+ // Prepare product collection
73
+ $limit = $this->getData('max_products');
74
+ /** @var $collection Mage_Catalog_Model_Resource_Product_Collection */
75
+ $collection = Mage::getResourceModel('catalog/product_collection');
76
+ $collection->addAttributeToSelect('*')
77
+ ->addUrlRewrite()
78
+ ->addAttributeToFilter('entity_id' ,array('in' => $recommendedIds))
79
+ ->addStoreFilter()
80
+ ->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
81
+ ->setPageSize($limit ? $limit : 6);
82
+
83
+ Mage::getModel('cataloginventory/stock')->addInStockFilterToCollection($collection);
84
+
85
+ $this->_items = $collection->getItems();
86
+ return $this;
87
+ }
88
+
89
+ /**
90
+ * @return Mage_Core_Block_Abstract
91
+ */
92
+ protected function _beforeToHtml() {
93
+ $this->_prepareData();
94
+ $this->addReviewSummaryTemplate('ntoklo_short', 'ntoklo/recommendations/widget/chart_review_short.phtml');
95
+ return parent::_beforeToHtml();
96
+ }
97
+
98
+ /**
99
+ * @return array
100
+ */
101
+ public function getItems() {
102
+ return $this->_items;
103
+ }
104
+
105
+ /**
106
+ * @return float
107
+ */
108
+ public function getRowCount() {
109
+ return ceil(count($this->getItems())/$this->getColumnCount());
110
+ }
111
+
112
+ /**
113
+ * @return int|mixed
114
+ */
115
+ public function getColumnCount() {
116
+ return $this->getData('column_count') ? $this->getData('column_count') : 4;
117
+ }
118
+
119
+ /**
120
+ * Returns the header to be used on frontend
121
+ * @return mixed
122
+ */
123
+ public function getHeader() {
124
+ return ($this->getData('widget_type') == Ntoklo_Recommendations_Model_Service::CALL_METHOD_CHART) ? $this->getData('header_chart') : $this->getData('header_recommendations');
125
+ }
126
+
127
+ /**
128
+ * Reset iterator
129
+ */
130
+ public function resetItemsIterator() {
131
+ reset($this->_items);
132
+ }
133
+
134
+ /**
135
+ * @return mixed
136
+ */
137
+ public function getIterableItem() {
138
+ $item = current($this->_items);
139
+ next($this->_items);
140
+ return $item;
141
+ }
142
+
143
+ /**
144
+ * Wrapper for standard strip_tags() function with extra functionality for html entities
145
+ * NOTE: copied from CE 1.7 Abstract class
146
+ *
147
+ * @param string $data
148
+ * @param string $allowableTags
149
+ * @param bool $allowHtmlEntities
150
+ * @return string
151
+ */
152
+ public function stripTags($data, $allowableTags = null, $escape = false) {
153
+ $result = strip_tags($data, $allowableTags);
154
+ return $escape ? $this->escapeHtml($result, $allowableTags) : $result;
155
+ }
156
+
157
+ /**
158
+ * @return bool
159
+ */
160
+ public function isChart() {
161
+ return $this->getData('widget_type') == Ntoklo_Recommendations_Model_Service::CALL_METHOD_CHART;
162
+ }
163
+
164
+ }
app/code/community/Ntoklo/Recommendations/Block/UniversalVariable.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+ /**
20
+ * Class Ntoklo_Recommendations_Block_UniversalVariable
21
+ */
22
+ class Ntoklo_Recommendations_Block_UniversalVariable extends Mage_Core_Block_Template {
23
+
24
+ /**
25
+ * @return mixed
26
+ */
27
+ public function getNtokloApiKey() {
28
+ return Mage::helper('ntoklo_recommendations')->getNtokloApiKey();
29
+ }
30
+
31
+ /**
32
+ * @return mixed
33
+ */
34
+ public function getNtokloApiServiceUrl() {
35
+ return Mage::helper('ntoklo_recommendations')->getNtokloApiServiceUrl();
36
+ }
37
+
38
+ /**
39
+ * @return mixed
40
+ */
41
+ public function getNtokloScriptUrl() {
42
+ return Mage::getStoreConfig(Ntoklo_Recommendations_Helper_Data::CONFIG_XPATH_API_SCRIPT_URL);
43
+ }
44
+
45
+ /**
46
+ * @return mixed
47
+ */
48
+ public function isNtokloDebugActive() {
49
+ return Mage::getStoreConfig(Ntoklo_Recommendations_Helper_Data::CONFIG_XPATH_API_DEBUG);
50
+ }
51
+
52
+ /**
53
+ * nToklo version of json UV object
54
+ *
55
+ * Required properties by nToklo are:
56
+ * - event
57
+ * - user (if it exists, i.e. use is logged in)
58
+ * - product (if you're on a product page, or multiple products if on a listing page, e.g. category, search)
59
+ * - pagesource (in the case of event.type=recommendation-click)
60
+ *
61
+ * @return string
62
+ */
63
+ public function getJsonUniversalVariable() {
64
+
65
+ $pageCategory = Mage::helper('ntoklo_recommendations')->getPageCategory();
66
+
67
+ $universalVariable = new Ntoklo_Recommendations_Model_UniversalVariable(array(
68
+ 'version' => '1.1.1',
69
+ 'magento_version' => Mage::getVersion(),
70
+ 'user' => Mage::helper('ntoklo_recommendations')->getUvMapUser()
71
+ ));
72
+
73
+ // Page UV object
74
+ $universalVariable->setProperties(array('page' => Mage::helper('ntoklo_recommendations')->getUvMapPage()));
75
+
76
+ // Listing UV object
77
+ if ($listing = Mage::helper('ntoklo_recommendations')->getUvMapListing()) {
78
+ $universalVariable->setProperties(array('listing' => $listing));
79
+ }
80
+
81
+ // Events UV object
82
+ $universalVariable->events = Mage::helper('ntoklo_recommendations')->getUvMapEvent();
83
+
84
+ // Product UV object
85
+ if ($product = Mage::helper('ntoklo_recommendations')->getUvMapProduct()) {
86
+ $universalVariable->setProperties(array('product' => $product));
87
+ }
88
+
89
+ // Basket UV object
90
+ if ($basket = Mage::helper('ntoklo_recommendations')->getUvMapBasket()) {
91
+ $universalVariable->setProperties(array('basket' => $basket));
92
+ }
93
+
94
+ // Transaction UV object
95
+ if ($transaction = Mage::helper('ntoklo_recommendations')->getUvMapTransaction()) {
96
+ $universalVariable->setProperties(array('transaction' => $transaction));
97
+ }
98
+
99
+ return json_encode($universalVariable);
100
+ }
101
+ }
app/code/community/Ntoklo/Recommendations/Helper/Data.php ADDED
@@ -0,0 +1,560 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+ /**
20
+ * Class Ntoklo_Recommendations_Helper_Data
21
+ */
22
+ class Ntoklo_Recommendations_Helper_Data extends Mage_Core_Helper_Abstract {
23
+
24
+ /**
25
+ * Config Xpath
26
+ */
27
+ const CONFIG_XPATH_IS_ENABLED = 'ntoklo_recommendations/settings/is_enabled';
28
+ const CONFIG_XPATH_API_KEY = 'ntoklo_recommendations/settings/api_key';
29
+ const CONFIG_XPATH_API_SECRET = 'ntoklo_recommendations/settings/api_secret';
30
+ const CONFIG_XPATH_API_SSL_KEY = 'ntoklo_recommendations/settings/api_ssl_key';
31
+ const CONFIG_XPATH_API_SSL_SECRET = 'ntoklo_recommendations/settings/api_ssl_secret';
32
+ const CONFIG_XPATH_API_SERVICE_URL = 'ntoklo_recommendations/settings/api_service_url';
33
+ const CONFIG_XPATH_API_SCRIPT_URL = 'ntoklo_recommendations/settings/api_script_url';
34
+ const CONFIG_XPATH_API_DEBUG = 'ntoklo_recommendations/settings/api_debug';
35
+
36
+
37
+ /**
38
+ * Page types as defined in nToklo API
39
+ */
40
+ const PAGE_CATEGORY_PRODUCT = 'product';
41
+ const PAGE_CATEGORY_CONFIRMATION = 'confirmation';
42
+ const PAGE_CATEGORY_RATE = 'rate';
43
+ const PAGE_CATEGORY_REVIEW = 'review';
44
+ const PAGE_CATEGORY_WISHLIST = 'wishlist';
45
+
46
+ /**
47
+ * Page types other than defined in nToklo API
48
+ */
49
+ const PAGE_CATEGORY_CATEGORY = 'category';
50
+ const PAGE_CATEGORY_HOME = 'home';
51
+ const PAGE_CATEGORY_CONTENT = 'content';
52
+ const PAGE_CATEGORY_SEARCH = 'search';
53
+ const PAGE_CATEGORY_BASKET = 'basket';
54
+ const PAGE_CATEGORY_CHECKOUT = 'checkout';
55
+
56
+ /**
57
+ * Cookie vars
58
+ */
59
+ const COOKIE_KEY_CONVERSION = 'ntoklo_conversion';
60
+
61
+
62
+ /**
63
+ * @return bool
64
+ */
65
+ protected function isSecure() {
66
+ return $this->_getRequest()->isSecure();
67
+ }
68
+
69
+ /**
70
+ * @return bool
71
+ */
72
+ public function isEnabled() {
73
+ return (bool)Mage::getStoreConfig(self::CONFIG_XPATH_IS_ENABLED);
74
+ }
75
+
76
+ /**
77
+ * @return mixed
78
+ */
79
+ public function getNtokloApiKey() {
80
+ return Mage::getStoreConfig(self::CONFIG_XPATH_API_KEY);
81
+ }
82
+
83
+ /**
84
+ * @return mixed
85
+ */
86
+ public function getNtokloSecretKey() {
87
+ return Mage::getStoreConfig(self::CONFIG_XPATH_API_SECRET);
88
+ }
89
+
90
+ /**
91
+ * @return mixed
92
+ */
93
+ public function getNtokloApiServiceUrl() {
94
+ return Mage::getStoreConfig(self::CONFIG_XPATH_API_SERVICE_URL);
95
+ }
96
+
97
+ /**
98
+ * Detects page category types
99
+ * @return string
100
+ */
101
+ public function getPageCategory() {
102
+ $request = Mage::app()->getRequest();
103
+
104
+ if ($request->getRequestString() == "/") {
105
+ return self::PAGE_CATEGORY_HOME;
106
+ }
107
+
108
+ if ($request->getModuleName() == 'cms') {
109
+ return self::PAGE_CATEGORY_CONTENT;
110
+ }
111
+
112
+ if ($request->getControllerName() == 'category') {
113
+ return self::PAGE_CATEGORY_CATEGORY;
114
+ }
115
+
116
+ if ($request->getModuleName() == 'catalogsearch') {
117
+ return self::PAGE_CATEGORY_SEARCH;
118
+ }
119
+
120
+ if ($request->getModuleName() == 'checkout' && $request->getControllerName() == 'cart') {
121
+ return self::PAGE_CATEGORY_BASKET;
122
+ }
123
+
124
+ if (strpos($request->getModuleName(), 'checkout') !== false && $request->getActionName() != 'success') {
125
+ return self::PAGE_CATEGORY_CHECKOUT;
126
+ }
127
+
128
+ if (strpos($request->getModuleName(), 'checkout') !== false && $request->getActionName() == 'success') {
129
+ return self::PAGE_CATEGORY_CONFIRMATION;
130
+ }
131
+
132
+ if ($request->getModuleName() == 'review' && $request->getActionName() == 'list') {
133
+ //return self::PAGE_CATEGORY_REVIEW;
134
+ return self::PAGE_CATEGORY_PRODUCT;
135
+ }
136
+
137
+ if ($request->getModuleName() == 'review' && $request->getActionName() == 'post') {
138
+ //return self::PAGE_CATEGORY_RATE;
139
+ return self::PAGE_CATEGORY_PRODUCT;
140
+ }
141
+
142
+ if (strpos($request->getModuleName(), 'wishlist')) {
143
+ return self::PAGE_CATEGORY_WISHLIST;
144
+ }
145
+
146
+ if (Mage::registry('current_product')) {
147
+ return self::PAGE_CATEGORY_PRODUCT;
148
+ }
149
+
150
+ return $request->getModuleName();
151
+ }
152
+
153
+ /**
154
+ * Maps the event types to page categories
155
+ * @param $pageCategory
156
+ */
157
+ public function getEventType($pageCategory = false) {
158
+
159
+ if (!$pageCategory) {
160
+ $pageCategory = $this->getPageCategory();
161
+ }
162
+
163
+ switch($pageCategory) {
164
+ case self::PAGE_CATEGORY_CONFIRMATION:
165
+ $type = 'purchase';
166
+ break;
167
+ case self::PAGE_CATEGORY_PRODUCT:
168
+ $type = 'preview';
169
+ break;
170
+ case self::PAGE_CATEGORY_RATE:
171
+ $type = 'rate';
172
+ break;
173
+ case self::PAGE_CATEGORY_REVIEW:
174
+ $type = 'review';
175
+ break;
176
+ case self::PAGE_CATEGORY_WISHLIST:
177
+ $type = 'wishlist';
178
+ break;
179
+ default:
180
+ $type = 'browse';
181
+ }
182
+ return $type;
183
+ }
184
+
185
+ /**
186
+ * Builds the event UV object
187
+ * @return Ntoklo_Recommendations_Model_UniversalVariable
188
+ */
189
+ public function getUvMapEvent() {
190
+
191
+ $object = array();
192
+
193
+ // Review click events
194
+ $messages = Mage::app()->getLayout()->getBlock('global_messages');
195
+ if (Mage::app()->getRequest()->getModuleName() == 'review' && $messages && count($messages->getMessages())) {
196
+ array_push($object, new Ntoklo_Recommendations_Model_UniversalVariable(array('type' => self::PAGE_CATEGORY_RATE)));
197
+ array_push($object, new Ntoklo_Recommendations_Model_UniversalVariable(array('type' => self::PAGE_CATEGORY_REVIEW)));
198
+ } else {
199
+ // Regular page category events
200
+ $item = new Ntoklo_Recommendations_Model_UniversalVariable(array(
201
+ 'type' => Mage::helper('ntoklo_recommendations')->getEventType($this->getPageCategory())
202
+ ));
203
+
204
+ // Recommendation click events
205
+ if ($pagesource = Mage::getSingleton('core/cookie')->get(self::COOKIE_KEY_CONVERSION)) {
206
+
207
+ Mage::getSingleton('core/cookie')->delete(self::COOKIE_KEY_CONVERSION, null, null, false, false);
208
+ $item->setProperties(array('cause' => 'recommendation-click',
209
+ 'pagesource' => json_decode($pagesource)));
210
+
211
+ }
212
+ array_push($object, $item);
213
+ }
214
+
215
+ return $object;
216
+ }
217
+
218
+ /**
219
+ * Creates the user UV object
220
+ * @return Ntoklo_Recommendations_Model_UniversalVariable
221
+ */
222
+ public function getUvMapUser() {
223
+
224
+ /** @var Mage_Customer_Model_Customer $customer */
225
+ $customer = Mage::helper('customer')->getCustomer();
226
+
227
+ /** @var Mage_Log_Model_Visitor $visitor */
228
+ $visitor = Mage::getSingleton('log/visitor');
229
+
230
+ // Returning Visitor & Language
231
+ $object = new Ntoklo_Recommendations_Model_UniversalVariable(array(
232
+ 'returning' => ($visitor->getFirstVisitAt() != $visitor->getLastVisitAt()),
233
+ 'language' => Mage::getStoreConfig('general/locale/code', Mage::app()->getStore()->getId())
234
+ ));
235
+
236
+ if ($userId = $this->getNtokloUserId()) {
237
+ $object->setProperties(array('user_id' => $userId));
238
+ }
239
+
240
+ // Name
241
+ $name = trim($customer->getName()); $orderName = '';
242
+
243
+ // Email && Has transacted
244
+ if ($orderId = Mage::getSingleton('checkout/session')->getLastOrderId()) {
245
+ /** @var Mage_Sales_Model_Order $order */
246
+ $order = Mage::getModel('sales/order')->load($orderId);
247
+ $orderName = $order->getCustomerName();
248
+ $object->setProperties(array('email' => $order->getCustomerEmail(),
249
+ 'has_transacted' => true));
250
+ }
251
+ else {
252
+ if ($customer->hasData('email')) {
253
+ $object->setProperties(array('email' => $customer->getData('email')));
254
+ }
255
+ $object->setProperties(array('has_transacted' => false));
256
+ }
257
+
258
+ // Name
259
+ if (!empty($name)) {
260
+ $object->setProperties(array('name' => $name));
261
+ }
262
+ elseif (!empty($orderName)) {
263
+ $object->setProperties(array('name' => $orderName));
264
+ }
265
+
266
+ return $object;
267
+ }
268
+
269
+ /**
270
+ * Creates Page UV object
271
+ * Renders on every page
272
+ *
273
+ * @return Ntoklo_Recommendations_Model_UniversalVariable
274
+ */
275
+ public function getUvMapPage() {
276
+ $pageCategory = $this->getPageCategory();
277
+
278
+ $object = new Ntoklo_Recommendations_Model_UniversalVariable(array(
279
+ 'category' => $pageCategory
280
+ ));
281
+
282
+ if ($pageCategory == self::PAGE_CATEGORY_CATEGORY || $pageCategory == self::PAGE_CATEGORY_PRODUCT) {
283
+ $object->setProperties(array('subcategory' => $this->getCategoryPath()));
284
+ }
285
+ return $object;
286
+ }
287
+
288
+ /**
289
+ * Creates Listing UV object
290
+ * @return Ntoklo_Recommendations_Model_UniversalVariable
291
+ */
292
+ public function getUvMapListing() {
293
+
294
+ $object = false;
295
+
296
+ // Build Items part - category context
297
+ $items = array();
298
+ /** @var $category Mage_Catalog_Model_Category */
299
+ $category = Mage::registry('current_category');
300
+ if ($category && !Mage::registry('current_product')) {
301
+ foreach ($category->getProductCollection() as $product) {
302
+ $product = $product->load($product->getId());
303
+ array_push($items, $this->getUvMapProduct($product));
304
+ }
305
+ }
306
+
307
+ /** @var Mage_Admin_Model_Session $session */
308
+ $session = Mage::getSingleton('customer/session');
309
+ if ($this->getPageCategory() == self::PAGE_CATEGORY_WISHLIST && $session->isLoggedIn()) {
310
+
311
+ $collection = Mage::getModel('wishlist/wishlist')->loadByCustomer($session->getCustomer())->getItemCollection();
312
+ foreach ($collection as $item) {
313
+ array_push($items, $this->getUvMapProduct($item->getProduct()));
314
+ }
315
+ }
316
+
317
+ // Build Query part
318
+ $query = '';
319
+ if (isset($_GET['q']) && $_GET['q'] != '') {
320
+ $query = $_GET['q'];
321
+ }
322
+ if (!empty($query) && ($this->getPageCategory() != self::PAGE_CATEGORY_SEARCH)) {
323
+ $query = '';
324
+ }
325
+
326
+ if ($this->getPageCategory() == self::PAGE_CATEGORY_CATEGORY) {
327
+ $query = $this->getCategoryPath();
328
+ }
329
+
330
+ // Build Items part - search context
331
+ // If it's a search result page than get the items from Search engine
332
+ if (!empty($query)) {
333
+ /** @var $listBlock Mage_Catalog_Block_Product_List */
334
+ $listBlock = Mage::app()->getLayout()->getBlockSingleton('catalog/product_list');
335
+
336
+ foreach ($listBlock->getLoadedProductCollection() as $product) {
337
+ array_push($items, $this->getUvMapProduct($product));
338
+ }
339
+
340
+ }
341
+
342
+ // Put together
343
+ if ($items) {
344
+ $object = new Ntoklo_Recommendations_Model_UniversalVariable();
345
+ $object->setProperties(array('query' => $query));
346
+ $object->items = $items;
347
+ }
348
+
349
+ return $object;
350
+ }
351
+
352
+ /**
353
+ * Creates the product UV object
354
+ * @return Ntoklo_Recommendations_Model_UniversalVariable
355
+ */
356
+ public function getUvMapProduct($product = false) {
357
+
358
+ if (!$product) {
359
+ $product = Mage::registry('current_product');
360
+ }
361
+
362
+ $session = Mage::getSingleton("core/session", array("name"=>"frontend"));
363
+ if (!$product && $session->hasData('current_wishlist_add_product')) {
364
+ $product = $session->getData('current_wishlist_add_product');
365
+ $session->unsetData('current_wishlist_add_product');
366
+ }
367
+
368
+ if (!$product) {
369
+ return false;
370
+ }
371
+
372
+ $object = new Ntoklo_Recommendations_Model_UniversalVariable(array(
373
+ 'id' => $product->getId(),
374
+ 'sku_code' => $product->getSku(),
375
+ 'url' => $product->getProductUrl(),
376
+ 'name' => $product->getName(),
377
+ 'unit_price' => (float) $product->getPrice(),
378
+ 'unit_sale_price' => (float) $product->getFinalPrice(),
379
+ 'currency' => Mage::app()->getStore()->getCurrentCurrencyCode(),
380
+ 'description' => $product->getShortDescription(),
381
+ 'stock' => (int) Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty()
382
+ ));
383
+
384
+ $categoryNames = array();
385
+ if ($categories = $product->getCategoryIds()) {
386
+ foreach ($categories as $categoryId) {
387
+ array_push($categoryNames, strtolower(Mage::getModel('catalog/category')->load($categoryId)->getName()));
388
+ }
389
+ }
390
+ if (!empty($categoryNames)) {
391
+ $object->setProperties(array('category' => implode(', ', $categoryNames)));
392
+ }
393
+
394
+ return $object;
395
+ }
396
+
397
+ /**
398
+ * Creates the Basket UV object
399
+ * Renders on every page
400
+ *
401
+ * @return Ntoklo_Recommendations_Model_UniversalVariable
402
+ */
403
+ public function getUvMapBasket() {
404
+
405
+ $cart = Mage::getSingleton('checkout/cart');
406
+ if ($this->getPageCategory() == self::PAGE_CATEGORY_CHECKOUT) {
407
+ $cart = Mage::getSingleton('checkout/session');
408
+ }
409
+
410
+ if (!($quote = $cart->getQuote())) {
411
+ return false;
412
+ }
413
+
414
+ $object = new Ntoklo_Recommendations_Model_UniversalVariable(array(
415
+ 'currency' => Mage::app()->getStore()->getCurrentCurrencyCode(),
416
+ 'subtotal' => (float) $quote->getSubtotal(),
417
+ 'subtotal_include_tax' => $this->_isTaxIncluded($quote),
418
+ 'tax' => (float) $quote->getTax(),
419
+ 'shipping_cost' => (float) $quote->getShippingAmount(),
420
+ 'total' => (float) $quote->getGrandTotal()
421
+ ));
422
+
423
+ if ($basketId = $quote->getId()) {
424
+ $object->setProperties(array('id' => $basketId));
425
+ }
426
+
427
+ if ($quote->getShippingMethod()) {
428
+ $object->setProperties(array('shipping_method' => $quote->getShippingMethod()));
429
+ }
430
+
431
+ if ($items = $quote->getAllItems()) {
432
+ $object->line_items = $this->_getUvMapLineItems($items);
433
+ }
434
+ else {
435
+ $object->line_items = array();
436
+ }
437
+
438
+
439
+ return $object;
440
+ }
441
+
442
+ /**
443
+ * Creates the line items UV object
444
+ * @param $items
445
+ * @return array
446
+ */
447
+ private function _getUvMapLineItems($items) {
448
+
449
+ $object = array();
450
+ foreach ($items as $item) {
451
+ array_push($object, new Ntoklo_Recommendations_Model_UniversalVariable(array(
452
+ 'product' => $this->getUvMapProduct(Mage::getModel('catalog/product')->load($item->getProductId())),
453
+ 'subtotal' => (float) $item->getRowTotalInclTax(),
454
+ 'total_discount' => (float) $item->getDiscountAmount(),
455
+ 'quantity' => ($this->getPageCategory() == self::PAGE_CATEGORY_BASKET) ? (float)$item->getQtyOrdered() : (float)$item->getQty(),
456
+ )));
457
+ }
458
+ return $object;
459
+ }
460
+
461
+ /**
462
+ * Creates transaction UV object
463
+ * @return bool|Ntoklo_Recommendations_Model_UniversalVariable
464
+ */
465
+ public function getUvMapTransaction() {
466
+
467
+ $orderId = Mage::getSingleton('checkout/session')->getLastOrderId();
468
+ if (!$orderId || ($this->getPageCategory() != self::PAGE_CATEGORY_CONFIRMATION)) {
469
+ return false;
470
+ }
471
+
472
+ $order = Mage::getModel('sales/order')->load($orderId);
473
+ $object = new Ntoklo_Recommendations_Model_UniversalVariable(array(
474
+ 'order_id' => $order->getIncrementId(),
475
+ 'currency' => Mage::app()->getStore()->getCurrentCurrencyCode(),
476
+ 'subtotal' => (float) $order->getSubtotal(),
477
+ 'subtotal_include_tax' => $this->_isTaxIncluded($order),
478
+ 'payment_type' => $order->getPayment()->getMethodInstance()->getTitle(),
479
+ 'total' => (float) $order->getGrandTotal(),
480
+ 'voucher' => $order->getCouponCode() ? $order->getCouponCode() : "",
481
+ 'voucher_discount' => (float)(-1 * $order->getDiscountAmount()),
482
+ 'tax' => (float) $order->getTax(),
483
+ 'shipping_cost' => (float) $order->getShippingAmount(),
484
+ 'shipping_method' => $order->getShippingMethod(),
485
+ 'billing' => $this->_getUvMapAddress($order->getBillingAddress()),
486
+ 'delivery' => $this->_getUvMapAddress($order->getShippingAddress())
487
+ ));
488
+ $object->line_items = $this->_getUvMapLineItems($order->getAllItems());
489
+
490
+ return $object;
491
+ }
492
+
493
+ /**
494
+ * Creates Address UV object
495
+ * @param $address Mage_Sales_Model_Order_Address
496
+ * @return Ntoklo_Recommendations_Model_UniversalVariable
497
+ */
498
+ private function _getUvMapAddress($address) {
499
+
500
+ /** @var $regionModel Mage_Directory_Model_Region */
501
+ $regionModel = Mage::getModel('directory/region')->load($address->getRegionId());
502
+
503
+ return new Ntoklo_Recommendations_Model_UniversalVariable(array(
504
+ 'name' => $address->getName(),
505
+ 'address' => $address->getStreetFull(),
506
+ 'city' => $address->getCity(),
507
+ 'postcode' => $address->getPostcode(),
508
+ 'country' => $address->getCountry(),
509
+ 'state' => $regionModel->getCode()
510
+ ));
511
+ }
512
+
513
+ /**
514
+ * @param $quote
515
+ * @return bool
516
+ */
517
+ private function _isTaxIncluded($quote) {
518
+ return (bool)($quote->getTax() == 0 || ($quote->getGrandTotal() - $quote->getShippingAmount() > $quote->getSubtotal()));
519
+ }
520
+
521
+ /**
522
+ * @return string
523
+ */
524
+ public function getCategoryPath() {
525
+ $path = "";
526
+ $breadcrumbs = Mage::helper('catalog')->getBreadcrumbPath();
527
+ if ($this->getPageCategory() == self::PAGE_CATEGORY_PRODUCT) {
528
+ array_pop($breadcrumbs);
529
+ }
530
+ foreach ($breadcrumbs as $element) {
531
+ $label = strtolower(str_replace('>', ' ', $element['label']));
532
+ $path .= ($path == '') ? $label : ' > '. $label;
533
+ }
534
+ return $path;
535
+ }
536
+
537
+ /**
538
+ * Computes the ntoklo User Id that will be tracking visitor
539
+ *
540
+ * @return string
541
+ */
542
+ public function getNtokloUserId() {
543
+
544
+ // Commented out as request to turn off the VisitorId usage: 26th April phone conversation.
545
+ // /** @var Mage_Log_Model_Visitor $visitor */
546
+ // $visitor = Mage::getSingleton('log/visitor');
547
+ // if ($visitor->getVisitorId()) {
548
+ // return $visitor->getVisitorId();
549
+ // }
550
+
551
+ /** @var Mage_Customer_Model_Customer $customer */
552
+ $customer = Mage::helper('customer')->getCustomer();
553
+ if ($customer->getId()) {
554
+ return $customer->getId();
555
+ }
556
+
557
+ return false;
558
+ }
559
+
560
+ }
app/code/community/Ntoklo/Recommendations/Model/Cache/UniversalVariable.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+ /**
20
+ * Class Ntoklo_Recommendations_Model_Cache_UniversalVariable
21
+ */
22
+ class Ntoklo_Recommendations_Model_Cache_UniversalVariable extends Enterprise_PageCache_Model_Container_Abstract {
23
+
24
+ /**
25
+ * Get container individual cache id
26
+ *
27
+ * @return string|false
28
+ */
29
+ protected function _getCacheId() {
30
+ $cacheId = $this->_getCookieValue('store', ''). '_'
31
+ . $this->_getCookieValue('currency', ''). '_'
32
+ . $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER_GROUP, ''). '_'
33
+ . $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER_LOGGED_IN, ''). '_'
34
+ . $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::CUSTOMER_SEGMENT_IDS, ''). '_'
35
+ . $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::IS_USER_ALLOWED_SAVE_COOKIE, ''). '_'
36
+ . $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, ''). '_'
37
+ . $this->_getCookieValue(Ntoklo_Recommendations_Helper_Data::COOKIE_KEY_CONVERSION, ''). '_';
38
+ return $cacheId;
39
+ }
40
+
41
+ /**
42
+ * Render block content from placeholder
43
+ *
44
+ * @return string|false
45
+ */
46
+ protected function _renderBlock() {
47
+ $block = $this->_getPlaceHolderBlock();
48
+ return $block->toHtml();
49
+ }
50
+
51
+
52
+ }
app/code/community/Ntoklo/Recommendations/Model/Observer.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+ /**
20
+ * Class Ntoklo_Recommendations_Model_Observer
21
+ */
22
+ class Ntoklo_Recommendations_Model_Observer {
23
+
24
+ /**
25
+ * Create and append UV block to layout
26
+ *
27
+ * @param $observer Varien_Event_Observer
28
+ * @return Ntoklo_Recommendations_Model_Observer
29
+ */
30
+ public function processUniversalVariable($observer) {
31
+
32
+ if (Mage::helper('ntoklo_recommendations')->isEnabled()) {
33
+ if ($headBlock = Mage::app()->getLayout()->getBlock('head')) {
34
+
35
+ /** @var $block Ntoklo_Recommendations_Block_UniversalVariable */
36
+ $block = Mage::app()->getLayout()->createBlock('ntoklo_recommendations/UniversalVariable', 'ntoklo_recommendations_uv');
37
+ $block->setTemplate('ntoklo/recommendations/universal_variable.phtml');
38
+
39
+ $headBlock->append($block, 'ntoklo.recommendations.uv');
40
+ }
41
+ }
42
+
43
+ return $this;
44
+ }
45
+
46
+ /**
47
+ * Captures the wishlist added product so it can be added on the UV.
48
+ *
49
+ * @param $observer
50
+ * @return $this
51
+ */
52
+ public function registerWishlistProduct($observer) {
53
+
54
+ $session = Mage::getSingleton("core/session", array("name"=>"frontend"));
55
+ $session->setData("current_wishlist_add_product", $observer->getEvent()->getProduct());
56
+ return $this;
57
+ }
58
+ }
app/code/community/Ntoklo/Recommendations/Model/Service.php ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+ /**
20
+ * Class Ntoklo_Recommendations_Model_Service
21
+ */
22
+ class Ntoklo_Recommendations_Model_Service extends Mage_Core_Model_Abstract {
23
+
24
+ const SRV_PARAM_SCOPE_CATEGORY = 'category';
25
+ const CALL_METHOD_RECOMMENDATIONS = 'recommendation';
26
+ const CALL_METHOD_CHART = 'chart';
27
+
28
+ // Private properties
29
+ private $_serviceUrl;
30
+ private $_apiKey;
31
+ private $_apiSecret;
32
+ private $_debug = false;
33
+
34
+ /**
35
+ * Initialize properties
36
+ */
37
+ public function __construct() {
38
+ $this->_serviceUrl = Mage::helper('ntoklo_recommendations/data')->getNtokloApiServiceUrl();
39
+ $this->_apiKey = Mage::helper('ntoklo_recommendations/data')->getNtokloApiKey();
40
+ $this->_apiSecret = Mage::helper('ntoklo_recommendations/data')->getNtokloSecretKey();
41
+ }
42
+
43
+ /**
44
+ * @param $str string
45
+ * @return string
46
+ */
47
+ protected function hmac_sha1($key, $data) {
48
+ // Adjust key to exactly 64 bytes
49
+ if (strlen($key) > 64) {
50
+ $key = str_pad(sha1($key, true), 64, chr(0));
51
+ }
52
+ if (strlen($key) < 64) {
53
+ $key = str_pad($key, 64, chr(0));
54
+ }
55
+
56
+ // Outter and Inner pad
57
+ $opad = str_repeat(chr(0x5C), 64);
58
+ $ipad = str_repeat(chr(0x36), 64);
59
+
60
+ // Xor key with opad & ipad
61
+ for ($i = 0; $i < strlen($key); $i++) {
62
+ $opad[$i] = $opad[$i] ^ $key[$i];
63
+ $ipad[$i] = $ipad[$i] ^ $key[$i];
64
+ }
65
+
66
+ return sha1($opad.sha1($ipad.$data, true));
67
+ }
68
+
69
+ /**
70
+ * Signs the data using Ntoklo keys
71
+ *
72
+ * @param $data string
73
+ * @return string
74
+ */
75
+ protected function _getRequestSignature($serviceUrl) {
76
+ $key = sprintf("%s&%s", $this->_apiKey, $this->_apiSecret);
77
+ $data = sprintf("%s&%s", Zend_Http_Client::GET, $serviceUrl);
78
+ return $this->hmac_sha1($key, $data);
79
+ }
80
+
81
+ /**
82
+ * Calls ntoklo API
83
+ *
84
+ * @param string $method
85
+ * @param array $params
86
+ * @return array
87
+ */
88
+ protected function _apiCall($method, $params = array()) {
89
+
90
+ $response = array();
91
+ $serviceUrl = $this->_serviceUrl. '/'. $method;
92
+ $k = 0;
93
+ foreach ($params as $key => $value) {
94
+ $serviceUrl .= ($k++ == 0 ? '?' : '&'). urlencode($key). '='. urlencode($value);
95
+ }
96
+ $headers = array('Authorization: NTOKLO '. $this->_apiKey. ':'. $this->_getRequestSignature($serviceUrl));
97
+
98
+ // Debug
99
+ if ($this->_debug) {
100
+ Mage::log('Ntoklo API: call '. $serviceUrl);
101
+ Mage::log('Ntoklo API: headers '. implode("\n", $headers));
102
+ }
103
+
104
+ $curl = new Varien_Http_Adapter_Curl();
105
+ $curl->setConfig(array('timeout' => 15));
106
+ $curl->write(Zend_Http_Client::GET, $serviceUrl, '1.0', $headers);
107
+ $result = $curl->read();
108
+ $curl->close();
109
+
110
+ if ($result === false) {
111
+ Mage::log('Ntoklo API call - no response', Zend_Log::ERR);
112
+ return $response;
113
+ }
114
+
115
+ if ($this->_debug) {
116
+ Mage::log('Ntoklo API: response ');
117
+ Mage::log($result);
118
+ }
119
+
120
+ $data = preg_split('/^\r?$/m', $result, 2);
121
+ if (isset($data[1])) {
122
+ $response = json_decode($data[1], TRUE);
123
+ }
124
+
125
+ if (!is_array($response)) { // !is_object($response)
126
+ Mage::log('Ntoklo API call - invalid response '. "\n". ' '.$result, Zend_Log::ERR);
127
+ return array();
128
+ }
129
+
130
+ return $response;
131
+ }
132
+
133
+ /**
134
+ * Parse recommended IDs from ntoklo
135
+ * @param Ntoklo_Recommendations_Block_Chart $chart
136
+ * @return array
137
+ */
138
+ public function getRecommendedIds($chart) {
139
+
140
+ $ids = array();
141
+ $err = false;
142
+ $response = $this->_apiCall($chart->getData('widget_type'), $this->getServiceParams($chart));
143
+
144
+ switch ($chart->getData('widget_type')) {
145
+ case self::CALL_METHOD_CHART:
146
+ foreach ($response as $item) {
147
+ if (array_key_exists('product', $item) && array_key_exists('id', $item['product'])) {
148
+ $ids[] = $item['product']['id'];
149
+ } else {
150
+ $err = true;
151
+ }
152
+ }
153
+ break;
154
+ case self::CALL_METHOD_RECOMMENDATIONS:
155
+ if (array_key_exists('items', $response)) {
156
+ foreach ($response['items'] as $item) {
157
+ if (array_key_exists('id', $item)) {
158
+ $ids[] = $item['id'];
159
+ } else {
160
+ $err = true;
161
+ }
162
+ }
163
+ } else {
164
+ $err = true;
165
+ }
166
+ break;
167
+ }
168
+
169
+ if (array_key_exists('error', $response)) {
170
+ Mage::log('Ntoklo API call - '. $response['error']['code']. ' '. $response['error']['reason'], Zend_Log::ERR);
171
+ } elseif ($err) {
172
+ Mage::log('Ntoklo API call - Unrecognized response format', Zend_Log::ERR);
173
+ Mage::log($response);
174
+ }
175
+
176
+ if ($this->_debug) {
177
+ // Force first 4 products from catalog
178
+ $ids = array();
179
+ $collection = Mage::getResourceModel('catalog/product_collection')->setPage(0, 4);
180
+ foreach ($collection as $item) {
181
+ $ids[] = $item->getId();
182
+ }
183
+ }
184
+
185
+ return $ids;
186
+ }
187
+
188
+ /**
189
+ * Generates the service call parameters depending on the
190
+ * page data availability and $context parameter
191
+ *
192
+ * @param Ntoklo_Recommendations_Block_Chart $chart
193
+ * @return array
194
+ */
195
+ public function getServiceParams($chart) {
196
+
197
+ $serviceParams = array();
198
+ $pageCategory = Mage::helper('ntoklo_recommendations/data')->getPageCategory();
199
+
200
+ if ($pageCategory == Ntoklo_Recommendations_Helper_Data::PAGE_CATEGORY_CATEGORY) {
201
+ $serviceParams['scope'] = self::SRV_PARAM_SCOPE_CATEGORY;
202
+ $serviceParams['value'] = strtolower(Mage::registry('current_category')->getName());
203
+ }
204
+
205
+ if ($chart->getData('widget_type') == self::CALL_METHOD_RECOMMENDATIONS) {
206
+ // Required Params
207
+ if ($userId = Mage::helper('ntoklo_recommendations')->getNtokloUserId()) {
208
+ $serviceParams['userId'] = $userId;
209
+ }
210
+ if ($product = Mage::registry('current_product')) {
211
+ $serviceParams['productId'] = $product->getId();
212
+ }
213
+
214
+ // Optional Params
215
+ if ($pageCategory) {
216
+ $serviceParams['pageCategory'] = $pageCategory;
217
+ }
218
+ if ($pageCategory == Ntoklo_Recommendations_Helper_Data::PAGE_CATEGORY_CATEGORY ||
219
+ $pageCategory == Ntoklo_Recommendations_Helper_Data::PAGE_CATEGORY_PRODUCT) {
220
+ $serviceParams['pageSubcategory'] = Mage::helper('ntoklo_recommendations/data')->getCategoryPath();
221
+ }
222
+ }
223
+ else {
224
+ // 'date' should be omitted per Paolo's request 15 May 2013
225
+ if ($chart->hasData('start_date')) {
226
+ $timestamp = strtotime($chart->getData('start_date'));
227
+ $serviceParams['date'] = mktime(0, 0, 0, date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp)). '000';
228
+ }
229
+
230
+
231
+ //$serviceParams['action'] = Mage::helper('ntoklo_recommendations/data')->getEventType($pageCategory);
232
+ $serviceParams['tw'] = $chart->getData('time_window');
233
+ $serviceParams['maxItems'] = (int)$chart->getData('max_products') > 0 ? (int)$chart->getData('max_products') : 10;
234
+ }
235
+
236
+ return $serviceParams;
237
+ }
238
+
239
+ /**
240
+ * Sets the debug mode
241
+ * @param bool $value
242
+ * @return $this
243
+ */
244
+ public function setDebug($value = false) {
245
+ $this->_debug = $value;
246
+ return $this;
247
+ }
248
+ }
app/code/community/Ntoklo/Recommendations/Model/UniversalVariable.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+ /**
20
+ * Class Ntoklo_Recommendations_Model_UniversalVariable
21
+ */
22
+ class Ntoklo_Recommendations_Model_UniversalVariable {
23
+
24
+ public function __construct($properties = array()) {
25
+ $this->setProperties($properties, $this);
26
+ }
27
+
28
+ public function setProperties($properties) {
29
+ foreach ($properties as $k => $v) {
30
+ if (is_array($v)) {
31
+ $this->$k = new Ntoklo_Recommendations_Model_UniversalVariable();
32
+ $this->$k->setProperties($v);
33
+ }
34
+ else {
35
+ $this->$k = $v;
36
+ }
37
+ }
38
+ }
39
+ }
app/code/community/Ntoklo/Recommendations/Model/Widget/Type.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+
19
+ class Ntoklo_Recommendations_Model_Widget_Type {
20
+
21
+ /**
22
+ * Options getter
23
+ *
24
+ * @return array
25
+ */
26
+ public function toOptionArray() {
27
+ return array(
28
+ array('value' => Ntoklo_Recommendations_Model_Service::CALL_METHOD_RECOMMENDATIONS, 'label'=>Mage::helper('ntoklo_recommendations')->__('Recommendations')),
29
+ array('value' => Ntoklo_Recommendations_Model_Service::CALL_METHOD_CHART, 'label'=>Mage::helper('ntoklo_recommendations')->__('Chart')),
30
+ );
31
+ }
32
+
33
+ /**
34
+ * Get options in "key-value" format
35
+ *
36
+ * @return array
37
+ */
38
+ public function toArray() {
39
+ return array(
40
+ Ntoklo_Recommendations_Model_Service::CALL_METHOD_RECOMMENDATIONS => Mage::helper('ntoklo_recommendations')->__('Recommendations'),
41
+ Ntoklo_Recommendations_Model_Service::CALL_METHOD_CHART => Mage::helper('ntoklo_recommendations')->__('Chart'),
42
+ );
43
+ }
44
+ }
app/code/community/Ntoklo/Recommendations/etc/adminhtml.xml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * nToklo
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ *
13
+ * @category Ntoklo
14
+ * @package Ntoklo_Recommendations
15
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ * @author nToklo
18
+ */
19
+ -->
20
+ <config>
21
+ <acl>
22
+ <resources>
23
+ <admin>
24
+ <children>
25
+ <system>
26
+ <children>
27
+ <config>
28
+ <children>
29
+ <ntoklo_recommendations translate="title" module="ntoklo_recommendations">
30
+ <title>Ntoklo Recommendations</title>
31
+ <sort_order>100</sort_order>
32
+ </ntoklo_recommendations>
33
+ </children>
34
+ </config>
35
+ </children>
36
+ </system>
37
+ </children>
38
+ </admin>
39
+ </resources>
40
+ </acl>
41
+ </config>
app/code/community/Ntoklo/Recommendations/etc/cache.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ /**
4
+ * nToklo
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ *
13
+ * @category Ntoklo
14
+ * @package Ntoklo_Recommendations
15
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ * @author nToklo
18
+ */
19
+ -->
20
+ <config>
21
+ <placeholders>
22
+ <ntoklo_universalvariable>
23
+ <block>ntoklo_recommendations/universalVariable</block>
24
+ <placeholder>NTOKLO_UV</placeholder>
25
+ <container>Ntoklo_Recommendations_Model_Cache_UniversalVariable</container>
26
+ <cache_lifetime>86400</cache_lifetime>
27
+ </ntoklo_universalvariable>
28
+ </placeholders>
29
+ </config>
app/code/community/Ntoklo/Recommendations/etc/config.xml ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * nToklo
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ *
13
+ * @category Ntoklo
14
+ * @package Ntoklo_Recommendations
15
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ * @author nToklo
18
+ */
19
+ -->
20
+ <config>
21
+ <modules>
22
+ <Ntoklo_Recommendations>
23
+ <version>0.1.0</version>
24
+ </Ntoklo_Recommendations>
25
+ </modules>
26
+ <global>
27
+ <models>
28
+ <ntoklo_recommendations>
29
+ <class>Ntoklo_Recommendations_Model</class>
30
+ </ntoklo_recommendations>
31
+ </models>
32
+ <blocks>
33
+ <ntoklo_recommendations>
34
+ <class>Ntoklo_Recommendations_Block</class>
35
+ </ntoklo_recommendations>
36
+ </blocks>
37
+ <helpers>
38
+ <ntoklo_recommendations>
39
+ <class>Ntoklo_Recommendations_Helper</class>
40
+ </ntoklo_recommendations>
41
+ </helpers>
42
+ </global>
43
+ <frontend>
44
+ <translate>
45
+ <modules>
46
+ <ntoklo_recommendations>
47
+ <files>
48
+ <default>ntoklo_recommendations.csv</default>
49
+ </files>
50
+ </ntoklo_recommendations>
51
+ </modules>
52
+ </translate>
53
+ <layout>
54
+ <updates>
55
+ <ntoklo_recommendations>
56
+ <file>ntoklo_recommendations.xml</file>
57
+ </ntoklo_recommendations>
58
+ </updates>
59
+ </layout>
60
+ <events>
61
+ <controller_action_layout_render_before>
62
+ <observers>
63
+ <ntoklo_recommendations>
64
+ <type>singleton</type>
65
+ <class>ntoklo_recommendations/observer</class>
66
+ <method>processUniversalVariable</method>
67
+ </ntoklo_recommendations>
68
+ </observers>
69
+ </controller_action_layout_render_before>
70
+ <wishlist_add_product>
71
+ <observers>
72
+ <ntoklo_recommendations>
73
+ <type>singleton</type>
74
+ <class>ntoklo_recommendations/observer</class>
75
+ <method>registerWishlistProduct</method>
76
+ </ntoklo_recommendations>
77
+ </observers>
78
+ </wishlist_add_product>
79
+ </events>
80
+ </frontend>
81
+ <default>
82
+ <ntoklo_recommendations>
83
+ <settings>
84
+ <is_enabled>1</is_enabled>
85
+ <api_key></api_key>
86
+ <api_secret></api_secret>
87
+ <api_ssl_key></api_ssl_key>
88
+ <api_ssl_secret></api_ssl_secret>
89
+ <api_service_url><![CDATA[https://api.ntoklo.com]]></api_service_url>
90
+ <api_script_url><![CDATA[https://console.ntoklo.com/static/js/ntoklo.js]]></api_script_url>
91
+ <api_debug>false</api_debug>
92
+ </settings>
93
+ </ntoklo_recommendations>
94
+ </default>
95
+ </config>
app/code/community/Ntoklo/Recommendations/etc/system.xml ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * nToklo
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ *
13
+ * @category Ntoklo
14
+ * @package Ntoklo_Recommendations
15
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ * @author nToklo
18
+ */
19
+ -->
20
+ <config>
21
+ <!--<tabs>-->
22
+ <!--<ntoklo_tab>-->
23
+ <!--<label>Ntoklo</label>-->
24
+ <!--<sort_order>199</sort_order>-->
25
+ <!--</ntoklo_tab>-->
26
+ <!--</tabs>-->
27
+ <sections>
28
+ <ntoklo_recommendations translate="label">
29
+ <!--<label><![CDATA[Recommendations & Charts]]></label>-->
30
+ <!--<tab>ntoklo_tab</tab>-->
31
+ <label>nToklo</label>
32
+ <tab>general</tab>
33
+ <frontend_type>text</frontend_type>
34
+ <sort_order>1100</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
+ <groups>
39
+ <settings translate="label">
40
+ <label>Settings</label>
41
+ <frontend_type>text</frontend_type>
42
+ <sort_order>10</sort_order>
43
+ <show_in_default>1</show_in_default>
44
+ <show_in_website>1</show_in_website>
45
+ <show_in_store>1</show_in_store>
46
+ <fields>
47
+ <is_enabled translate="label">
48
+ <label>Enabled</label>
49
+ <frontend_type>select</frontend_type>
50
+ <source_model>adminhtml/system_config_source_yesno</source_model>
51
+ <sort_order>10</sort_order>
52
+ <show_in_default>1</show_in_default>
53
+ <show_in_website>1</show_in_website>
54
+ <show_in_store>1</show_in_store>
55
+ <comment><![CDATA[Enable/Disable event submission to nToklo service. This switch also disables all "nToklo" widgets from been displayed.]]></comment>
56
+ </is_enabled>
57
+
58
+ <!--<auth_separator>-->
59
+ <!--<label>API Authentication</label>-->
60
+ <!--<sort_order>20</sort_order>-->
61
+ <!--<frontend_model>adminhtml/system_config_form_field_heading</frontend_model>-->
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
+ <!--</auth_separator>-->
66
+ <api_key translate="label">
67
+ <label>Api Key</label>
68
+ <frontend_type>text</frontend_type>
69
+ <sort_order>30</sort_order>
70
+ <show_in_default>1</show_in_default>
71
+ <show_in_website>1</show_in_website>
72
+ <show_in_store>1</show_in_store>
73
+ <comment><![CDATA[Your API Key from nToklo Console.]]></comment>
74
+ </api_key>
75
+ <api_secret translate="label">
76
+ <label>Api Secret</label>
77
+ <frontend_type>text</frontend_type>
78
+ <!--<frontend_type>obscure</frontend_type>-->
79
+ <!--<backend_model>adminhtml/system_config_backend_encrypted</backend_model>-->
80
+ <sort_order>40</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
+ <comment><![CDATA[Your API Secret from nToklo Console.]]></comment>
85
+ </api_secret>
86
+
87
+ <!--<advanced_separator>-->
88
+ <!--<label>Advanced Configuration</label>-->
89
+ <!--<sort_order>50</sort_order>-->
90
+ <!--<frontend_model>adminhtml/system_config_form_field_heading</frontend_model>-->
91
+ <!--<show_in_default>1</show_in_default>-->
92
+ <!--<show_in_website>1</show_in_website>-->
93
+ <!--<show_in_store>1</show_in_store>-->
94
+ <!--</advanced_separator>-->
95
+
96
+ <!-- Commented out per Paolo's request 21 May 2013 -->
97
+ <!--<api_service_url translate="label">-->
98
+ <!--<label>Api Service URL</label>-->
99
+ <!--<frontend_type>text</frontend_type>-->
100
+ <!--<sort_order>60</sort_order>-->
101
+ <!--<show_in_default>1</show_in_default>-->
102
+ <!--<show_in_website>1</show_in_website>-->
103
+ <!--<show_in_store>1</show_in_store>-->
104
+ <!--<comment><![CDATA[nToklo API Service endpoint.]]></comment>-->
105
+ <!--</api_service_url>-->
106
+ <!--<api_script_url translate="label">-->
107
+ <!--<label>Api Script URL</label>-->
108
+ <!--<frontend_type>text</frontend_type>-->
109
+ <!--<sort_order>70</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
+ <!--<comment><![CDATA[nToklo js script location]]></comment>-->
114
+ <!--</api_script_url>-->
115
+ </fields>
116
+ </settings>
117
+ </groups>
118
+ </ntoklo_recommendations>
119
+ </sections>
120
+ </config>
app/code/community/Ntoklo/Recommendations/etc/widget.xml ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * nToklo
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ *
13
+ * @category Ntoklo
14
+ * @package Ntoklo_Recommendations
15
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ * @author nToklo
18
+ */
19
+ -->
20
+
21
+ <widgets>
22
+ <ntoklo_recommendations_chart type="ntoklo_recommendations/chart" translate="name description" module="ntoklo_recommendations">
23
+ <name>nToklo</name>
24
+ <description type="desc"><![CDATA[Outputs nToklo recommended products.]]></description>
25
+ <parameters>
26
+ <widget_type translate="label">
27
+ <label>Widget type</label>
28
+ <visible>1</visible>
29
+ <required>1</required>
30
+ <type>select</type>
31
+ <source_model>ntoklo_recommendations/widget_type</source_model>
32
+ <value>recommendation</value>
33
+ </widget_type>
34
+ <widget_type_helper translate="label">
35
+ <visible>1</visible>
36
+ <required>0</required>
37
+ <type>label</type>
38
+ <helper_block>
39
+ <type>ntoklo_recommendations/adminhtml_widget_type_helper</type>
40
+ </helper_block>
41
+ <depends>
42
+ <widget_type>
43
+ <value>chart</value>
44
+ </widget_type>
45
+ </depends>
46
+ </widget_type_helper>
47
+ <header_recommendations translate="label description">
48
+ <label>Header</label>
49
+ <visible>1</visible>
50
+ <required>0</required>
51
+ <type>text</type>
52
+ <description><![CDATA[Widget's header been displayed on the page.]]></description>
53
+ <value><![CDATA[Recommended For You]]></value>
54
+ <depends>
55
+ <widget_type>
56
+ <value>recommendation</value>
57
+ </widget_type>
58
+ </depends>
59
+ </header_recommendations>
60
+ <header_chart translate="label description">
61
+ <label>Header</label>
62
+ <visible>1</visible>
63
+ <required>0</required>
64
+ <type>text</type>
65
+ <description><![CDATA[Widget's header been displayed on the page.]]></description>
66
+ <value><![CDATA[Trending Products]]></value>
67
+ <depends>
68
+ <widget_type>
69
+ <value>chart</value>
70
+ </widget_type>
71
+ </depends>
72
+ </header_chart>
73
+ <time_window translate="label description">
74
+ <label>Time Window</label>
75
+ <visible>1</visible>
76
+ <required>1</required>
77
+ <type>select</type>
78
+ <description><![CDATA[The time window for which the charts are requested.]]></description>
79
+ <values>
80
+ <daily translate="label">
81
+ <value>DAILY</value>
82
+ <label>Daily</label>
83
+ </daily>
84
+ <weekly>
85
+ <value>WEEKLY</value>
86
+ <label>Weekly</label>
87
+ </weekly>
88
+ </values>
89
+ <value>DAILY</value>
90
+ <depends>
91
+ <widget_type>
92
+ <value>chart</value>
93
+ </widget_type>
94
+ </depends>
95
+ </time_window>
96
+ <!--Commented out per Paolo's request 21 May 2013-->
97
+ <!--<start_date translate="label description">-->
98
+ <!--<label>Start Date</label>-->
99
+ <!--<visible>1</visible>-->
100
+ <!--<required>0</required>-->
101
+ <!--<description><![CDATA[Use recommendations data starting with this date. Leave blank for default.]]></description>-->
102
+ <!--<type>label</type>-->
103
+ <!--<helper_block>-->
104
+ <!--<type>ntoklo_recommendations/adminhtml_widget_date_helper</type>-->
105
+ <!--</helper_block>-->
106
+ <!--<depends>-->
107
+ <!--<widget_type>-->
108
+ <!--<value>chart</value>-->
109
+ <!--</widget_type>-->
110
+ <!--</depends>-->
111
+ <!--</start_date>-->
112
+ <max_products translate="label description">
113
+ <label>Max products</label>
114
+ <description><![CDATA[Limits the number of products displayed in the widget.]]></description>
115
+ <visible>1</visible>
116
+ <required>1</required>
117
+ <type>text</type>
118
+ <value>4</value>
119
+ </max_products>
120
+ <column_count translate="label description">
121
+ <label>Column count</label>
122
+ <description><![CDATA[The number of columns used when displaying in <strong>nToklo Grid Template</strong>.]]></description>
123
+ <visible>1</visible>
124
+ <required>0</required>
125
+ <type>text</type>
126
+ <value>4</value>
127
+ </column_count>
128
+ <cache_lifetime translate="label description">
129
+ <label>Cache lifetime</label>
130
+ <description><![CDATA[86400 by default, if not set. To refresh instantly, Clear the Blocks HTML Output Cache.]]></description>
131
+ <visible>1</visible>
132
+ <type>text</type>
133
+ </cache_lifetime>
134
+ <!--Commented out per Anton's request 29 May 2013-->
135
+ <!--<debug translate="label description">-->
136
+ <!--<label>Debug</label>-->
137
+ <!--<description><![CDATA[Turn this ON to force logging of API call and set the first 4 products from catalog as API response to test the look and feel of the widget.]]></description>-->
138
+ <!--<visible>1</visible>-->
139
+ <!--<required>0</required>-->
140
+ <!--<type>select</type>-->
141
+ <!--<source_model>adminhtml/system_config_source_yesno</source_model>-->
142
+ <!--<value>0</value>-->
143
+ <!--</debug>-->
144
+ <template translate="label">
145
+ <label>Frontend Template</label>
146
+ <visible>1</visible>
147
+ <required>1</required>
148
+ <type>select</type>
149
+ <values>
150
+ <vertical translate="label">
151
+ <value>ntoklo/recommendations/widget/chart_vertical.phtml</value>
152
+ <label>nToklo Column Template</label>
153
+ </vertical>
154
+ <landscape translate="label">
155
+ <value>ntoklo/recommendations/widget/chart_horisontal.phtml</value>
156
+ <label>nToklo Grid Template</label>
157
+ </landscape>
158
+ </values>
159
+ <value>ntoklo/recommendations/widget/chart_vertical.phtml</value>
160
+ </template>
161
+ </parameters>
162
+ </ntoklo_recommendations_chart>
163
+ </widgets>
app/design/frontend/base/default/layout/ntoklo_recommendations.xml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * nToklo
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ *
13
+ * @category Ntoklo
14
+ * @package Ntoklo_Recommendations
15
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ * @author nToklo
18
+ */
19
+ -->
20
+ <layout version="0.1.0">
21
+ <default>
22
+ <reference name="head">
23
+ <action method="addItem"><type>js</type><name>ntoklo/util.js</name></action>
24
+ <action method="addCss"><stylesheet>css/ntoklo/widgets.css</stylesheet></action>
25
+ </reference>
26
+ </default>
27
+ </layout>
app/design/frontend/base/default/template/ntoklo/recommendations/universal_variable.phtml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+ ?>
19
+ <!-- nToklo Start -->
20
+ <script type="text/javascript">
21
+ //<![CDATA[
22
+ var _ntoklo_key = "<?php echo $this->getNtokloApiKey(); ?>";
23
+ var _ntoklo_debug = <?php echo $this->isNtokloDebugActive(); ?>;
24
+ var _ntoklo_host = "<?php echo $this->getNtokloApiServiceUrl(); ?>";
25
+ var _ntoklo_event_rate = "<?php echo Ntoklo_Recommendations_Helper_Data::PAGE_CATEGORY_RATE; ?>";
26
+ var _ntoklo_event_review = "<?php echo Ntoklo_Recommendations_Helper_Data::PAGE_CATEGORY_REVIEW; ?>";
27
+
28
+ Event.observe(window, 'load', function(){
29
+ window.universal_variable = window.universal_variable || {};
30
+ var _ntoklo = new Ntoklo("<?php echo $this->getNtokloScriptUrl(); ?>", (<?php echo $this->getJsonUniversalVariable(); ?>));
31
+ _ntoklo.loadEvent();
32
+ });
33
+ //]]>
34
+ </script>
35
+ <!-- nToklo End -->
app/design/frontend/base/default/template/ntoklo/recommendations/widget/chart_horisontal.phtml ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+ ?>
19
+
20
+ <?php if (($_products = $this->getItems()) && count($_products)): ?>
21
+ <!-- nToklo Chart -->
22
+ <div class="widget widget-ntoklo-container">
23
+ <div class="widget-title">
24
+ <h2><?php echo $this->getHeader() ?></h2>
25
+ </div>
26
+ <div class="widget-products ntoklo-horisontal">
27
+ <?php $_columnCount = $this->getColumnCount(); ?>
28
+ <?php $i=0; foreach ($_products as $_product): ?>
29
+ <?php if ($i++%$_columnCount==0): ?>
30
+ <ol class="products-grid <?php if($this->isChart()) echo 'chart';?>">
31
+ <?php endif ?>
32
+ <li class="item<?php if(($i-1)%$_columnCount==0): ?> first<?php elseif($i%$_columnCount==0): ?> last<?php endif; ?>">
33
+ <span>
34
+ <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($_product->getName(), null, true) ?>" class="product-image ntoklo_conversion"><img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135) ?>" width="135" height="135" alt="<?php echo $this->stripTags($_product->getName(), null, true) ?>" /></a>
35
+ <h3 class="product-name"><a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($_product->getName(), null, true) ?>)" class="ntoklo_conversion"><?php echo $this->helper('catalog/output')->productAttribute($_product, $_product->getName() , 'name') ?></a></h3>
36
+ <?php echo $this->getReviewsSummaryHtml($_product, 'ntoklo_short') ?>
37
+ <?php echo $this->getPriceHtml($_product, true, '-widget-ntoklo-chart') ?>
38
+ <div class="actions">
39
+ <?php if ($_product->isSaleable()): ?>
40
+ <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')" class="ntoklo_conversion"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
41
+ <?php else: ?>
42
+ <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
43
+ <?php endif; ?>
44
+ <ul class="add-to-links">
45
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
46
+ <li><a href="<?php echo $this->getAddToWishlistUrl($_product) ?>" class="link-wishlist ntoklo_conversion"><?php echo $this->__('Add to Wishlist') ?></a></li>
47
+ <?php endif; ?>
48
+ <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
49
+ <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare ntoklo_conversion"><?php echo $this->__('Add to Compare') ?></a></li>
50
+ <?php endif; ?>
51
+ </ul>
52
+ </div>
53
+ </span>
54
+ </li>
55
+ <?php if ($i%$_columnCount==0 || $i==count($_products)): ?>
56
+ </ol>
57
+ <?php endif ?>
58
+ <?php endforeach; ?>
59
+ </div>
60
+ </div>
61
+ <!-- //END nToklo Chart -->
62
+ <?php endif; ?>
app/design/frontend/base/default/template/ntoklo/recommendations/widget/chart_review_short.phtml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+ ?>
19
+
20
+ <?php if ($this->getReviewsCount()): ?>
21
+ <div class="ratings">
22
+ <?php if ($this->getRatingSummary()):?>
23
+ <div class="rating-box">
24
+ <div class="rating" style="width:<?php echo $this->getRatingSummary() ?>%"></div>
25
+ </div>
26
+ <?php endif;?>
27
+ <span class="amount"><a href="<?php echo $this->getReviewsUrl() ?>" class="ntoklo_conversion"><?php echo $this->__('%d Review(s)', $this->getReviewsCount()) ?></a></span>
28
+ </div>
29
+ <?php elseif ($this->getDisplayIfEmpty()): ?>
30
+ <p class="no-rating"><a href="<?php echo $this->getReviewsUrl() ?>#review-form" class="ntoklo_conversion"><?php echo $this->__('Be the first to review this product') ?></a></p>
31
+ <?php endif; ?>
app/design/frontend/base/default/template/ntoklo/recommendations/widget/chart_vertical.phtml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * nToklo
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Ntoklo
13
+ * @package Ntoklo_Recommendations
14
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ * @author nToklo
17
+ */
18
+ ?>
19
+
20
+ <?php if(count($this->getItems())): ?>
21
+ <!-- nToklo Chart -->
22
+ <div class="block widget-ntoklo-container">
23
+ <div class="block-title">
24
+ <strong><span><?php echo $this->getHeader() ?></span></strong>
25
+ </div>
26
+ <div class="block-content ntoklo-vertical">
27
+ <ol class="mini-products-list <?php if($this->isChart()) echo 'chart';?>" id="block-ntoklo-chart">
28
+ <?php foreach($this->getItems() as $_item): ?>
29
+ <li class="item">
30
+ <?php if(!$_item->isComposite() && $_item->isSaleable()): ?>
31
+ <div class="product">
32
+ <a href="<?php echo $_item->getProductUrl() ?>" title="<?php echo $this->htmlEscape($_item->getName()) ?>" class="product-image ntoklo_conversion"><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>
33
+ <div class="product-details">
34
+ <p class="product-name"><a href="<?php echo $_item->getProductUrl() ?>" class="ntoklo_conversion"><?php echo $this->htmlEscape($_item->getName()) ?></a></p>
35
+ <?php echo $this->getPriceHtml($_item, true, '-ntoklo-chart') ?>
36
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
37
+ <a href="<?php echo $this->getAddToWishlistUrl($_item) ?>" class="link-wishlist ntoklo_conversion"><?php echo $this->__('Add to Wishlist') ?></a>
38
+ <?php endif; ?>
39
+ </div>
40
+ </div>
41
+ <?php endif; ?>
42
+ </li>
43
+ <?php endforeach ?>
44
+ </ol>
45
+ <script type="text/javascript">decorateList('block-ntoklo-chart', 'none-recursive')</script>
46
+ </div>
47
+ </div>
48
+ <!-- //END nToklo Chart -->
49
+ <?php endif ?>
app/etc/modules/Ntoklo_Recommendations.xml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * nToklo
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ *
13
+ * @category Ntoklo
14
+ * @package Ntoklo_Recommendations
15
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ * @author nToklo
18
+ */
19
+ -->
20
+ <config>
21
+ <modules>
22
+ <Ntoklo_Recommendations>
23
+ <active>true</active>
24
+ <codePool>community</codePool>
25
+ <depends>
26
+ <Mage_Cms />
27
+ </depends>
28
+ </Ntoklo_Recommendations>
29
+ </modules>
30
+ </config>
app/locale/en_US/ntoklo_recommendations.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Ntoklo Recommendations","Ntoklo Recommendations"
2
+ "Outputs Ntoklo recommendaded products, regardless page context","Outputs Ntoklo recommendaded products, regardless page context"
3
+ "Widget type","Widget type"
4
+ "Header","Header"
5
+ "Widget's header been displayed on the page.","Widget's header been displayed on the page."
6
+ "Time Window","Time Window"
7
+ "The time window for which the charts are requested.","The time window for which the charts are requested."
8
+ "Max products","Max products"
9
+ "Limits the number of products displayed in the widget.","Limits the number of products displayed in the widget."
10
+ "Column count","Column count"
11
+ "The number of columns used when displaying in <strong>Recommendation Grid Template</strong>.","The number of columns used when displaying in <strong>Recommendation Grid Template</strong>."
12
+ "Cache lifetime","Cache lifetime"
13
+ "86400 by default, if not set. To refresh instantly, Clear the Blocks HTML Output Cache.","86400 by default, if not set. To refresh instantly, Clear the Blocks HTML Output Cache."
14
+ "Debug","Debug"
15
+ "Turn this ON to force logging of API call and set the first 4 products from catalog as API response to test the look and feel of the widget.","Turn this ON to force logging of API call and set the first 4 products from catalog as API response to test the look and feel of the widget."
16
+ "Frontend Template","Frontend Template"
documentation/.DS_Store ADDED
Binary file
documentation/readme.html ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2
+ <html>
3
+ <head>
4
+ <title>nToklo Recommendations : readme</title>
5
+ <link rel="stylesheet" href="skin/style.css" type="text/css" />
6
+ <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
7
+ </head>
8
+ <body>
9
+ <div id="main-container">
10
+ <div id="header">
11
+ <div id="logo">
12
+ <a href="http://www.ntoklo.com"><img src="skin/img/logo.png"/></a>
13
+ </div>
14
+ <div id="address">
15
+ 1st Floor, 48 Warwick Street<br/>
16
+ London, W1B 5NL, United Kingdom<br/>
17
+ T: +44 (0) 20 7747 1080<br/>
18
+ F: +44 (0) 20 7747 1010<br/>
19
+ Email: <a href="mailto:support@ntoklo.com">support@ntoklo.com</a><br/>
20
+ </div>
21
+ <div class="clearer"></div>
22
+ </div>
23
+ <div id="main">
24
+ <br/><br/>
25
+ <h1>nToklo Recommendations</h1>
26
+ <h1>Table of Contents</h1>
27
+ <ol>
28
+ <li><a href="#description">Description</a></li>
29
+ <li><a href="#features">Features</a></li>
30
+ <li><a href="#installation">Installation</a></li>
31
+ <li><a href="#configuration">Configuration</a></li>
32
+ <li><a href="#widgets">Widgets</a></li>
33
+ <li><a href="#widget-options">Widget Options</a></li>
34
+ </ol>
35
+
36
+
37
+ <h1 id="description">Description</h1>
38
+ <strong>Version 0.1.0</strong>
39
+ <br/><br/>
40
+ Magento Connect extension page: <a href="http://www.magentocommerce.com/magento-connect/ntoklo-recommendations.html">http://www.magentocommerce.com/magento-connect/ntoklo-recommendations.html</a>
41
+ <p>Displays personalised product recommendations and trending product charts through integration with nToklo for retail platform.</p>
42
+
43
+ <h1 id="features">Features</h1>
44
+ <ul>
45
+ <li>Seamlessly Integrates with nToklo for retail recommendations API’s.</li>
46
+ <li>Uses the Open Data Alliance Universal Variable - Generats UniversalVariable JSON object and submits it to nToklo for processing to leverage user behaviour.</li>
47
+ <li>Utilises native Magento widgets to render personalised product recommendations and trending product charts through nToklo API’s.</li>
48
+ <li>Integrates with your store CMS to account for product categories.</li>
49
+ </ul>
50
+
51
+ <h1 id="installation">Installation</h1>
52
+
53
+ <p><strong>Backup your data</strong></p>
54
+ <p>Backup the database and your store's web directory.</p>
55
+
56
+ <p><strong>Disable Compilation</strong></p>
57
+ <p>This step is for Magento 1.4+ versions. If you are running an older version, this step can be skipped. In the Magento admin panel, go to System->Tools->Compilation.
58
+ In case "Compiler Status" is "Enabled", click on the "Disable" button (in case the status is disabled you can skip this step): </p>
59
+ <img src="skin/img/disablec1.png"/>
60
+
61
+ <p>This screen should now look like this:</p>
62
+ <img src="skin/img/disablec2.png"/>
63
+
64
+ <p><strong>Download and Extract</strong></p>
65
+ <p>Download and extract (unzip) the extension's contents on you computer. Navigate inside the extracted folder.</p>
66
+
67
+ <p><strong>Upload files</strong></p>
68
+ <p>Using a FTP client, upload the content of the extension directory to the store's document root, so that the app directory in
69
+ the extension folder overwrites the app directory on the server. If asked to replace any files, select "Yes".</p>
70
+
71
+ <p><strong>Clear the cache</strong></p>
72
+ <p>In the Magento admin panel, go to <b>System -> Cache Management</b> and press the "Flush Magento Cache" button:</p>
73
+ <img src="skin/img/cc.png"/>
74
+
75
+
76
+ <h1 id="configuration">Configuration</h1>
77
+ <p>You will need an nToklo account.</p>
78
+ <p>After successfully installing the extension, go to <a href="http://console.ntoklo.com/register">http://console.ntoklo.com/register</a> and register an account if you don’t already have one. From within your console, create an application using your store domain name.<br />
79
+ When entering the domain of your application, do not put the http:// or trailing path. For example, if your store url is http://mydomain.com/store. Simply enter the domain mydomain.com</p>
80
+ <p>Navigate to <b>Admin -> System -> Configuration -> nToklo</b>.
81
+ <ul>
82
+ <li><b>Enabled</b> - Turn this on to send the UniversalVariable object to nToklo and also allow widgets to display on pages.</li>
83
+ <li><b>Api Key</b> - The API key of the application you registered in your nToklo console (<a href="http://console.ntoklo.com">http://console.ntoklo.com</a>)</li>
84
+ <li><b>Api Secret</b> - This can be found along with the API Key in the nToklo console for your application. (<a href="http://console.ntoklo.com">http://console.ntoklo.com</a>)</li>
85
+ </ul>
86
+ </p>
87
+ <img src="skin/img/config.png"/>
88
+
89
+ <h1 id="widgets">Widgets</h1>
90
+ <p>Displaying the product recommendations or trending product chart requires you to configure nToklo widgets on the pages you select.<br/><br />
91
+ Navigate to <b>Admin -> CMS -> Widgets</b> and choose "Add New Widget Instance".<br /><br />
92
+ Select Type nToklo.</p>
93
+ <img src="skin/img/widgets_1.png"/>
94
+
95
+ <br />
96
+ <p>Under "Frontend Properties" choose the appropriate store and theme. Under Layout Updates define the pages/regions where you need your widgets to be placed<br /><br />
97
+ Choosing <b>Template</b> under <b>Layout Updates</b>:
98
+ <ol>
99
+ <li>nToklo Column Template - use it to place the widget under left / right column regions.</li>
100
+ <li>nToklo Grid Template - use it to place the widget wider spaces like Main Content Area.</li>
101
+ </ol>
102
+ </p>
103
+ <img src="skin/img/widgets_2.png"/>
104
+
105
+ <h1 id="widget-options">Widget Options</h1>
106
+ <p>Here you can chose what type of widget you would like and how it should behave.</p>
107
+ <img src="skin/img/widgets_4.png"/>
108
+
109
+ <br />
110
+ <p>Options:
111
+ <ul>
112
+ <li><b>Widget type</b>:
113
+ <ul>
114
+ <li>Recommendations - Select this option to present personalized product recommendations in the widget. Where the user is anonymous the best option recommendations will be served. Where available, item context like the product category is used. So recommendations on product / category pages will be scoped appropriately.</li>
115
+ <li>Trending product chart - this widget type is non-personalized as it provides a billboard type chart of products. Items in the widget are numbered numerically. Where available, item context like the product category is used. So charts on product / category pages will be scoped appropriately. You may select a daily or weekly chart.</li>
116
+ </ul>
117
+ </li>
118
+ <li><b>Header</b>: - the widget title.</li>
119
+ <li><b>Time Window</b>: - option only available for "Charts". The option specifies whether to show a daily, i.e. the trending products from yesterday, or, weekly chart, i.e. the trending products from last week. A week is taken as the last 7 days, i.e. it’s a rolling week.</li>
120
+ <li><b>Max Products</b>: - The maximum number of products to show in the widget.</li>
121
+ <li><b>Column count</b>: - this defines the number of columns to be displayed when using the "nToklo Grid Template" in the Widget Properties tab.</li>
122
+ <li><b>Cache lifetime</b>: - allows you to define the refresh interval. 86400 is the default Magento cache lifetime.</li>
123
+ </ul>
124
+ </p>
125
+ <img src="skin/img/widgets_3.png"/>
126
+ </div>
127
+
128
+ <div id="footer">
129
+ &copy; <a href="http://www.ntoklo.com/">nToklo</a>
130
+ </div>
131
+ </div>
132
+ </body>
133
+ </html>
documentation/skin/.DS_Store ADDED
Binary file
documentation/skin/img/.DS_Store ADDED
Binary file
documentation/skin/img/cc.png ADDED
Binary file
documentation/skin/img/config.png ADDED
Binary file
documentation/skin/img/disablec1.png ADDED
Binary file
documentation/skin/img/disablec2.png ADDED
Binary file
documentation/skin/img/logo.png ADDED
Binary file
documentation/skin/img/widgets_1.png ADDED
Binary file
documentation/skin/img/widgets_2.png ADDED
Binary file
documentation/skin/img/widgets_3.png ADDED
Binary file
documentation/skin/img/widgets_4.png ADDED
Binary file
documentation/skin/style.css ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ .clearer {clear:both}
2
+ body{font: 14px "museo-sans", sans-serif, Helvetica, Arial;color: #444;}
3
+ a {color: #DD3F2B;text-decoration:none;}
4
+ a:hover{text-decoration: underline;}
5
+ #footer {margin-top:20px;margin-bottom:30px;border-top: 1px solid black;}
6
+ h1 {font-size: 30px;line-height: 40px;}
7
+ #main-container {margin: 0 auto 0 auto;width:1024px;}
8
+ #header {margin-bottom:20px}
9
+ #logo {float:left;}
10
+ #address {float:right;margin-top:10px;}
11
+
js/ntoklo/util.js ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * nToklo
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Open Software License (OSL 3.0)
7
+ * that is bundled with this package in the file LICENSE.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ *
11
+ * @category Ntoklo
12
+ * @package Ntoklo_Recommendations
13
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
14
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15
+ * @author nToklo
16
+ */
17
+
18
+ // Fix prototype 1.6 conversion of JSON Array to Strings
19
+ if(window.Prototype) {
20
+ delete Array.prototype.toJSON;
21
+ //delete Object.prototype.toJSON;
22
+ //delete Hash.prototype.toJSON;
23
+ //delete String.prototype.toJSON;
24
+ }
25
+
26
+ // Ntoklo submit UV implementation
27
+ var Ntoklo = Class.create({
28
+
29
+ initialize: function(ntoklo_js_url, universal_variable) {
30
+ // initialize the UV
31
+ this.uv = universal_variable;
32
+ // initialize ntoklo.js
33
+ this.nt = {'src' : ntoklo_js_url,
34
+ 'type': 'text/javascript',
35
+ 'async': true,
36
+ 'id': 'ntoklo_js'};
37
+
38
+ // register recommended clickEvent
39
+ var ntoklo = this;
40
+ $$('.ntoklo_conversion').each(function(elem){
41
+ $(elem).observe('click', function(){
42
+ ntoklo.clickEvent('conversion');
43
+ });
44
+ });
45
+
46
+ // //register rate clickEvent
47
+ // if ($('review-form')) {
48
+ // $('review-form').observe('submit', function(event){
49
+ // if (!event.stopped) {
50
+ // event.preventDefault();
51
+ // ntoklo.clickEvent('review');
52
+ // }
53
+ // });
54
+ // }
55
+ },
56
+
57
+ typeOf: function(value) {
58
+ var s = typeof value;
59
+ if (s === 'object') {
60
+ if (value) {
61
+ if (Object.prototype.toString.call(value) == '[object Array]') {
62
+ s = 'array';
63
+ }
64
+ } else {
65
+ s = 'null';
66
+ }
67
+ }
68
+ return s;
69
+ },
70
+
71
+ mergeUv: function(destObj, srcObj) {
72
+ if (this.typeOf(srcObj) !== 'object' || this.typeOf(srcObj) === 'undefined') {
73
+ srcObj = this.uv;
74
+ }
75
+ if (this.typeOf(destObj) !== 'object' && typeof window.universal_variable === 'object') {
76
+ destObj = window.universal_variable;
77
+ }
78
+ for( var p in srcObj ) {
79
+ if( this.typeOf(destObj[p]) === 'undefined' ) {
80
+ destObj[p] = ( this.typeOf(srcObj[p]) === 'array' ) ? [] : {};
81
+ destObj[p] = ( this.typeOf(srcObj[p]) === 'object' ) ? this.mergeUv(destObj[p], srcObj[p]) : srcObj[p];
82
+ } else {
83
+ if ( this.typeOf(srcObj[p]) === 'object' ) {
84
+ this.mergeUv(destObj[p], srcObj[p]);
85
+ }
86
+ }
87
+ }
88
+ return destObj;
89
+ },
90
+
91
+ submitUv: function (callback) {
92
+ // Debug
93
+ console.log(window.universal_variable);
94
+
95
+ if ($(this.nt.id)) {
96
+ this.nt.id += '_n';
97
+ }
98
+ var nt = document.createElement('script');
99
+ nt.type = this.nt.type; nt.async = this.nt.async; nt.src = this.nt.src; nt.id = this.nt.id;
100
+ var head = document.getElementsByTagName('head')[0]; head.insertBefore(nt, head.firstChild);
101
+ nt.onload = nt.onreadystatechange = function() {
102
+ if (this.readyState == "loaded" || this.readyState == "complete") {
103
+ if (callback) {
104
+ callback();
105
+ }
106
+ }
107
+ }
108
+ },
109
+
110
+ setConversion: function() {
111
+ var pagesource = window.universal_variable.page;
112
+ document.cookie = "ntoklo_conversion=" + JSON.stringify(pagesource)+ "; path="+ Mage.Cookies.path+ "; domain = "+ Mage.Cookies.domain+ "";
113
+ },
114
+
115
+ loadEvent: function() {
116
+ window.universal_variable = this.mergeUv();
117
+ this.submitUv();
118
+ },
119
+
120
+ clickEvent: function(event_type) {
121
+ if (!event_type) {
122
+ return false;
123
+ }
124
+ window.universal_variable = this.mergeUv();
125
+ switch (event_type) {
126
+ case 'review':
127
+ window.universal_variable.events.items = new Array({'type' : _ntoklo_event_rate}, {'type' : _ntoklo_event_review});
128
+ this.submitUv(this.reviewCallback);
129
+ break;
130
+ case 'conversion':
131
+ this.setConversion();
132
+ break;
133
+ }
134
+ return true;
135
+ },
136
+
137
+ reviewCallback: function() {
138
+ $('review-form').submit();
139
+ }
140
+ });
package.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>ntoklo_recommendations</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/OSL-3.0">OSL v3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Displays personalised product recommendations and trending product charts through integration with nToklo for retail platform.</summary>
10
+ <description>Seamlessly Integrates with nToklo for retail recommendations API&#x2019;s.&#xD;
11
+ &#xD;
12
+ Uses the Open Data Alliance Universal Variable - Generats UniversalVariable JSON object and submits it to nToklo for processing to leverage user behaviour.&#xD;
13
+ &#xD;
14
+ Utilises native Magento widgets to render personalised product recommendations and trending product charts through nToklo API&#x2019;s.&#xD;
15
+ Integrates with your store CMS to account for product categories.</description>
16
+ <notes>initial release</notes>
17
+ <authors><author><name>nToklo</name><user>ntoklo</user><email>dev@ntoklo.com</email></author></authors>
18
+ <date>2013-06-11</date>
19
+ <time>12:13:20</time>
20
+ <contents><target name="magecommunity"><dir><dir name="Ntoklo"><dir name="Recommendations"><dir name="Block"><dir name="Adminhtml"><dir name="Widget"><dir name="Date"><file name="Helper.php" hash="6df6eb6926c5f06b085c980f0d640b72"/></dir><dir name="Type"><file name="Helper.php" hash="7003dba7c2b54e7dd03013de2f41a4e1"/></dir></dir></dir><file name="Chart.php" hash="e1550e586c10b78d2133fd9a9357a8bc"/><file name="UniversalVariable.php" hash="ccb989862b31cdec6bae7ed823026819"/></dir><dir name="Helper"><file name="Data.php" hash="cab1091fa7a00b5727a77e19009bbe02"/></dir><dir name="Model"><dir name="Cache"><file name="UniversalVariable.php" hash="761f465d4fda0e3d48541fc67af5c4b1"/></dir><file name="Observer.php" hash="79bd41f44e0e743ee50dfb55176d8812"/><file name="Service.php" hash="842507619406f53f312cb5ef01c37799"/><file name="UniversalVariable.php" hash="7744caef59b5c3f056f89577c108e0f5"/><dir name="Widget"><file name="Type.php" hash="f399f8084a0c9c270c92e5fccd74e50f"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="aff0945a94da77aab01ef814d14309d5"/><file name="cache.xml" hash="9be6ef2826f8e880e0c2db016787cacf"/><file name="config.xml" hash="b8a1f80d0e052d87d9bfc91a9ce43827"/><file name="system.xml" hash="6e9ca200e15d3df11f48d55d7b81947a"/><file name="widget.xml" hash="e94eaffd9ce677d742161bca542c069b"/></dir></dir></dir></dir></target><target name="magedesign"><dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="ntoklo"><dir name="recommendations"><file name="universal_variable.phtml" hash="e25a87c2244ca1c93b133e0b5db5f5f6"/><dir name="widget"><file name="chart_horisontal.phtml" hash="ccba6e9cf4b0d1edb47fa7e3468ac264"/><file name="chart_review_short.phtml" hash="25a789e2e031e33e6e82fcd8fd73aa23"/><file name="chart_vertical.phtml" hash="0f29a662e402cc0d23e7ec97cdf71aa4"/></dir></dir></dir></dir><dir name="layout"><file name="ntoklo_recommendations.xml" hash="54426563db6994151279dde06ac298c8"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir><dir name="modules"><file name="Ntoklo_Recommendations.xml" hash="d809f1cc3329034ac5d3ffcc4fe40d4c"/></dir></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="ntoklo_recommendations.csv" hash="ba56401beed41df865bd37b1df0c82aa"/></dir></dir></target><target name="mageweb"><dir><dir name="js"><dir name="ntoklo"><file name="util.js" hash="051d37aa940bb1b877435698e1827295"/></dir></dir></dir></target><target name="mage"><dir><dir><file name="LICENSE.txt" hash="dbef313ce1d00e89c7a2ab5deee450aa"/></dir><dir name="documentation"><file name="readme.html" hash="bc1c15663f3e6b152d37982ee94faea2"/><dir name="skin"><dir name="img"><file name="cc.png" hash="83f629e3f2c6e94df256a92a0d826079"/><file name="config.png" hash="a0f8540c37bbaa614a6e6818c52b9b1e"/><file name="disablec1.png" hash="3b7a509db5f2228c1187dd169c8a7c34"/><file name="disablec2.png" hash="ce25b484b08735a1890a4871eefd23ef"/><file name="logo.png" hash="5bbc2b3e56f571eb96923185485c3a27"/><file name="widgets_1.png" hash="61c6c6acc64e9bad49e2546d43032767"/><file name="widgets_2.png" hash="a357562e6cb535458c30f8a6c53bd44d"/><file name="widgets_3.png" hash="cc6ec6b496b03e516c29eb8ed63aa7a9"/><file name="widgets_4.png" hash="1feb96648e38c0e95629bf897baeb26b"/><file name=".DS_Store" hash="b9cc4725553142cb76a203801d267143"/></dir><file name="style.css" hash="47075b5c784e810c68e506b6a4fe9b7e"/><file name=".DS_Store" hash="9f9a463a038249614133f19302f63178"/></dir><file name=".DS_Store" hash="a31191cb36ae0fd176e70d14c1999652"/></dir></dir></target><target name="mageskin"><dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><dir name="ntoklo"><file name="widgets.css" hash="2437f25f0847229039184ed6e8615abe"/></dir></dir></dir></dir></dir></dir></target></contents>
21
+ <compatible/>
22
+ <dependencies><required><php><min>4.2.0</min><max>6.0.0</max></php></required></dependencies>
23
+ </package>
skin/frontend/base/default/css/ntoklo/widgets.css ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * nToklo
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Open Software License (OSL 3.0)
7
+ * that is bundled with this package in the file LICENSE.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ *
11
+ * @category Ntoklo
12
+ * @package Ntoklo_Recommendations
13
+ * @copyright Copyright (c) 2013 nToklo (http://ntoklo.com)
14
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15
+ * @author nToklo
16
+ */
17
+ div.widget-ntoklo-container .block-title, div.widget-ntoklo-container .block-title span {color: #e25203;}
18
+ div.widget-ntoklo-container ol.chart {list-style-type:decimal;}
19
+ div.widget-ntoklo-container ol.chart li {color: #e25203; font-weight: bold;}
20
+ div.widget-ntoklo-container div.ntoklo-vertical {padding: 10px 10px 17px 17px;}
21
+ div.widget-ntoklo-container div.ntoklo-vertical ol.chart li.item {margin-left: 7px; padding: 7px 0;}
22
+ div.widget-ntoklo-container div.ntoklo-horisontal ol.chart {list-style-position:inside;}
23
+ div.widget-ntoklo-container div.ntoklo-horisontal ol.chart li.first {margin-left: 7px;}
24
+ div.widget-ntoklo-container div.ntoklo-horisontal ol.chart li.item {padding: 12px 9px 90px; font-size: 13px;}
25
+ div.widget-ntoklo-container div.ntoklo-horisontal ol.chart li.item .product-image {height: auto;}
26
+