Version Notes
Version number: 1.1.0.2
Stability: Stable
Compatibility: CE 1.6.x, 1.7.x, 1.8.x, 1.9.x
Download this release
Release Info
Developer | Gravity Recommendations |
Extension | Me_Gravity |
Version | 1.1.0.2 |
Comparing to | |
See all releases |
Code changes from version 1.1.0.1 to 1.1.0.2
- app/code/community/Me/Gravity/Block/Adminhtml/System/Config/Form/Synch.php +93 -0
- app/code/community/Me/Gravity/Helper/Data.php +8 -8
- app/code/community/Me/Gravity/Model/Export/Catalog/Product.php +1 -0
- app/code/community/Me/Gravity/Model/Method/Request.php +56 -10
- app/code/community/Me/Gravity/Model/Observer.php +136 -9
- app/code/community/Me/Gravity/Model/System/Config/Source/Layout/Pages.php +8 -5
- app/code/community/Me/Gravity/etc/config.xml +25 -1
- app/code/community/Me/Gravity/etc/system.xml +17 -7
- app/design/adminhtml/default/default/template/me/gravity/system/config/form/GravityClient.php +1124 -0
- app/design/adminhtml/default/default/template/me/gravity/system/config/form/synch.phtml +111 -0
- app/design/frontend/base/default/template/me/gravity/catalogsearch/js/gravity.phtml +1 -1
- app/design/frontend/base/default/template/me/gravity/page/js/gravity.phtml +22 -0
- app/design/frontend/base/default/template/me/gravity/widget/boxes/widget.phtml +10 -0
- package.xml +4 -4
app/code/community/Me/Gravity/Block/Adminhtml/System/Config/Form/Synch.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Class Me_Gravity_Block_Adminhtml_System_Config_Form_Test
|
4 |
+
*
|
5 |
+
* @category Me
|
6 |
+
* @package Me_Gravity
|
7 |
+
* @author Attila S�gi <sagi.attila@magevolve.com>
|
8 |
+
* @copyright 2015 Magevolve Ltd. (http://magevolve.com)
|
9 |
+
* @license http://magevolve.com/terms-and-conditions Magevolve Ltd. License
|
10 |
+
* @link http://magevolve.com
|
11 |
+
*/
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class Me_Gravity_Block_Adminhtml_System_Config_Form_Test
|
15 |
+
*/
|
16 |
+
class Me_Gravity_Block_Adminhtml_System_Config_Form_Synch extends Mage_Adminhtml_Block_System_Config_Form_Field
|
17 |
+
{
|
18 |
+
/**
|
19 |
+
* Construct
|
20 |
+
*
|
21 |
+
* @return void
|
22 |
+
*/
|
23 |
+
protected function _construct()
|
24 |
+
{
|
25 |
+
parent::_construct();
|
26 |
+
$this->setTemplate('me/gravity/system/config/form/synch.phtml');
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Return element html
|
31 |
+
*
|
32 |
+
* @param Varien_Data_Form_Element_Abstract $element element
|
33 |
+
* @return string
|
34 |
+
*/
|
35 |
+
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
|
36 |
+
{
|
37 |
+
return $this->_toHtml();
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Return ajax url for button
|
42 |
+
*
|
43 |
+
* @return string
|
44 |
+
*/
|
45 |
+
public function getAjaxTestUrl()
|
46 |
+
{
|
47 |
+
return Mage::helper('adminhtml')->getUrl('adminhtml/gravity/test');
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Generate button html
|
52 |
+
*
|
53 |
+
* @return string
|
54 |
+
*/
|
55 |
+
public function getButtonHtml()
|
56 |
+
{
|
57 |
+
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
|
58 |
+
->setData(
|
59 |
+
array(
|
60 |
+
'id' => 'gravity_test_button',
|
61 |
+
'label' => $this->_getGravityHelper()->__('Test Connection'),
|
62 |
+
'onclick' => 'javascript:check(); return false;',
|
63 |
+
'disabled' => $this->_getIsButtonEnabled()
|
64 |
+
)
|
65 |
+
);
|
66 |
+
|
67 |
+
return $button->toHtml();
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Check if button enabled
|
72 |
+
*
|
73 |
+
* @return bool
|
74 |
+
*/
|
75 |
+
private function _getIsButtonEnabled()
|
76 |
+
{
|
77 |
+
if ($this->_getGravityHelper()->isFullyEnabled()) {
|
78 |
+
return false;
|
79 |
+
} else {
|
80 |
+
return true;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Get Gravity extension helper
|
86 |
+
*
|
87 |
+
* @return Me_Gravity_Helper_Data
|
88 |
+
*/
|
89 |
+
public function _getGravityHelper()
|
90 |
+
{
|
91 |
+
return Mage::helper('me_gravity');
|
92 |
+
}
|
93 |
+
}
|
app/code/community/Me/Gravity/Helper/Data.php
CHANGED
@@ -41,7 +41,7 @@ class Me_Gravity_Helper_Data extends Mage_Core_Helper_Data
|
|
41 |
*
|
42 |
* @var string
|
43 |
*/
|
44 |
-
const XML_PATH_DEBUG = 'gravity/
|
45 |
|
46 |
/**
|
47 |
* Path to store config API username
|
@@ -62,14 +62,14 @@ class Me_Gravity_Helper_Data extends Mage_Core_Helper_Data
|
|
62 |
*
|
63 |
* @var string
|
64 |
*/
|
65 |
-
const XML_PATH_CUSTOM_JS_ENABLED = 'gravity/
|
66 |
|
67 |
/**
|
68 |
* Path to store config custom Gravity JS
|
69 |
*
|
70 |
* @var string
|
71 |
*/
|
72 |
-
const XML_PATH_CUSTOM_JS = 'gravity/
|
73 |
|
74 |
/**
|
75 |
* Path to store config catalog export path
|
@@ -83,14 +83,14 @@ class Me_Gravity_Helper_Data extends Mage_Core_Helper_Data
|
|
83 |
*
|
84 |
* @var string
|
85 |
*/
|
86 |
-
const XML_PATH_USE_TEMPLATE = 'gravity/
|
87 |
|
88 |
/**
|
89 |
* Path to store config use bulk recommendation
|
90 |
*
|
91 |
* @var string
|
92 |
*/
|
93 |
-
const XML_PATH_USE_BULK = 'gravity/
|
94 |
|
95 |
/**
|
96 |
* Path to store config catalog export all
|
@@ -139,7 +139,7 @@ class Me_Gravity_Helper_Data extends Mage_Core_Helper_Data
|
|
139 |
*
|
140 |
* @var string
|
141 |
*/
|
142 |
-
const XML_PATH_EXPORT_CATALOG_ADDITIONAL = 'gravity/
|
143 |
|
144 |
/**
|
145 |
* Path to store config additional customer attributes for export
|
@@ -153,7 +153,7 @@ class Me_Gravity_Helper_Data extends Mage_Core_Helper_Data
|
|
153 |
*
|
154 |
* @var string
|
155 |
*/
|
156 |
-
const XML_PATH_EXPORT_ONLY_SALABLE = 'gravity/
|
157 |
|
158 |
/**
|
159 |
* Path to store config product status parameter for export
|
@@ -445,7 +445,7 @@ class Me_Gravity_Helper_Data extends Mage_Core_Helper_Data
|
|
445 |
*/
|
446 |
public function useGravityTemplate($store = null)
|
447 |
{
|
448 |
-
return
|
449 |
}
|
450 |
|
451 |
/**
|
41 |
*
|
42 |
* @var string
|
43 |
*/
|
44 |
+
const XML_PATH_DEBUG = 'gravity/advanced/log';
|
45 |
|
46 |
/**
|
47 |
* Path to store config API username
|
62 |
*
|
63 |
* @var string
|
64 |
*/
|
65 |
+
const XML_PATH_CUSTOM_JS_ENABLED = 'gravity/advanced/enabled_js';
|
66 |
|
67 |
/**
|
68 |
* Path to store config custom Gravity JS
|
69 |
*
|
70 |
* @var string
|
71 |
*/
|
72 |
+
const XML_PATH_CUSTOM_JS = 'gravity/advanced/custom_js';
|
73 |
|
74 |
/**
|
75 |
* Path to store config catalog export path
|
83 |
*
|
84 |
* @var string
|
85 |
*/
|
86 |
+
const XML_PATH_USE_TEMPLATE = 'gravity/advanced/template';
|
87 |
|
88 |
/**
|
89 |
* Path to store config use bulk recommendation
|
90 |
*
|
91 |
* @var string
|
92 |
*/
|
93 |
+
const XML_PATH_USE_BULK = 'gravity/advanced/bulk';
|
94 |
|
95 |
/**
|
96 |
* Path to store config catalog export all
|
139 |
*
|
140 |
* @var string
|
141 |
*/
|
142 |
+
const XML_PATH_EXPORT_CATALOG_ADDITIONAL = 'gravity/sync/additional';
|
143 |
|
144 |
/**
|
145 |
* Path to store config additional customer attributes for export
|
153 |
*
|
154 |
* @var string
|
155 |
*/
|
156 |
+
const XML_PATH_EXPORT_ONLY_SALABLE = 'gravity/sync/only_salable';
|
157 |
|
158 |
/**
|
159 |
* Path to store config product status parameter for export
|
445 |
*/
|
446 |
public function useGravityTemplate($store = null)
|
447 |
{
|
448 |
+
return 0;
|
449 |
}
|
450 |
|
451 |
/**
|
app/code/community/Me/Gravity/Model/Export/Catalog/Product.php
CHANGED
@@ -197,6 +197,7 @@ class Me_Gravity_Model_Export_Catalog_Product extends Me_Gravity_Model_Export_Ab
|
|
197 |
|
198 |
foreach ($collection as $category) {
|
199 |
$structure = preg_split('#/+#', $category->getPath());
|
|
|
200 |
$pathSize = count($structure);
|
201 |
if ($pathSize > 1) {
|
202 |
$path = array();
|
197 |
|
198 |
foreach ($collection as $category) {
|
199 |
$structure = preg_split('#/+#', $category->getPath());
|
200 |
+
|
201 |
$pathSize = count($structure);
|
202 |
if ($pathSize > 1) {
|
203 |
$path = array();
|
app/code/community/Me/Gravity/Model/Method/Request.php
CHANGED
@@ -41,6 +41,7 @@ class Me_Gravity_Model_Method_Request extends Me_Gravity_Model_Method_Abstract
|
|
41 |
* Update / add event type
|
42 |
*/
|
43 |
const EVENT_TYPE_UPDATE = 'UPDATE';
|
|
|
44 |
|
45 |
/**
|
46 |
* Event type customer update
|
@@ -160,6 +161,8 @@ class Me_Gravity_Model_Method_Request extends Me_Gravity_Model_Method_Abstract
|
|
160 |
*
|
161 |
* @return void
|
162 |
*/
|
|
|
|
|
163 |
public function _construct()
|
164 |
{
|
165 |
parent::_construct();
|
@@ -364,7 +367,23 @@ class Me_Gravity_Model_Method_Request extends Me_Gravity_Model_Method_Abstract
|
|
364 |
if ($this->_helper->getDebugMode()) {
|
365 |
$this->_helper->getLogger($params);
|
366 |
}
|
367 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
$userId = $this->_getCustomerId();
|
369 |
$cookieId = $this->_gravityCookie;
|
370 |
$recommendationContext = new GravityRecommendationContext();
|
@@ -377,10 +396,12 @@ class Me_Gravity_Model_Method_Request extends Me_Gravity_Model_Method_Abstract
|
|
377 |
}
|
378 |
|
379 |
$storeValue = new GravityNameValue('storeId', $this->_storeId);
|
380 |
-
$
|
|
|
|
|
381 |
|
382 |
if (isset($params['itemId']) && $params['itemId']) {
|
383 |
-
$pageItemId = new GravityNameValue('
|
384 |
$recommendationContext->nameValues = array_merge(array($pageItemId), $recommendationContext->nameValues);
|
385 |
}
|
386 |
|
@@ -440,7 +461,23 @@ class Me_Gravity_Model_Method_Request extends Me_Gravity_Model_Method_Abstract
|
|
440 |
if ($this->_helper->getDebugMode()) {
|
441 |
$this->_helper->getLogger($params);
|
442 |
}
|
443 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
444 |
$recommendationContextArray = array();
|
445 |
$userId = $this->_getCustomerId();
|
446 |
$cookieId = $this->_gravityCookie;
|
@@ -462,10 +499,12 @@ class Me_Gravity_Model_Method_Request extends Me_Gravity_Model_Method_Abstract
|
|
462 |
}
|
463 |
|
464 |
$storeValue = new GravityNameValue('storeId', $this->_storeId);
|
465 |
-
|
|
|
|
|
466 |
|
467 |
if (isset($param['itemId']) && $param['itemId']) {
|
468 |
-
$pageItemId = new GravityNameValue('
|
469 |
$recommendationContext->nameValues = array_merge(array($pageItemId), $recommendationContext->nameValues);
|
470 |
}
|
471 |
|
@@ -542,7 +581,7 @@ class Me_Gravity_Model_Method_Request extends Me_Gravity_Model_Method_Abstract
|
|
542 |
$item = new GravityItem();
|
543 |
$item->itemId = $params['itemid'];
|
544 |
if ($params['storeId'] == 1) {
|
545 |
-
|
546 |
}
|
547 |
$item->hidden = $params['hidden'];
|
548 |
if ($this->_canDebugLog) {
|
@@ -552,20 +591,27 @@ class Me_Gravity_Model_Method_Request extends Me_Gravity_Model_Method_Abstract
|
|
552 |
unset($params['type']);
|
553 |
unset($params['itemid']);
|
554 |
unset($params['hidden']);
|
|
|
555 |
//$item->nameValues[] = new GravityNameValue("log", "".var_export($params,true));
|
556 |
foreach ($params as $attribute => $value) {
|
557 |
if ($value) {
|
558 |
//$item->nameValues[] = new GravityNameValue($attribute, $value);
|
559 |
//foreach ($stores as $store) {
|
560 |
if ($params['storeId'] != 0) {
|
561 |
-
$
|
|
|
|
|
|
|
562 |
} else {
|
563 |
-
|
|
|
|
|
|
|
564 |
}
|
565 |
}
|
566 |
}
|
567 |
$isAsync = true;
|
568 |
-
$result = $client->
|
569 |
|
570 |
} else {
|
571 |
Mage::throwException($this->_helper->__('Invalid ' . $params['type'] . ' parameters'));
|
41 |
* Update / add event type
|
42 |
*/
|
43 |
const EVENT_TYPE_UPDATE = 'UPDATE';
|
44 |
+
|
45 |
|
46 |
/**
|
47 |
* Event type customer update
|
161 |
*
|
162 |
* @return void
|
163 |
*/
|
164 |
+
|
165 |
+
|
166 |
public function _construct()
|
167 |
{
|
168 |
parent::_construct();
|
367 |
if ($this->_helper->getDebugMode()) {
|
368 |
$this->_helper->getLogger($params);
|
369 |
}
|
370 |
+
$collection = Mage::getResourceModel('catalog/category_collection')
|
371 |
+
->setStoreId($this->_storeId)
|
372 |
+
->addNameToResult();
|
373 |
+
$layer = Mage::getSingleton('catalog/layer');
|
374 |
+
if(isset($layer)){
|
375 |
+
$_category = $layer->getCurrentCategory();
|
376 |
+
$currentCategoryId= $_category->getId();
|
377 |
+
$_cat = Mage::getModel('catalog/category')->load($currentCategoryId);
|
378 |
+
$structure = preg_split('#/+#', $_cat->getPath());
|
379 |
+
for($j=0; $j<count($structure); $j=$j+1){
|
380 |
+
$structure[$j]=$collection->getItemById($structure[$j])->getName();
|
381 |
+
}
|
382 |
+
$currentCategoryPath = implode("/", $structure);
|
383 |
+
}else{
|
384 |
+
$currentCategoryId='';
|
385 |
+
$currentCategoryPath='';
|
386 |
+
}
|
387 |
$userId = $this->_getCustomerId();
|
388 |
$cookieId = $this->_gravityCookie;
|
389 |
$recommendationContext = new GravityRecommendationContext();
|
396 |
}
|
397 |
|
398 |
$storeValue = new GravityNameValue('storeId', $this->_storeId);
|
399 |
+
$categoryId = new GravityNameValue('categoryId', $currentCategoryId);
|
400 |
+
$categoryPath = new GravityNameValue('categoryPath', $currentCategoryPath);
|
401 |
+
$recommendationContext->nameValues = array($storeValue,$categoryId,$categoryPath);
|
402 |
|
403 |
if (isset($params['itemId']) && $params['itemId']) {
|
404 |
+
$pageItemId = new GravityNameValue('itemId', $params['itemId']);
|
405 |
$recommendationContext->nameValues = array_merge(array($pageItemId), $recommendationContext->nameValues);
|
406 |
}
|
407 |
|
461 |
if ($this->_helper->getDebugMode()) {
|
462 |
$this->_helper->getLogger($params);
|
463 |
}
|
464 |
+
$collection = Mage::getResourceModel('catalog/category_collection')
|
465 |
+
->setStoreId($this->_storeId)
|
466 |
+
->addNameToResult();
|
467 |
+
$layer = Mage::getSingleton('catalog/layer');
|
468 |
+
if(isset($layer)){
|
469 |
+
$_category = $layer->getCurrentCategory();
|
470 |
+
$currentCategoryId= $_category->getId();
|
471 |
+
$_cat = Mage::getModel('catalog/category')->load($currentCategoryId);
|
472 |
+
$structure = preg_split('#/+#', $_cat->getPath());
|
473 |
+
for($j=0; $j<count($structure); $j=$j+1){
|
474 |
+
$structure[$j]=$collection->getItemById($structure[$j])->getName();
|
475 |
+
}
|
476 |
+
$currentCategoryPath = implode("/", $structure);
|
477 |
+
}else{
|
478 |
+
$currentCategoryId='';
|
479 |
+
$currentCategoryPath='';
|
480 |
+
}
|
481 |
$recommendationContextArray = array();
|
482 |
$userId = $this->_getCustomerId();
|
483 |
$cookieId = $this->_gravityCookie;
|
499 |
}
|
500 |
|
501 |
$storeValue = new GravityNameValue('storeId', $this->_storeId);
|
502 |
+
$categoryId = new GravityNameValue('categoryId', $currentCategoryId);
|
503 |
+
$categoryPath = new GravityNameValue('categoryPath', $currentCategoryPath);
|
504 |
+
$recommendationContext->nameValues = array($storeValue,$categoryId,$categoryPath);
|
505 |
|
506 |
if (isset($param['itemId']) && $param['itemId']) {
|
507 |
+
$pageItemId = new GravityNameValue('itemId', $param['itemId']);
|
508 |
$recommendationContext->nameValues = array_merge(array($pageItemId), $recommendationContext->nameValues);
|
509 |
}
|
510 |
|
581 |
$item = new GravityItem();
|
582 |
$item->itemId = $params['itemid'];
|
583 |
if ($params['storeId'] == 1) {
|
584 |
+
// $item->title = $params['title'];
|
585 |
}
|
586 |
$item->hidden = $params['hidden'];
|
587 |
if ($this->_canDebugLog) {
|
591 |
unset($params['type']);
|
592 |
unset($params['itemid']);
|
593 |
unset($params['hidden']);
|
594 |
+
|
595 |
//$item->nameValues[] = new GravityNameValue("log", "".var_export($params,true));
|
596 |
foreach ($params as $attribute => $value) {
|
597 |
if ($value) {
|
598 |
//$item->nameValues[] = new GravityNameValue($attribute, $value);
|
599 |
//foreach ($stores as $store) {
|
600 |
if ($params['storeId'] != 0) {
|
601 |
+
foreach($value as $val){
|
602 |
+
array_push($item->nameValues, new GravityNameValue($attribute, $val));
|
603 |
+
}
|
604 |
+
//$item->nameValues[] = new GravityNameValue($attribute, $value);
|
605 |
} else {
|
606 |
+
//$item->nameValues[] = new GravityNameValue($attribute, $value);
|
607 |
+
foreach($value as $val){
|
608 |
+
array_push($item->nameValues, new GravityNameValue($attribute, $val));
|
609 |
+
}
|
610 |
}
|
611 |
}
|
612 |
}
|
613 |
$isAsync = true;
|
614 |
+
$result = $client->addItem($item, $isAsync);
|
615 |
|
616 |
} else {
|
617 |
Mage::throwException($this->_helper->__('Invalid ' . $params['type'] . ' parameters'));
|
app/code/community/Me/Gravity/Model/Observer.php
CHANGED
@@ -20,6 +20,8 @@ class Me_Gravity_Model_Observer
|
|
20 |
*
|
21 |
* @var array
|
22 |
*/
|
|
|
|
|
23 |
protected $_productRecommendationTypes = array(
|
24 |
'similar' => Me_Gravity_Model_Method_Request::PRODUCT_PAGE_SIMILAR,
|
25 |
'personal' => Me_Gravity_Model_Method_Request::PRODUCT_PAGE_PERSONAL,
|
@@ -55,6 +57,7 @@ class Me_Gravity_Model_Observer
|
|
55 |
*/
|
56 |
protected $_filters = null;
|
57 |
|
|
|
58 |
/**
|
59 |
* Add Gravity block to catalog product view
|
60 |
*
|
@@ -358,13 +361,19 @@ class Me_Gravity_Model_Observer
|
|
358 |
|
359 |
$customer = $observer->getCustomer();
|
360 |
if (!is_null($customer) && $customer->getId()) {
|
361 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
362 |
$parameters = array(
|
363 |
'type' => Me_Gravity_Model_Method_Request::EVENT_TYPE_CUSTOMER_UPDATE,
|
364 |
'userid' => $customer->getId(),
|
365 |
'email' => $customer->getEmail(),
|
366 |
-
|
367 |
-
|
368 |
);
|
369 |
|
370 |
Mage::getModel('me_gravity/method_request')->sendRequest(
|
@@ -385,20 +394,63 @@ class Me_Gravity_Model_Observer
|
|
385 |
|
386 |
return $this;
|
387 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
/**
|
390 |
* Gravity product update event observer
|
391 |
*
|
392 |
* @param Varien_Event_Observer $observer observer
|
393 |
* @return $this
|
394 |
*/
|
395 |
-
|
396 |
-
|
397 |
-
|
|
|
|
|
398 |
return false;
|
399 |
}
|
400 |
-
|
401 |
-
|
402 |
$storeId = Mage::app()->getDefaultStoreView()->getId();
|
403 |
$param = Mage::app()->getRequest()->getParam('store');
|
404 |
if (isset($param) && $param) {
|
@@ -414,7 +466,7 @@ class Me_Gravity_Model_Observer
|
|
414 |
'type' => Me_Gravity_Model_Method_Request::EVENT_TYPE_PRODUCT_UPDATE,
|
415 |
'itemid' => $product->getId(),
|
416 |
'title' => htmlspecialchars($product->getName()),
|
417 |
-
'hidden' =>
|
418 |
'link' => $productUrl ? $productUrl : $product->getProductUrl(),
|
419 |
'image_link' => htmlspecialchars($this->_getCatalogBaseMediaUrl() . $product->getImage()),
|
420 |
'description' => htmlspecialchars($product->getDescription()),
|
@@ -446,6 +498,81 @@ class Me_Gravity_Model_Observer
|
|
446 |
}
|
447 |
|
448 |
return $this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
}
|
450 |
|
451 |
/**
|
20 |
*
|
21 |
* @var array
|
22 |
*/
|
23 |
+
|
24 |
+
|
25 |
protected $_productRecommendationTypes = array(
|
26 |
'similar' => Me_Gravity_Model_Method_Request::PRODUCT_PAGE_SIMILAR,
|
27 |
'personal' => Me_Gravity_Model_Method_Request::PRODUCT_PAGE_PERSONAL,
|
57 |
*/
|
58 |
protected $_filters = null;
|
59 |
|
60 |
+
|
61 |
/**
|
62 |
* Add Gravity block to catalog product view
|
63 |
*
|
361 |
|
362 |
$customer = $observer->getCustomer();
|
363 |
if (!is_null($customer) && $customer->getId()) {
|
364 |
+
if($customer->getGender()==1){
|
365 |
+
$gender = 'male';
|
366 |
+
}elseif($customer->getGender()==2){
|
367 |
+
$gender = 'female';
|
368 |
+
}else{
|
369 |
+
$gender = 'not specified';
|
370 |
+
}
|
371 |
$parameters = array(
|
372 |
'type' => Me_Gravity_Model_Method_Request::EVENT_TYPE_CUSTOMER_UPDATE,
|
373 |
'userid' => $customer->getId(),
|
374 |
'email' => $customer->getEmail(),
|
375 |
+
'name' => $customer->getName(),
|
376 |
+
'sex' => $gender
|
377 |
);
|
378 |
|
379 |
Mage::getModel('me_gravity/method_request')->sendRequest(
|
394 |
|
395 |
return $this;
|
396 |
}
|
397 |
+
|
398 |
+
|
399 |
+
public function gravityCustomerSave(arien_Event_Observer $observer){
|
400 |
+
if (!$this->_getGravityHelper()->isFullyEnabled() || !$this->_getGravityHelper()->getCustomerUpdateEnabled()) {
|
401 |
+
return false;
|
402 |
+
}
|
403 |
+
try {
|
404 |
+
|
405 |
+
$customer = $observer->getCustomer();
|
406 |
+
if (!is_null($customer) && $customer->getId()) {
|
407 |
+
|
408 |
+
$parameters = array(
|
409 |
+
'type' => Me_Gravity_Model_Method_Request::EVENT_TYPE_CUSTOMER_UPDATE
|
410 |
+
);
|
411 |
|
412 |
+
$exportModel = Mage::getModel('me_gravity/customers');
|
413 |
+
foreach ($exportModel->getExportHeaders() as $attribute) {
|
414 |
+
if ($attribute == 'userid') {
|
415 |
+
$parameters[$attribute] = $customer->getId();
|
416 |
+
} elseif ($attributeValue = $exportModel->getAttributeValueByCode($customer, $attribute)) {
|
417 |
+
$parameters[$attribute] = $attributeValue;
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
Mage::getModel('me_gravity/method_request')->sendRequest(
|
422 |
+
Me_Gravity_Model_Method_Request::EVENT_TYPE_UPDATE,
|
423 |
+
$parameters
|
424 |
+
);
|
425 |
+
|
426 |
+
}
|
427 |
+
|
428 |
+
} catch (Mage_Core_Exception $e) {
|
429 |
+
$this->_getGravityHelper()->getLogger($e->getMessage());
|
430 |
+
} catch (Exception $e) {
|
431 |
+
$this->_getGravityHelper()->getLogger(
|
432 |
+
$e->getMessage(),
|
433 |
+
$this->_getGravityHelper()->__('An error occurred while sending customer update event to Gravity.')
|
434 |
+
);
|
435 |
+
}
|
436 |
+
|
437 |
+
return $this;
|
438 |
+
}
|
439 |
/**
|
440 |
* Gravity product update event observer
|
441 |
*
|
442 |
* @param Varien_Event_Observer $observer observer
|
443 |
* @return $this
|
444 |
*/
|
445 |
+
|
446 |
+
|
447 |
+
public function gravityProductDelete(Varien_Event_Observer $observer){
|
448 |
+
|
449 |
+
if (!$this->_getGravityHelper()->isFullyEnabled() || !$this->_getGravityHelper()->getProductUpdateEnabled()) {
|
450 |
return false;
|
451 |
}
|
452 |
+
|
453 |
+
try {
|
454 |
$storeId = Mage::app()->getDefaultStoreView()->getId();
|
455 |
$param = Mage::app()->getRequest()->getParam('store');
|
456 |
if (isset($param) && $param) {
|
466 |
'type' => Me_Gravity_Model_Method_Request::EVENT_TYPE_PRODUCT_UPDATE,
|
467 |
'itemid' => $product->getId(),
|
468 |
'title' => htmlspecialchars($product->getName()),
|
469 |
+
'hidden' => true,
|
470 |
'link' => $productUrl ? $productUrl : $product->getProductUrl(),
|
471 |
'image_link' => htmlspecialchars($this->_getCatalogBaseMediaUrl() . $product->getImage()),
|
472 |
'description' => htmlspecialchars($product->getDescription()),
|
498 |
}
|
499 |
|
500 |
return $this;
|
501 |
+
|
502 |
+
}
|
503 |
+
public function gravityProductUpdate(Varien_Event_Observer $observer)
|
504 |
+
{
|
505 |
+
|
506 |
+
|
507 |
+
if (!$this->_getGravityHelper()->isFullyEnabled() || !$this->_getGravityHelper()->getProductUpdateEnabled()) {
|
508 |
+
return false;
|
509 |
+
}
|
510 |
+
|
511 |
+
try {
|
512 |
+
$storeId = Mage::app()->getDefaultStoreView()->getId();
|
513 |
+
$param = Mage::app()->getRequest()->getParam('store');
|
514 |
+
if (isset($param) && $param) {
|
515 |
+
$storeId = $param;
|
516 |
+
}
|
517 |
+
$collection = Mage::getResourceModel('catalog/category_collection')
|
518 |
+
->setStoreId($storeId)
|
519 |
+
->addNameToResult();
|
520 |
+
$prod = $observer->getProduct();
|
521 |
+
$product = Mage::getModel('catalog/product')->load($prod->getId());
|
522 |
+
$hidden = ($product->getVisibility() == Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE) ? 'true' : 'false';
|
523 |
+
if (!is_null($product) && $product->getId()) {
|
524 |
+
$cats = $product->getCategoryIds();
|
525 |
+
if(count($cats)==0){
|
526 |
+
$hidden = 'true';
|
527 |
+
}
|
528 |
+
$catPath = array();
|
529 |
+
foreach ($cats as $category_id) {
|
530 |
+
$_cat = Mage::getModel('catalog/category')->load($category_id) ;
|
531 |
+
$structure = preg_split('#/+#', $_cat->getPath());
|
532 |
+
for($j=0; $j<count($structure); $j=$j+1){
|
533 |
+
$structure[$j]=$collection->getItemById($structure[$j])->getName();
|
534 |
+
}
|
535 |
+
array_push($catPath, implode("/", $structure));
|
536 |
+
}
|
537 |
+
$baseUrl = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
|
538 |
+
$exportModel = Mage::getModel('me_gravity/products');
|
539 |
+
$productUrl = htmlspecialchars($baseUrl . $product->getUrlPath());
|
540 |
+
$parameters = array(
|
541 |
+
'type' => Me_Gravity_Model_Method_Request::EVENT_TYPE_PRODUCT_UPDATE,
|
542 |
+
'itemid' => $product->getId(),
|
543 |
+
'title' => array(htmlspecialchars($product->getName())),
|
544 |
+
'hidden' => $hidden,
|
545 |
+
'URL' => array($productUrl ? $productUrl : $product->getProductUrl()),
|
546 |
+
'Image' => array(htmlspecialchars($this->_getCatalogBaseMediaUrl() . $product->getImage())),
|
547 |
+
'Price' => array($product->getFinalPrice()),
|
548 |
+
'categoryPath' => $catPath,
|
549 |
+
'categoryId' => $cats,
|
550 |
+
'storeId' => array($storeId),
|
551 |
+
'Description'=> array($product->getDescription())
|
552 |
+
);
|
553 |
+
|
554 |
+
$additionalParameters = $exportModel->getAdditionalAttributesXml($product, false, $storeId);
|
555 |
+
if ($additionalParameters) {
|
556 |
+
$parameters = array_merge($parameters, $additionalParameters);
|
557 |
+
}
|
558 |
+
|
559 |
+
Mage::getModel('me_gravity/method_request')->sendRequest(
|
560 |
+
Me_Gravity_Model_Method_Request::EVENT_TYPE_UPDATE,
|
561 |
+
$parameters
|
562 |
+
);
|
563 |
+
|
564 |
+
}
|
565 |
+
|
566 |
+
} catch (Mage_Core_Exception $e) {
|
567 |
+
$this->_getGravityHelper()->getLogger($e->getMessage());
|
568 |
+
} catch (Exception $e) {
|
569 |
+
$this->_getGravityHelper()->getLogger(
|
570 |
+
$e->getMessage(),
|
571 |
+
$this->_getGravityHelper()->__('An error occurred while sending product update event to Gravity.')
|
572 |
+
);
|
573 |
+
}
|
574 |
+
|
575 |
+
return $this;
|
576 |
}
|
577 |
|
578 |
/**
|
app/code/community/Me/Gravity/Model/System/Config/Source/Layout/Pages.php
CHANGED
@@ -25,13 +25,16 @@ class Me_Gravity_Model_System_Config_Source_Layout_Pages
|
|
25 |
$options = array();
|
26 |
|
27 |
$_helper = $this->_getGravityHelper();
|
28 |
-
|
29 |
-
|
30 |
-
$
|
|
|
31 |
array('value' => 'customer_account_index', 'label'=> $_helper->__('Account Dashboard')),
|
32 |
-
array('value' => 'contacts_index_index', 'label'=> $_helper->__('Contact Us'))
|
|
|
|
|
|
|
33 |
);
|
34 |
-
$options = array_merge($options, $additionalOptions);
|
35 |
|
36 |
return $options;
|
37 |
}
|
25 |
$options = array();
|
26 |
|
27 |
$_helper = $this->_getGravityHelper();
|
28 |
+
// $options[] = array('label' => '', 'value' => '');
|
29 |
+
// $options = array_merge($options, Mage::getSingleton('adminhtml/system_config_source_cms_page')->toOptionArray());
|
30 |
+
$options = array(
|
31 |
+
array('value' => 'cms_index_index', 'label'=> $_helper->__('Home')),
|
32 |
array('value' => 'customer_account_index', 'label'=> $_helper->__('Account Dashboard')),
|
33 |
+
array('value' => 'contacts_index_index', 'label'=> $_helper->__('Contact Us')),
|
34 |
+
array('value' => 'cms_index_noRoute', 'label'=> $_helper->__('404 Not Found'))
|
35 |
+
|
36 |
+
|
37 |
);
|
|
|
38 |
|
39 |
return $options;
|
40 |
}
|
app/code/community/Me/Gravity/etc/config.xml
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
<config>
|
13 |
<modules>
|
14 |
<Me_Gravity>
|
15 |
-
<version>1.0.
|
16 |
</Me_Gravity>
|
17 |
</modules>
|
18 |
<global>
|
@@ -74,6 +74,14 @@
|
|
74 |
</me_gravity_update_cart_after>
|
75 |
</observers>
|
76 |
</checkout_cart_update_items_before>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
<sales_order_place_after>
|
78 |
<observers>
|
79 |
<me_gravity_order_place_after>
|
@@ -129,6 +137,14 @@
|
|
129 |
</me_gravity_customer_save_after>
|
130 |
</observers>
|
131 |
</customer_save_after>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
<catalog_product_save_after>
|
133 |
<observers>
|
134 |
<me_gravity_product_save_after>
|
@@ -137,6 +153,14 @@
|
|
137 |
</me_gravity_product_save_after>
|
138 |
</observers>
|
139 |
</catalog_product_save_after>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
</events>
|
141 |
</adminhtml>
|
142 |
<crontab>
|
12 |
<config>
|
13 |
<modules>
|
14 |
<Me_Gravity>
|
15 |
+
<version>1.1.0.0</version>
|
16 |
</Me_Gravity>
|
17 |
</modules>
|
18 |
<global>
|
74 |
</me_gravity_update_cart_after>
|
75 |
</observers>
|
76 |
</checkout_cart_update_items_before>
|
77 |
+
<customer_save_after>
|
78 |
+
<observers>
|
79 |
+
<me_gravity_customer_save>
|
80 |
+
<class>me_gravity/observer</class>
|
81 |
+
<method>gravityCustomerSave</method>
|
82 |
+
</me_gravity_customer_save>
|
83 |
+
</observers>
|
84 |
+
</customer_save_after>
|
85 |
<sales_order_place_after>
|
86 |
<observers>
|
87 |
<me_gravity_order_place_after>
|
137 |
</me_gravity_customer_save_after>
|
138 |
</observers>
|
139 |
</customer_save_after>
|
140 |
+
<catalog_product_delete_after>
|
141 |
+
<observers>
|
142 |
+
<me_gravity_product_delete_after>
|
143 |
+
<class>me_gravity/observer</class>
|
144 |
+
<method>gravityProductDelete</method>
|
145 |
+
</me_gravity_product_delete_after>
|
146 |
+
</observers>
|
147 |
+
</catalog_product_delete_after>
|
148 |
<catalog_product_save_after>
|
149 |
<observers>
|
150 |
<me_gravity_product_save_after>
|
153 |
</me_gravity_product_save_after>
|
154 |
</observers>
|
155 |
</catalog_product_save_after>
|
156 |
+
<catalog_product_save_before>
|
157 |
+
<observers>
|
158 |
+
<me_gravity_product_save_after>
|
159 |
+
<class>me_gravity/observer</class>
|
160 |
+
<method>gravityProductUpdate</method>
|
161 |
+
</me_gravity_product_save_after><!--új-->
|
162 |
+
</observers>
|
163 |
+
</catalog_product_save_before>
|
164 |
</events>
|
165 |
</adminhtml>
|
166 |
<crontab>
|
app/code/community/Me/Gravity/etc/system.xml
CHANGED
@@ -136,7 +136,7 @@
|
|
136 |
</bulk>-->
|
137 |
</fields>
|
138 |
</config>
|
139 |
-
|
140 |
<label>Export Products</label>
|
141 |
<frontend_type>text</frontend_type>
|
142 |
<sort_order>20</sort_order>
|
@@ -921,7 +921,7 @@
|
|
921 |
</top_box_columns>
|
922 |
</fields>
|
923 |
</category_display>
|
924 |
-
|
925 |
<label>Search Result Page Display</label>
|
926 |
<frontend_type>text</frontend_type>
|
927 |
<sort_order>70</sort_order>
|
@@ -995,7 +995,7 @@
|
|
995 |
</depends>
|
996 |
</search_box_columns>
|
997 |
</fields>
|
998 |
-
</search_display
|
999 |
<cart_display translate="label">
|
1000 |
<label>Cart Page Display</label>
|
1001 |
<frontend_type>text</frontend_type>
|
@@ -1078,7 +1078,7 @@
|
|
1078 |
<show_in_website>1</show_in_website>
|
1079 |
<show_in_store>1</show_in_store>
|
1080 |
<fields>
|
1081 |
-
|
1082 |
<label>Additional Attributes</label>
|
1083 |
<frontend_type>multiselect</frontend_type>
|
1084 |
<source_model>me_gravity/system_config_source_catalog_attributes</source_model>
|
@@ -1087,7 +1087,17 @@
|
|
1087 |
<show_in_website>0</show_in_website>
|
1088 |
<show_in_store>0</show_in_store>
|
1089 |
<comment>Select additional attributes for catalog export.</comment>
|
1090 |
-
</additional
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1091 |
<only_salable translate="label">
|
1092 |
<label>Only In-stock</label>
|
1093 |
<frontend_type>select</frontend_type>
|
@@ -1160,7 +1170,7 @@
|
|
1160 |
<enabled_js>1</enabled_js>
|
1161 |
</depends>
|
1162 |
</custom_js>
|
1163 |
-
|
1164 |
<label>Use Yusp Template</label>
|
1165 |
<frontend_type>select</frontend_type>
|
1166 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
@@ -1169,7 +1179,7 @@
|
|
1169 |
<show_in_website>1</show_in_website>
|
1170 |
<show_in_store>1</show_in_store>
|
1171 |
<comment>General display setting. If switched to YES, all boxes will use a Yusp template.</comment>
|
1172 |
-
</template
|
1173 |
<bulk translate="label">
|
1174 |
<label>Enable Bulk Recommendation</label>
|
1175 |
<frontend_type>select</frontend_type>
|
136 |
</bulk>-->
|
137 |
</fields>
|
138 |
</config>
|
139 |
+
<!-- <export translate="label">
|
140 |
<label>Export Products</label>
|
141 |
<frontend_type>text</frontend_type>
|
142 |
<sort_order>20</sort_order>
|
921 |
</top_box_columns>
|
922 |
</fields>
|
923 |
</category_display>
|
924 |
+
<!-- <search_display translate="label">
|
925 |
<label>Search Result Page Display</label>
|
926 |
<frontend_type>text</frontend_type>
|
927 |
<sort_order>70</sort_order>
|
995 |
</depends>
|
996 |
</search_box_columns>
|
997 |
</fields>
|
998 |
+
</search_display>-->
|
999 |
<cart_display translate="label">
|
1000 |
<label>Cart Page Display</label>
|
1001 |
<frontend_type>text</frontend_type>
|
1078 |
<show_in_website>1</show_in_website>
|
1079 |
<show_in_store>1</show_in_store>
|
1080 |
<fields>
|
1081 |
+
<!--<additional translate="label">
|
1082 |
<label>Additional Attributes</label>
|
1083 |
<frontend_type>multiselect</frontend_type>
|
1084 |
<source_model>me_gravity/system_config_source_catalog_attributes</source_model>
|
1087 |
<show_in_website>0</show_in_website>
|
1088 |
<show_in_store>0</show_in_store>
|
1089 |
<comment>Select additional attributes for catalog export.</comment>
|
1090 |
+
</additional>-->
|
1091 |
+
<resynch translate="label">
|
1092 |
+
<label>Synchronization</label>
|
1093 |
+
<frontend_type>button</frontend_type>
|
1094 |
+
<frontend_model>me_gravity/adminhtml_system_config_form_synch</frontend_model>
|
1095 |
+
<sort_order>60</sort_order>
|
1096 |
+
<show_in_default>1</show_in_default>
|
1097 |
+
<show_in_website>1</show_in_website>
|
1098 |
+
<show_in_store>1</show_in_store>
|
1099 |
+
<comment>Every user and product item will be exported or updated in your database.</comment>
|
1100 |
+
</resynch>
|
1101 |
<only_salable translate="label">
|
1102 |
<label>Only In-stock</label>
|
1103 |
<frontend_type>select</frontend_type>
|
1170 |
<enabled_js>1</enabled_js>
|
1171 |
</depends>
|
1172 |
</custom_js>
|
1173 |
+
<!-- <template translate="label">
|
1174 |
<label>Use Yusp Template</label>
|
1175 |
<frontend_type>select</frontend_type>
|
1176 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
1179 |
<show_in_website>1</show_in_website>
|
1180 |
<show_in_store>1</show_in_store>
|
1181 |
<comment>General display setting. If switched to YES, all boxes will use a Yusp template.</comment>
|
1182 |
+
</template>-->
|
1183 |
<bulk translate="label">
|
1184 |
<label>Enable Bulk Recommendation</label>
|
1185 |
<frontend_type>select</frontend_type>
|
app/design/adminhtml/default/default/template/me/gravity/system/config/form/GravityClient.php
ADDED
@@ -0,0 +1,1124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Gravity;
|
4 |
+
/**
|
5 |
+
* The GravityClient and related classes are used to connect to and communicate with the
|
6 |
+
* Gravity recommendation engine.
|
7 |
+
*
|
8 |
+
* @package GravityClient
|
9 |
+
*/
|
10 |
+
|
11 |
+
/**
|
12 |
+
* The GravityClient class can be used to send events, item and user information to
|
13 |
+
* the recommendation engine and get recommendations.
|
14 |
+
*
|
15 |
+
* Example usage:
|
16 |
+
*
|
17 |
+
* <pre>
|
18 |
+
* function createGravityClient() {
|
19 |
+
* $config = new GravityClientConfig();
|
20 |
+
* $config->remoteUrl = 'https://<CUSTOMERID>-<SERVERLOCATION>.gravityrd-services.com/grrec-<CUSTOMERID>-war/WebshopServlet';
|
21 |
+
* $config->user = 'sampleUser';
|
22 |
+
* $config->password = 'samplePasswd';
|
23 |
+
* $config->retry = 0;
|
24 |
+
* return new GravityClient($config);
|
25 |
+
* }
|
26 |
+
* $client = createGravityClient();
|
27 |
+
* $context = new GravityRecommendationContext();
|
28 |
+
* $context->numberLimit = 5;
|
29 |
+
* $context->scenarioId = 'HOMEPAGE_MAIN';
|
30 |
+
* $context->nameValues = array(
|
31 |
+
* new GravityNameValue('minPrice', '100'),
|
32 |
+
* );
|
33 |
+
* $client->getItemRecommendation('user1', '123456789abcdef', $context);
|
34 |
+
* </pre>
|
35 |
+
*
|
36 |
+
* Please do not modify the GravityClient.php file (e.g. do not write your configuration parameters into the GravityClient.php file).
|
37 |
+
* Using an unmodified client makes version updates easier.
|
38 |
+
* Use your own factory function (like createGravityClient in the example above) to pass your configuration information to the GravityClient constructor.
|
39 |
+
*
|
40 |
+
*/
|
41 |
+
|
42 |
+
class GravityClient {
|
43 |
+
|
44 |
+
/**
|
45 |
+
* The version info of the client.
|
46 |
+
*/
|
47 |
+
public $version = '1.0.13';
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Creates a new client instance with the specified configuration
|
51 |
+
* @param GravityClientConfig <var>$config</var> The configuration
|
52 |
+
*/
|
53 |
+
public function __construct(GravityClientConfig $config) {
|
54 |
+
if ($config->timeoutSeconds <= 0) {
|
55 |
+
throw new GravityException(
|
56 |
+
'Invalid configuration. Timeout must be a positive integer.',
|
57 |
+
new GravityFaultInfo(GRAVITY_ERRORCODE_CONFIG_ERROR));
|
58 |
+
}
|
59 |
+
if (!$config->remoteUrl) {
|
60 |
+
throw new GravityException(
|
61 |
+
'Invalid configuration. Remote URL must be specified.',
|
62 |
+
new GravityFaultInfo(GRAVITY_ERRORCODE_CONFIG_ERROR));
|
63 |
+
}
|
64 |
+
$this->config = $config;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Adds an event to the recommendation engine.
|
69 |
+
*
|
70 |
+
* @param GravityEvent <var>$event</var> The event to add.
|
71 |
+
* @param boolean <var>$async</var> true if the call is asynchronous. An asynchronous call
|
72 |
+
* returns immediately after an input data checking,
|
73 |
+
* a synchronous call returns only after the data is saved to database.
|
74 |
+
*/
|
75 |
+
public function addEvent(GravityEvent $event, $async) {
|
76 |
+
$this->addEvents(array($event), $async);
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Adds multiple events to the recommendation engine.
|
81 |
+
*
|
82 |
+
* @param GravityEvent[] <var>$events</var> The events to add.
|
83 |
+
* @param boolean <var>$async</var> true if the call is asynchronous. An asynchronous call
|
84 |
+
* returns immediately after an input data checking,
|
85 |
+
* a synchronous call returns only after the data is saved to database.
|
86 |
+
*/
|
87 |
+
public function addEvents(array $events, $async) {
|
88 |
+
$this->sendRequest('addEvents', array('async' => $async), $events, false);
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Adds an item to the recommendation engine.
|
93 |
+
* If the item already exists with the specified itemId,
|
94 |
+
* the entire item along with its NameValue pairs will be replaced to the new item specified here.
|
95 |
+
*
|
96 |
+
* @param GravityItem <var>$item</var> The item to add
|
97 |
+
* @param boolean <var>$async</var> true if the call is asynchronous. An asynchronous call
|
98 |
+
* returns immediately after an input data checking,
|
99 |
+
* a synchronous call returns only after the data is saved to database.
|
100 |
+
*/
|
101 |
+
public function addItem(GravityItem $item, $async) {
|
102 |
+
$this->addItems(array($item), $async);
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Adds items to the recommendation engine.
|
107 |
+
* If an item already exists with the specified itemId,
|
108 |
+
* the entire item along with its NameValue pairs will be replaced to the new item specified here.
|
109 |
+
*
|
110 |
+
* @param GravityItem[] <var>$items</var> The items to add
|
111 |
+
* @param boolean <var>$async</var> true if the call is asynchronous. An asynchronous call
|
112 |
+
* returns immediately after an input data checking,
|
113 |
+
* a synchronous call returns only after the data is saved to database.
|
114 |
+
*/
|
115 |
+
public function addItems(array $items, $async) {
|
116 |
+
$this->sendRequest('addItems', array('async' => $async), $items, false);
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Existing item will be updated. If item does not exist Exception will be thrown.
|
121 |
+
* Update rules:
|
122 |
+
* - Key-value pairs won't be deleted only existing ones updated or new ones added. But If a key occurs in the key
|
123 |
+
* value list, then all values with the given key will be deleted and new values added in the recengine.
|
124 |
+
* - Hidden field has to be always specified!
|
125 |
+
*
|
126 |
+
* @param GravityItem $item The item to update
|
127 |
+
*/
|
128 |
+
public function updateItem(GravityItem $item) {
|
129 |
+
$this->updateItems(array($item));
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Existing items will be updated. If item does not exist Exception will be thrown.
|
134 |
+
* Update rules:
|
135 |
+
* - Key-value pairs won't be deleted only existing ones updated or new ones added. But If a key occurs in the key
|
136 |
+
* value list, then all values with the given key will be deleted and new values added in the recengine.
|
137 |
+
* - Hidden field has to be always specified!
|
138 |
+
*
|
139 |
+
* @param GravityItem[] $items The items to update
|
140 |
+
*/
|
141 |
+
public function updateItems(array $items) {
|
142 |
+
$this->sendRequest('updateItems', NULL, $items, false);
|
143 |
+
}
|
144 |
+
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Adds user to the recommendation engine.
|
148 |
+
* If the user already exists with the specified userId,
|
149 |
+
* the entire user will be replaced with the new user specified here.
|
150 |
+
*
|
151 |
+
* @param GravityUser <var>$user</var> The user to add.
|
152 |
+
* @param boolean <var>$async</var> true if the call is asynchronous. An asynchronous call
|
153 |
+
* returns immediately after an input data checking,
|
154 |
+
* a synchronous call returns only after the data is saved to database.
|
155 |
+
*/
|
156 |
+
public function addUser(GravityUser $user, $async) {
|
157 |
+
$this->addUsers(array($user), $async);
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Adds users to the recommendation engine. The existing users will be updated.
|
162 |
+
* If a user already exists with the specified userId,
|
163 |
+
* the entire user will be replaced with the new user specified here.
|
164 |
+
*
|
165 |
+
* @param GravityUser[] <var>$users</var> The users to add.
|
166 |
+
* @param boolean <var>$async</var> true if the call is asynchronous. An asynchronous call
|
167 |
+
* returns immediately after an input data checking,
|
168 |
+
* a synchronous call returns only after the data is saved to database.
|
169 |
+
*/
|
170 |
+
public function addUsers(array $users, $async) {
|
171 |
+
$this->sendRequest('addUsers', array('async' => $async), $users, false);
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Returns a list of recommended items, based on the given context parameters.
|
176 |
+
*
|
177 |
+
* @param string <var>$userId</var> The identifier of the logged in user. If no user is logged in, null should be specified.
|
178 |
+
* @param string <var>$cookieId</var> It should be a permanent identifier for the end users computer, preserving its value across browser sessions.
|
179 |
+
* It should be always specified.
|
180 |
+
* @param GravityRecommendationContext <var>$context</var>
|
181 |
+
* Additional information which describes the actual scenario.
|
182 |
+
* @return GravityItemRecommendation
|
183 |
+
* An object containing the recommended items and other information about the recommendation.
|
184 |
+
*/
|
185 |
+
public function getItemRecommendation($userId, $cookieId, GravityRecommendationContext $context) {
|
186 |
+
return $this->sendRequest(
|
187 |
+
'getItemRecommendation',
|
188 |
+
array(
|
189 |
+
'userId' => $userId,
|
190 |
+
'cookieId' => $cookieId,
|
191 |
+
),
|
192 |
+
$context,
|
193 |
+
true
|
194 |
+
);
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Given the userId and the cookieId, we can request recommendations for multiple scenarios (described by the context).
|
199 |
+
* This function returns lists of recommended items for each of the given scenarios in an array.
|
200 |
+
*
|
201 |
+
* @param string <var>$userId</var> The identifier of the logged in user. If no user is logged in, null should be specified.
|
202 |
+
* @param string <var>$cookieId</var> It should be a permanent identifier for the end users computer, preserving its value across browser sessions.
|
203 |
+
* It should be always specified.
|
204 |
+
* @param GravityRecommendationContext[] <var>$context</var>
|
205 |
+
* Additional Array of information which describes the actual scenarios.
|
206 |
+
* @return GravityItemRecommendation[]
|
207 |
+
* An Array containing the recommended items for each scenario with other information about the recommendation.
|
208 |
+
*/
|
209 |
+
public function getItemRecommendationBulk($userId, $cookieId, array $context) {
|
210 |
+
foreach ($context as $element) {
|
211 |
+
$element->cookieId = $cookieId;
|
212 |
+
$element->userId = $userId;
|
213 |
+
}
|
214 |
+
return $this->sendRequest(
|
215 |
+
'getItemRecommendationBulk',
|
216 |
+
array(
|
217 |
+
'userId' => $userId,
|
218 |
+
'cookieId' => $cookieId,
|
219 |
+
),
|
220 |
+
$context,
|
221 |
+
true
|
222 |
+
);
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Simple test function to test without side effects whether the service is alive.
|
227 |
+
* @return string "Hello " + <code>$name</code>
|
228 |
+
*/
|
229 |
+
public function test($name) {
|
230 |
+
return $this->sendRequest('test', array('name' => $name), $name, true);
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Simple test function to test throwing an exception.
|
235 |
+
*/
|
236 |
+
public function testException() {
|
237 |
+
$this->sendRequest('testException', null, null, true);
|
238 |
+
}
|
239 |
+
|
240 |
+
private function getRequestQueryString($methodName, $queryStringParams) {
|
241 |
+
$queryString = $queryStringParams ? http_build_query($queryStringParams, null, '&') : '';
|
242 |
+
if ($queryString) {
|
243 |
+
$queryString = "&" . $queryString;
|
244 |
+
}
|
245 |
+
return "?method=" . urlencode($methodName) . $queryString . "&_v=" . urlencode($this->version);
|
246 |
+
}
|
247 |
+
|
248 |
+
private function sendRequestRetry($requestUrl, $requestBody, $isLast) {
|
249 |
+
$ch = curl_init();
|
250 |
+
curl_setopt($ch, CURLOPT_URL, $requestUrl);
|
251 |
+
|
252 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
253 |
+
|
254 |
+
if (is_int($this->config->timeoutSeconds)) {
|
255 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, $this->config->timeoutSeconds);
|
256 |
+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->config->timeoutSeconds);
|
257 |
+
}
|
258 |
+
else {
|
259 |
+
curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->config->timeoutSeconds*1000);
|
260 |
+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $this->config->timeoutSeconds*1000);
|
261 |
+
}
|
262 |
+
|
263 |
+
if (strpos($this->config->remoteUrl, 'https') === 0) {
|
264 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->config->verifyPeer);
|
265 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
266 |
+
}
|
267 |
+
|
268 |
+
if ($this->config->user) {
|
269 |
+
curl_setopt($ch, CURLOPT_USERPWD, $this->config->user . ':' . $this->config->password);
|
270 |
+
}
|
271 |
+
|
272 |
+
if ($requestBody) {
|
273 |
+
curl_setopt($ch, CURLOPT_POST, true);
|
274 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestBody));
|
275 |
+
}
|
276 |
+
|
277 |
+
$header = array("X-Gravity-RecEng-ClientVersion: $this->version");
|
278 |
+
if ($this->config->forwardClientInfo) {
|
279 |
+
try {
|
280 |
+
if (array_key_exists('REMOTE_ADDR', $_SERVER)) {
|
281 |
+
$header[] = "X-Forwarded-For: ".$_SERVER['REMOTE_ADDR'];
|
282 |
+
}
|
283 |
+
if (array_key_exists('HTTP_REFERER', $_SERVER)) {
|
284 |
+
$header[] = "X-Original-Referer: ".$_SERVER['HTTP_REFERER'];
|
285 |
+
}
|
286 |
+
if (array_key_exists('HTTP_USER_AGENT', $_SERVER)) {
|
287 |
+
$header[] = "X-Device-User-Agent: ".$_SERVER['HTTP_USER_AGENT'];
|
288 |
+
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
|
289 |
+
}
|
290 |
+
if (array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
|
291 |
+
$header[] = "X-Device-Accept-Language: ".$_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
292 |
+
}
|
293 |
+
$originalRequestUri = $this->guessOriginalRequestURI();
|
294 |
+
if (!empty($originalRequestUri)) {
|
295 |
+
$header[] = "X-Original-RequestUri: ".$this->guessOriginalRequestURI();
|
296 |
+
} else {
|
297 |
+
// could not detect original request URI, send SAPI name for debugging purposes
|
298 |
+
$header[] = "X-PhpServerAPIName: ".php_sapi_name();
|
299 |
+
}
|
300 |
+
} catch (Exception $e) {
|
301 |
+
// FIXME: add error to the param list ...
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
// disable Expect: 100-Continue, it would cause an unnecessary roundtrip
|
306 |
+
// see http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3
|
307 |
+
$header[] = 'Expect:';
|
308 |
+
|
309 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
310 |
+
|
311 |
+
$result = curl_exec($ch);
|
312 |
+
$err_code = curl_errno($ch);
|
313 |
+
|
314 |
+
|
315 |
+
if($isLast) {
|
316 |
+
$verbStr = '';
|
317 |
+
if($this->config->verbose) {
|
318 |
+
$hostname = "nan";
|
319 |
+
if(gethostname())
|
320 |
+
$hostname = gethostname();
|
321 |
+
|
322 |
+
$serverip = "nan";
|
323 |
+
if(array_key_exists('SERVER_ADDR', $_SERVER))
|
324 |
+
$serverip = $_SERVER['SERVER_ADDR'];
|
325 |
+
|
326 |
+
$curlinfo = curl_getinfo($ch);
|
327 |
+
$name_lookup_time = "nan";
|
328 |
+
if($curlinfo["namelookup_time"])
|
329 |
+
$name_lookup_time = $curlinfo["namelookup_time"];
|
330 |
+
|
331 |
+
$verbStr = "\nHOST: " .$hostname . "\nIP: " . $serverip . "\nlookup time: " . $name_lookup_time . "\nURL: " . $requestUrl . "\nBODY: " . print_r($requestBody, true) . "\n";
|
332 |
+
}
|
333 |
+
$rc = $this->handleError($ch, $result, $verbStr);
|
334 |
+
}
|
335 |
+
if (is_resource($ch)) {
|
336 |
+
curl_close($ch);
|
337 |
+
}
|
338 |
+
|
339 |
+
return array($err_code, $result);
|
340 |
+
}
|
341 |
+
|
342 |
+
private function sendRequest($methodName, $queryStringParams, $requestBody, $hasAnswer) {
|
343 |
+
$retry = 0;
|
344 |
+
if(isset($this->config->retry) && is_int($this->config->retry)) {
|
345 |
+
$retry = $this->config->retry;
|
346 |
+
}
|
347 |
+
if ($this->config->retryMethods) {
|
348 |
+
$retryEnabled = in_array($methodName, $this->config->retryMethods);
|
349 |
+
}
|
350 |
+
$isLast = !($retryEnabled && $retry > 0);
|
351 |
+
|
352 |
+
$requestUrl = $this->config->remoteUrl . "/" . $methodName . $this->getRequestQueryString($methodName, $queryStringParams);
|
353 |
+
$result_arr = $this->sendRequestRetry($requestUrl, $requestBody, $isLast);
|
354 |
+
$errnum = $result_arr[0];
|
355 |
+
|
356 |
+
while ($retryEnabled && $retry > 0 && $errnum != 0) {
|
357 |
+
$isLast = $retry <= 1;
|
358 |
+
|
359 |
+
$requestUrl = $requestUrl . "&_er=" . $errnum;
|
360 |
+
$result_arr = $this->sendRequestRetry($requestUrl, $requestBody, $isLast);
|
361 |
+
$errnum = $result_arr[0];
|
362 |
+
|
363 |
+
$retry--;
|
364 |
+
}
|
365 |
+
|
366 |
+
if ($hasAnswer) {
|
367 |
+
$result = $result_arr[1];
|
368 |
+
return json_decode($result, false);
|
369 |
+
} else {
|
370 |
+
return null;
|
371 |
+
}
|
372 |
+
}
|
373 |
+
|
374 |
+
private function handleError($ch, $result, $verbStr) {
|
375 |
+
$errorNumber = curl_errno($ch);
|
376 |
+
if ($errorNumber != 0) {
|
377 |
+
$errorMessage = curl_error($ch);
|
378 |
+
curl_close($ch);
|
379 |
+
switch ($errorNumber) {
|
380 |
+
case 6: //CURLE_COULDNT_RESOLVE_HOST
|
381 |
+
throw new GravityException(
|
382 |
+
"CURLE$errorNumber Could not resolve host error during curl_exec(): $errorMessage" . $verbStr,
|
383 |
+
new GravityFaultInfo(GRAVITY_ERRORCODE_COMM_HOSTRESOLVE));
|
384 |
+
case 7: //CURLE_COULDNT_CONNECT
|
385 |
+
throw new GravityException(
|
386 |
+
"CURLE$errorNumber Could not connect to host error during curl_exec(): $errorMessage" . $verbStr,
|
387 |
+
new GravityFaultInfo(GRAVITY_ERRORCODE_COMM_CONNECT));
|
388 |
+
case 28: //CURLE_OPERATION_TIMEDOUT
|
389 |
+
throw new GravityException(
|
390 |
+
"CURLE$errorNumber Timeout error during curl_exec(): $errorMessage" . $verbStr,
|
391 |
+
new GravityFaultInfo(GRAVITY_ERRORCODE_COMM_TIMEOUT));
|
392 |
+
default:
|
393 |
+
throw new GravityException(
|
394 |
+
"CURLE$errorNumber Error during curl_exec(): $errorMessage" . $verbStr,
|
395 |
+
new GravityFaultInfo(GRAVITY_ERRORCODE_COMM_OTHER));
|
396 |
+
}
|
397 |
+
} else {
|
398 |
+
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
399 |
+
if ($responseCode != 200) {
|
400 |
+
curl_close($ch);
|
401 |
+
$e = json_decode($result, false);
|
402 |
+
$supplement = "";
|
403 |
+
if (is_object($e)) {
|
404 |
+
$supplement = ", Message: $e->message" . $verbStr;
|
405 |
+
}
|
406 |
+
throw new GravityException(
|
407 |
+
"Non-200 HTTP response code: $responseCode $supplement",
|
408 |
+
new GravityFaultInfo(GRAVITY_ERRORCODE_COMM_HTTPERRORCODE));
|
409 |
+
}
|
410 |
+
return $responseCode;
|
411 |
+
}
|
412 |
+
}
|
413 |
+
|
414 |
+
private function guessOriginalRequestURI()
|
415 |
+
{
|
416 |
+
$sapi_name = php_sapi_name();
|
417 |
+
if ($sapi_name == 'cli') {
|
418 |
+
// using CLI PHP
|
419 |
+
return null;
|
420 |
+
}
|
421 |
+
$ssl = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? true:false;
|
422 |
+
$sp = strtolower($_SERVER['SERVER_PROTOCOL']);
|
423 |
+
$protocol = substr($sp, 0, strpos($sp, '/')) . (($ssl) ? 's' : '');
|
424 |
+
$port = $_SERVER['SERVER_PORT'];
|
425 |
+
$port = ((!$ssl && $port=='80') || ($ssl && $port=='443')) ? '' : ':'.$port;
|
426 |
+
$host = isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
|
427 |
+
$uri = $protocol . '://' . $host . $port . $_SERVER['REQUEST_URI'];
|
428 |
+
return $uri;
|
429 |
+
}
|
430 |
+
/**
|
431 |
+
* The client configuration.
|
432 |
+
*
|
433 |
+
* @var GravityClientConfig
|
434 |
+
*/
|
435 |
+
private $config;
|
436 |
+
}
|
437 |
+
|
438 |
+
|
439 |
+
/**
|
440 |
+
* Contains a list of recommended items. This class is here only to describe the result,
|
441 |
+
* the actual result will not be an instance of this class because of json deserialization.
|
442 |
+
*/
|
443 |
+
class GravityItemRecommendation {
|
444 |
+
function __construct() {
|
445 |
+
}
|
446 |
+
|
447 |
+
/**
|
448 |
+
*
|
449 |
+
* Array containing the recommended items.
|
450 |
+
* This is populated only if the scenario specifies to do so, otherwise this is null.
|
451 |
+
* itemIds is always populated.
|
452 |
+
* The items in this list only have the NameValues specified by the scenario.
|
453 |
+
* The list of NameValues specified by the scenario can be overridden by the
|
454 |
+
* GravityRecommendationContext resultNameValues on a per request basis.
|
455 |
+
*
|
456 |
+
* @var GravityItem[]
|
457 |
+
*/
|
458 |
+
public $items;
|
459 |
+
|
460 |
+
/**
|
461 |
+
*
|
462 |
+
* The identifiers of the recommended items. Only if not a NameValue recommendation.
|
463 |
+
*
|
464 |
+
* @var int
|
465 |
+
*/
|
466 |
+
public $itemIds;
|
467 |
+
|
468 |
+
/**
|
469 |
+
*
|
470 |
+
* The unique identifier of the recommendation generated by the recommendation engine.
|
471 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
472 |
+
*
|
473 |
+
* @var string
|
474 |
+
*/
|
475 |
+
public $recommendationId;
|
476 |
+
|
477 |
+
/**
|
478 |
+
* Array containing additional name-value pairs for recommendations.
|
479 |
+
* e.g.: AllItemCount for paging responses.
|
480 |
+
*
|
481 |
+
* @var GravityNameValue[]
|
482 |
+
*/
|
483 |
+
public $outputNameValues;
|
484 |
+
}
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Describes an event for the recommendation engine, for example a user viewed an item.
|
488 |
+
*/
|
489 |
+
class GravityEvent {
|
490 |
+
function __construct() {
|
491 |
+
$this->time = time();
|
492 |
+
$this->nameValues = array();
|
493 |
+
}
|
494 |
+
|
495 |
+
/**
|
496 |
+
*
|
497 |
+
* The event type determines the namevalues which can be passed.
|
498 |
+
* <p>Possible list event types, which can be expanded based on what can the external system support:</p>
|
499 |
+
* <table border="1">
|
500 |
+
* <tr><th><code>Event Type</code><th>Category</th></th><th>Description</th><th>NameValues for the event</th></tr>
|
501 |
+
* <tr><td><code>VIEW</code></td><td>GENERAL</td><td>The user viewed the info page of an item.</td><td></td></tr>
|
502 |
+
* <tr><td><code>BUY</code></td><td>GENERAL</td><td>The user bought an item.</td><td>
|
503 |
+
* <table>
|
504 |
+
* <tr><td><code>OrderId</code></td><td></td></tr>
|
505 |
+
* <tr><td><code>UnitPrice</code></td><td>Formatted as a decimal number, for example 1234 or 12345.67</td></tr>
|
506 |
+
* <tr><td><code>Currency</code></td><td></td></tr>
|
507 |
+
* <tr><td><code>Quantity</code></td><td>Formatted as a decimal number.</td></tr>
|
508 |
+
* </table>
|
509 |
+
* </td></tr>
|
510 |
+
* <tr><td><code>RATING</code></td><td>GENERAL</td><td>The user rated an item.</td><td>
|
511 |
+
* <table>
|
512 |
+
* <tr><td><code>Value</code></td><td>The value of the rating.</td></tr>
|
513 |
+
* </table>
|
514 |
+
* </td></tr>
|
515 |
+
* <tr><td><code>ADD_TO_CART</code></td><td>GENERAL</td><td>The user added an item to the shopping cart.</td><td>
|
516 |
+
* <table>
|
517 |
+
* <tr><td><code>Quantity</code></td><td></td></tr>
|
518 |
+
* </table>
|
519 |
+
* </td></tr>
|
520 |
+
* <tr><td><code>REMOVE_FROM_CART</code></td><td>GENERAL</td><td>The user removed an item from the shopping cart.</td><td>
|
521 |
+
* <table>
|
522 |
+
* <tr><td><code>Quantity</code></td><td></td></tr>
|
523 |
+
* </table>
|
524 |
+
* </td></tr>
|
525 |
+
* <tr><td><code>ADD_TO_FAVORITES</code></td><td>GENERAL</td><td>The user added the item to his favorites.</td><td>
|
526 |
+
* <table>
|
527 |
+
* <tr><td><code>ListId</code></td><td>Use if the webshop supports multiple favorites lists.</td></tr>
|
528 |
+
* </table>
|
529 |
+
* </td></tr>
|
530 |
+
* <tr><td><code>REMOVE_FROM_FAVORITES</code></td><td>GENERAL</td><td>The user removed an item from his favorites.</td><td>
|
531 |
+
* <table>
|
532 |
+
* <tr><td><code>ListId</code></td><td>Use if the webshop supports multiple favorites lists.</td></tr>
|
533 |
+
* </table>
|
534 |
+
* </td></tr>
|
535 |
+
* <tr><td><code>REC_CLICK</code></td><td>GENERAL</td><td>The user clicked on a recommended item.</td><td>
|
536 |
+
* <table>
|
537 |
+
* <tr><td><code>Position</code></td><td>The position of the clicked item in the recommendation list. The position of the first item is 1.</td></tr>
|
538 |
+
* </table>
|
539 |
+
* </td></tr>
|
540 |
+
* <tr><td><code>LOGIN</code></td><td>GENERAL</td><td>The user logged in to the site. For this event the cookieId and also the userId must be specified.</td><td></td></tr>
|
541 |
+
* <tr><td><code>ADD_TO_WISHLIST</code></td><td>ADDITIONAL</td><td>The user added the item to his wishlist.</td><td>
|
542 |
+
* <table>
|
543 |
+
* <tr><td><code>ListId</code></td><td>Use if the webshop supports multiple wishlists.</td></tr>
|
544 |
+
* </table>
|
545 |
+
* </td></tr>
|
546 |
+
* <tr><td><code>REMOVE_FROM_WISHLIST</code></td><td>ADDITIONAL</td><td>The user removed an item from his wishlist.</td><td>
|
547 |
+
* <table>
|
548 |
+
* <tr><td><code>ListId</code></td><td>Use if the webshop supports multiple wishlists.</td></tr>
|
549 |
+
* </table>
|
550 |
+
* </td></tr>
|
551 |
+
* <tr><td><code>HIDE_PRODUCT</code></td><td>ADDITIONAL</td><td>The user hides a product that should not be recommended to him.</td><td></td></tr>
|
552 |
+
* <tr><td><code>UNHIDE_PRODUCT</code></td><td>ADDITIONAL</td><td>The user unhides a product that he marked as hidden previously.</td><td></td></tr>
|
553 |
+
* <tr><td><code>PRODUCT_SEARCH</code></td><td>ADDITIONAL</td><td>A list of products was displayed to the user, for example by browsing a category or by free text search.</td><td>
|
554 |
+
* <table>
|
555 |
+
* <tr><td><code>SearchString</code></td><td>The search string, if the list is based on a free text search.</td></tr>
|
556 |
+
* <tr><td><code>Filter.*</code></td><td>If the listing is based on comparing an item namevalue to a filter value, you can provide the actual filter here.
|
557 |
+
* For example, if the user was browsing a specific category, name='Filter.CategoryId' and value='CategoryA' can be specified.</td></tr>
|
558 |
+
* </table>
|
559 |
+
* </td></tr>
|
560 |
+
* <tr><td><code>NEXT_RECOMMENDATION</code></td><td>ADDITIONAL</td><td>The user asked for more recommendation.</td><td></td></tr>
|
561 |
+
* <tr><td><code>COMMENT</code></td><td>ADDITIONAL</td><td>The user wrote a comment for the item.</td><td></td></tr>
|
562 |
+
* <tr><td><code>NOT_INTERESTED</code></td><td>ADDITIONAL</td><td>The user would not like this item and similar items to be recommended to him, but he also does not want to give a negative rating for this item.</td><td></td></tr>
|
563 |
+
* <tr><td><code>LETTER_READ</code></td><td>ADDITIONAL</td><td>T The user read a letter which sent for him by the system (eg. a newsletter).</td><td></td></tr>
|
564 |
+
* <tr><td><code>CLICK_OUT</code></td><td>PRICE COMPARISON</td><td>The user jumps to an external webshop to buy the product. Used by price comparison sites.</td><td></td></tr>
|
565 |
+
* <tr><td><code>LANCE</code></td><td>AUCTION</td><td>The user place a bid on the item.</td><td><code>Value</code>The value of the bid as a decimal number.</td></tr>
|
566 |
+
* <tr><td><code>LETTER_SEND</code></td><td>AUCTION, ADVERTISING</td><td>The user sent a message to the advertiser.</td><td></td></tr>
|
567 |
+
* <tr><td><code>ADD_ITEM</code></td><td>AUCTION, ADVERTISING</td><td>The user added an item to the site.</td><td></td></tr>
|
568 |
+
* <tr><td><code>FREE_VIEW</code></td><td>MEDIA</td><td>The user wached/listened an item for free.</td><td><code>Duration</code>How long the user wached the item in seconds as a decimal number.</td></tr>
|
569 |
+
* <tr><td><code>PAID_VIEW</code></td><td>MEDIA</td><td>The user payed for waching/listening an item.</td><td>
|
570 |
+
* <table>
|
571 |
+
* <tr><td><code>Duration</code></td><td>How long the user wached the item in seconds. A decimal number.</td></tr>
|
572 |
+
* <tr><td><code>Value</code></td><td>How much the user payed for waching the item. A decimal number.</td></tr>
|
573 |
+
* </table>
|
574 |
+
* </td></tr>
|
575 |
+
* <tr><td><code>SUBSCRIPTION_VIEW</code></td><td>MEDIA</td><td>The user watched an item that was available for him by a subscription.</td><td>
|
576 |
+
* <table>
|
577 |
+
* <tr><td><code>Duration</code></td><td>How long the user wached the item in seconds. A decimal number.</td></tr>
|
578 |
+
* </table>
|
579 |
+
* </td></tr>
|
580 |
+
* <tr><td><code>FOLLOW_USER</code></td><td>SOCIAL</td><td>The user follows an other user.</td><td><code>OtherUserId</code>The identifier of the followed user.</td></tr>
|
581 |
+
* <tr><td><code>SHARE</code></td><td>SOCIAL</td><td>The user share the item on a social site (eg. Facebook, Twitter,...).</td><td></td></tr>
|
582 |
+
* <tr><td><code>REDEEM</code></td><td>COUPON</td><td>The user redeem the item (eg. a coupon).</td><td></td></tr>
|
583 |
+
* </table>
|
584 |
+
*
|
585 |
+
* @var string
|
586 |
+
*/
|
587 |
+
public $eventType;
|
588 |
+
|
589 |
+
/**
|
590 |
+
*
|
591 |
+
* This is the identifier of the item which was viewed/bought/etc. by the user.
|
592 |
+
* Set to null if it does no make sense, for example in case of a login event.
|
593 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
594 |
+
*
|
595 |
+
* @var string
|
596 |
+
*/
|
597 |
+
public $itemId;
|
598 |
+
|
599 |
+
/**
|
600 |
+
*
|
601 |
+
* It should be an id of a previous recommendation, if this event is a consequence of a recommendation.
|
602 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
603 |
+
*
|
604 |
+
* @var string
|
605 |
+
*/
|
606 |
+
public $recommendationId;
|
607 |
+
|
608 |
+
/**
|
609 |
+
*
|
610 |
+
* The UNIX timestamp of the event, as returned by the standard time() PHP function.
|
611 |
+
*
|
612 |
+
* @var int
|
613 |
+
*/
|
614 |
+
public $time;
|
615 |
+
|
616 |
+
/**
|
617 |
+
*
|
618 |
+
* This is the identifier of the user who generated the event.
|
619 |
+
* If unknown set to null (for example if the user is not logged in yet).
|
620 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
621 |
+
*
|
622 |
+
* @var string
|
623 |
+
*/
|
624 |
+
public $userId;
|
625 |
+
|
626 |
+
/**
|
627 |
+
*
|
628 |
+
* A cookieId should be a permanent identifier for the end users computer, preserving its value across browser sessions.
|
629 |
+
* This way not logged in users can be recognized, if they have logged in previously from the same computer.
|
630 |
+
* The cookieId should be always specified.
|
631 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
632 |
+
*
|
633 |
+
* @var string
|
634 |
+
*/
|
635 |
+
public $cookieId;
|
636 |
+
|
637 |
+
/**
|
638 |
+
*
|
639 |
+
* The NameValues for the event. The possible list of namevalues depends on the event type.
|
640 |
+
* NameValues provide additional description of the event.
|
641 |
+
* There can multiple NameValues with the same name.
|
642 |
+
* The order of NameValues will not be preserved, but the order of the values for the same name will be preserved.
|
643 |
+
*
|
644 |
+
* @var GravityNameValue[]
|
645 |
+
*/
|
646 |
+
public $nameValues;
|
647 |
+
}
|
648 |
+
|
649 |
+
/**
|
650 |
+
* A user in the recommendation system. A user is an entity which generates event, and can get recommendations.
|
651 |
+
*/
|
652 |
+
class GravityUser {
|
653 |
+
function __construct() {
|
654 |
+
$this->nameValues = array();
|
655 |
+
}
|
656 |
+
|
657 |
+
/**
|
658 |
+
*
|
659 |
+
* This is a unqiue identifier for a registered user.
|
660 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
661 |
+
*
|
662 |
+
* @var string
|
663 |
+
*/
|
664 |
+
public $userId;
|
665 |
+
|
666 |
+
/**
|
667 |
+
*
|
668 |
+
* NameValues provide additional description of the user.
|
669 |
+
* There can multiple NameValues with the same name.
|
670 |
+
* The order of NameValues will not be preserved.
|
671 |
+
*
|
672 |
+
* The recommendation engine in most cases does not require detailed information about the users, usually only some basic information can be used to enhance the quality of recommendation.
|
673 |
+
* For example:
|
674 |
+
* <table border="1">
|
675 |
+
* <tr><th>Name</th><th>Description</th></tr>
|
676 |
+
* <tr><td>ZipCode</td><td>The zip code of the user.</td></tr>
|
677 |
+
* <tr><td>City</td><td>The city of the user.</td></tr>
|
678 |
+
* <tr><td>Country</td><td>The country of the user.</td></tr>
|
679 |
+
* </table>
|
680 |
+
*
|
681 |
+
* @var GravityNameValue[]
|
682 |
+
*/
|
683 |
+
public $nameValues;
|
684 |
+
|
685 |
+
/**
|
686 |
+
*
|
687 |
+
* True if the user is hidden. A no more existing user should be set to hidden.
|
688 |
+
*
|
689 |
+
* @var boolean
|
690 |
+
*/
|
691 |
+
public $hidden;
|
692 |
+
}
|
693 |
+
|
694 |
+
/**
|
695 |
+
* An item is something that can be recommended to users.
|
696 |
+
*/
|
697 |
+
class GravityItem {
|
698 |
+
function __construct() {
|
699 |
+
$this->fromDate = 0;
|
700 |
+
$this->toDate = 2147483647;
|
701 |
+
$this->nameValues = array();
|
702 |
+
}
|
703 |
+
|
704 |
+
/**
|
705 |
+
*
|
706 |
+
* The itemId is a unique identifier of the item.
|
707 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
708 |
+
*
|
709 |
+
* @var string
|
710 |
+
*/
|
711 |
+
public $itemId;
|
712 |
+
|
713 |
+
/**
|
714 |
+
* The item title. This is a short, human-readable name of the item.
|
715 |
+
* If the title is available in multiple languages, try to use your system's primary language, for example English.
|
716 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
717 |
+
*
|
718 |
+
* @var string
|
719 |
+
*/
|
720 |
+
public $title;
|
721 |
+
|
722 |
+
/**
|
723 |
+
*
|
724 |
+
* The type of the item. It can be used to create different item families.
|
725 |
+
* The purpose of itemtype is to differentiate items which will have different namevalue properties.
|
726 |
+
* Examples:
|
727 |
+
* <ul>
|
728 |
+
* <li>Book</li>
|
729 |
+
* <li>Ticket</li>
|
730 |
+
* <li>Computer</li>
|
731 |
+
* <li>Food</li>
|
732 |
+
* </ul>
|
733 |
+
*
|
734 |
+
* @var string
|
735 |
+
*/
|
736 |
+
public $itemType;
|
737 |
+
|
738 |
+
/**
|
739 |
+
* The value of hidden. A hidden item will be never recommended.
|
740 |
+
*
|
741 |
+
* @var boolean
|
742 |
+
*/
|
743 |
+
public $hidden;
|
744 |
+
|
745 |
+
/**
|
746 |
+
*
|
747 |
+
* An item is never recommended before this date.
|
748 |
+
* The date in unixtime format, the number of seconds elapsed since 1970.01.01 00:00:00 UTC, as returned by the standard time() PHP function.
|
749 |
+
* Set it to 0 if not important.
|
750 |
+
*
|
751 |
+
* @var int
|
752 |
+
*/
|
753 |
+
public $fromDate;
|
754 |
+
|
755 |
+
/**
|
756 |
+
*
|
757 |
+
* An item is never recommended after this date.
|
758 |
+
* The date in unixtime format, the number of seconds elapsed since 1970.01.01 00:00:00 UTC, as returned by the standard time() PHP function.
|
759 |
+
* Set it to a big number (eg. 2147483647) if not important.
|
760 |
+
*
|
761 |
+
* @var int
|
762 |
+
*/
|
763 |
+
public $toDate;
|
764 |
+
|
765 |
+
|
766 |
+
/**
|
767 |
+
*
|
768 |
+
* The NameValues for the item.
|
769 |
+
* <p>NameValues provide additional description of the item.</p>
|
770 |
+
* <p>There can multiple NameValues with the same name.</p>
|
771 |
+
* <p>The order of NameValues among different names will not be preserved, but the order of the values for the same name will be preserved.</p>
|
772 |
+
* <p>The recommendation engine can be configured to use some properties to create a relation between items.</p>
|
773 |
+
* <p>A possible list of names:</p>
|
774 |
+
* <table border="1">
|
775 |
+
* <tr><th>Name</th><th>Localizable</th><th>Description</th></tr>
|
776 |
+
* <tr><td>Title</td><td>Yes</td><td>The title of the item.</td></tr>
|
777 |
+
* <tr><td>Description</td><td>Yes</td><td>The description of item.</td></tr>
|
778 |
+
* <tr><td>CategoryPath</td><td>No</td><td>The full path of the item's category.
|
779 |
+
* For example, CategoryPath might be "books/computers/databases" for a book about databases.
|
780 |
+
* CategoryPath can be repeated if an item belongs to multiple categories. Use "/" only for separating levels.
|
781 |
+
* Later it is possible to use the recommendation engine to filter the list of items based on category, so it can provide recommendations for "Computer Books" category or only for "Computer Books > Database" category.
|
782 |
+
* </td></tr>
|
783 |
+
* <tr><td>Tags</td><td>No</td><td>Tags for the item. Specify a separate namevalue for each tag.</td></tr>
|
784 |
+
* <tr><td>State</td><td>No</td><td>The state of the item, for example 'available', 'out of stock' etc.</td></tr>
|
785 |
+
* <tr><td>Price</td><td>No</td><td>The price of the item.</td></tr>
|
786 |
+
* </table>
|
787 |
+
*
|
788 |
+
* The recommendation engine can accept arbitrary namevalues, the list above is just an example of basic properties that are used almost everywhere.
|
789 |
+
* The NameValues which are relevant to business rules and possible content based filtering should be provided to the recommendation engine.
|
790 |
+
*
|
791 |
+
* <p>You can use localization by appending a language identifier to the Name of the NameValue. For example, Title_EN, Title_HU.
|
792 |
+
* It is possible to use both non-localized and localized version.
|
793 |
+
* </p>
|
794 |
+
*
|
795 |
+
* @var GravityNameValue[]
|
796 |
+
*/
|
797 |
+
public $nameValues;
|
798 |
+
|
799 |
+
}
|
800 |
+
|
801 |
+
/**
|
802 |
+
* Contains information for a recommendation request.
|
803 |
+
*/
|
804 |
+
class GravityRecommendationContext {
|
805 |
+
function __construct() {
|
806 |
+
$this->recommendationTime = time();
|
807 |
+
}
|
808 |
+
|
809 |
+
/**
|
810 |
+
*
|
811 |
+
* The time of the recommendation (seconds in unixtime format), the time when it will be shown to the end user.
|
812 |
+
* Use a value as returned by the standard time() PHP function.
|
813 |
+
*
|
814 |
+
* @var int
|
815 |
+
*/
|
816 |
+
public $recommendationTime;
|
817 |
+
|
818 |
+
/**
|
819 |
+
*
|
820 |
+
* The value of the maximum number of items in the result.
|
821 |
+
* The maximum number of the items in the result can be also limited by the configuration of the scenario.
|
822 |
+
* If set to 0, this number of items is determined by the scenario.
|
823 |
+
*
|
824 |
+
* @var int
|
825 |
+
*/
|
826 |
+
public $numberLimit;
|
827 |
+
|
828 |
+
/**
|
829 |
+
*
|
830 |
+
* The value of scenarioId. Scenarios are defined by the scenario management API.
|
831 |
+
* A scenario describes a way how recommended items will be filtered, ordered.
|
832 |
+
*
|
833 |
+
* @var string
|
834 |
+
*/
|
835 |
+
public $scenarioId;
|
836 |
+
|
837 |
+
/**
|
838 |
+
*
|
839 |
+
* The NameValues for the context.
|
840 |
+
* NameValues can describe the parameters for the actual scenario, like current item id, filtering by category etc.
|
841 |
+
* Item-to-item recommendation is possible by a specific scenario which parses a NameValue describing the current item,
|
842 |
+
* or multiple NameValues if there are multiple actual items.
|
843 |
+
* The list of allowed names depends on the actual scenario.
|
844 |
+
* <p>The scenario can also specify that the result is not a list of items, but a list of values of item NameValues.</p>
|
845 |
+
|
846 |
+
* <table border="1">
|
847 |
+
* <tr><th>Name</th><th>Description</th></tr>
|
848 |
+
* <tr><td>CurrentItemId</td><td>The identifier of the actual item, if the current page is an item page.</td></tr>
|
849 |
+
* <tr><td>ItemOnPage</td><td>Identifier of item displayed elsewhere on the page. They will be excluded from recommendation. This namevalue can be used multiple times to provide a list of items.</td></tr>
|
850 |
+
* <tr><td>CartItemId</td><td>Identifier of item in the current shopping cart. This can provide additional information to improve the quality of recommendation. This namevalue must be used as many times as many items the shopping cart contains.</td></tr>
|
851 |
+
* <tr><td>CartItemQuantity</td><td>The quantity of items in the current shopping cart, in the same order as CartItemId namevalues.</td></tr>
|
852 |
+
* <tr><td>Filter.*</td><td>If specified, only items having the specified name and value as metadata will be in the result.
|
853 |
+
* For example, the namevalue with name='Filter'.'CategoryId' and value='A' means that only items belonging to category 'A' will be in the result.</td></tr>
|
854 |
+
*
|
855 |
+
* </table>
|
856 |
+
*
|
857 |
+
* @var GravityNameValue[]
|
858 |
+
*/
|
859 |
+
public $nameValues;
|
860 |
+
|
861 |
+
/**
|
862 |
+
* If not null, specifies which NameValues of the recommended items should be included in the result.
|
863 |
+
* If null, the returned NameValues are determined by the actual scenario.
|
864 |
+
*
|
865 |
+
* @var GravityNameValue[]
|
866 |
+
*/
|
867 |
+
public $resultNameValues;
|
868 |
+
|
869 |
+
}
|
870 |
+
|
871 |
+
|
872 |
+
/**
|
873 |
+
* A name and a value. This can be used to provide information about items, users and events.
|
874 |
+
*/
|
875 |
+
class GravityNameValue {
|
876 |
+
/**
|
877 |
+
*
|
878 |
+
* The name.
|
879 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
880 |
+
*
|
881 |
+
* @var string
|
882 |
+
*/
|
883 |
+
public $name;
|
884 |
+
|
885 |
+
/**
|
886 |
+
*
|
887 |
+
* The value.
|
888 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
889 |
+
*
|
890 |
+
* @var string
|
891 |
+
*/
|
892 |
+
public $value;
|
893 |
+
|
894 |
+
/**
|
895 |
+
* Creates a new instance of a namevalue pair.
|
896 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
897 |
+
*
|
898 |
+
* @param string <var>$name</var> The name.
|
899 |
+
* @param string <var>$value</var> The value.
|
900 |
+
*/
|
901 |
+
public function __construct($name, $value) {
|
902 |
+
$this->name = $name;
|
903 |
+
$this->value = $value;
|
904 |
+
}
|
905 |
+
}
|
906 |
+
|
907 |
+
|
908 |
+
|
909 |
+
class GravityClientConfig {
|
910 |
+
function __construct() {
|
911 |
+
$this->timeoutSeconds = 2;
|
912 |
+
$this->verifyPeer = true;
|
913 |
+
$this->retryMethods = array("addUsers", "addItems", "addEvents", "getItemRecommendation");
|
914 |
+
$this->retry = 0;
|
915 |
+
$this->verbose = true;
|
916 |
+
$this->forwardClientInfo = true;
|
917 |
+
}
|
918 |
+
|
919 |
+
/**
|
920 |
+
* Forwards the user-agent, referrer, browser language and client IP to the recommendation engine.
|
921 |
+
* Default value is true;
|
922 |
+
*
|
923 |
+
* @var boolean
|
924 |
+
*/
|
925 |
+
public $forwardClientInfo;
|
926 |
+
|
927 |
+
/**
|
928 |
+
* The URL of the server side interface. It has no default value, must be specified.
|
929 |
+
* Strings in the PHP client are always UTF-8 encoded.
|
930 |
+
*
|
931 |
+
* @var string
|
932 |
+
*/
|
933 |
+
public $remoteUrl;
|
934 |
+
|
935 |
+
/**
|
936 |
+
* The timeout for the operations in seconds. The default value is 3 seconds.
|
937 |
+
* Double values are supported after PHP version 5.2.3 (uses miliseconds timeout)
|
938 |
+
* @var int
|
939 |
+
*/
|
940 |
+
public $timeoutSeconds;
|
941 |
+
|
942 |
+
/**
|
943 |
+
* The setting of cURL option <code>CURLOPT_SSL_VERIFYPEER</code> in case of https connection.
|
944 |
+
* Set it to <code>false</code> if your server could not accept our certificate.
|
945 |
+
* The default value is true.
|
946 |
+
* Leave it blank in case of http connection.
|
947 |
+
*
|
948 |
+
* @var boolean
|
949 |
+
*/
|
950 |
+
public $verifyPeer;
|
951 |
+
|
952 |
+
/**
|
953 |
+
*
|
954 |
+
* The user name for the http authenticated connection. Leave it blank in case of
|
955 |
+
* connection without authentication.
|
956 |
+
*
|
957 |
+
* @var string
|
958 |
+
*/
|
959 |
+
public $user;
|
960 |
+
|
961 |
+
/**
|
962 |
+
* The password for the http authenticated connection. Leave it blank in case of
|
963 |
+
* connection without authentication.
|
964 |
+
*
|
965 |
+
* @var string
|
966 |
+
*/
|
967 |
+
public $password;
|
968 |
+
|
969 |
+
/**
|
970 |
+
* The list of method names which should be retried after communication error.
|
971 |
+
*
|
972 |
+
* @var array(string)
|
973 |
+
*/
|
974 |
+
public $retryMethods;
|
975 |
+
|
976 |
+
/**
|
977 |
+
* More verbose error messages in case of error.
|
978 |
+
*
|
979 |
+
* @var boolean
|
980 |
+
*/
|
981 |
+
public $verbose;
|
982 |
+
|
983 |
+
/**
|
984 |
+
* If > 1 enables retry for the methods specified in $retryMethods.
|
985 |
+
*
|
986 |
+
* @var int
|
987 |
+
*/
|
988 |
+
public $retry;
|
989 |
+
}
|
990 |
+
|
991 |
+
/**
|
992 |
+
* The client was initilized with invalid configuration.
|
993 |
+
* You should never use the value of the constant, always use it be referencing its name.
|
994 |
+
*/
|
995 |
+
define('GRAVITY_ERRORCODE_CONFIG_ERROR', -1);
|
996 |
+
|
997 |
+
/**
|
998 |
+
* Unknown error during communication.
|
999 |
+
* You should never use the value of the constant, always use it be referencing its name.
|
1000 |
+
*/
|
1001 |
+
define('GRAVITY_ERRORCODE_COMM_OTHER', -2);
|
1002 |
+
|
1003 |
+
/**
|
1004 |
+
* Could not resolve the remote host name.
|
1005 |
+
* You should never use the value of the constant, always use it be referencing its name.
|
1006 |
+
*/
|
1007 |
+
define('GRAVITY_ERRORCODE_COMM_HOSTRESOLVE', -3);
|
1008 |
+
|
1009 |
+
/**
|
1010 |
+
* Timeout during communication.
|
1011 |
+
* You should never use the value of the constant, always use it be referencing its name.
|
1012 |
+
*/
|
1013 |
+
define('GRAVITY_ERRORCODE_COMM_TIMEOUT', -4);
|
1014 |
+
|
1015 |
+
/**
|
1016 |
+
* Could not connect to remote host.
|
1017 |
+
* You should never use the value of the constant, always use it be referencing its name.
|
1018 |
+
*/
|
1019 |
+
define('GRAVITY_ERRORCODE_COMM_CONNECT', -5);
|
1020 |
+
|
1021 |
+
/**
|
1022 |
+
* A non-200 HTTP response code was received.
|
1023 |
+
* You should never use the value of the constant, always use it be referencing its name.
|
1024 |
+
*/
|
1025 |
+
define('GRAVITY_ERRORCODE_COMM_HTTPERRORCODE', -6);
|
1026 |
+
|
1027 |
+
/**
|
1028 |
+
* The exception class used by the recommendation engine client in case of an error.
|
1029 |
+
*/
|
1030 |
+
class GravityException extends \Exception {
|
1031 |
+
/**
|
1032 |
+
* Creates a new instance of GravityException.
|
1033 |
+
*
|
1034 |
+
* @param string <var>$message</var> The error message.
|
1035 |
+
* @param GravityFaultInfo <var>$faultInfo</var> Contains information about the error.
|
1036 |
+
*
|
1037 |
+
*/
|
1038 |
+
public function __construct($message, $faultInfo) {
|
1039 |
+
parent::__construct($message, $faultInfo->errorCode);
|
1040 |
+
$this->faultInfo = $faultInfo;
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
/**
|
1044 |
+
* The object describing the error.
|
1045 |
+
*
|
1046 |
+
* @var GravityFaultInfo
|
1047 |
+
*/
|
1048 |
+
public $faultInfo;
|
1049 |
+
}
|
1050 |
+
|
1051 |
+
/**
|
1052 |
+
* Describes the error occured during a request.
|
1053 |
+
*/
|
1054 |
+
class GravityFaultInfo {
|
1055 |
+
function __construct($errorCode) {
|
1056 |
+
$this->errorCode = $errorCode;
|
1057 |
+
}
|
1058 |
+
|
1059 |
+
public $errorCode;
|
1060 |
+
}
|
1061 |
+
|
1062 |
+
/**
|
1063 |
+
* This class used to deserialize exceptions coming from the recommendation engine.
|
1064 |
+
*/
|
1065 |
+
class GravityRecEngException {
|
1066 |
+
|
1067 |
+
public $message;
|
1068 |
+
|
1069 |
+
/**
|
1070 |
+
*
|
1071 |
+
* Currently defined error codes:
|
1072 |
+
* <ul>
|
1073 |
+
* <li>ERR_ITEMS_IS_NULL</li>
|
1074 |
+
* <li>ERR_ITEMS_HAS_NULL_ELEMENT</li>
|
1075 |
+
* <li>ERR_ITEMID_IS_NULL_OR_EMPTY</li>
|
1076 |
+
* <li>ERR_USERS_IS_NULL</li>
|
1077 |
+
* <li>ERR_USERS_HAS_NULL_ELEMENT</li>
|
1078 |
+
* <li>ERR_USERID_IS_NULL_OR_EMPTY</li>
|
1079 |
+
* <li>ERR_RATINGS_IS_NULL</li>
|
1080 |
+
* <li>ERR_RATINGS_HAS_NULL_ELEMENT</li>
|
1081 |
+
* <li>ERR_RECOMMENDATIONID_IS_NULL_OR_EMPTY</li>
|
1082 |
+
* <li>ERR_ITEM_NOT_FOUND</li>
|
1083 |
+
* <li>ERR_USER_NOT_FOUND</li>
|
1084 |
+
* <li>ERR_EVENTS_IS_NULL</li>
|
1085 |
+
* <li>ERR_EVENTS_HAS_NULL_ELEMENT</li>
|
1086 |
+
* <li>ERR_INVALID_EVENT_TYPE</li>
|
1087 |
+
* <li>ERR_PARAM_IS_NULL</li>
|
1088 |
+
* <li>ERR_NAMEVALUE_IS_NULL</li>
|
1089 |
+
* <li>ERR_NAME_IN_NAMEVALUE_IS_NULL_OR_EMPTY</li>
|
1090 |
+
* <li>ERR_VALUE_IN_NAMEVALUE_IS_NULL</li>
|
1091 |
+
* <li>ERR_NAME_IN_NAMEVALUE_IS_NOT_ALLOWED</li>
|
1092 |
+
* <li>ERR_ITEMID_INVALID_FROMTODATE</li>
|
1093 |
+
* <li>ERR_INVALID_EVENT_RECOMMENDATIONID</li>
|
1094 |
+
* <li>ERR_INTERNAL_ERROR</li>
|
1095 |
+
* <li>ERR_INVALID_METHOD_NAME</li>
|
1096 |
+
* </ul>
|
1097 |
+
*
|
1098 |
+
* @var string
|
1099 |
+
*/
|
1100 |
+
public $faultInfo;
|
1101 |
+
}
|
1102 |
+
|
1103 |
+
class Message{
|
1104 |
+
|
1105 |
+
public function getMessage($errorcode){
|
1106 |
+
|
1107 |
+
switch($errorcode){
|
1108 |
+
case -1:
|
1109 |
+
return 'The client was initilized with invalid configuration.';
|
1110 |
+
case -2:
|
1111 |
+
return 'Unknown error during communication.';
|
1112 |
+
case -3:
|
1113 |
+
return 'Bad Webshop Servlet URL, please try again!<br>';
|
1114 |
+
case -4:
|
1115 |
+
return 'Timeout during communication.';
|
1116 |
+
case -5:
|
1117 |
+
return 'Could not connect to remote host.';
|
1118 |
+
case -6:
|
1119 |
+
return 'Bad customer id or password, please try again!<br>';
|
1120 |
+
default:
|
1121 |
+
return '';
|
1122 |
+
}
|
1123 |
+
}
|
1124 |
+
}
|
app/design/adminhtml/default/default/template/me/gravity/system/config/form/synch.phtml
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
include("GravityClient.php");
|
4 |
+
use Magento\Framework\Event\ObserverInterface;
|
5 |
+
use Magento\Framework\Message\ManagerInterface as MessageManager;
|
6 |
+
use Gravity\GravityItem;
|
7 |
+
use Gravity\GravityClient;
|
8 |
+
use Gravity\GravityClientConfig;
|
9 |
+
use Gravity\GravityException;
|
10 |
+
use Gravity\GravityNameValue;
|
11 |
+
use Gravity\GravityUser;
|
12 |
+
use Gravity\Message;
|
13 |
+
|
14 |
+
function resync() {
|
15 |
+
$store =Mage::app()->getStore();
|
16 |
+
$baseUrl = Mage::app()->getStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
|
17 |
+
$apiUser = Mage::getStoreConfig('gravity/config/api_user', $store);
|
18 |
+
$apiPassword = Mage::getStoreConfig('gravity/config/api_password', $store);
|
19 |
+
$apiUrl = Mage::getStoreConfig('gravity/config/api_url', $store);
|
20 |
+
$inStock = Mage::getStoreConfig('gravity/sync/only_salable', $store);
|
21 |
+
$config = new GravityClientConfig();
|
22 |
+
$config->user = $apiUser;
|
23 |
+
$config->remoteUrl = $apiUrl;
|
24 |
+
$config->password = $apiPassword;
|
25 |
+
$client = new GravityClient($config);
|
26 |
+
$products = Mage::getModel('catalog/product')->getCollection();
|
27 |
+
$collection = Mage::getResourceModel('catalog/category_collection')
|
28 |
+
->setStoreId($store->getId())
|
29 |
+
->addNameToResult();
|
30 |
+
$itemCollection = array();
|
31 |
+
foreach($products as $prod) {
|
32 |
+
$product = Mage::getModel('catalog/product')->load($prod->getId());
|
33 |
+
if($inStock==1 && $product->getStockItem()->getQty()<1){
|
34 |
+
|
35 |
+
}
|
36 |
+
elseif(count($product->getCategoryIds())==0){
|
37 |
+
|
38 |
+
}
|
39 |
+
else{
|
40 |
+
$item = new GravityItem();
|
41 |
+
$item->itemId = $product->getId();
|
42 |
+
$item->title = $product->getName();
|
43 |
+
if($product->getVisibility()==1){
|
44 |
+
$item->hidden = true;
|
45 |
+
}else {
|
46 |
+
$item->hidden=false;
|
47 |
+
}
|
48 |
+
$cats = $product->getCategoryIds();
|
49 |
+
$url =$baseUrl.$product->getUrlPath();
|
50 |
+
$imageUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'catalog/product'.$product->getImage();
|
51 |
+
$item->nameValues = array(new GravityNameValue('Price', $product->getFinalPrice()),
|
52 |
+
new GravityNameValue('URL', $url),
|
53 |
+
new GravityNameValue('storeId', $store->getStoreId()),
|
54 |
+
new GravityNameValue('Image', $imageUrl),
|
55 |
+
new GravityNameValue('Description', $product->getDescription()));
|
56 |
+
|
57 |
+
foreach ($cats as $category_id) {
|
58 |
+
|
59 |
+
$_cat = Mage::getModel('catalog/category')->load($category_id) ;
|
60 |
+
$structure = preg_split('#/+#', $_cat->getPath());
|
61 |
+
for($j=0; $j<count($structure); $j=$j+1){
|
62 |
+
$structure[$j]=$collection->getItemById($structure[$j])->getName();
|
63 |
+
}
|
64 |
+
array_push($item->nameValues, new GravityNameValue('categoryPath', implode("/", $structure)));
|
65 |
+
array_push($item->nameValues, new GravityNameValue('categoryId', $category_id));
|
66 |
+
}
|
67 |
+
|
68 |
+
array_push($itemCollection, $item);
|
69 |
+
} }
|
70 |
+
$chunkedItems = array_chunk($itemCollection, 100);
|
71 |
+
$chunkedItemsNum = count($chunkedItems);
|
72 |
+
for($i=0; $i<$chunkedItemsNum; $i++){
|
73 |
+
try {
|
74 |
+
$client->addItems($chunkedItems[$i], true);
|
75 |
+
} catch (GravityException $e) {
|
76 |
+
}
|
77 |
+
}
|
78 |
+
$users = mage::getModel('customer/customer')->getCollection();
|
79 |
+
$gravityUserCollection = array();
|
80 |
+
foreach ($users as $user){
|
81 |
+
$user = Mage::getModel('customer/customer')->load($user->getId());
|
82 |
+
$gravityUser = new GravityUser();
|
83 |
+
$gravityUser->userId = $user->getId();
|
84 |
+
$gravityUser->hidden = false;
|
85 |
+
if($user->getGender()==1){
|
86 |
+
$gender = 'male';
|
87 |
+
}elseif($user->getGender()==2){
|
88 |
+
$gender = 'female';
|
89 |
+
}else{
|
90 |
+
$gender = 'not specified';
|
91 |
+
}
|
92 |
+
$gravityUser->nameValues = array(new GravityNameValue('name', $user->getName()),
|
93 |
+
new GravityNameValue('sex', $gender),
|
94 |
+
new GravityNameValue('email', $user->getEmail()));
|
95 |
+
array_push($gravityUserCollection, $gravityUser);
|
96 |
+
}
|
97 |
+
$chunkedUsers = array_chunk($gravityUserCollection, 100);
|
98 |
+
$chunkedUsersNum = count($chunkedUsers);
|
99 |
+
for($i=0; $i<$chunkedUsersNum; $i++){
|
100 |
+
try {
|
101 |
+
$client->addUsers($chunkedUsers[$i], true);
|
102 |
+
} catch (GravityException $e) {
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
106 |
+
if (isset($_GET['hello'])) {
|
107 |
+
resync();
|
108 |
+
}
|
109 |
+
?>
|
110 |
+
<a href='index.php?hello=true'><input type="button" value="Export Catalog" class="form-button"/></a>
|
111 |
+
|
app/design/frontend/base/default/template/me/gravity/catalogsearch/js/gravity.phtml
CHANGED
@@ -30,7 +30,7 @@
|
|
30 |
type: "event",
|
31 |
eventType: "SEARCH",
|
32 |
storeId: <?php echo $this->getStoreId() ?>,
|
33 |
-
|
34 |
});
|
35 |
//]]>
|
36 |
</script>
|
30 |
type: "event",
|
31 |
eventType: "SEARCH",
|
32 |
storeId: <?php echo $this->getStoreId() ?>,
|
33 |
+
searchExpression: "<?php echo $this->getSearchKeyword() ?>",
|
34 |
});
|
35 |
//]]>
|
36 |
</script>
|
app/design/frontend/base/default/template/me/gravity/page/js/gravity.phtml
CHANGED
@@ -18,6 +18,28 @@
|
|
18 |
* @see Me_Gravity_Block_Page_Js_Gravity
|
19 |
*/
|
20 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
<?php if ($this->isEnabled() && $this->getGravityCustomerId()) : ?>
|
22 |
<?php $gravityHelper = $this->getGravityHelper(); ?>
|
23 |
<?php if ($this->isCustomJsEnabled()) : ?>
|
18 |
* @see Me_Gravity_Block_Page_Js_Gravity
|
19 |
*/
|
20 |
?>
|
21 |
+
<?php
|
22 |
+
$store =Mage::app()->getStore();
|
23 |
+
$collection = Mage::getResourceModel('catalog/category_collection')
|
24 |
+
->setStoreId($store->getId())
|
25 |
+
->addNameToResult();
|
26 |
+
$layer = Mage::getSingleton('catalog/layer');
|
27 |
+
if(isset($layer)){
|
28 |
+
$_category = $layer->getCurrentCategory();
|
29 |
+
$currentCategoryId= $_category->getId();
|
30 |
+
$_cat = Mage::getModel('catalog/category')->load($currentCategoryId);
|
31 |
+
$structure = preg_split('#/+#', $_cat->getPath());
|
32 |
+
for($j=0; $j<count($structure); $j=$j+1){
|
33 |
+
$structure[$j]=$collection->getItemById($structure[$j])->getName();
|
34 |
+
}
|
35 |
+
$currentCategoryPath = implode("/", $structure);
|
36 |
+
|
37 |
+
?>
|
38 |
+
<script>
|
39 |
+
var _gravity = _gravity || [];
|
40 |
+
_gravity.push({type: 'set', categoryPath: '<?=$currentCategoryPath?>'});
|
41 |
+
</script>
|
42 |
+
<?php } ?>
|
43 |
<?php if ($this->isEnabled() && $this->getGravityCustomerId()) : ?>
|
44 |
<?php $gravityHelper = $this->getGravityHelper(); ?>
|
45 |
<?php if ($this->isCustomJsEnabled()) : ?>
|
app/design/frontend/base/default/template/me/gravity/widget/boxes/widget.phtml
CHANGED
@@ -15,6 +15,15 @@
|
|
15 |
* @see Me_Gravity_Block_Widget_Boxes_Widget
|
16 |
*/
|
17 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
<?php $gravityHelper = $this->getGravityHelper(); ?>
|
19 |
<?php if ($this->getTemplateType()) : ?>
|
20 |
<?php $storeId = $this->getStoreId(); ?>
|
@@ -50,6 +59,7 @@
|
|
50 |
type: "recommendation",
|
51 |
scenarioId: "<?php echo $this->getRecommendationType() ?>",
|
52 |
numberLimit: <?php echo $this->getRecommendationLimit() ?>,
|
|
|
53 |
storeId: <?php echo $storeId ?>,
|
54 |
resultNames: ["itemId", "title_<?php echo $storeId ?>", "link_<?php echo $storeId ?>", "image_link_<?php echo $storeId ?>"],
|
55 |
templating: {
|
15 |
* @see Me_Gravity_Block_Widget_Boxes_Widget
|
16 |
*/
|
17 |
?>
|
18 |
+
<?php
|
19 |
+
$layer = Mage::getSingleton('catalog/layer');
|
20 |
+
if(isset($layer)){
|
21 |
+
$_category = $layer->getCurrentCategory();
|
22 |
+
$currentCategoryId= $_category->getId();
|
23 |
+
}
|
24 |
+
else{
|
25 |
+
$currentCategoryId = '';
|
26 |
+
}?>
|
27 |
<?php $gravityHelper = $this->getGravityHelper(); ?>
|
28 |
<?php if ($this->getTemplateType()) : ?>
|
29 |
<?php $storeId = $this->getStoreId(); ?>
|
59 |
type: "recommendation",
|
60 |
scenarioId: "<?php echo $this->getRecommendationType() ?>",
|
61 |
numberLimit: <?php echo $this->getRecommendationLimit() ?>,
|
62 |
+
categoryId: "<?php echo $currentCategoryId ?>",
|
63 |
storeId: <?php echo $storeId ?>,
|
64 |
resultNames: ["itemId", "title_<?php echo $storeId ?>", "link_<?php echo $storeId ?>", "image_link_<?php echo $storeId ?>"],
|
65 |
templating: {
|
package.xml
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Me_Gravity</name>
|
4 |
-
<version>1.1.0.
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://www.gravityrd.com/">Gravity R&D, Ltd.</license>
|
7 |
<channel>community</channel>
|
@@ -19,13 +19,13 @@ Yusp so the system can perform the analysis of customer behavior on the
|
|
19 |
site and calculate recommendations accordingly. With the extension, it
|
20 |
is also possible to export product catalogs and customers, or run daily
|
21 |
scheduled exports on cron jobs.</description>
|
22 |
-
<notes>Version number: 1.1.0.
|
23 |
Stability: Stable
|
24 |
Compatibility: CE 1.6.x, 1.7.x, 1.8.x, 1.9.x </notes>
|
25 |
<authors><author><name>Gravity Recommendations</name><user>gravity_rd</user><email>web-integration@gravityrd.com</email></author></authors>
|
26 |
<date>2016-10-15</date>
|
27 |
-
<time>
|
28 |
-
<contents><target name="mageetc"><dir name="modules"><file name="Me_Gravity.xml" hash="a385bf72a5c2f0f040d2bb0850ca0b7c"/></dir></target><target name="magecommunity"><dir name="Me"><dir name="Gravity"><dir name="Block"><file name="Abstract.php" hash="586409500493a209ba021f8d471c793c"/><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><file name="Catalog.php" hash="6adcc355986762d7cc19f854c5fdd067"/><file name="Customer.php" hash="50336da73ad37e3895f82980387f6970"/><file name="Test.php" hash="07d7fce9dd15eb623918d6f01505cc32"/><file name="Version.php" hash="cdaa1bf4da1dffefb71aa3a27a63d2f1"/></dir></dir></dir></dir><dir name="Catalog"><dir name="Category"><dir name="Boxes"><file name="Category.php" hash="436b2d56c25114b152d786a939071cc4"/><file name="Personal.php" hash="7773ddf6e4a109e2cb16665ab1f469e6"/><file name="Top.php" hash="662641627445dd1a650467dfb2318151"/></dir></dir><dir name="Product"><dir name="View"><dir name="Boxes"><file name="Accessories.php" hash="765e6c65419b4c09702655d2e315835a"/><file name="Personal.php" hash="c3a1d8903982887485b1b0ca2c1548ec"/><file name="Product.php" hash="bc40a2d7e854fa9e6d8bb7b2bdd37a25"/><file name="Similar.php" hash="47099324fca5883edb881c8e4a3eb6bd"/></dir><dir name="Js"><file name="Gravity.php" hash="cba4e59a726e2ff10d746748731ac35e"/></dir></dir></dir></dir><dir name="Catalogsearch"><dir name="Advanced"><dir name="Js"><file name="Gravity.php" hash="a37130181b430d057fa2dcb76de0ff60"/></dir></dir><dir name="Boxes"><file name="Result.php" hash="1c59e5b53cbef273f6cb7cd3448aa45b"/></dir><dir name="Js"><file name="Gravity.php" hash="d065f4ef6555312988c2e165621ea2a8"/></dir></dir><dir name="Checkout"><dir name="Cart"><dir name="Boxes"><file name="Cart.php" hash="b720e576c5123f9d52ee98807cb7ac36"/></dir></dir></dir><dir name="General"><dir name="Boxes"><file name="Best.php" hash="07299f81cbf42d2fda4bfb31964f7c24"/><file name="History.php" hash="b50a5a27a6920efbf0ff51e349543e13"/><file name="Others.php" hash="263af4423f1dc40640c2bd0f3366cec5"/><file name="Popular.php" hash="d50fdf81725bd55be46141c5d5515480"/></dir></dir><dir name="Page"><dir name="Js"><file name="Gravity.php" hash="6f78a812fa42227b25780a483fd202d8"/></dir></dir><file name="Recommendation.php" hash="c0d131d38d35f18b596119c6c5253c13"/><dir name="Widget"><dir name="Boxes"><file name="Widget.php" hash="17560f25437bf04f2f8069b1aeee010e"/></dir></dir></dir><dir name="Helper"><file name="Boxes.php" hash="9d498b80819c6f8b5f94e77801e312ec"/><file name="Data.php" hash="
|
29 |
<compatible/>
|
30 |
<dependencies><required><php><min>5.3.0</min><max>5.6.15</max></php></required></dependencies>
|
31 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Me_Gravity</name>
|
4 |
+
<version>1.1.0.2</version>
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://www.gravityrd.com/">Gravity R&D, Ltd.</license>
|
7 |
<channel>community</channel>
|
19 |
site and calculate recommendations accordingly. With the extension, it
|
20 |
is also possible to export product catalogs and customers, or run daily
|
21 |
scheduled exports on cron jobs.</description>
|
22 |
+
<notes>Version number: 1.1.0.2
|
23 |
Stability: Stable
|
24 |
Compatibility: CE 1.6.x, 1.7.x, 1.8.x, 1.9.x </notes>
|
25 |
<authors><author><name>Gravity Recommendations</name><user>gravity_rd</user><email>web-integration@gravityrd.com</email></author></authors>
|
26 |
<date>2016-10-15</date>
|
27 |
+
<time>08:33:30</time>
|
28 |
+
<contents><target name="mageetc"><dir name="modules"><file name="Me_Gravity.xml" hash="a385bf72a5c2f0f040d2bb0850ca0b7c"/></dir></target><target name="magecommunity"><dir name="Me"><dir name="Gravity"><dir name="Block"><file name="Abstract.php" hash="586409500493a209ba021f8d471c793c"/><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><file name="Catalog.php" hash="6adcc355986762d7cc19f854c5fdd067"/><file name="Customer.php" hash="50336da73ad37e3895f82980387f6970"/><file name="Synch.php" hash="c088bdb8abc2ca0411f6a8e905144d6b"/><file name="Test.php" hash="07d7fce9dd15eb623918d6f01505cc32"/><file name="Version.php" hash="cdaa1bf4da1dffefb71aa3a27a63d2f1"/></dir></dir></dir></dir><dir name="Catalog"><dir name="Category"><dir name="Boxes"><file name="Category.php" hash="436b2d56c25114b152d786a939071cc4"/><file name="Personal.php" hash="7773ddf6e4a109e2cb16665ab1f469e6"/><file name="Top.php" hash="662641627445dd1a650467dfb2318151"/></dir></dir><dir name="Product"><dir name="View"><dir name="Boxes"><file name="Accessories.php" hash="765e6c65419b4c09702655d2e315835a"/><file name="Personal.php" hash="c3a1d8903982887485b1b0ca2c1548ec"/><file name="Product.php" hash="bc40a2d7e854fa9e6d8bb7b2bdd37a25"/><file name="Similar.php" hash="47099324fca5883edb881c8e4a3eb6bd"/></dir><dir name="Js"><file name="Gravity.php" hash="cba4e59a726e2ff10d746748731ac35e"/></dir></dir></dir></dir><dir name="Catalogsearch"><dir name="Advanced"><dir name="Js"><file name="Gravity.php" hash="a37130181b430d057fa2dcb76de0ff60"/></dir></dir><dir name="Boxes"><file name="Result.php" hash="1c59e5b53cbef273f6cb7cd3448aa45b"/></dir><dir name="Js"><file name="Gravity.php" hash="d065f4ef6555312988c2e165621ea2a8"/></dir></dir><dir name="Checkout"><dir name="Cart"><dir name="Boxes"><file name="Cart.php" hash="b720e576c5123f9d52ee98807cb7ac36"/></dir></dir></dir><dir name="General"><dir name="Boxes"><file name="Best.php" hash="07299f81cbf42d2fda4bfb31964f7c24"/><file name="History.php" hash="b50a5a27a6920efbf0ff51e349543e13"/><file name="Others.php" hash="263af4423f1dc40640c2bd0f3366cec5"/><file name="Popular.php" hash="d50fdf81725bd55be46141c5d5515480"/></dir></dir><dir name="Page"><dir name="Js"><file name="Gravity.php" hash="6f78a812fa42227b25780a483fd202d8"/></dir></dir><file name="Recommendation.php" hash="c0d131d38d35f18b596119c6c5253c13"/><dir name="Widget"><dir name="Boxes"><file name="Widget.php" hash="17560f25437bf04f2f8069b1aeee010e"/></dir></dir></dir><dir name="Helper"><file name="Boxes.php" hash="9d498b80819c6f8b5f94e77801e312ec"/><file name="Data.php" hash="e4e59320874f84d6b928895eec36b106"/></dir><dir name="Model"><dir name="Client"><file name="GravityClient.php" hash="361edf56f609ce392a748a7a91d718e6"/></dir><file name="Customers.php" hash="7399f7fb93965a3c67f5e2c941209ffe"/><dir name="Export"><file name="Abstract.php" hash="9f42701355b6bb288b4ead0eadcf19f0"/><dir name="Catalog"><file name="Product.php" hash="2e6ffa32925cbf0ee110d17ca57e7ba8"/></dir><dir name="Customer"><file name="Customer.php" hash="d3577acc08cd3004ccfb865232eebb9c"/></dir></dir><dir name="Method"><file name="Abstract.php" hash="c907e89db6238c5001cf653b31afa56e"/><file name="Request.php" hash="31584c1e561651d0da15c0b0869cc3de"/></dir><file name="Observer.php" hash="216a6c6cab01c9c52254d3dcf396ec39"/><file name="Products.php" hash="3b76c51170818f04fe94606f85e09dd2"/><dir name="System"><dir name="Config"><dir name="Backend"><dir name="Catalog"><file name="Cron.php" hash="395fbd5f3d41223a336057b5bba6f4cc"/></dir></dir><dir name="Source"><dir name="Catalog"><file name="Attributes.php" hash="72df90bea6566c5e843c2301ba4dd6e1"/></dir><dir name="Customer"><file name="Attributes.php" hash="1e940ae61c568d83bc541b0fb8e87de1"/></dir><dir name="Layout"><file name="Layout.php" hash="18ab5c014f802bea1f6a841d062439ac"/><file name="Pages.php" hash="0eb22c10429bb136bd900b5b953887e5"/></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="GravityController.php" hash="c6237b4322d5a7a33d191789325b8036"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="17bf0f5989e14d857252726fef4fad6d"/><file name="config.xml" hash="22a061c8dd3d9ce6de4f72a5aa23f86a"/><file name="system.xml" hash="2a015e0bbf753f9ee96a7d324253d605"/><file name="system_backup.xml" hash="55672758af380c029374dadd629479b7"/><file name="widget.xml" hash="9662aa456d8dcf6b38503944427c247e"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="me"><dir name="gravity"><dir name="catalog"><dir name="category"><dir name="boxes"><file name="default.phtml" hash="f1569ed325e167d4e24b48101c109bed"/><file name="sidebar.phtml" hash="bfd9e6b741652779fea92b059f991822"/></dir></dir><dir name="product"><dir name="view"><dir name="boxes"><file name="default.phtml" hash="c916e1eeae7a719a2f284c19627eb50e"/><file name="sidebar.phtml" hash="c603cab98a672f113f0850ac850ee492"/></dir><dir name="js"><file name="gravity.phtml" hash="21b1752933f49d4fdf77c1dff3e8accb"/></dir></dir></dir></dir><dir name="catalogsearch"><dir name="advanced"><dir name="js"><file name="gravity.phtml" hash="ed37b5368abb0e5e1fddaf7d94f1634f"/></dir></dir><dir name="boxes"><file name="default.phtml" hash="600f331b3ef8772b652cc7fcde0270d6"/><file name="sidebar.phtml" hash="f9b64de7698f8d5a30da7dda56ef8f1d"/></dir><dir name="js"><file name="gravity.phtml" hash="64a5f0cd6f8e7098c744a7d3ea90961b"/></dir></dir><dir name="checkout"><dir name="cart"><dir name="boxes"><file name="default.phtml" hash="20aedc8eed8ab7e4c139f06cd6c0266f"/><file name="sidebar.phtml" hash="1b1f4c63788bfc9f9e338f664c50af64"/></dir></dir></dir><dir name="general"><dir name="boxes"><file name="default.phtml" hash="4b1308c89763c49b197883a9ae70e65b"/><file name="sidebar.phtml" hash="db426a25d29aaddf2c037aa471b0b855"/></dir></dir><dir name="page"><dir name="js"><file name="body-end.phtml" hash="c68cf0e1b26964c5867bd9fa1bf548c3"/><file name="gravity.phtml" hash="6aced3013b87635268b647cadd567aab"/></dir></dir><dir name="widget"><dir name="boxes"><file name="widget.phtml" hash="cbeca616b0b872437b1e52167ead0123"/></dir></dir></dir></dir></dir><dir name="layout"><dir name="me"><file name="gravity.xml" hash="47f5ea1f53290cfd3f6a48bd2c64a7fc"/></dir></dir></dir></dir><dir name="rwd"><dir name="default"><dir name="template"><dir name="me"><dir name="gravity"><dir name="catalog"><dir name="category"><dir name="boxes"><file name="default.phtml" hash="4c4c9c68a8695e4ee0e8df9372e3e545"/><file name="sidebar.phtml" hash="7e7226aed80cd351b66e2b0c599608d5"/></dir></dir><dir name="product"><dir name="view"><dir name="boxes"><file name="default.phtml" hash="b68aa48c1e3ff9884884084660cb04cd"/><file name="sidebar.phtml" hash="3dfdc2dbdb9c69dbad73e93759fe6dee"/></dir></dir></dir></dir><dir name="catalogsearch"><dir name="boxes"><file name="default.phtml" hash="8dc241f668fad3b36e1a26d8c3b01802"/><file name="sidebar.phtml" hash="6aa688d961dfc9818001ae39866a4992"/></dir></dir><dir name="checkout"><dir name="cart"><dir name="boxes"><file name="default.phtml" hash="c81b3af4fe4fc03444da83f7416d0fc7"/><file name="sidebar.phtml" hash="d78a9160cbeded38e6a989eefe3c3753"/></dir></dir></dir><dir name="general"><dir name="boxes"><file name="default.phtml" hash="ec7412c0f1a6c8c15b859f5277c53885"/><file name="sidebar.phtml" hash="db426a25d29aaddf2c037aa471b0b855"/></dir></dir><dir name="widget"><dir name="boxes"><file name="widget.phtml" hash="41552aa04ba7810eada0706a8ee7f5ec"/></dir></dir></dir></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="me"><dir name="gravity"><dir name="system"><dir name="config"><dir name="form"><file name="GravityClient.php" hash="15a4d36e2b697bf3e579fa3d0eb89c77"/><file name="synch.phtml" hash="dbd5e7f3a11b4f07c96cf0997c0bfa26"/><file name="test.phtml" hash="d9d972a23b04a34ab5f4d70a732d65b3"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><dir name="me"><dir name="gravity"><file name="gravity.css" hash="c2c4c7d30bced9a311c98032e38e0e11"/></dir></dir></dir></dir></dir></dir></target><target name="magelocal"><dir name="en_US"><file name="Me_Gravity.csv" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir></target></contents>
|
29 |
<compatible/>
|
30 |
<dependencies><required><php><min>5.3.0</min><max>5.6.15</max></php></required></dependencies>
|
31 |
</package>
|