Version Notes
Version 1.3.1.
Download this release
Release Info
| Developer | Intuiko |
| Extension | ICS_Connector |
| Version | 1.3.1 |
| Comparing to | |
| See all releases | |
Version 1.3.1
- app/code/local/Intuiko/ConnectedStore/Block/Button.php +37 -0
- app/code/local/Intuiko/ConnectedStore/Exception.php +11 -0
- app/code/local/Intuiko/ConnectedStore/Helper/ICSHelper.php +507 -0
- app/code/local/Intuiko/ConnectedStore/Helper/ICSTwitterHelper.php +22 -0
- app/code/local/Intuiko/ConnectedStore/Logger/ICSLogger.php +39 -0
- app/code/local/Intuiko/ConnectedStore/Model/Bag.php +670 -0
- app/code/local/Intuiko/ConnectedStore/Model/Cart.php +233 -0
- app/code/local/Intuiko/ConnectedStore/Model/Customer.php +129 -0
- app/code/local/Intuiko/ConnectedStore/Model/Entities.php +148 -0
- app/code/local/Intuiko/ConnectedStore/Model/MergeMethods.php +16 -0
- app/code/local/Intuiko/ConnectedStore/Model/Messages.php +35 -0
- app/code/local/Intuiko/ConnectedStore/Model/Observer.php +417 -0
- app/code/local/Intuiko/ConnectedStore/Model/Order.php +52 -0
- app/code/local/Intuiko/ConnectedStore/Model/Resource/ICSResource.php +16 -0
- app/code/local/Intuiko/ConnectedStore/Model/Wishlist.php +331 -0
- app/code/local/Intuiko/ConnectedStore/controllers/PingController.php +24 -0
- app/code/local/Intuiko/ConnectedStore/etc/adminhtml.xml +23 -0
- app/code/local/Intuiko/ConnectedStore/etc/config.xml +136 -0
- app/code/local/Intuiko/ConnectedStore/etc/system.xml +107 -0
- app/etc/modules/Intuiko_All.xml +9 -0
- package.xml +2 -0
app/code/local/Intuiko/ConnectedStore/Block/Button.php
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
class Intuiko_ConnectedStore_Block_Button extends Mage_Adminhtml_Block_System_Config_Form_Field
|
| 3 |
+
{
|
| 4 |
+
|
| 5 |
+
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
|
| 6 |
+
{
|
| 7 |
+
$this->setElement($element);
|
| 8 |
+
|
| 9 |
+
$url = Mage::getBaseUrl() . "ping/ping";
|
| 10 |
+
|
| 11 |
+
$jsScript = "document.getElementById('intuiko_connectedstore_test_connection').innerHTML = 'Trying to connect to the ICS API...';";
|
| 12 |
+
$jsScript .= "var xmlhttp = new XMLHttpRequest();";
|
| 13 |
+
$jsScript .= "xmlhttp.onreadystatechange = function() {";
|
| 14 |
+
$jsScript .= "if (xmlhttp.readyState == XMLHttpRequest.DONE ) {";
|
| 15 |
+
$jsScript .= "if(xmlhttp.status == 200){";
|
| 16 |
+
$jsScript .= "document.getElementById('intuiko_connectedstore_test_connection').innerHTML = xmlhttp.responseText;";
|
| 17 |
+
$jsScript .= "}else{";
|
| 18 |
+
$jsScript .= "document.getElementById('intuiko_connectedstore_test_connection').innerHTML = 'Connection failed';";
|
| 19 |
+
$jsScript .= "}}};";
|
| 20 |
+
$jsScript .= "xmlhttp.open('GET', '" . $url . "', true);";
|
| 21 |
+
$jsScript .= "xmlhttp.send();";
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
$html = $this->getLayout()->createBlock('adminhtml/widget_button')
|
| 26 |
+
->setType('button')
|
| 27 |
+
->setClass('scalable')
|
| 28 |
+
->setLabel('Test Connection')
|
| 29 |
+
->setOnClick($jsScript)
|
| 30 |
+
->toHtml();
|
| 31 |
+
|
| 32 |
+
$html .= "<div id='intuiko_connectedstore_test_connection'></div>";
|
| 33 |
+
|
| 34 |
+
return $html;
|
| 35 |
+
}
|
| 36 |
+
}
|
| 37 |
+
?>
|
app/code/local/Intuiko/ConnectedStore/Exception.php
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Intuiko_ConnectedStore_Exception extends Zend_Exception {
|
| 4 |
+
public $codeError;
|
| 5 |
+
|
| 6 |
+
public function __construct($msg = '', $codeError = 0) {
|
| 7 |
+
ICSLogger::error($msg);
|
| 8 |
+
$this->codeError = $codeError;
|
| 9 |
+
parent::__construct($msg, 0, null);
|
| 10 |
+
}
|
| 11 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Helper/ICSHelper.php
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Magento
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
*
|
| 8 |
+
* Helper class to uses to request Api ICS
|
| 9 |
+
* Example:
|
| 10 |
+
* http://support.qualityunit.com/061754-How-to-make-REST-calls-in-PHP
|
| 11 |
+
*
|
| 12 |
+
*/
|
| 13 |
+
class Intuiko_ConnectedStore_Helper_ICSHelper extends Mage_Core_Helper_Abstract {
|
| 14 |
+
|
| 15 |
+
private static $ICS_Error = 'ICS_Error';
|
| 16 |
+
private static $CURLE_OPERATION_TIMEDOUT = '28';
|
| 17 |
+
|
| 18 |
+
private static $API_VERSION = "1.3" ;
|
| 19 |
+
|
| 20 |
+
/** ICS connector status */
|
| 21 |
+
private $status = NULL;
|
| 22 |
+
|
| 23 |
+
/** ICS api url */
|
| 24 |
+
private $uri = NULL;
|
| 25 |
+
|
| 26 |
+
/** Application api key */
|
| 27 |
+
private $apikey = NULL;
|
| 28 |
+
|
| 29 |
+
/** Tenant id */
|
| 30 |
+
private $tenantId = NULL;
|
| 31 |
+
|
| 32 |
+
/** Brand Id */
|
| 33 |
+
private $brandId = NULL;
|
| 34 |
+
|
| 35 |
+
/** Bag Merge Method */
|
| 36 |
+
private $mergeMethod = NULL;
|
| 37 |
+
|
| 38 |
+
/** Time of timeout */
|
| 39 |
+
private $timeout = NULL;
|
| 40 |
+
|
| 41 |
+
/**
|
| 42 |
+
* Init param to call api ICS
|
| 43 |
+
*/
|
| 44 |
+
public function Intuiko_ConnectedStore_Helper_ICSHelper(){
|
| 45 |
+
$this->status = Mage::getStoreConfig('connectedstore_section/connectedstore_group/status_field');
|
| 46 |
+
$this->uri = Mage::getStoreConfig('connectedstore_section/connectedstore_group/urlservice_field');
|
| 47 |
+
$this->apikey = Mage::getStoreConfig('connectedstore_section/connectedstore_group/apikey_field');
|
| 48 |
+
$this->tenantId = Mage::getStoreConfig('connectedstore_section/connectedstore_group/tenantid_field');
|
| 49 |
+
$this->brandId = Mage::getStoreConfig('connectedstore_section/connectedstore_group/brandid_field');
|
| 50 |
+
$this->mergeMethod = Mage::getStoreConfig('connectedstore_section/connectedstore_group/mergemethod_field');
|
| 51 |
+
$this->timeout = Mage::getStoreConfig('connectedstore_section/connectedstore_group/timeout_field');
|
| 52 |
+
|
| 53 |
+
if($this->status && (empty($this->uri) || empty($this->apikey) || empty($this->tenantId) || empty($this->brandId))) {
|
| 54 |
+
ICSLogger::error('A field is missing in the configuration, ICS connector will be deactivated.');
|
| 55 |
+
$this->status = false;
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
/**
|
| 60 |
+
* Set the flag value of mode timeout in the session
|
| 61 |
+
*
|
| 62 |
+
* @param Boolean $value The boolean to set in the session
|
| 63 |
+
*/
|
| 64 |
+
public static function setIcsFlagError($value){
|
| 65 |
+
$session = Mage::getSingleton('core/session');
|
| 66 |
+
$session->setData(self::$ICS_Error, $value);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
/**
|
| 70 |
+
* Get the flag value of mode timeout from the session
|
| 71 |
+
*
|
| 72 |
+
* @return Boolean The flag value
|
| 73 |
+
*/
|
| 74 |
+
public static function getIcsFlagError(){
|
| 75 |
+
$session = Mage::getSingleton('core/session');
|
| 76 |
+
return $session->getData(self::$ICS_Error);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
/**
|
| 81 |
+
* Generate authentication key as followed:
|
| 82 |
+
* 'ICS ' . sha256($salt . $apiKey)
|
| 83 |
+
* where $salt is a timestamp.
|
| 84 |
+
*
|
| 85 |
+
* @param Integer $time The timestamp used as salt
|
| 86 |
+
* @return String The generated authentication key
|
| 87 |
+
*/
|
| 88 |
+
private function getKey($time){
|
| 89 |
+
return "ICS " . hash('sha256', $time . $this->apikey);
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
/**
|
| 93 |
+
* Generate header to build a http request on Api ICS
|
| 94 |
+
*
|
| 95 |
+
* @return Array The array of headers used for ICS api request
|
| 96 |
+
*/
|
| 97 |
+
|
| 98 |
+
private function getHeader(){
|
| 99 |
+
$date = new DateTime();
|
| 100 |
+
$key = $this->getKey($date->getTimestamp());
|
| 101 |
+
|
| 102 |
+
if($key == NULL){
|
| 103 |
+
return NULL;
|
| 104 |
+
}
|
| 105 |
+
return array(
|
| 106 |
+
'x-timestamp: '. $date->getTimestamp(),
|
| 107 |
+
'Authorization: '. $key,
|
| 108 |
+
'Content-type: application/json; version=' . self::$API_VERSION . '; charset=utf-8',
|
| 109 |
+
'Accept: application/json; version=' . self::$API_VERSION . '; charset=utf-8'
|
| 110 |
+
) ;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
/**
|
| 114 |
+
* Check if the ICS module is in timeout mode.
|
| 115 |
+
*
|
| 116 |
+
* @return bool True if the module is enabled, false otherwise
|
| 117 |
+
*/
|
| 118 |
+
public function isICSModuleEnabled() {
|
| 119 |
+
return $this->status && !$this->getIcsFlagError();
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
/**
|
| 123 |
+
* Check if the ICS module is enabled
|
| 124 |
+
*
|
| 125 |
+
* @return bool True if the module is enabled, false otherwise
|
| 126 |
+
*/
|
| 127 |
+
public function isIcsModuleStatusEnabled() {
|
| 128 |
+
return $this->status;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
/**
|
| 132 |
+
* This function does a ping to initialize the communication
|
| 133 |
+
*
|
| 134 |
+
* @return String A pong class response which contains these attributes : tenantName, applicationProfile, active, apiVersion
|
| 135 |
+
*/
|
| 136 |
+
public function ping(){
|
| 137 |
+
$header = $this->getHeader();
|
| 138 |
+
|
| 139 |
+
if($header == NULL){
|
| 140 |
+
return NULL;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
$opts = array('http' => array('method'=>'GET', 'header'=> $header));
|
| 144 |
+
$context = stream_context_create($opts);
|
| 145 |
+
|
| 146 |
+
$time = microtime(true);
|
| 147 |
+
|
| 148 |
+
$pong = json_decode(file_get_contents( $this->uri . 'tenants/' . $this->tenantId . '/brands/' . $this->brandId . '/ping', false, $context));
|
| 149 |
+
|
| 150 |
+
$timeElapsed = microtime(true) - $time;
|
| 151 |
+
|
| 152 |
+
if($pong == false){
|
| 153 |
+
return NULL;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
$pong->timeElapsed = round($timeElapsed * 1000);
|
| 157 |
+
|
| 158 |
+
return $pong;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
/**
|
| 162 |
+
* Call the save method of ICS api to save the given bag.
|
| 163 |
+
*
|
| 164 |
+
* @param Bag $bag The bag to be saved in ICS.
|
| 165 |
+
* @return Array|False The api response as an array, or false if an error occurred
|
| 166 |
+
*/
|
| 167 |
+
public function save($bag) {
|
| 168 |
+
if(empty($bag)) {
|
| 169 |
+
return false;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
$path = 'tenants/' . $this->tenantId . '/brands/' . $this->brandId . '/bags';
|
| 173 |
+
try {
|
| 174 |
+
$response = $this->post($bag, $path);
|
| 175 |
+
} catch(Intuiko_ConnectedStore_Exception $e) {
|
| 176 |
+
return false;
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
return json_decode($response, true);
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
/**
|
| 183 |
+
* Call the save method of ICS api to save the given customer.
|
| 184 |
+
*
|
| 185 |
+
* @param Customer $customer The customer to be saved in ICS.
|
| 186 |
+
* @return True|False True if everything is OK, or false if an error occurred
|
| 187 |
+
*/
|
| 188 |
+
public function saveCustomer($customer) {
|
| 189 |
+
if(empty($customer)) {
|
| 190 |
+
return false;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
$path = 'tenants/' . $this->tenantId . '/brands/' . $this->brandId . '/customers';
|
| 194 |
+
try {
|
| 195 |
+
$this->post($customer, $path);
|
| 196 |
+
} catch(Intuiko_ConnectedStore_Exception $e) {
|
| 197 |
+
return false;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
return true;
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
/**
|
| 204 |
+
* Call the search method of ICS api to get ids of the bags matching the given bag type and belonging to the
|
| 205 |
+
* customer defined by the given appCustomerId or email.
|
| 206 |
+
*
|
| 207 |
+
* @param String $type The bag type
|
| 208 |
+
* @param Mixed $appCustomerId The customer business identifier
|
| 209 |
+
* @param String $email The customer email
|
| 210 |
+
* @param String $twitterId The customer twitter id
|
| 211 |
+
* @return Array|False|Int The api response as an array, or an error code/false if an error occurred
|
| 212 |
+
*/
|
| 213 |
+
public function searchBagsIds($type, $appCustomerId, $email, $twitterId) {
|
| 214 |
+
if(empty($type) || (empty($appCustomerId) && empty($email) && empty($twitterId))) {
|
| 215 |
+
return false;
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
$searchBagMessage = new SearchBagMessage($type, $appCustomerId, $email, $twitterId);
|
| 219 |
+
$path = 'tenants/' . $this->tenantId . '/brands/' . $this->brandId . '/bags/_search';
|
| 220 |
+
try {
|
| 221 |
+
$response = $this->put($searchBagMessage, $path);
|
| 222 |
+
} catch(Intuiko_ConnectedStore_Exception $e) {
|
| 223 |
+
return !empty($e->codeError) ? $e->codeError : false;
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
return json_decode($response);
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
/**
|
| 230 |
+
* Call the get method of ICS api to get the bag matching the given id.
|
| 231 |
+
* If a timestamp is provided, the bag will be retrieved if and only if it is more recent than the given timestamp.
|
| 232 |
+
*
|
| 233 |
+
* @param String $bagId The id of the bag to retrieve from ICS
|
| 234 |
+
* @param Int $timestamp The timestamp (default value: NULL)
|
| 235 |
+
* @return Array|False|Int The api response as an array or a int (see get($path) method), or false if an error occurred.
|
| 236 |
+
*/
|
| 237 |
+
public function getBagById($bagId, $timestamp = NULL) {
|
| 238 |
+
if(empty($bagId)) {
|
| 239 |
+
return false;
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
$path = 'tenants/' . $this->tenantId . '/brands/' . $this->brandId . '/bags/' . $bagId;
|
| 243 |
+
if(!empty($timestamp)) {
|
| 244 |
+
$path = $path . '?timestamp=' . $timestamp;
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
try {
|
| 248 |
+
$response = $this->get($path);
|
| 249 |
+
} catch(Intuiko_ConnectedStore_Exception $e) {
|
| 250 |
+
return false;
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
if(!empty($response) && is_numeric($response)) {
|
| 254 |
+
return $response;
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
return json_decode($response, true);
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
/**
|
| 261 |
+
* Call the merge method of ICS api to merge two bags.
|
| 262 |
+
* All the modifications will be done on the bag matching the masterBagId.
|
| 263 |
+
* See the api documentation for more details on the different possible merge.
|
| 264 |
+
*
|
| 265 |
+
* @param String $masterBagId The id of the bag that will be considered as the master
|
| 266 |
+
* @param String $slaveBagId The id of the bag that will be considered as the slave
|
| 267 |
+
* @return Array|False The api response as an array, or false if an error occurred
|
| 268 |
+
*/
|
| 269 |
+
public function merge($masterBagId, $slaveBagId) {
|
| 270 |
+
if(empty($this->mergeMethod) || empty($masterBagId) || empty($slaveBagId)) {
|
| 271 |
+
return false;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
$mergeMessage = new MergeMessage($masterBagId, $slaveBagId, $this->mergeMethod);
|
| 275 |
+
$path = 'tenants/' . $this->tenantId . '/brands/' . $this->brandId . '/bags/_merge';
|
| 276 |
+
try {
|
| 277 |
+
$response = $this->post($mergeMessage, $path);
|
| 278 |
+
} catch (Intuiko_ConnectedStore_Exception $e) {
|
| 279 |
+
return false;
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
return json_decode($response, true);
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
/**
|
| 286 |
+
* Call the delete method of ICS api to delete the bag matching the given id.
|
| 287 |
+
*
|
| 288 |
+
* @param String $bagId The id of the bag to delete
|
| 289 |
+
*/
|
| 290 |
+
public function delete($bagId) {
|
| 291 |
+
if(empty($bagId)) {
|
| 292 |
+
return;
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
$deleteMessage = new DeleteMessage($bagId);
|
| 296 |
+
$path = 'tenants/' . $this->tenantId . '/brands/' . $this->brandId . '/bags/_delete';
|
| 297 |
+
try {
|
| 298 |
+
$this->put($deleteMessage, $path);
|
| 299 |
+
} catch(Intuiko_ConnectedStore_Exception $e) {}
|
| 300 |
+
}
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
/**
|
| 304 |
+
* Run Exception if Detect that curl is in timeOut
|
| 305 |
+
*
|
| 306 |
+
* @param curl $ch
|
| 307 |
+
* @param time $time
|
| 308 |
+
* @throws Intuiko_ConnectedStore_Exception
|
| 309 |
+
*/
|
| 310 |
+
public function checkTimeOut($ch, $time){
|
| 311 |
+
if(curl_errno($ch) == self::$CURLE_OPERATION_TIMEDOUT){
|
| 312 |
+
curl_close($ch);
|
| 313 |
+
$this->setIcsFlagError(true);
|
| 314 |
+
throw new Intuiko_ConnectedStore_Exception('request ended in timeout error after ' . $time . 's');
|
| 315 |
+
}
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
/**
|
| 319 |
+
* return true when status code is in error, otherwise false.
|
| 320 |
+
*
|
| 321 |
+
* @param unknown_type $statusCode
|
| 322 |
+
*/
|
| 323 |
+
public function checkStatusError($statusCode){
|
| 324 |
+
if ($statusCode == 0 || $statusCode >= 300) {
|
| 325 |
+
if ($statusCode == 0 || $statusCode >= 500){
|
| 326 |
+
$this->setIcsFlagError(true);
|
| 327 |
+
}
|
| 328 |
+
return true;
|
| 329 |
+
}
|
| 330 |
+
return false;
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
/**
|
| 334 |
+
* Convert an object to JsonObject without its null attributes
|
| 335 |
+
*
|
| 336 |
+
* @param $entity The object to convert
|
| 337 |
+
*/
|
| 338 |
+
private function toJsonObjectWithoutNullAttributes($entity) {
|
| 339 |
+
return json_encode(array_filter((array) $entity, 'filterCallback'));
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
/**
|
| 343 |
+
* Sent POST request with the provided path and entity
|
| 344 |
+
*
|
| 345 |
+
* @param Mixed $entity The entity to send in the request body. It will be encoded in JSON.
|
| 346 |
+
* @param String $path The path of the api method. It will be concatenated to the api url.
|
| 347 |
+
* @throws Intuiko_ConnectedStore_Exception If the http request ends with an error
|
| 348 |
+
* @return String The api response
|
| 349 |
+
*/
|
| 350 |
+
private function post($entity, $path){
|
| 351 |
+
$header = $this->getHeader();
|
| 352 |
+
|
| 353 |
+
if($header == NULL){
|
| 354 |
+
throw new Intuiko_ConnectedStore_Exception('Header cannot be null.');
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
if($path == NULL){
|
| 358 |
+
throw new Intuiko_ConnectedStore_Exception('Path cannot be null.');
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
$data = $this->toJsonObjectWithoutNullAttributes($entity);
|
| 362 |
+
$url = $this->uri . $path;
|
| 363 |
+
|
| 364 |
+
ICSLogger::debug('Sent POST request with url=[' . $url . '] and data=[' . $data . ']');
|
| 365 |
+
|
| 366 |
+
$ch = curl_init();
|
| 367 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
| 368 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
| 369 |
+
curl_setopt($ch, CURLOPT_POST, true);
|
| 370 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
| 371 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
| 372 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
| 373 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
| 374 |
+
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
| 375 |
+
curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->timeout);
|
| 376 |
+
|
| 377 |
+
$result = curl_exec($ch);
|
| 378 |
+
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
| 379 |
+
$time = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
|
| 380 |
+
|
| 381 |
+
//Controle erreur
|
| 382 |
+
$this->checkTimeOut($ch, $time);
|
| 383 |
+
curl_close($ch);
|
| 384 |
+
|
| 385 |
+
if($this->checkStatusError($statusCode)){
|
| 386 |
+
$error = json_decode($result, true);
|
| 387 |
+
throw new Intuiko_ConnectedStore_Exception(
|
| 388 |
+
'POST request ended with error=['. $error['httpCode'] .' - '. $error['message'] .'] - url=['. $url .'] and data=['. $data .']' . $time . 's');
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
ICSLogger::debug('POST request ended with statusCode=[' . $statusCode . '] and content=[' . $result . '] in ' . $time . 's');
|
| 392 |
+
return $result;
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
/**
|
| 396 |
+
* Sent PUT request with the provided path and entity
|
| 397 |
+
*
|
| 398 |
+
* @param Mixed $entity The entity to send in the request body. It will be encoded in JSON.
|
| 399 |
+
* @param String $path The path of the api method. It will be concatenated to the api url.
|
| 400 |
+
* @throws Intuiko_ConnectedStore_Exception
|
| 401 |
+
* @return String The response content or null if an error occurred.
|
| 402 |
+
*/
|
| 403 |
+
public function put($entity, $path){
|
| 404 |
+
$header = $this->getHeader();
|
| 405 |
+
|
| 406 |
+
if($header == NULL){
|
| 407 |
+
throw new Intuiko_ConnectedStore_Exception('Header cannot be null.');
|
| 408 |
+
}
|
| 409 |
+
|
| 410 |
+
if($path == NULL){
|
| 411 |
+
throw new Intuiko_ConnectedStore_Exception('Path cannot be null.');
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
$data = $this->toJsonObjectWithoutNullAttributes($entity);
|
| 415 |
+
$url = $this->uri . $path;
|
| 416 |
+
ICSLogger::debug('Sent PUT request with url=[' . $url . '] and data=[' . $data . ']');
|
| 417 |
+
|
| 418 |
+
$ch = curl_init();
|
| 419 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
| 420 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
| 421 |
+
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
|
| 422 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
| 423 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
| 424 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
| 425 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
| 426 |
+
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
| 427 |
+
curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->timeout);
|
| 428 |
+
|
| 429 |
+
$result = curl_exec($ch);
|
| 430 |
+
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
| 431 |
+
$time = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
|
| 432 |
+
|
| 433 |
+
|
| 434 |
+
//Controle erreur
|
| 435 |
+
$this->checkTimeOut($ch, $time);
|
| 436 |
+
curl_close($ch);
|
| 437 |
+
|
| 438 |
+
if($this->checkStatusError($statusCode)){
|
| 439 |
+
$error = json_decode($result, true);
|
| 440 |
+
if($statusCode === 0 || $statusCode === 500) {
|
| 441 |
+
$error['errorCode'] = -500;
|
| 442 |
+
}
|
| 443 |
+
throw new Intuiko_ConnectedStore_Exception(
|
| 444 |
+
'PUT request ended with error=['. $error['httpCode'] .' - '. $error['message'] .'] - url=['. $url .'] and data=[' . $data . ']' . $time . 's', $error['errorCode']);
|
| 445 |
+
}
|
| 446 |
+
|
| 447 |
+
ICSLogger::debug('PUT request ended with statusCode=[' . $statusCode . '] and content=[' . $result . '] in ' . $time . 's');
|
| 448 |
+
|
| 449 |
+
return $result;
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
/**
|
| 453 |
+
* Sent GET request with the provided path
|
| 454 |
+
*
|
| 455 |
+
* @param String $path The path of the api method. It will be concatenated to the api url.
|
| 456 |
+
* @throws Intuiko_ConnectedStore_Exception
|
| 457 |
+
* @return String The response content or null if an error occurred.
|
| 458 |
+
*/
|
| 459 |
+
public function get($path){
|
| 460 |
+
|
| 461 |
+
$header = $this->getHeader();
|
| 462 |
+
|
| 463 |
+
if($header == NULL){
|
| 464 |
+
throw new Intuiko_ConnectedStore_Exception('Header cannot be null.');
|
| 465 |
+
}
|
| 466 |
+
|
| 467 |
+
if($path == NULL){
|
| 468 |
+
throw new Intuiko_ConnectedStore_Exception('Path cannot be null.');
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
$url = $this->uri . $path;
|
| 472 |
+
ICSLogger::debug('Sent GET request with url=[' . $url . ']');
|
| 473 |
+
|
| 474 |
+
$ch = curl_init();
|
| 475 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
| 476 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
| 477 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
| 478 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
| 479 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
| 480 |
+
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
| 481 |
+
curl_setopt($ch, CURLOPT_HEADER, false);
|
| 482 |
+
curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->timeout);
|
| 483 |
+
|
| 484 |
+
$result = curl_exec($ch);
|
| 485 |
+
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
| 486 |
+
$time = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
|
| 487 |
+
|
| 488 |
+
|
| 489 |
+
//Controle erreur
|
| 490 |
+
$this->checkTimeOut($ch, $time);
|
| 491 |
+
curl_close($ch);
|
| 492 |
+
|
| 493 |
+
if (!$statusCode === 404 && $this->checkStatusError($statusCode)) {
|
| 494 |
+
$error = json_decode($result, true);
|
| 495 |
+
throw new Intuiko_ConnectedStore_Exception(
|
| 496 |
+
'GET request ended with error=['. $error['httpCode'] .' - '. $error['message'] .'] - url=['. $url .']' . $time . 's');
|
| 497 |
+
}
|
| 498 |
+
|
| 499 |
+
ICSLogger::debug('GET request ended with statusCode=[' . $statusCode . '] and content=[' . $result . '] in ' . $time . 's');
|
| 500 |
+
|
| 501 |
+
if($statusCode === 404 || $statusCode === 204) {
|
| 502 |
+
return $statusCode;
|
| 503 |
+
}
|
| 504 |
+
|
| 505 |
+
return $result;
|
| 506 |
+
}
|
| 507 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Helper/ICSTwitterHelper.php
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Magento
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
*
|
| 9 |
+
* Helper class to uses with Twitter Connectors for ICS
|
| 10 |
+
*
|
| 11 |
+
*/
|
| 12 |
+
class Intuiko_ConnectedStore_Helper_ICSTwitterHelper extends Mage_Core_Helper_Abstract {
|
| 13 |
+
|
| 14 |
+
public function getTwitterId($customer) {
|
| 15 |
+
if (empty($customer)) {
|
| 16 |
+
return null;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
// override this return statement to return the customer's twitterId
|
| 20 |
+
return null;
|
| 21 |
+
}
|
| 22 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Logger/ICSLogger.php
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class ICSLogger {
|
| 4 |
+
|
| 5 |
+
const ERROR = 1;
|
| 6 |
+
const WARN = 2;
|
| 7 |
+
const INFO = 3;
|
| 8 |
+
const DEBUG = 4;
|
| 9 |
+
|
| 10 |
+
const LOG_FILE = 'ics.log';
|
| 11 |
+
|
| 12 |
+
const LOG_LEVEL = self::DEBUG;
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
public static function error($message) {
|
| 16 |
+
self::log($message, self::ERROR, Zend_Log::ERR);
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
public static function warn($message) {
|
| 21 |
+
self::log($message, self::WARN, Zend_Log::WARN);
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
public static function debug($message) {
|
| 26 |
+
self::log($message, self::DEBUG, Zend_Log::DEBUG);
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
public static function info($message) {
|
| 31 |
+
self::log($message, self::INFO, Zend_Log::INFO);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
private static function log($message, $level, $zendLevel) {
|
| 35 |
+
if($level <= self::LOG_LEVEL) {
|
| 36 |
+
Mage::log($message, $zendLevel, self::LOG_FILE);
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Bag.php
ADDED
|
@@ -0,0 +1,670 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
include 'Entities.php';
|
| 4 |
+
include 'Resource/ICSResource.php';
|
| 5 |
+
|
| 6 |
+
class Bag extends Message {
|
| 7 |
+
|
| 8 |
+
private static $ICS_FlagSynchro = 'ICS_FlagSynchro';
|
| 9 |
+
const DOT_REPLACE = '\uff0e';
|
| 10 |
+
|
| 11 |
+
public $bagId = null;
|
| 12 |
+
public $bagType = null;
|
| 13 |
+
public $bagName = null;
|
| 14 |
+
public $bagItems = array();
|
| 15 |
+
public $coupons = null;
|
| 16 |
+
public $totals = null;
|
| 17 |
+
public $paymentMethod = null;
|
| 18 |
+
public $shipmentMethod = null;
|
| 19 |
+
public $refBagOrigin = null;
|
| 20 |
+
public $lastUpdate = null;
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* Default constructor
|
| 24 |
+
*/
|
| 25 |
+
private function __construct() {}
|
| 26 |
+
|
| 27 |
+
/**
|
| 28 |
+
* Set the flag value in the session
|
| 29 |
+
*
|
| 30 |
+
* @param Boolean $value The boolean to set in the session
|
| 31 |
+
*/
|
| 32 |
+
public static function setIcsFlagSynchroInSession($value){
|
| 33 |
+
$session = Mage::getSingleton('core/session');
|
| 34 |
+
$session->setData(self::$ICS_FlagSynchro, $value);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
/**
|
| 38 |
+
* Get the flag value from the session
|
| 39 |
+
*
|
| 40 |
+
* @return Boolean The flag value
|
| 41 |
+
*/
|
| 42 |
+
public static function getIcsFlagSynchroInSession(){
|
| 43 |
+
$session = Mage::getSingleton('core/session');
|
| 44 |
+
return $session->getData(self::$ICS_FlagSynchro);
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
/**
|
| 48 |
+
* Generates a checksum from the current bag information
|
| 49 |
+
*
|
| 50 |
+
* @return String The checksum of the current bag
|
| 51 |
+
*/
|
| 52 |
+
public function getCheckSum() {
|
| 53 |
+
$data = array();
|
| 54 |
+
$data['bagId'] = $this->bagId;
|
| 55 |
+
$data['bagType'] = $this->bagType;
|
| 56 |
+
$data['bagName'] = $this->bagName;
|
| 57 |
+
$data['coupons'] = $this->coupons;
|
| 58 |
+
$data['totals'] = $this->totals;
|
| 59 |
+
$data['paymentMethod'] = $this->paymentMethod;
|
| 60 |
+
$data['shipmentMethod'] = $this->shipmentMethod;
|
| 61 |
+
|
| 62 |
+
$bagItemsChecksum = 0;
|
| 63 |
+
if($this->bagItems != null && is_array($this->bagItems)) {
|
| 64 |
+
foreach($this->bagItems as $bagItem){
|
| 65 |
+
$bagItemsChecksum += hexdec(md5(json_encode($bagItem)));
|
| 66 |
+
}
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
$checksum = hexdec(md5(json_encode($data)));
|
| 70 |
+
return $checksum + $bagItemsChecksum;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
/**
|
| 74 |
+
* Allows to convert an array from a json stream which represents an ics bag
|
| 75 |
+
*
|
| 76 |
+
* @param Object $jsonBag The json object that represents a bag
|
| 77 |
+
*/
|
| 78 |
+
protected function createBagFromJsonObject($jsonBag){
|
| 79 |
+
$this->bagId = $jsonBag['id'];
|
| 80 |
+
$this->lastUpdate = $jsonBag['lastUpdate'];
|
| 81 |
+
$this->bagName = $jsonBag['name'];
|
| 82 |
+
$this->bagType = $jsonBag['bagType'];
|
| 83 |
+
$this->customer = $this->createBagCustomer(Mage::getSingleton('customer/session')->getCustomer());
|
| 84 |
+
|
| 85 |
+
$bagItems = array();
|
| 86 |
+
if($jsonBag['bagItems'] != null){
|
| 87 |
+
foreach($jsonBag['bagItems'] as $serial => $bagItem){
|
| 88 |
+
$currentBagItem = new BagItem();
|
| 89 |
+
if(isset($bagItem['comment'])){
|
| 90 |
+
$currentBagItem->comment = $bagItem['comment'];
|
| 91 |
+
}
|
| 92 |
+
if(isset($bagItem['ean'])){
|
| 93 |
+
$currentBagItem->ean = $bagItem['ean'];
|
| 94 |
+
}
|
| 95 |
+
$currentBagItem->qtyToBill = $bagItem['qtyToBill'];
|
| 96 |
+
$currentBagItem->imgUrl = $bagItem['imgUrl'];
|
| 97 |
+
$currentBagItem->label = $bagItem['label'];
|
| 98 |
+
$currentBagItem->language = $bagItem['language'];
|
| 99 |
+
$currentBagItem->orderedQty = $bagItem['orderedQty'];
|
| 100 |
+
$currentBagItem->qtyUnit = $bagItem['qtyUnit'];
|
| 101 |
+
$currentBagItem->qtyToShip = $bagItem['qtyToShip'];
|
| 102 |
+
$currentBagItem->skuRef = $bagItem['skuRef'];
|
| 103 |
+
$currentBagItem->type = $bagItem['type'];
|
| 104 |
+
$currentBagItem->family = $bagItem['family'];
|
| 105 |
+
|
| 106 |
+
$attributes = array();
|
| 107 |
+
if($bagItem['attributes'] != null) {
|
| 108 |
+
foreach($bagItem['attributes'] as $key=>$value){
|
| 109 |
+
$currentAttribute = new Attribute();
|
| 110 |
+
$currentAttribute->value = $value['value'];
|
| 111 |
+
$attributes[$key] = $currentAttribute;
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
$currentBagItem->attributes = $attributes;
|
| 116 |
+
|
| 117 |
+
if($bagItem['price'] != null){
|
| 118 |
+
$currentPrice = $bagItem['price'];
|
| 119 |
+
$price = new Price();
|
| 120 |
+
$price->base = (float) $currentPrice['base'];
|
| 121 |
+
$price->currency = $currentPrice['currency'];
|
| 122 |
+
$price->sale = $currentPrice['sale'] != null ? (float) $currentPrice['sale'] : null;
|
| 123 |
+
$price->sell = (float) $currentPrice['sell'];
|
| 124 |
+
$price->vat = (float) $currentPrice['vat'];
|
| 125 |
+
$price->vatRate = (float) $currentPrice['vatRate'];
|
| 126 |
+
$currentBagItem->price = $price;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
if(isset($bagItem['rawData'])) {
|
| 130 |
+
$currentRawData = $bagItem['rawData'];
|
| 131 |
+
$rawData = new RawData();
|
| 132 |
+
$rawData->buyRequest = $currentRawData['buyRequest'];
|
| 133 |
+
$rawData->parentSku = $currentRawData['parentSku'];
|
| 134 |
+
$currentBagItem->rawData = $rawData;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
$bagItems[$serial] = $currentBagItem;
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
$this->bagItems = $bagItems;
|
| 142 |
+
$this->coupons = $jsonBag['coupons'];
|
| 143 |
+
|
| 144 |
+
$totals = new Totals();
|
| 145 |
+
|
| 146 |
+
if($jsonBag['totals'] != null){
|
| 147 |
+
$bagTotals = $jsonBag['totals'];
|
| 148 |
+
|
| 149 |
+
$totals->currency = $bagTotals['currency'];
|
| 150 |
+
$totals->discount = $bagTotals['discount'];
|
| 151 |
+
$totals->shipping= $bagTotals['shipping'];
|
| 152 |
+
$totals->total = $bagTotals['total'];
|
| 153 |
+
$totals->vat = $bagTotals['vat'];
|
| 154 |
+
$totals->vatRate = $bagTotals['vatRate'];
|
| 155 |
+
$totals->subtotal = $bagTotals['subtotal'];
|
| 156 |
+
|
| 157 |
+
$this->totals = $totals;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
$this->paymentMethod = $jsonBag['paymentMethod'];
|
| 161 |
+
$this->shipmentMethod = $jsonBag['shipmentMethod'];
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
/**
|
| 165 |
+
* Get ICS geolocalisation from gps.
|
| 166 |
+
*
|
| 167 |
+
* @param String $gps The String containing the latitude and longitude information
|
| 168 |
+
* @return Geoloc The ICS geoloc built from latitude and longitude information
|
| 169 |
+
*/
|
| 170 |
+
private function getGeoloc($gps){
|
| 171 |
+
$geoloc = new Geoloc();
|
| 172 |
+
list($lat, $lng) = explode('::', $gps);
|
| 173 |
+
$geoloc->lat = $lat;
|
| 174 |
+
$geoloc->lng = $lng;
|
| 175 |
+
|
| 176 |
+
return $geoloc;
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
/**
|
| 180 |
+
* Get ICS referer from server information.
|
| 181 |
+
*
|
| 182 |
+
* @return Referer The ICS referer built from server information
|
| 183 |
+
*/
|
| 184 |
+
private function getReferer(){
|
| 185 |
+
$referer = new Referer();
|
| 186 |
+
$referer->name = $_SERVER['HTTP_REFERER'];
|
| 187 |
+
return $referer;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
/**
|
| 191 |
+
* Get an ICS context from the magento core session.
|
| 192 |
+
*
|
| 193 |
+
* @param Mage_Core_Model_Session $session
|
| 194 |
+
* @return Context The ICS context built from the session
|
| 195 |
+
*/
|
| 196 |
+
protected function getContext($session){
|
| 197 |
+
$context = new Context();
|
| 198 |
+
$context->device = $session->getData("_session_validator_data/http_user_agent");
|
| 199 |
+
$context->ipAddress = $_SERVER['REMOTE_ADDR'];
|
| 200 |
+
$context->referer = $this->getReferer();
|
| 201 |
+
|
| 202 |
+
if (isset($_COOKIE['gps'])) {
|
| 203 |
+
$gps = $_COOKIE["gps"];
|
| 204 |
+
if($gps != NULL){
|
| 205 |
+
$context->geoloc = $this->getGeoloc($gps);
|
| 206 |
+
}
|
| 207 |
+
}
|
| 208 |
+
return $context;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
/**
|
| 212 |
+
* Get an ICS price from a magento's product.
|
| 213 |
+
*
|
| 214 |
+
* @param Mage_Catalog_Model_Product $product The magento's product
|
| 215 |
+
* @return Price The ICS price built from a product
|
| 216 |
+
*/
|
| 217 |
+
protected function getPriceIcs($product) {
|
| 218 |
+
$price = new Price();
|
| 219 |
+
if($product->getPrice() != null) {
|
| 220 |
+
$price->base = (float) $product->getPrice();
|
| 221 |
+
} else {
|
| 222 |
+
$price->base = (float) $product->getFinalPrice();
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
// $price->sale = 0; // FIXME
|
| 226 |
+
$price->sell = (float) $product->getFinalPrice();
|
| 227 |
+
$price->vat = (float) 2.1; // FIXME
|
| 228 |
+
$price->vatRate = (float) 20; // FIXME
|
| 229 |
+
$price->currency = Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE);
|
| 230 |
+
return $price;
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
/**
|
| 234 |
+
* Gets the selections id array from bundle options
|
| 235 |
+
*
|
| 236 |
+
* @param Array $bundleOptions The array of bundle options
|
| 237 |
+
* @return Array The array of selections id built from the bundle options
|
| 238 |
+
*/
|
| 239 |
+
private function getBundleSelectionIdsFromBundleOptions($bundleOptions) {
|
| 240 |
+
$selectionIds = array();
|
| 241 |
+
foreach($bundleOptions as $selectionId) {
|
| 242 |
+
if(!is_array($selectionId)) {
|
| 243 |
+
array_push($selectionIds, $selectionId);
|
| 244 |
+
} else {
|
| 245 |
+
foreach($selectionId as $selectId) {
|
| 246 |
+
array_push($selectionIds, $selectId);
|
| 247 |
+
}
|
| 248 |
+
}
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
return $selectionIds;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
/**
|
| 255 |
+
* Get ics attributes from super attributes from buyRequest
|
| 256 |
+
*
|
| 257 |
+
* @param Array $buyRequest The buy request of an item
|
| 258 |
+
* @return Array An array of ICS attributes built from super attributes
|
| 259 |
+
*/
|
| 260 |
+
protected function getIcsAttributesFromSuperAttributes($buyRequest) {
|
| 261 |
+
$attributes = array();
|
| 262 |
+
|
| 263 |
+
if(isset($buyRequest['super_attribute'])) {
|
| 264 |
+
$superAttributes = $buyRequest['super_attribute'];
|
| 265 |
+
foreach($superAttributes as $attributeId => $valueId) {
|
| 266 |
+
$attribute = $this->getAttributeByIdOrCode($attributeId);
|
| 267 |
+
|
| 268 |
+
$bagAttribute = new Attribute();
|
| 269 |
+
$bagAttribute->value = $attribute->getSource()->getOptionText($valueId);
|
| 270 |
+
$attributes[$attribute->getData('attribute_code')] = $bagAttribute;
|
| 271 |
+
}
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
return $attributes;
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
/**
|
| 278 |
+
* Get ics bagItems from bundle options from buyRequest
|
| 279 |
+
*
|
| 280 |
+
* @param Array $buyRequest The buy request of an item
|
| 281 |
+
* @return BagItem The ICS item built from bundle options
|
| 282 |
+
*/
|
| 283 |
+
protected function getIcsItemsFromBundleOptions($buyRequest) {
|
| 284 |
+
$storeId = Mage::app()->getStore()->getId();
|
| 285 |
+
$bagItems = array();
|
| 286 |
+
|
| 287 |
+
if(isset($buyRequest['bundle_option'])) {
|
| 288 |
+
$selectionIds = $this->getBundleSelectionIdsFromBundleOptions($buyRequest['bundle_option']);
|
| 289 |
+
|
| 290 |
+
foreach($selectionIds as $selectionId) {
|
| 291 |
+
$selection = ICSResource::getSelectionById($selectionId);
|
| 292 |
+
$productId = $selection['product_id'];
|
| 293 |
+
$product = Mage::helper('catalog/product')->getProduct($productId, $storeId, 'productId');
|
| 294 |
+
|
| 295 |
+
if(!is_null($product)) {
|
| 296 |
+
$options = $product->getTypeInstance(true)->getOrderOptions($product);
|
| 297 |
+
$bagItems[$product->getSku()] = $this->getIcsItemFromProduct($product, $options['info_buyRequest'], $selection['selection_qty']);
|
| 298 |
+
}
|
| 299 |
+
}
|
| 300 |
+
}
|
| 301 |
+
|
| 302 |
+
return $bagItems;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
/**
|
| 306 |
+
* Get ics bagItems from super group from buyRequest
|
| 307 |
+
*
|
| 308 |
+
* @param Array $buyRequest The buy request of an item
|
| 309 |
+
* @return BagItem The ICS item built from super group
|
| 310 |
+
*/
|
| 311 |
+
protected function getIcsItemsFromSuperGroup($buyRequest) {
|
| 312 |
+
$storeId = Mage::app()->getStore()->getId();
|
| 313 |
+
$bagItems = array();
|
| 314 |
+
|
| 315 |
+
if(isset($buyRequest['super_group'])) {
|
| 316 |
+
$superGroup = $buyRequest['super_group'];
|
| 317 |
+
|
| 318 |
+
foreach($superGroup as $productId => $qty) {
|
| 319 |
+
$product = Mage::helper('catalog/product')->getProduct($productId, $storeId, 'productId');
|
| 320 |
+
|
| 321 |
+
if($product != null) {
|
| 322 |
+
$options = $product->getTypeInstance(true)->getOrderOptions($product);
|
| 323 |
+
$bagItems[$product->getSku()] = $this->getIcsItemFromProduct($product, $options['info_buyRequest'], $qty);
|
| 324 |
+
}
|
| 325 |
+
}
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
return $bagItems;
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
/**
|
| 332 |
+
* Turn a Quote item into an ICS item
|
| 333 |
+
*
|
| 334 |
+
* @param Mage_Wishlist_Model_Item $item The magento's item
|
| 335 |
+
* @return BagItem The ICS item built from magento's one
|
| 336 |
+
*/
|
| 337 |
+
private function getIcsItemFromQuoteItem($item) {
|
| 338 |
+
$product = $item->getProduct();
|
| 339 |
+
$options = $product->getTypeInstance(true)->getOrderOptions($product);
|
| 340 |
+
$buyRequest = $options['info_buyRequest'];
|
| 341 |
+
|
| 342 |
+
$bagItem = $this->getIcsItemFromProduct($product, $buyRequest, $item->getData('qty'));
|
| 343 |
+
|
| 344 |
+
if(isset($buyRequest['options']) || isset($buyRequest['bundle_option']) || isset($buyRequest['links'])) {
|
| 345 |
+
$bagItem->rawData->buyRequest = $buyRequest;
|
| 346 |
+
$bagItem->innerItems = $this->getIcsItemsFromBundleOptions($buyRequest);
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
return $bagItem;
|
| 350 |
+
}
|
| 351 |
+
|
| 352 |
+
/**
|
| 353 |
+
* Get an ICS item from a magento's product
|
| 354 |
+
*
|
| 355 |
+
* @param Mage_Catalog_Model_Product $product The magento's product
|
| 356 |
+
* @param $buyRequest Array The buy request of the item represented by the given product
|
| 357 |
+
* @param Integer $qty The quantity of the product (default: 1)
|
| 358 |
+
* @return BagItem The ICS item built from magento's product
|
| 359 |
+
*/
|
| 360 |
+
protected function getIcsItemFromProduct($product, $buyRequest, $qty = 1) {
|
| 361 |
+
$bagItem = new BagItem();
|
| 362 |
+
$qty = round($qty, 2);
|
| 363 |
+
|
| 364 |
+
$bagItem = $this->setSkuInICSItemFromProduct($bagItem, $product);
|
| 365 |
+
$bagItem->orderedQty = $qty;
|
| 366 |
+
$bagItem->qtyUnit = "piece";
|
| 367 |
+
$bagItem->label = $product->getName();
|
| 368 |
+
$bagItem->language = Mage::getBlockSingleton('page/html')->getLang();
|
| 369 |
+
$bagItem->type = $product->getTypeId();
|
| 370 |
+
$bagItem->family = Mage::getModel("eav/entity_attribute_set")->load($product->getAttributeSetId())->getAttributeSetName();
|
| 371 |
+
$bagItem->imgUrl = Mage::getModel('catalog/product_media_config')->getMediaUrl($product->getSmallImage());
|
| 372 |
+
$bagItem->attributes = $this->getIcsAttributesFromSuperAttributes($buyRequest);
|
| 373 |
+
$bagItem->price = $this->getPriceIcs($product);
|
| 374 |
+
|
| 375 |
+
return $bagItem;
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
/**
|
| 379 |
+
* Set the sku and the parent sku if needed in an ICS item from a magento product.
|
| 380 |
+
*
|
| 381 |
+
* @param BagItem $bagItem The ICS item to set sku and parent sku
|
| 382 |
+
* @param Mage_Catalog_Model_Product $product The magento product.
|
| 383 |
+
* @return BagItem The modified item
|
| 384 |
+
*/
|
| 385 |
+
protected function setSkuInICSItemFromProduct($bagItem, $product) {
|
| 386 |
+
$parentSku = $product->getData('sku');
|
| 387 |
+
$sku = $product->getSku();
|
| 388 |
+
|
| 389 |
+
if($parentSku != $sku && $product->getTypeId() != Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
|
| 390 |
+
$bagItem->skuRef = $sku;
|
| 391 |
+
$bagItem->rawData->parentSku = $parentSku;
|
| 392 |
+
} else {
|
| 393 |
+
/* We took the parent sku to avoid dynamic sku (which are stored in the getSku() method of product model) */
|
| 394 |
+
$bagItem->skuRef = $parentSku;
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
return $bagItem;
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
/**
|
| 401 |
+
* Check if all super attributes from buy request are set.
|
| 402 |
+
*
|
| 403 |
+
* @param Array $buyRequest the buyRequest of an item
|
| 404 |
+
* @return Boolean false if all super attributes have a value, true otherwise.
|
| 405 |
+
*/
|
| 406 |
+
protected function isAllAttributesSet($buyRequest) {
|
| 407 |
+
if(isset($buyRequest['super_attribute'])) {
|
| 408 |
+
foreach($buyRequest['super_attribute'] as $valueId) {
|
| 409 |
+
if(!isset($valueId) || empty($valueId)) {
|
| 410 |
+
return false;
|
| 411 |
+
}
|
| 412 |
+
}
|
| 413 |
+
}
|
| 414 |
+
return true;
|
| 415 |
+
}
|
| 416 |
+
|
| 417 |
+
/**
|
| 418 |
+
* Create an light ICS customer from a Magento Customer
|
| 419 |
+
*
|
| 420 |
+
* @param Mage_Customer_Model_Customer $customer The customer from Magento
|
| 421 |
+
* @return Customer A light ICS customer built from the magento's one
|
| 422 |
+
*/
|
| 423 |
+
protected function createBagCustomer($customer){
|
| 424 |
+
$res = new Customer();
|
| 425 |
+
$res->appCustomerId = $customer->getId();
|
| 426 |
+
$res->email = $customer->getEmail();
|
| 427 |
+
$res->twitterId = Mage::helper('connectedstore/ICSTwitterHelper')->getTwitterId($customer);
|
| 428 |
+
return $res;
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
/**
|
| 432 |
+
*
|
| 433 |
+
* Get guest customer information from quote.
|
| 434 |
+
*
|
| 435 |
+
* @param Mage_Sales_Model_Quote $quote The quote
|
| 436 |
+
* @return Customer The customer in guest mode
|
| 437 |
+
*/
|
| 438 |
+
protected function getGuestFromQuote($quote) {
|
| 439 |
+
$res = new Customer();
|
| 440 |
+
$res->appCustomerId = $quote->getData('customer_id');
|
| 441 |
+
$res->firstName = $quote->getData('customer_firstname');
|
| 442 |
+
$res->lastName = $quote->getData('customer_lastname');
|
| 443 |
+
$res->email = $quote->getData('customer_email');
|
| 444 |
+
|
| 445 |
+
$addresses = $quote->getAllAddresses();
|
| 446 |
+
// We get the billing address
|
| 447 |
+
$billingAddress = NULL;
|
| 448 |
+
if($addresses != NULL && count($addresses) == 1) {
|
| 449 |
+
$billingAddress = $addresses[0];
|
| 450 |
+
} else if($addresses != NULL && count($addresses) > 0) {
|
| 451 |
+
for($i=0; $i<count($addresses); $i++) {
|
| 452 |
+
$address = $addresses[$i];
|
| 453 |
+
if($address != null && $address->getData('address_type') != null && $address->getData('address_type') === Mage_Sales_Model_Quote_Address::TYPE_BILLING) {
|
| 454 |
+
$billingAddress = $addresses[$i];
|
| 455 |
+
break;
|
| 456 |
+
}
|
| 457 |
+
}
|
| 458 |
+
}
|
| 459 |
+
|
| 460 |
+
if($billingAddress != NULL) {
|
| 461 |
+
$res->city = $billingAddress->getCity();
|
| 462 |
+
$res->country = $billingAddress->getCountryId();
|
| 463 |
+
$res->zipCode = $billingAddress->getPostcode();
|
| 464 |
+
$res->address = $billingAddress->getData("street");
|
| 465 |
+
}
|
| 466 |
+
|
| 467 |
+
return $res;
|
| 468 |
+
}
|
| 469 |
+
|
| 470 |
+
/**
|
| 471 |
+
* Generate a key for a configurable product
|
| 472 |
+
* The key is generated as followed: sku-attribute1-attribute2-...
|
| 473 |
+
*
|
| 474 |
+
* @param BagItem $bagItem An ICS item
|
| 475 |
+
* @return String A generated key from the attributes of the item
|
| 476 |
+
*/
|
| 477 |
+
protected function generateBagItemKeyFromAttributes($bagItem) {
|
| 478 |
+
$sku = $bagItem->skuRef;
|
| 479 |
+
$attributes = $bagItem->attributes;
|
| 480 |
+
|
| 481 |
+
$key = $sku;
|
| 482 |
+
if(isset($attributes)) {
|
| 483 |
+
foreach($attributes as $value) {
|
| 484 |
+
$attributeValue = $value->value;
|
| 485 |
+
if(isset($attributeValue) && !empty($attributeValue)) {
|
| 486 |
+
$key .= '-' . $value->value;
|
| 487 |
+
}
|
| 488 |
+
}
|
| 489 |
+
}
|
| 490 |
+
return str_replace('.', self::DOT_REPLACE, $key);
|
| 491 |
+
}
|
| 492 |
+
|
| 493 |
+
/**
|
| 494 |
+
* Generates a key with a bagItem inner items.
|
| 495 |
+
*
|
| 496 |
+
* @param BagItem $bagItem The item which key needs to be generated
|
| 497 |
+
* @return String The generated key
|
| 498 |
+
*/
|
| 499 |
+
protected function generateBagItemKeyFromChildren($bagItem){
|
| 500 |
+
$str = $bagItem->skuRef;
|
| 501 |
+
if(!is_null($bagItem->innerItems)){
|
| 502 |
+
foreach($bagItem->innerItems as $children){
|
| 503 |
+
$qty = round($children->orderedQty, 2);
|
| 504 |
+
$str .= '-' . $qty . '-' . $children->skuRef;
|
| 505 |
+
}
|
| 506 |
+
}
|
| 507 |
+
return str_replace('.', self::DOT_REPLACE, $str);
|
| 508 |
+
}
|
| 509 |
+
|
| 510 |
+
/**
|
| 511 |
+
* Create a cart or an order from a quote
|
| 512 |
+
*
|
| 513 |
+
* @param Mage_Sales_Model_Quote $quote The quote
|
| 514 |
+
*/
|
| 515 |
+
protected function constructCartOrOrderFromQuote($quote) {
|
| 516 |
+
$session = Mage::getSingleton('core/session');
|
| 517 |
+
|
| 518 |
+
// We get the customer
|
| 519 |
+
$customerSession = Mage::getSingleton('customer/session')->getCustomer();
|
| 520 |
+
$customer = $this->createBagCustomer($customerSession);
|
| 521 |
+
if($customer != null && $customer->email != null){
|
| 522 |
+
$this->customer = $customer;
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
//set origin
|
| 526 |
+
if(Mage::app()->getRequest()->getModuleName() == 'wishlist' && Mage::app()->getRequest()->getActionName() == 'cart'){
|
| 527 |
+
$this->refBagOrigin = Wishlist::getIcsWishlistIdInSession();
|
| 528 |
+
}
|
| 529 |
+
|
| 530 |
+
$context = $this->getContext($session);
|
| 531 |
+
$this->context = $context;
|
| 532 |
+
|
| 533 |
+
// We get the bagId in session
|
| 534 |
+
$cartId = $session->getData(Cart::$ICS_CartId);
|
| 535 |
+
if($cartId != NULL) {
|
| 536 |
+
$this->bagId = $cartId;
|
| 537 |
+
}
|
| 538 |
+
|
| 539 |
+
$this->bagItems = array();
|
| 540 |
+
foreach ($quote->getAllVisibleItems() as $item) {
|
| 541 |
+
$icsItem = $this->getIcsItemFromQuoteItem($item);
|
| 542 |
+
if($icsItem->type === 'bundle') {
|
| 543 |
+
$key = $this->generateBagItemKeyFromChildren($icsItem);
|
| 544 |
+
} else {
|
| 545 |
+
$key = str_replace('.', self::DOT_REPLACE, $item->getProduct()->getSku());
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
if(isset($this->bagItems[$key])) {
|
| 549 |
+
$bagItem = $this->bagItems[$key];
|
| 550 |
+
$bagItem->orderedQty += $icsItem->orderedQty;
|
| 551 |
+
$bagItem->qtyToShip += $icsItem->qtyToShip;
|
| 552 |
+
$bagItem->qtyToBill += $icsItem->qtyToBill;
|
| 553 |
+
$this->bagItems[$key] = $bagItem;
|
| 554 |
+
} else {
|
| 555 |
+
$this->bagItems[$key] = $icsItem;
|
| 556 |
+
}
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
+
if(strlen($quote->getData('coupon_code'))) {
|
| 560 |
+
$this->coupons = array($quote->getData('coupon_code') => 1);
|
| 561 |
+
} else {
|
| 562 |
+
$this->coupons = null;
|
| 563 |
+
}
|
| 564 |
+
}
|
| 565 |
+
|
| 566 |
+
/**
|
| 567 |
+
* Build an array of magento useful attributes to add a product into a cart/wishlist
|
| 568 |
+
*
|
| 569 |
+
* @param BagItem $bagItem The ICS item
|
| 570 |
+
* @return array An array containing all attributes to add a product into a cart/wishlist
|
| 571 |
+
*/
|
| 572 |
+
public function getProductDataFromBagItem($bagItem) {
|
| 573 |
+
$productData = array();
|
| 574 |
+
|
| 575 |
+
$rawData = $bagItem->rawData;
|
| 576 |
+
if(isset($rawData) && isset($rawData->buyRequest)) {
|
| 577 |
+
$productData = $rawData->buyRequest;
|
| 578 |
+
$productData['product_id'] = $productData['product'];
|
| 579 |
+
} else {
|
| 580 |
+
$productModel = Mage::getModel('catalog/product');
|
| 581 |
+
$productId = $productModel->getIdBySku($bagItem->skuRef);
|
| 582 |
+
|
| 583 |
+
if(isset($bagItem->attributes) && count($bagItem->attributes) > 0) {
|
| 584 |
+
$product = $productModel->load($productId);
|
| 585 |
+
$superAttributes = array();
|
| 586 |
+
foreach($bagItem->attributes as $key=>$value) {
|
| 587 |
+
$superAttributes[$this->getAttributeIdByCode($key)] = $product->getData($key);
|
| 588 |
+
}
|
| 589 |
+
$productData['super_attribute'] = $superAttributes;
|
| 590 |
+
}
|
| 591 |
+
|
| 592 |
+
$productData['sku'] = isset($rawData->parentSku) ? $rawData->parentSku : $bagItem->skuRef;
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
$productData['qty'] = $bagItem->orderedQty;
|
| 596 |
+
|
| 597 |
+
return $productData;
|
| 598 |
+
}
|
| 599 |
+
|
| 600 |
+
/**
|
| 601 |
+
* Get an attribute code by its id
|
| 602 |
+
*
|
| 603 |
+
* @param Integer $attributeId The attribute id
|
| 604 |
+
* @return String The attribute code matching the given id
|
| 605 |
+
*/
|
| 606 |
+
public function getAttributeCodeById($attributeId) {
|
| 607 |
+
return $this->getAttributeByIdOrCode($attributeId)->getData('attribute_code');
|
| 608 |
+
}
|
| 609 |
+
|
| 610 |
+
/**
|
| 611 |
+
* Get an attribute id by its code
|
| 612 |
+
*
|
| 613 |
+
* @param String $attributeCode The attribute code
|
| 614 |
+
* @return Integer The attribute id matching the given code
|
| 615 |
+
*/
|
| 616 |
+
public function getAttributeIdByCode($attributeCode) {
|
| 617 |
+
return $this->getAttributeByIdOrCode($attributeCode)->getData('attribute_id');
|
| 618 |
+
}
|
| 619 |
+
|
| 620 |
+
/**
|
| 621 |
+
* Get an attribute by its code or id.
|
| 622 |
+
* The entity type of the attribute is fixed to catalog_product
|
| 623 |
+
*
|
| 624 |
+
* @param Integer|String The code or the id of the attribute to retrieve
|
| 625 |
+
* @return Mage_Eav_Model_Entity_Attribute_Abstract The attribute matching the given id/code
|
| 626 |
+
*/
|
| 627 |
+
public function getAttributeByIdOrCode($identifier) {
|
| 628 |
+
$model = Mage::getModel('eav/config');
|
| 629 |
+
$entityType = $model->getEntityType(Mage_Catalog_Model_Product::ENTITY);
|
| 630 |
+
return $model->getAttribute($entityType, $identifier);
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
/**
|
| 634 |
+
* Check some fields and gives them always the same value if they are null or empty.
|
| 635 |
+
* The goal is to avoid a field is empty at a moment and null at another moment.
|
| 636 |
+
*
|
| 637 |
+
* This method does NOT check mandatory fields.
|
| 638 |
+
*/
|
| 639 |
+
public function checkFields() {
|
| 640 |
+
// bag items
|
| 641 |
+
if(!is_null($this->bagItems)) {
|
| 642 |
+
foreach($this->bagItems as $key=>$bagItem) {
|
| 643 |
+
$bagItem->checkFields();
|
| 644 |
+
$this->bagItems[$key] = splitNullValuesInObject($bagItem);
|
| 645 |
+
}
|
| 646 |
+
}
|
| 647 |
+
|
| 648 |
+
// totals
|
| 649 |
+
if($this->totals != null) {
|
| 650 |
+
$this->totals = splitNullValuesInObject($this->totals);
|
| 651 |
+
}
|
| 652 |
+
|
| 653 |
+
// context
|
| 654 |
+
if($this->context != null) {
|
| 655 |
+
$this->context->checkFields();
|
| 656 |
+
$this->context = splitNullValuesInObject($this->context);
|
| 657 |
+
}
|
| 658 |
+
|
| 659 |
+
// customer
|
| 660 |
+
if($this->customer != null) {
|
| 661 |
+
$this->customer->checkFields();
|
| 662 |
+
$this->customer = splitNullValuesInObject($this->customer);
|
| 663 |
+
}
|
| 664 |
+
}
|
| 665 |
+
}
|
| 666 |
+
|
| 667 |
+
class Message {
|
| 668 |
+
public $context = null;
|
| 669 |
+
public $customer = null;
|
| 670 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Cart.php
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Cart extends Bag {
|
| 4 |
+
|
| 5 |
+
protected static $ICS_CartId = 'ICS_CartId';
|
| 6 |
+
protected static $ICS_CartChecksum = 'ICS_CartChecksum';
|
| 7 |
+
protected static $ICS_CartLastUpdate = 'ICS_CartLastUpdate';
|
| 8 |
+
/** Name of the ICS type for cart */
|
| 9 |
+
const ICS_TYPE = 'CART';
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* Default constructor.
|
| 14 |
+
*/
|
| 15 |
+
public function __construct() {
|
| 16 |
+
$this->checkFields();
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
/**
|
| 20 |
+
* A static function which instanciates a Cart and feeds it with quote information.
|
| 21 |
+
*
|
| 22 |
+
* @param Mage_Sales_Model_Quote $quote The cart's quote
|
| 23 |
+
* @return Cart A new cart built from the quote
|
| 24 |
+
*/
|
| 25 |
+
public static function createCart($quote) {
|
| 26 |
+
$cart = new Cart();
|
| 27 |
+
$cart->bagType = self::ICS_TYPE;
|
| 28 |
+
$cart->constructCartOrOrderFromQuote($quote);
|
| 29 |
+
$cart->setTotalsForCart($quote);
|
| 30 |
+
$cart->checkFields();
|
| 31 |
+
return $cart;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/**
|
| 35 |
+
* Create a Cart from the given json object.
|
| 36 |
+
*
|
| 37 |
+
* @param Object $jsonObject The json stream that represents a cart
|
| 38 |
+
* @return Cart A cart built from the json stream
|
| 39 |
+
*/
|
| 40 |
+
public static function createCartFromJsonObject($jsonObject) {
|
| 41 |
+
$cart = new Cart();
|
| 42 |
+
|
| 43 |
+
if(empty($jsonObject)) {
|
| 44 |
+
return $cart;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
$cart->createBagFromJsonObject($jsonObject);
|
| 48 |
+
$cart->checkFields();
|
| 49 |
+
return $cart;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
/**
|
| 53 |
+
* Set the cart's checksum given in parameter in session.
|
| 54 |
+
*
|
| 55 |
+
* @param String $checksum The cart checksum
|
| 56 |
+
*/
|
| 57 |
+
public static function setCartChecksumInSession($checksum){
|
| 58 |
+
Mage::getSingleton('core/session')->setData(self::$ICS_CartChecksum, $checksum);
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
/**
|
| 62 |
+
* Get the current cart's checksum in session.
|
| 63 |
+
*
|
| 64 |
+
* @return String The cart checksum
|
| 65 |
+
*/
|
| 66 |
+
public static function getCartChecksumInSession(){
|
| 67 |
+
return Mage::getSingleton('core/session')->getData(self::$ICS_CartChecksum);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
/**
|
| 71 |
+
* Set the Cart id given in parameter in session.
|
| 72 |
+
*
|
| 73 |
+
* @param Integer $cartId The current cartId
|
| 74 |
+
*/
|
| 75 |
+
public static function setIcsCartIdInSession($cartId){
|
| 76 |
+
Mage::getSingleton('core/session')->setData(self::$ICS_CartId, $cartId);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
/**
|
| 80 |
+
* Get the current cart id from the session.
|
| 81 |
+
*
|
| 82 |
+
* @return Integer the current cart id
|
| 83 |
+
*/
|
| 84 |
+
public static function getIcsCartIdInSession(){
|
| 85 |
+
return Mage::getSingleton('core/session')->getData(self::$ICS_CartId);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
/**
|
| 89 |
+
* Set the Cart's date of last update given in parameter in session.
|
| 90 |
+
*
|
| 91 |
+
* @param String $date The date to set in the session
|
| 92 |
+
*/
|
| 93 |
+
public static function setCartLastUpdateInSession($date){
|
| 94 |
+
Mage::getSingleton('core/session')->setData(self::$ICS_CartLastUpdate, $date);
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
/**
|
| 98 |
+
* Get the cart's date of last update from session.
|
| 99 |
+
*
|
| 100 |
+
* @return String Cart's date of last update in session
|
| 101 |
+
*/
|
| 102 |
+
public static function getCartLastUpdateInSession(){
|
| 103 |
+
return Mage::getSingleton('core/session')->getData(self::$ICS_CartLastUpdate);
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
/**
|
| 107 |
+
* Set the several information in session:
|
| 108 |
+
* -> The given cartId
|
| 109 |
+
* -> The given checksum
|
| 110 |
+
* -> The given lastUpdate
|
| 111 |
+
*
|
| 112 |
+
* @param Integer $cartId The current cartId
|
| 113 |
+
* @param String $checksum The cart checksum
|
| 114 |
+
* @param String $lastUpdate The cart last update
|
| 115 |
+
*/
|
| 116 |
+
public static function setIcsInfoInSession($cartId, $checksum, $lastUpdate) {
|
| 117 |
+
self::setIcsCartIdInSession($cartId);
|
| 118 |
+
self::setCartChecksumInSession($checksum);
|
| 119 |
+
self::setCartLastUpdateInSession($lastUpdate);
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
/**
|
| 123 |
+
* Flush all cart information in session
|
| 124 |
+
*/
|
| 125 |
+
public static function resetIcsInfoInSession() {
|
| 126 |
+
self::setIcsCartIdInSession(null);
|
| 127 |
+
self::setCartChecksumInSession(null);
|
| 128 |
+
self::setCartLastUpdateInSession(null);
|
| 129 |
+
Mage::helper('connectedstore/ICSHelper')->setIcsFlagError(false);
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
/**
|
| 133 |
+
* Flush the quote of the given customer.
|
| 134 |
+
*
|
| 135 |
+
* @param Mage_Customer_Model_Customer $customer The customer
|
| 136 |
+
*/
|
| 137 |
+
public static function flushCustomerQuote($customer){
|
| 138 |
+
if(empty($customer)) {
|
| 139 |
+
return;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
$quote = Mage::getModel('sales/quote')->loadByCustomer($customer);
|
| 143 |
+
$quote = self::removeAllItems($quote);
|
| 144 |
+
$quote->collectTotals()->save();
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
/**
|
| 148 |
+
* Import the current cart in the quote of the given customer.
|
| 149 |
+
*
|
| 150 |
+
* @param Mage_Customer_Model_Customer $customer The current customer
|
| 151 |
+
*/
|
| 152 |
+
public function importIntoMagento($customer) {
|
| 153 |
+
$storeId = Mage::app()->getStore()->getId();
|
| 154 |
+
if(empty($this->bagId) || empty($storeId)) {
|
| 155 |
+
return;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
self::flushCustomerQuote($customer);
|
| 159 |
+
$quoteId = Mage::getModel('sales/quote')->loadByCustomer($customer)->getId();
|
| 160 |
+
|
| 161 |
+
if(!empty($this->bagItems)) {
|
| 162 |
+
$api = new Mage_Checkout_Model_Cart_Product_Api();
|
| 163 |
+
$productsData = array();
|
| 164 |
+
foreach($this->bagItems as $bagItem) {
|
| 165 |
+
$productData = $this->getProductDataFromBagItem($bagItem);
|
| 166 |
+
$productId = empty($productData['product_id'])
|
| 167 |
+
? Mage::getModel('catalog/product')->getIdBySku($productData['sku'])
|
| 168 |
+
: $productData['product_id'];
|
| 169 |
+
$productToTest = Mage::getModel('catalog/product')->loadByAttribute('entity_id', $productId);
|
| 170 |
+
$productData['product_id'] = $productId;
|
| 171 |
+
if(!empty($productToTest)) {
|
| 172 |
+
array_push($productsData, $productData);
|
| 173 |
+
}
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
if(!(empty($productsData))) {
|
| 177 |
+
try {
|
| 178 |
+
$api->add($quoteId, $productsData, $storeId);
|
| 179 |
+
} catch (Exception $e) {
|
| 180 |
+
ICSLogger::error('At least one product does not exist in database for bag : ' . $this->bagId);
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
if(!empty($this->coupons) && is_array($this->coupons)){
|
| 186 |
+
$apiCoupon = new Mage_Checkout_Model_Cart_Coupon_Api();
|
| 187 |
+
$keys = array_keys($this->coupons);
|
| 188 |
+
$apiCoupon->add($quoteId, $keys[0], $storeId);
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
/**
|
| 193 |
+
* Set the cart's totals
|
| 194 |
+
*
|
| 195 |
+
* @param Mage_Sales_Model_Quote $quote The cart's quote
|
| 196 |
+
*/
|
| 197 |
+
private function setTotalsForCart($quote) {
|
| 198 |
+
$totals = new Totals();
|
| 199 |
+
|
| 200 |
+
$cartTotals = $quote->getTotals();
|
| 201 |
+
|
| 202 |
+
$totals->subtotal = $cartTotals["subtotal"]->getValue();
|
| 203 |
+
$totals->total = $cartTotals["grand_total"]->getValue();
|
| 204 |
+
|
| 205 |
+
if(isset($cartTotals['discount']) && $cartTotals['discount']->getValue()) {
|
| 206 |
+
$totals->discount = $cartTotals['discount']->getValue();
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
if(isset($cartTotals['tax']) && $cartTotals['tax']->getValue()) {
|
| 210 |
+
$totals->vat = $cartTotals['tax']->getValue();
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
$totals->currency = Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE);
|
| 214 |
+
|
| 215 |
+
$this->totals = $totals;
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
/**
|
| 219 |
+
* Removes all the items of a quote given in parameter
|
| 220 |
+
*
|
| 221 |
+
* @param Quote $quote A quote to flush
|
| 222 |
+
*/
|
| 223 |
+
private static function removeAllItems($quote) {
|
| 224 |
+
foreach ($quote->getItemsCollection() as $itemId => $item) {
|
| 225 |
+
if (is_null($item->getId())) {
|
| 226 |
+
$quote->getItemsCollection()->removeItemByKey($itemId);
|
| 227 |
+
} else {
|
| 228 |
+
$item->isDeleted(true);
|
| 229 |
+
}
|
| 230 |
+
}
|
| 231 |
+
return $quote;
|
| 232 |
+
}
|
| 233 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Customer.php
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Customer {
|
| 4 |
+
protected static $ICS_CustomerChecksum = 'ICS_CustomerChecksum';
|
| 5 |
+
|
| 6 |
+
public $appCustomerId = NULL;
|
| 7 |
+
public $email = NULL;
|
| 8 |
+
public $firstName = NULL;
|
| 9 |
+
public $lastName = NULL;
|
| 10 |
+
public $address = NULL;
|
| 11 |
+
public $zipCode = NULL;
|
| 12 |
+
public $city = NULL;
|
| 13 |
+
public $country = NULL;
|
| 14 |
+
public $loyaltyCards = array();
|
| 15 |
+
public $rawData = NULL;
|
| 16 |
+
public $twitterId = NULL;
|
| 17 |
+
|
| 18 |
+
/**
|
| 19 |
+
* Check some fields and gives them always the same value if they are null or empty.
|
| 20 |
+
* The goal is to avoid a field is empty at a moment and null at another moment.
|
| 21 |
+
*
|
| 22 |
+
* This method does NOT check mandatory fields.
|
| 23 |
+
*/
|
| 24 |
+
public function checkFields() {
|
| 25 |
+
// loyalty cards
|
| 26 |
+
if(!is_null($this->loyaltyCards)) {
|
| 27 |
+
foreach($this->loyaltyCards as $key=>$loyaltyCard) {
|
| 28 |
+
$loyaltyCard->checkFields();
|
| 29 |
+
$this->loyaltyCards[$key] = splitNullValuesInObject($loyaltyCard);
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
// rawData
|
| 34 |
+
if($this->rawData != null) {
|
| 35 |
+
$this->rawData = splitNullValuesInObject($this->rawData);
|
| 36 |
+
}
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* Create an ICS customer from a Magento Customer
|
| 41 |
+
*
|
| 42 |
+
* @param Mage_Customer_Model_Customer $customer The customer from Magento
|
| 43 |
+
* @return Customer An ICS customer built from the magento's one
|
| 44 |
+
*/
|
| 45 |
+
public static function createIcsCustomer($customer){
|
| 46 |
+
$addresses = $customer->getAddressesCollection()->getItems();
|
| 47 |
+
|
| 48 |
+
$res = new Customer();
|
| 49 |
+
$res->appCustomerId = $customer->getId();
|
| 50 |
+
$res->firstName = $customer->getFirstname();
|
| 51 |
+
$res->lastName = $customer->getLastname();
|
| 52 |
+
$res->email = $customer->getEmail();
|
| 53 |
+
$res->twitterId = Mage::helper('connectedstore/ICSTwitterHelper')->getTwitterId($customer);
|
| 54 |
+
|
| 55 |
+
// Array indexes are the addresses' ids
|
| 56 |
+
$keys = array_keys($addresses);
|
| 57 |
+
|
| 58 |
+
$billingAddress = NULL;
|
| 59 |
+
if($addresses != NULL && count($addresses) == 1){
|
| 60 |
+
$billingAddress = $addresses[$keys[0]];
|
| 61 |
+
}else if($addresses != NULL && count($addresses) > 0){
|
| 62 |
+
for($i=0; $i<count($addresses); $i++) {
|
| 63 |
+
$address = $addresses[$keys[$i]];
|
| 64 |
+
if($address->getId() != NULL && $customer->getDefaultBilling() === $address->getId()) {
|
| 65 |
+
$billingAddress = $addresses[$keys[$i]];
|
| 66 |
+
break;
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
if($billingAddress != NULL) {
|
| 72 |
+
$res->city = $billingAddress->getCity();
|
| 73 |
+
$res->country = $billingAddress->getCountryId();
|
| 74 |
+
$res->zipCode = $billingAddress->getPostcode();
|
| 75 |
+
$res->address = $billingAddress->getData("street");
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
return $res;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
/**
|
| 82 |
+
* Generate a checksum for this
|
| 83 |
+
*/
|
| 84 |
+
public function getCheckSum() {
|
| 85 |
+
$data = array();
|
| 86 |
+
|
| 87 |
+
$data['appCustomerId'] = $this->appCustomerId;
|
| 88 |
+
$data['email'] = $this->email;
|
| 89 |
+
$data['firstName'] = $this->firstName;
|
| 90 |
+
$data['lastName'] = $this->lastName;
|
| 91 |
+
$data['address'] = $this->address;
|
| 92 |
+
$data['zipCode'] = $this->zipCode;
|
| 93 |
+
$data['city'] = $this->city;
|
| 94 |
+
$data['country'] = $this->country;
|
| 95 |
+
// TODO : g�rer les cartes de fid
|
| 96 |
+
//$data['loyaltyCards'] = $this->bagType;
|
| 97 |
+
$data['rawData'] = $this->rawData;
|
| 98 |
+
$data['twitterId'] = $this->twitterId;
|
| 99 |
+
|
| 100 |
+
$checksum = hexdec(md5(json_encode($data)));
|
| 101 |
+
return $checksum;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
/**
|
| 106 |
+
* Set the checksum of the customer given in parameter in session.
|
| 107 |
+
*
|
| 108 |
+
* @param String $checksum The cart checksum
|
| 109 |
+
*/
|
| 110 |
+
public static function setCustomerChecksumInSession($checksum){
|
| 111 |
+
Mage::getSingleton('core/session')->setData(self::$ICS_CustomerChecksum, $checksum);
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
/**
|
| 115 |
+
* Get the current checksum of the customer in session.
|
| 116 |
+
*
|
| 117 |
+
* @return String The cart checksum
|
| 118 |
+
*/
|
| 119 |
+
public static function getCustomerChecksumInSession(){
|
| 120 |
+
return Mage::getSingleton('core/session')->getData(self::$ICS_CustomerChecksum);
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
/**
|
| 124 |
+
* Reset the checksum of the customer in session
|
| 125 |
+
*/
|
| 126 |
+
public static function resetCustomerChecksumInSession() {
|
| 127 |
+
self::setCustomerChecksumInSession(null);
|
| 128 |
+
}
|
| 129 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Entities.php
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
include 'Customer.php';
|
| 4 |
+
|
| 5 |
+
function filterCallback($var) {
|
| 6 |
+
if(is_object($var)) {
|
| 7 |
+
$tmp = get_object_vars($var);
|
| 8 |
+
return count($tmp) > 0;
|
| 9 |
+
}
|
| 10 |
+
return $var === 0 || !empty($var);
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Delete all null values in an object
|
| 15 |
+
*
|
| 16 |
+
* @param $object
|
| 17 |
+
*/
|
| 18 |
+
function splitNullValuesInObject($object) {
|
| 19 |
+
return (object) array_filter((array) $object, 'filterCallback');
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
class Geoloc {
|
| 23 |
+
public $lat = NULL;
|
| 24 |
+
public $lng = NULL;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
class Referer {
|
| 28 |
+
public $type = NULL;
|
| 29 |
+
public $name = NULL;
|
| 30 |
+
public $campaign = NULL;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
class Context {
|
| 34 |
+
public $device = NULL;
|
| 35 |
+
public $geoloc = NULL;
|
| 36 |
+
public $refSalesAssociate = NULL;
|
| 37 |
+
public $refShop = NULL;
|
| 38 |
+
public $referer = NULL;
|
| 39 |
+
public $ipAddress = NULL;
|
| 40 |
+
public $checkIn = NULL; // Boolean
|
| 41 |
+
|
| 42 |
+
/**
|
| 43 |
+
* Check some fields and gives them always the same value if they are null or empty.
|
| 44 |
+
* The goal is to avoid a field is empty at a moment and null at another moment.
|
| 45 |
+
*
|
| 46 |
+
* This method does NOT check mandatory fields.
|
| 47 |
+
*/
|
| 48 |
+
public function checkFields() {
|
| 49 |
+
// referer
|
| 50 |
+
if($this->referer != null) {
|
| 51 |
+
$this->referer = splitNullValuesInObject($this->referer);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// geoloc
|
| 55 |
+
if($this->geoloc != null) {
|
| 56 |
+
$this->geoloc = splitNullValuesInObject($this->geoloc);
|
| 57 |
+
}
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
class LoyaltyCard {
|
| 62 |
+
public $refBrand = NULL;
|
| 63 |
+
public $number = NULL;
|
| 64 |
+
public $rawData = NULL;
|
| 65 |
+
|
| 66 |
+
/**
|
| 67 |
+
* Check some fields and gives them always the same value if they are null or empty.
|
| 68 |
+
* The goal is to avoid a field is empty at a moment and null at another moment.
|
| 69 |
+
*
|
| 70 |
+
* This method does NOT check mandatory fields.
|
| 71 |
+
*/
|
| 72 |
+
public function checkFields() {
|
| 73 |
+
// rawData
|
| 74 |
+
if($this->rawData != null) {
|
| 75 |
+
$this->rawData = splitNullValuesInObject($this->rawData);
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
class Attribute {
|
| 81 |
+
public $value = NULL;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
class Price {
|
| 85 |
+
public $base = NULL;
|
| 86 |
+
public $sale = NULL;
|
| 87 |
+
public $sell = NULL;
|
| 88 |
+
public $vat = NULL;
|
| 89 |
+
public $vatRate = NULL;
|
| 90 |
+
public $currency = NULL;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
class BagItem {
|
| 94 |
+
|
| 95 |
+
public $ean = NULL;
|
| 96 |
+
public $skuRef = NULL;
|
| 97 |
+
public $orderedQty = NULL;
|
| 98 |
+
public $qtyToBill = NULL;
|
| 99 |
+
public $qtyToShip = NULL;
|
| 100 |
+
public $qtyUnit = NULL;
|
| 101 |
+
public $label = NULL;
|
| 102 |
+
public $language = NULL;
|
| 103 |
+
public $type = NULL;
|
| 104 |
+
public $family = NULL;
|
| 105 |
+
public $imgUrl = NULL;
|
| 106 |
+
public $comment = NULL;
|
| 107 |
+
public $attributes = array();
|
| 108 |
+
public $price = NULL;
|
| 109 |
+
public $rawData = NULL;
|
| 110 |
+
public $innerItems = array();
|
| 111 |
+
|
| 112 |
+
public function __construct() {
|
| 113 |
+
$this->rawData = new RawData();
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
/**
|
| 117 |
+
* Check some fields and gives them always the same value if they are null or empty.
|
| 118 |
+
* The goal is to avoid a field is empty at a moment and null at another moment.
|
| 119 |
+
*
|
| 120 |
+
* This method does NOT check mandatory fields.
|
| 121 |
+
*/
|
| 122 |
+
public function checkFields() {
|
| 123 |
+
// price
|
| 124 |
+
if($this->price != null) {
|
| 125 |
+
$this->price = splitNullValuesInObject($this->price);
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
// rawData
|
| 129 |
+
if($this->rawData != null) {
|
| 130 |
+
$this->rawData = splitNullValuesInObject($this->rawData);
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
class RawData {
|
| 136 |
+
public $buyRequest = NULL;
|
| 137 |
+
public $parentSku = NULL;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
class Totals {
|
| 141 |
+
public $subtotal = NULL;
|
| 142 |
+
public $discount = NULL;
|
| 143 |
+
public $shipping = NULL;
|
| 144 |
+
public $total = NULL;
|
| 145 |
+
public $vat = NULL;
|
| 146 |
+
public $vatRate = NULL;
|
| 147 |
+
public $currency = NULL;
|
| 148 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/MergeMethods.php
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Intuiko_ConnectedStore_Model_MergeMethods
|
| 4 |
+
{
|
| 5 |
+
public function toOptionArray()
|
| 6 |
+
{
|
| 7 |
+
return array(
|
| 8 |
+
array('value'=>'CLASSIC', 'label'=>'Classic'),
|
| 9 |
+
array('value'=>'KEEP_HIGHEST_QUANTITIES', 'label'=>'Keep highest quantities'),
|
| 10 |
+
array('value'=>'KEEP_SLAVE', 'label'=>'Keep slave'),
|
| 11 |
+
array('value'=>'KEEP_MASTER', 'label'=>'Keep master'),
|
| 12 |
+
array('value'=>'EXCLUSIVE_ADD_FROM_SLAVE', 'label'=>'Exclusive add from slave'),
|
| 13 |
+
array('value'=>'EXCLUSIVE_ADD_FROM_MASTER', 'label'=>'Exclusive add from master')
|
| 14 |
+
);
|
| 15 |
+
}
|
| 16 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Messages.php
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class SearchBagMessage {
|
| 4 |
+
public $type = NULL;
|
| 5 |
+
public $appCustomerId = NULL;
|
| 6 |
+
public $email = NULL;
|
| 7 |
+
public $twitterId = NULL;
|
| 8 |
+
|
| 9 |
+
public function __construct($type, $appCustomerId, $email, $twitterId) {
|
| 10 |
+
$this->type = $type;
|
| 11 |
+
$this->appCustomerId = $appCustomerId;
|
| 12 |
+
$this->email = $email;
|
| 13 |
+
$this->twitterId = $twitterId;
|
| 14 |
+
}
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
class MergeMessage {
|
| 18 |
+
public $masterBagId = NULL;
|
| 19 |
+
public $slaveBagId = NULL;
|
| 20 |
+
public $method = NULL;
|
| 21 |
+
|
| 22 |
+
public function __construct($masterBagId, $slaveBagId, $method) {
|
| 23 |
+
$this->masterBagId = $masterBagId;
|
| 24 |
+
$this->slaveBagId = $slaveBagId;
|
| 25 |
+
$this->method = $method;
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
class DeleteMessage {
|
| 30 |
+
public $bagId = NULL;
|
| 31 |
+
|
| 32 |
+
public function __construct($bagId) {
|
| 33 |
+
$this->bagId = $bagId;
|
| 34 |
+
}
|
| 35 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Observer.php
ADDED
|
@@ -0,0 +1,417 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
include_once 'Bag.php';
|
| 4 |
+
include_once 'Cart.php';
|
| 5 |
+
include_once 'Wishlist.php';
|
| 6 |
+
include_once 'Order.php';
|
| 7 |
+
include_once 'Messages.php';
|
| 8 |
+
include_once 'app/code/local/Intuiko/ConnectedStore/Logger/ICSLogger.php';
|
| 9 |
+
|
| 10 |
+
class Intuiko_ConnectedStore_Model_Observer extends Varien_Event_Observer {
|
| 11 |
+
|
| 12 |
+
private static $ICSIsLoggedIn = 'ICSIsLoggedIn';
|
| 13 |
+
|
| 14 |
+
const CART_KEY = "cart";
|
| 15 |
+
const WISHLIST_KEY = "wishlist";
|
| 16 |
+
const FORCED_SAVE_KEY = "forcedSave";
|
| 17 |
+
|
| 18 |
+
/**
|
| 19 |
+
* Save a cart in ICS after a cart update.
|
| 20 |
+
* Called on magento event [checkout_cart_save_after].
|
| 21 |
+
*/
|
| 22 |
+
public function onSaveCart($observer) {
|
| 23 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isICSModuleEnabled()) {
|
| 24 |
+
return;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
ICSLogger::debug('*** Beginning SaveCart event (checkout_cart_save_after)');
|
| 28 |
+
$this->performCartSave(Cart::getCartChecksumInSession(), Cart::createCart($observer->getEvent()->_data['cart']->getQuote()));
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
/**
|
| 32 |
+
* Save a wishlist in ICS after a wishlist update.
|
| 33 |
+
* Called on magento event [wishlist_items_renewed].
|
| 34 |
+
*/
|
| 35 |
+
public function onSaveWishlist() {
|
| 36 |
+
$customer = Mage::getSingleton('customer/session')->getCustomer();
|
| 37 |
+
$isLoggedIn = Mage::getSingleton('core/session')->getData(self::$ICSIsLoggedIn);
|
| 38 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isICSModuleEnabled() || empty($isLoggedIn) || !$customer->getId()){
|
| 39 |
+
return;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
ICSLogger::debug('*** Beginning SaveWishlist event (wishlist_items_renewed)');
|
| 43 |
+
$this->performWishlistSave(Wishlist::getWishlistChecksumInSession(), Wishlist::createWishlist($customer, Mage::helper('wishlist')->getWishlist()));
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
/**
|
| 47 |
+
* Save an order in ICS after an order update.
|
| 48 |
+
* Called on magento event [checkout_submit_all_after].
|
| 49 |
+
*/
|
| 50 |
+
public function onSaveOrder($observer) {
|
| 51 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isICSModuleEnabled()) {
|
| 52 |
+
return;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
ICSLogger::debug('*** Beginning SaveOrder event (checkout_submit_all_after)');
|
| 56 |
+
|
| 57 |
+
$bag = Order::createOrder($observer->getEvent()->_data['quote'], $observer->getEvent()->_data['order']);
|
| 58 |
+
$response = Mage::helper('connectedstore/ICSHelper')->save($bag);
|
| 59 |
+
|
| 60 |
+
if(empty($response)) {
|
| 61 |
+
return;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
Cart::resetIcsInfoInSession();
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
/**
|
| 68 |
+
* Manage login event, to get the customer cart and wishlist.
|
| 69 |
+
* At this point, the customer may have an anonymous bag (stored in the magento session) and/or a non-anonymous bag in the ICS database.
|
| 70 |
+
* Following the cases, this method get the non-anonymous bag, the anonymous one, or merge the two bags to get the final bag of the customer.
|
| 71 |
+
* This final bag is finally imported into the magento's quote and possibly saved again in ICS.
|
| 72 |
+
*
|
| 73 |
+
* Called on magento event [customer_login].
|
| 74 |
+
*/
|
| 75 |
+
public function onLogin() {
|
| 76 |
+
$customer = Mage::getSingleton('customer/session')->getCustomer();
|
| 77 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isICSModuleEnabled() || !$customer->getId()) {
|
| 78 |
+
return;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
$this->sendIcsCustomer($customer);
|
| 82 |
+
|
| 83 |
+
ICSLogger::debug('*** Beginning Login event (customer_login)');
|
| 84 |
+
|
| 85 |
+
$twitterId = Mage::helper('connectedstore/ICSTwitterHelper')->getTwitterId($customer);
|
| 86 |
+
$searchResponseCart = Mage::helper('connectedstore/ICSHelper')->searchBagsIds(Cart::ICS_TYPE, $customer->getId(), $customer->getEmail(), $twitterId);
|
| 87 |
+
$searchResponseWishlist = Mage::helper('connectedstore/ICSHelper')->searchBagsIds(Wishlist::ICS_TYPE, $customer->getId(), $customer->getEmail(), $twitterId);
|
| 88 |
+
|
| 89 |
+
ICSLogger::debug('+ Retrieving cart...');
|
| 90 |
+
if(is_numeric($searchResponseCart) && $searchResponseCart !== -1) {
|
| 91 |
+
return;
|
| 92 |
+
}
|
| 93 |
+
$array = $this->getCartForLogin($customer, $searchResponseCart);
|
| 94 |
+
$bag = $array[self::CART_KEY];
|
| 95 |
+
$forcedSave = $array[self::FORCED_SAVE_KEY];
|
| 96 |
+
|
| 97 |
+
ICSLogger::debug("Importing cart into magento");
|
| 98 |
+
$bag->importIntoMagento($customer);
|
| 99 |
+
$finalBag = Cart::createCart(Mage::getModel('sales/quote')->loadByCustomer($customer));
|
| 100 |
+
$this->performCartSave($bag->getCheckSum(), $finalBag, $forcedSave);
|
| 101 |
+
|
| 102 |
+
ICSLogger::debug('+ Retrieving wishlist...');
|
| 103 |
+
if(is_numeric($searchResponseWishlist) && $searchResponseWishlist !== -1) {
|
| 104 |
+
return;
|
| 105 |
+
}
|
| 106 |
+
$array = $this->getWishlistForLogin($customer, $searchResponseWishlist);
|
| 107 |
+
$bag = $array[self::WISHLIST_KEY];
|
| 108 |
+
$forcedSave = $array[self::FORCED_SAVE_KEY];
|
| 109 |
+
|
| 110 |
+
ICSLogger::debug("Importing wishlist into magento");
|
| 111 |
+
$bag->importIntoMagento($customer);
|
| 112 |
+
$finalBag = Wishlist::createWishlist($customer, Mage::helper('wishlist')->getWishlist());
|
| 113 |
+
$this->performWishlistSave($bag->getCheckSum(), $finalBag, $forcedSave);
|
| 114 |
+
|
| 115 |
+
Mage::getSingleton('core/session')->setData(self::$ICSIsLoggedIn, 1);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
/**
|
| 119 |
+
* Reset cart and wishlist in session.
|
| 120 |
+
* Called on magento event [customer_logout].
|
| 121 |
+
*/
|
| 122 |
+
public function onLogout(){
|
| 123 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isICSModuleEnabled()) {
|
| 124 |
+
return;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
Cart::resetIcsInfoInSession();
|
| 128 |
+
Wishlist::resetIcsInfoInSession();
|
| 129 |
+
Customer::resetCustomerChecksumInSession();
|
| 130 |
+
Mage::getSingleton('core/session')->setData(self::$ICSIsLoggedIn, 0);
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
/**
|
| 134 |
+
* Check synchronize flag and synchronize cart and wishlist if needed.
|
| 135 |
+
* Called on magento event [controller_action_predispatch].
|
| 136 |
+
*/
|
| 137 |
+
public function synchroBag() {
|
| 138 |
+
$customer = Mage::getSingleton('customer/session')->getCustomer();
|
| 139 |
+
$flag = Bag::getIcsFlagSynchroInSession();
|
| 140 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isICSModuleEnabled() || !empty($flag) || !$customer->getId()) {
|
| 141 |
+
return;
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
ICSLogger::debug('*** Beginning SynchroBag event (controller_action_predispatch)');
|
| 145 |
+
|
| 146 |
+
ICSLogger::debug('+ Synchronising cart...');
|
| 147 |
+
$this->synchroCart($customer);
|
| 148 |
+
ICSLogger::debug('+ Synchronising wishlist...');
|
| 149 |
+
$this->synchroWishlist($customer);
|
| 150 |
+
Bag::setIcsFlagSynchroInSession(true);
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
/**
|
| 154 |
+
* Function for enable the next synchronize of bags.
|
| 155 |
+
* Called on magento event [controller_action_layout_generate_blocks_after].
|
| 156 |
+
*/
|
| 157 |
+
public function resetFlagSynchro(){
|
| 158 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isICSModuleEnabled()) {
|
| 159 |
+
return;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
Bag::setIcsFlagSynchroInSession(false);
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
/**
|
| 166 |
+
* Synchronize cart from ICS.
|
| 167 |
+
*
|
| 168 |
+
* @param Mage_Customer_Model_Customer $customer The magento customer
|
| 169 |
+
*/
|
| 170 |
+
private function synchroCart($customer) {
|
| 171 |
+
$twitterId = Mage::helper('connectedstore/ICSTwitterHelper')->getTwitterId($customer);
|
| 172 |
+
$searchResponse = Mage::helper('connectedstore/ICSHelper')->searchBagsIds(Cart::ICS_TYPE, $customer->getId(), $customer->getEmail(), $twitterId);
|
| 173 |
+
|
| 174 |
+
if(is_numeric($searchResponse)) {
|
| 175 |
+
return;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
if(empty($searchResponse)) {
|
| 179 |
+
if(!Mage::helper('connectedstore/ICSHelper')->getIcsFlagError()){
|
| 180 |
+
ICSLogger::debug('No cart found, quote will be flushed');
|
| 181 |
+
Cart::flushCustomerQuote($customer);
|
| 182 |
+
}else{
|
| 183 |
+
ICSLogger::debug("No cart found, response error from ICS.");
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
Cart::resetIcsInfoInSession();
|
| 187 |
+
return;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
$icsBagId = $searchResponse[0];
|
| 191 |
+
$bagId = Cart::getIcsCartIdInSession();
|
| 192 |
+
|
| 193 |
+
if(!empty($bagId) && $bagId == $icsBagId) {
|
| 194 |
+
$getResponse = Mage::helper('connectedstore/ICSHelper')->getBagById($bagId, Cart::getCartLastUpdateInSession());
|
| 195 |
+
if(!empty($getResponse) && is_numeric($getResponse)) {
|
| 196 |
+
ICSLogger::debug('Cart up to date, nothing is done');
|
| 197 |
+
return;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
ICSLogger::debug('Cart out of date, it will be updated');
|
| 201 |
+
$bag = Cart::createCartFromJsonObject($getResponse);
|
| 202 |
+
} else {
|
| 203 |
+
ICSLogger::debug('New cart has been found, get request will be sent');
|
| 204 |
+
$bag = Cart::createCartFromJsonObject(Mage::helper('connectedstore/ICSHelper')->getBagById($icsBagId));
|
| 205 |
+
Cart::setIcsCartIdInSession($icsBagId);
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
ICSLogger::debug("Importing cart into magento");
|
| 209 |
+
$bag->importIntoMagento($customer);
|
| 210 |
+
Cart::setCartLastUpdateInSession($bag->lastUpdate);
|
| 211 |
+
$finalBag = Cart::createCart(Mage::getModel('sales/quote')->loadByCustomer($customer));
|
| 212 |
+
$this->performCartSave($bag->getCheckSum(), $finalBag);
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
/**
|
| 216 |
+
* Synchronize wishlist from ICS.
|
| 217 |
+
*
|
| 218 |
+
* @param Mage_Customer_Model_Customer $customer The magento customer
|
| 219 |
+
*/
|
| 220 |
+
private function synchroWishlist($customer){
|
| 221 |
+
$twitterId = Mage::helper('connectedstore/ICSTwitterHelper')->getTwitterId($customer);
|
| 222 |
+
$searchResponse = Mage::helper('connectedstore/ICSHelper')->searchBagsIds(Wishlist::ICS_TYPE, $customer->getId(), $customer->getEmail(), $twitterId);
|
| 223 |
+
|
| 224 |
+
if(is_numeric($searchResponse)) {
|
| 225 |
+
return;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
if(empty($searchResponse)) {
|
| 229 |
+
ICSLogger::debug('No wishlist found, it will be flushed');
|
| 230 |
+
Wishlist::flushWishlist();
|
| 231 |
+
Wishlist::resetIcsInfoInSession();
|
| 232 |
+
return;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
$icsBagId = $searchResponse[0];
|
| 236 |
+
$bagId = Wishlist::getIcsWishlistIdInSession();
|
| 237 |
+
|
| 238 |
+
if(!empty($bagId) && $bagId == $icsBagId) {
|
| 239 |
+
$getResponse = Mage::helper('connectedstore/ICSHelper')->getBagById($bagId, Wishlist::getWishlistLastUpdateInSession());
|
| 240 |
+
if(!empty($getResponse) && is_numeric($getResponse)) {
|
| 241 |
+
ICSLogger::debug('Wishlist up to date, nothing is done');
|
| 242 |
+
return;
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
ICSLogger::debug('Wishlist out of date, it will be updated');
|
| 246 |
+
$bag = Wishlist::createWishlistFromJsonObject($getResponse);
|
| 247 |
+
} else {
|
| 248 |
+
ICSLogger::debug('New wishlist has been found, get request will be sent');
|
| 249 |
+
$bag = Wishlist::createWishlistFromJsonObject(Mage::helper('connectedstore/ICSHelper')->getBagById($icsBagId));
|
| 250 |
+
Wishlist::setIcsWishlistIdInSession($icsBagId);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
ICSLogger::debug("Importing wishlist into magento");
|
| 254 |
+
$bag->importIntoMagento($customer);
|
| 255 |
+
$finalBag = Wishlist::createWishlist($customer, Mage::helper('wishlist')->getWishlist());
|
| 256 |
+
Wishlist::setWishlistLastUpdateInSession($bag->lastUpdate);
|
| 257 |
+
$this->performWishlistSave($bag->getCheckSum(), $finalBag);
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
/**
|
| 261 |
+
* Perform a call to the save method of the api if needed.
|
| 262 |
+
* The save is needed if the given bag's checksum is different than the given old checksum.
|
| 263 |
+
*
|
| 264 |
+
* @param String $oldChecksum The old checksum
|
| 265 |
+
* @param Cart $bag The bag to save
|
| 266 |
+
* @param Bool $forcedSave True for the bag to be saved even if the old checksum and the given bag's checksum are the same.
|
| 267 |
+
*/
|
| 268 |
+
private function performCartSave($oldChecksum, $bag, $forcedSave = false) {
|
| 269 |
+
if(!is_null($oldChecksum) && strcmp($bag->getCheckSum(), $oldChecksum) == 0 && !$forcedSave) {
|
| 270 |
+
ICSLogger::debug('Cart has not been modified, nothing is done');
|
| 271 |
+
return;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
ICSLogger::debug('Cart has been modified, save request will be sent');
|
| 275 |
+
$response = Mage::helper('connectedstore/ICSHelper')->save($bag);
|
| 276 |
+
|
| 277 |
+
if(empty($response)) {
|
| 278 |
+
return;
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
$bag->bagId = $response['bagId'];
|
| 282 |
+
Cart::setIcsInfoInSession($response['bagId'], $bag->getCheckSum(), $response['lastUpdate']);
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
/**
|
| 286 |
+
* Perform a call to the save method of the api if needed.
|
| 287 |
+
* The save is needed if the given bag's checksum is different than the old checksum.
|
| 288 |
+
*
|
| 289 |
+
* @param String $oldChecksum The old checksum
|
| 290 |
+
* @param Wishlist $bag The bag to save
|
| 291 |
+
* @param Bool $forcedSave True for the bag to be saved even if the old checksum and the given bag's checksum are the same.
|
| 292 |
+
*/
|
| 293 |
+
private function performWishlistSave($oldChecksum, $bag, $forcedSave = false) {
|
| 294 |
+
if(!is_null($oldChecksum) && strcmp($bag->getCheckSum(), $oldChecksum) == 0 && !$forcedSave) {
|
| 295 |
+
ICSLogger::debug('Wishlist has not been modified, nothing is done');
|
| 296 |
+
return;
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
ICSLogger::debug('Wishlist has been modified, save request will be sent');
|
| 300 |
+
$response = Mage::helper('connectedstore/ICSHelper')->save($bag);
|
| 301 |
+
|
| 302 |
+
if(empty($response)) {
|
| 303 |
+
return;
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
$bag->bagId = $response['bagId'];
|
| 307 |
+
Wishlist::setIcsInfoInSession($response['bagId'], $bag->getCheckSum(), $response['lastUpdate']);
|
| 308 |
+
}
|
| 309 |
+
|
| 310 |
+
/**
|
| 311 |
+
* Get an array containing the current cart of the customer and if it must be saved.
|
| 312 |
+
* The cart is retrieved following the different possible cases.
|
| 313 |
+
*
|
| 314 |
+
* @param Mage_Customer_Model_Customer $customer The current customer
|
| 315 |
+
* @param Array $searchResponse The response of a search call
|
| 316 |
+
* @return Array An array containing, for the key "cart" the current cart of the customer,
|
| 317 |
+
* and for the key "forcedSave" a boolean that tells if that cart must be saved.
|
| 318 |
+
*/
|
| 319 |
+
private function getCartForLogin($customer, $searchResponse) {
|
| 320 |
+
$bag = new Cart();
|
| 321 |
+
$forcedSave = false;
|
| 322 |
+
$currentBagId = Cart::getIcsCartIdInSession();
|
| 323 |
+
|
| 324 |
+
if($searchResponse === -1 && empty($currentBagId)){
|
| 325 |
+
ICSLogger::debug("Customer not known in ICS");
|
| 326 |
+
$bag = Cart::createCart(Mage::getModel('sales/quote')->loadByCustomer($customer));
|
| 327 |
+
$forcedSave = true;
|
| 328 |
+
}
|
| 329 |
+
else if($searchResponse === -1 && !empty($currentBagId)) {
|
| 330 |
+
ICSLogger::debug('Customer not known in ICS with a cart in magento\'s session');
|
| 331 |
+
$bag = Cart::createCartFromJsonObject(Mage::helper('connectedstore/ICSHelper')->getBagById($currentBagId));
|
| 332 |
+
$forcedSave = true;
|
| 333 |
+
}
|
| 334 |
+
else if(empty($searchResponse) && !empty($currentBagId)) {
|
| 335 |
+
ICSLogger::debug('Customer has a cart in magento\'s session and not in ICS');
|
| 336 |
+
$bag = Cart::createCartFromJsonObject(Mage::helper('connectedstore/ICSHelper')->getBagById($currentBagId));
|
| 337 |
+
$forcedSave = true;
|
| 338 |
+
}
|
| 339 |
+
else if(!empty($searchResponse) && empty($currentBagId)) {
|
| 340 |
+
ICSLogger::debug('Customer has at least one cart in ICS and not in magento\'s session');
|
| 341 |
+
$bag = Cart::createCartFromJsonObject(Mage::helper('connectedstore/ICSHelper')->getBagById($searchResponse[0]));
|
| 342 |
+
Cart::setIcsInfoInSession($bag->bagId, $bag->getCheckSum(), $bag->lastUpdate);
|
| 343 |
+
}
|
| 344 |
+
else if(!empty($searchResponse) && !empty($currentBagId)) {
|
| 345 |
+
ICSLogger::debug('Customer has a cart in magento\'s session and at least one cart in ICS');
|
| 346 |
+
$bag = Cart::createCartFromJsonObject(Mage::helper('connectedstore/ICSHelper')->merge($searchResponse[0], $currentBagId));
|
| 347 |
+
ICSLogger::debug('Merge done, delete request will be sent for the anonymous cart');
|
| 348 |
+
Mage::helper('connectedstore/ICSHelper')->delete($currentBagId);
|
| 349 |
+
Cart::setIcsInfoInSession($bag->bagId, $bag->getCheckSum(), $bag->lastUpdate);
|
| 350 |
+
}
|
| 351 |
+
else if(empty($searchResponse) && empty($currentBagId)) {
|
| 352 |
+
ICSLogger::debug("Customer has no magento cart and no ICS cart");
|
| 353 |
+
Cart::flushCustomerQuote($customer);
|
| 354 |
+
Cart::resetIcsInfoInSession();
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
return array(self::CART_KEY => $bag, self::FORCED_SAVE_KEY => $forcedSave);
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
/**
|
| 361 |
+
* Get an array containing the current wishlist of the customer.
|
| 362 |
+
* The wishlist is retrieved following the different possible cases.
|
| 363 |
+
*
|
| 364 |
+
* @param Mage_Customer_Model_Customer $customer The current customer
|
| 365 |
+
* @param Array $searchResponse The response of a search call
|
| 366 |
+
* @return Array An array containing, for the key "wishlist" the current wishlist of the customer,
|
| 367 |
+
* and for the key "forcedSave" a boolean that tells if that wishlist must be saved.
|
| 368 |
+
*/
|
| 369 |
+
private function getWishlistForLogin($customer, $searchResponse) {
|
| 370 |
+
$bag = new Wishlist();
|
| 371 |
+
$forcedSave = false;
|
| 372 |
+
|
| 373 |
+
if($searchResponse === -1){
|
| 374 |
+
ICSLogger::debug("Customer not known in ICS");
|
| 375 |
+
$bag = Wishlist::createWishlist($customer, Mage::helper('wishlist')->getWishlist());
|
| 376 |
+
$forcedSave = true;
|
| 377 |
+
}
|
| 378 |
+
else if(!empty($searchResponse)) {
|
| 379 |
+
ICSLogger::debug('Customer has at least one wishlist in ICS');
|
| 380 |
+
$bag = Wishlist::createWishlistFromJsonObject(Mage::helper('connectedstore/ICSHelper')->getBagById($searchResponse[0]));
|
| 381 |
+
Wishlist::setIcsInfoInSession($bag->bagId, $bag->getCheckSum(), $bag->lastUpdate);
|
| 382 |
+
}
|
| 383 |
+
else if(empty($searchResponse)) {
|
| 384 |
+
ICSLogger::debug("Customer has no ICS wishlist");
|
| 385 |
+
Wishlist::flushWishlist();
|
| 386 |
+
Wishlist::resetIcsInfoInSession();
|
| 387 |
+
}
|
| 388 |
+
|
| 389 |
+
return array(self::WISHLIST_KEY => $bag, self::FORCED_SAVE_KEY => $forcedSave);
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
public function onCustomerSaveAfter() {
|
| 393 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isICSModuleEnabled()) {
|
| 394 |
+
return;
|
| 395 |
+
}
|
| 396 |
+
ICSLogger::debug('*** Beginning SaveCustomer event (customer_save_after)');
|
| 397 |
+
$this->sendIcsCustomer(Mage::getSingleton('customer/session')->getCustomer());
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
private function sendIcsCustomer($customerSession) {
|
| 401 |
+
if($customerSession == null || $customerSession->getId() == null) {
|
| 402 |
+
return;
|
| 403 |
+
}
|
| 404 |
+
$customerToSend = Customer::createIcsCustomer($customerSession);
|
| 405 |
+
$oldChecksum = Customer::getCustomerChecksumInSession();
|
| 406 |
+
$checksum = $customerToSend->getCheckSum();
|
| 407 |
+
ICSLogger::debug("Customer checksum verification");
|
| 408 |
+
if($oldChecksum == null || $oldChecksum != $checksum) {
|
| 409 |
+
ICSLogger::debug("Checksums are not the same. We save.");
|
| 410 |
+
$response = Mage::helper('connectedstore/ICSHelper')->saveCustomer($customerToSend);
|
| 411 |
+
if(empty($response)) {
|
| 412 |
+
return;
|
| 413 |
+
}
|
| 414 |
+
Customer::setCustomerChecksumInSession($checksum);
|
| 415 |
+
}
|
| 416 |
+
}
|
| 417 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Order.php
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Order extends Bag {
|
| 4 |
+
|
| 5 |
+
/**
|
| 6 |
+
* Default constructor.
|
| 7 |
+
*/
|
| 8 |
+
private function __construct() {
|
| 9 |
+
$this->checkFields();
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* A static method which instanciates an Order and feeds it with quote information.
|
| 14 |
+
*
|
| 15 |
+
* @param Mage_Sales_Model_Quote $quote The cart's quote
|
| 16 |
+
* @param Mage_Sales_Model_Order $order The order's information
|
| 17 |
+
* @return Cart A new order built from the cart and the checkout information
|
| 18 |
+
*/
|
| 19 |
+
public static function createOrder($quote, $order) {
|
| 20 |
+
$bag = new Order();
|
| 21 |
+
$bag->bagType = 'ORDER';
|
| 22 |
+
$bag->constructCartOrOrderFromQuote($quote);
|
| 23 |
+
$bag->setTotalsForOrder($order);
|
| 24 |
+
$bag->paymentMethod = $quote->getPayment()->getMethodInstance()->getTitle();
|
| 25 |
+
$bag->shipmentMethod = $order->getShippingDescription();
|
| 26 |
+
// if guest, special customer method
|
| 27 |
+
if($quote->getData('checkout_method') === Mage_Checkout_Model_Type_Onepage::METHOD_GUEST){
|
| 28 |
+
$bag->customer = $bag->getGuestFromQuote($quote);
|
| 29 |
+
}
|
| 30 |
+
$bag->checkFields();
|
| 31 |
+
return $bag;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/**
|
| 35 |
+
* Set the order's totals
|
| 36 |
+
*
|
| 37 |
+
* @param Mage_Sales_Model_Order $order The order
|
| 38 |
+
*/
|
| 39 |
+
private function setTotalsForOrder($order) {
|
| 40 |
+
$totals = new Totals();
|
| 41 |
+
|
| 42 |
+
$totals->subtotal = $order->getSubtotal();
|
| 43 |
+
$totals->total = $order->getGrandTotal();
|
| 44 |
+
$totals->discount = $order->getDiscountAmount();
|
| 45 |
+
$totals->shipping = $order->getShippingAmount();
|
| 46 |
+
$totals->vat = $order->getTaxAmount();
|
| 47 |
+
// TODO: vatRate
|
| 48 |
+
$totals->currency = Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE);
|
| 49 |
+
|
| 50 |
+
$this->totals = $totals;
|
| 51 |
+
}
|
| 52 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Resource/ICSResource.php
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class ICSResource {
|
| 4 |
+
|
| 5 |
+
/**
|
| 6 |
+
* Get bundle selection from id
|
| 7 |
+
*/
|
| 8 |
+
public static function getSelectionById($selectionId) {
|
| 9 |
+
$resource = Mage::getModel('bundle/option')->getResource();
|
| 10 |
+
$adapter = $resource->getReadConnection();
|
| 11 |
+
$select = $adapter->select()
|
| 12 |
+
->from('catalog_product_bundle_selection')
|
| 13 |
+
->where('selection_id = ?', $selectionId);
|
| 14 |
+
return $adapter->fetchRow($select);
|
| 15 |
+
}
|
| 16 |
+
}
|
app/code/local/Intuiko/ConnectedStore/Model/Wishlist.php
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Wishlist extends Bag {
|
| 4 |
+
|
| 5 |
+
protected static $ICS_WishlistId = 'ICS_WishlistId';
|
| 6 |
+
protected static $ICS_WishlistChecksum = 'ICS_WishlistChecksum';
|
| 7 |
+
protected static $ICS_WishlistLastUpdate = 'ICS_WishlistLastUpdate';
|
| 8 |
+
/** Name of the ICS type for cart */
|
| 9 |
+
const ICS_TYPE = 'WISHLIST';
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* Default constructor
|
| 14 |
+
*/
|
| 15 |
+
public function __construct() {
|
| 16 |
+
$this->checkFields();
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
/**
|
| 20 |
+
* A static function which instanciates a Wishlist and feeds it current Magento wishlist information
|
| 21 |
+
*
|
| 22 |
+
* @param Mage_Customer_Model_Customer $customer The magento's customer
|
| 23 |
+
* @param Mage_Wishlist_Model_Wishlist $wishlist The magento's wishlist
|
| 24 |
+
* @return Wishlist The ICS wishlist built from the magento's one
|
| 25 |
+
*/
|
| 26 |
+
public static function createWishlist($customer, $wishlist) {
|
| 27 |
+
$bag = new Wishlist();
|
| 28 |
+
$bag->bagType = 'WISHLIST';
|
| 29 |
+
$bag->bagName = 'default';
|
| 30 |
+
$bag->constructWishlist($customer, $wishlist);
|
| 31 |
+
$bag->setTotalsForWishlist($wishlist);
|
| 32 |
+
$bag->checkFields();
|
| 33 |
+
return $bag;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
/**
|
| 37 |
+
* Create a Wishlist from the given json object.
|
| 38 |
+
*
|
| 39 |
+
* @param Object $jsonObject The json stream that represents a wishlist
|
| 40 |
+
* @return Wishlist A wishlist built from the json stream
|
| 41 |
+
*/
|
| 42 |
+
public static function createWishlistFromJsonObject($jsonObject) {
|
| 43 |
+
$wishlist = new Wishlist();
|
| 44 |
+
|
| 45 |
+
if(empty($jsonObject)) {
|
| 46 |
+
return $wishlist;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
$wishlist->createBagFromJsonObject($jsonObject);
|
| 50 |
+
$wishlist->checkFields();
|
| 51 |
+
return $wishlist;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
/**
|
| 55 |
+
* Set the wishlist's checksum given in parameter in session
|
| 56 |
+
*
|
| 57 |
+
* @param String $checksum The checksum to set in the session
|
| 58 |
+
*/
|
| 59 |
+
public static function setWishlistChecksumInSession($checksum){
|
| 60 |
+
Mage::getSingleton('core/session')->setData(self::$ICS_WishlistChecksum, $checksum);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
/**
|
| 64 |
+
* Get the current wishlist's checksum in session
|
| 65 |
+
*
|
| 66 |
+
* @return String The current wishlist checksum
|
| 67 |
+
*/
|
| 68 |
+
public static function getWishlistChecksumInSession(){
|
| 69 |
+
return Mage::getSingleton('core/session')->getData(self::$ICS_WishlistChecksum);
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
/**
|
| 73 |
+
* Set the wishlist id given in parameter in session
|
| 74 |
+
*
|
| 75 |
+
* @param Integer $wishlistId The id to set in the session
|
| 76 |
+
*/
|
| 77 |
+
public static function setIcsWishlistIdInSession($wishlistId){
|
| 78 |
+
Mage::getSingleton('core/session')->setData(self::$ICS_WishlistId, $wishlistId);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
/**
|
| 82 |
+
* Get the wishlist id from the session
|
| 83 |
+
*
|
| 84 |
+
* @return Integer the current wishlist id
|
| 85 |
+
*/
|
| 86 |
+
public static function getIcsWishlistIdInSession(){
|
| 87 |
+
return Mage::getSingleton('core/session')->getData(self::$ICS_WishlistId);
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
/**
|
| 91 |
+
* Set the wishlist's date of last update given in parameter in session
|
| 92 |
+
*
|
| 93 |
+
* @param String $date The date to set in the session
|
| 94 |
+
*/
|
| 95 |
+
public static function setWishlistLastUpdateInSession($date){
|
| 96 |
+
Mage::getSingleton('core/session')->setData(self::$ICS_WishlistLastUpdate, $date);
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
/**
|
| 100 |
+
* Get the Wishlist's date of last update in session
|
| 101 |
+
*
|
| 102 |
+
* @return String The wishlist's date of last update in session
|
| 103 |
+
*/
|
| 104 |
+
public static function getWishlistLastUpdateInSession(){
|
| 105 |
+
return Mage::getSingleton('core/session')->getData(self::$ICS_WishlistLastUpdate);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
/**
|
| 109 |
+
* Set the several information in session:
|
| 110 |
+
* -> The given wishlistId
|
| 111 |
+
* -> The given checksum
|
| 112 |
+
* -> The given lastUpdate
|
| 113 |
+
*
|
| 114 |
+
* @param Integer $wishlistId The current wishlistId
|
| 115 |
+
* @param String $checksum The wishlist checksum
|
| 116 |
+
* @param String $lastUpdate The wishlist last update
|
| 117 |
+
*/
|
| 118 |
+
public static function setIcsInfoInSession($wishlistId, $checksum, $lastUpdate) {
|
| 119 |
+
self::setIcsWishlistIdInSession($wishlistId);
|
| 120 |
+
self::setWishlistChecksumInSession($checksum);
|
| 121 |
+
self::setWishlistLastUpdateInSession($lastUpdate);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
/**
|
| 125 |
+
* Flush all wishlist information in session
|
| 126 |
+
*/
|
| 127 |
+
public static function resetIcsInfoInSession() {
|
| 128 |
+
self::setIcsWishlistIdInSession(null);
|
| 129 |
+
self::setWishlistChecksumInSession(null);
|
| 130 |
+
self::setWishlistLastUpdateInSession(null);
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
/**
|
| 134 |
+
* Flush the wishlist of the current customer.
|
| 135 |
+
*/
|
| 136 |
+
public static function flushWishlist(){
|
| 137 |
+
$wishlist = Mage::helper('wishlist')->getWishlist();
|
| 138 |
+
if(is_null($wishlist) || is_null($wishlist->getId())) {
|
| 139 |
+
return;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
$items = Mage::helper('wishlist')->getWishlistItemCollection();
|
| 143 |
+
foreach($items as $item) {
|
| 144 |
+
Mage::getModel('wishlist/item')->load($item->getId())->delete();
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
$wishlist->save();
|
| 148 |
+
$wishlist = Mage::getModel('wishlist/wishlist')->load($wishlist->getId());
|
| 149 |
+
Mage::unregister('wishlist');
|
| 150 |
+
Mage::register('wishlist', $wishlist);
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
/**
|
| 154 |
+
* Import the current wishlist in the magento's one.
|
| 155 |
+
*
|
| 156 |
+
* @param Mage_Customer_Model_Customer $customer The current customer
|
| 157 |
+
*/
|
| 158 |
+
public function importIntoMagento($customer){
|
| 159 |
+
self::flushWishlist();
|
| 160 |
+
|
| 161 |
+
$wishlist = Mage::helper('wishlist')->getWishlist();
|
| 162 |
+
if(is_null($wishlist) || is_null($wishlist->getId())) {
|
| 163 |
+
$wishlist = Mage::getSingleton('wishlist/wishlist')->loadByCustomer($customer, true);
|
| 164 |
+
}
|
| 165 |
+
$wishlist = Mage::getModel('wishlist/wishlist')->load($wishlist->getId());
|
| 166 |
+
|
| 167 |
+
if(!empty($this->bagItems)) {
|
| 168 |
+
foreach($this->bagItems as $bagItem) {
|
| 169 |
+
$productData = $this->getProductDataFromBagItem($bagItem);
|
| 170 |
+
|
| 171 |
+
// Getting product id
|
| 172 |
+
$sku = empty($bagItem->rawData->parentSku) ? $bagItem->skuRef : $bagItem->rawData->parentSku;
|
| 173 |
+
$product = Mage::getModel('catalog/product')->load(Mage::getModel('catalog/product')->getIdBySku($sku));
|
| 174 |
+
|
| 175 |
+
// Wishlist creation
|
| 176 |
+
try {
|
| 177 |
+
$item = $wishlist->addNewItem($product, $productData);
|
| 178 |
+
$item->description = $bagItem->comment;
|
| 179 |
+
} catch (Exception $e) {
|
| 180 |
+
ICSLogger::error('At least one product does not exist in database when loading wishlist : ' . $this->bagId);
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
$wishlist->save();
|
| 184 |
+
}
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
$wishlist->save();
|
| 188 |
+
$wishlist = Mage::getModel('wishlist/wishlist')->load($wishlist->getId());
|
| 189 |
+
Mage::unregister('wishlist');
|
| 190 |
+
Mage::register('wishlist', $wishlist);
|
| 191 |
+
Mage::unregister('_helper/wishlist');
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
/**
|
| 195 |
+
* Construct a bag message for the current customer wishlist
|
| 196 |
+
*
|
| 197 |
+
* @param Mage_Customer_Model_Customer $customer
|
| 198 |
+
* @param Mage_Wishlist_Model_Wishlist $wishlist
|
| 199 |
+
*/
|
| 200 |
+
private function constructWishlist($customer, $wishlist) {
|
| 201 |
+
$session = Mage::getSingleton('core/session');
|
| 202 |
+
// We add the customer
|
| 203 |
+
$this->customer = $this->createBagCustomer($customer);
|
| 204 |
+
// We get the context
|
| 205 |
+
$this->context = $this->getContext($session);
|
| 206 |
+
|
| 207 |
+
//set origin
|
| 208 |
+
if(Mage::app()->getRequest()->getModuleName() == 'wishlist' && Mage::app()->getRequest()->getActionName() == 'fromcart'){
|
| 209 |
+
$this->refBagOrigin = Cart::getIcsCartIdInSession();
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
// We get the bagId in session
|
| 213 |
+
$bagId = $session->getData(self::$ICS_WishlistId);
|
| 214 |
+
if($bagId != NULL) {
|
| 215 |
+
$this->bagId = $bagId;
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
$this->bagItems = array();
|
| 219 |
+
foreach($wishlist->getItemCollection() as $item) {
|
| 220 |
+
$product = $item->getProduct();
|
| 221 |
+
$icsItem = $this->getBagItemIcsFromWishlistItem($item);
|
| 222 |
+
|
| 223 |
+
switch ($product->getTypeId()) {
|
| 224 |
+
case Mage_Catalog_Model_Product_Type::TYPE_BUNDLE :
|
| 225 |
+
$key = $this->generateBagItemKeyFromChildren($icsItem);
|
| 226 |
+
break;
|
| 227 |
+
case Mage_Catalog_Model_Product_Type::TYPE_GROUPED :
|
| 228 |
+
$key = $this->generateBagItemKeyFromChildren($icsItem);
|
| 229 |
+
break;
|
| 230 |
+
case Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE :
|
| 231 |
+
$key = $this->generateBagItemKeyFromAttributes($icsItem);
|
| 232 |
+
break;
|
| 233 |
+
default:
|
| 234 |
+
$key = str_replace('.', self::DOT_REPLACE, $product->getData('sku'));
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
$this->bagItems[$key] = $icsItem;
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
/**
|
| 242 |
+
* Generate a bagItem from a wishlist item
|
| 243 |
+
*
|
| 244 |
+
* @param Mage_Wishlist_Model_Item $item The magento's item
|
| 245 |
+
* @return BagItem The ICS item built from the magento's one
|
| 246 |
+
*/
|
| 247 |
+
private function getBagItemIcsFromWishlistItem($item) {
|
| 248 |
+
$product = $item->getProduct();
|
| 249 |
+
$buyRequest = $item->getBuyRequest()->getData();
|
| 250 |
+
|
| 251 |
+
$bagItem = $this->getIcsItemFromProduct($product, $buyRequest, $item->getData('qty'));
|
| 252 |
+
$bagItem->comment = $item->getDescription();
|
| 253 |
+
|
| 254 |
+
$fullyConfiguredProduct = $this->isAllAttributesSet($buyRequest);
|
| 255 |
+
if(isset($buyRequest['options']) || isset($buyRequest['super_group']) || isset($buyRequest['bundle_option']) || isset($buyRequest['links'])
|
| 256 |
+
|| !$fullyConfiguredProduct) {
|
| 257 |
+
$bagItem->rawData->buyRequest = $buyRequest;
|
| 258 |
+
|
| 259 |
+
if(isset($buyRequest['bundle_option'])) {
|
| 260 |
+
$bagItem->innerItems = $this->getIcsItemsFromBundleOptions($buyRequest);
|
| 261 |
+
} else if(isset($buyRequest['super_group'])) {
|
| 262 |
+
$bagItem->innerItems = $this->getIcsItemsFromSuperGroup($buyRequest);
|
| 263 |
+
}
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
if($fullyConfiguredProduct && $product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
|
| 267 |
+
$bagItem->rawData->parentSku = $bagItem->skuRef;
|
| 268 |
+
$bagItem->skuRef = $this->getSkuFromConfigurableProduct($product, $buyRequest);
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
return $bagItem;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
/**
|
| 275 |
+
* Get the child sku from a fully configured product.
|
| 276 |
+
*
|
| 277 |
+
* @param Mage_Catalog_Model_Product $parentProduct The parent product
|
| 278 |
+
* @param Array $buyRequest The item's buy request
|
| 279 |
+
* @return String The child sku if found, the parent one otherwise
|
| 280 |
+
*/
|
| 281 |
+
private function getSkuFromConfigurableProduct($parentProduct, $buyRequest) {
|
| 282 |
+
$products = array();
|
| 283 |
+
|
| 284 |
+
if(isset($buyRequest['super_attribute'])) {
|
| 285 |
+
$products = Mage::getModel('catalog/product')->getCollection()->addStoreFilter();
|
| 286 |
+
|
| 287 |
+
foreach($buyRequest['super_attribute'] as $attributeId => $valueId) {
|
| 288 |
+
$code = $this->getAttributeCodeById($attributeId);
|
| 289 |
+
$products = $products->addAttributeToFilter($code, $valueId);
|
| 290 |
+
}
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
$sku = $parentProduct->getSku();
|
| 294 |
+
$parentId = $parentProduct->getId();
|
| 295 |
+
foreach($products as $product) {
|
| 296 |
+
$found = false;
|
| 297 |
+
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getData('entity_id'));
|
| 298 |
+
foreach($parentIds as $id) {
|
| 299 |
+
if($parentId == $id) {
|
| 300 |
+
$found = true;
|
| 301 |
+
break;
|
| 302 |
+
}
|
| 303 |
+
}
|
| 304 |
+
if($found) {
|
| 305 |
+
$sku = $product->getSku();
|
| 306 |
+
break;
|
| 307 |
+
}
|
| 308 |
+
}
|
| 309 |
+
|
| 310 |
+
return $sku;
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
/**
|
| 314 |
+
* Set the wishlist's totals
|
| 315 |
+
*
|
| 316 |
+
* @param Mage_Wishlist_Model_Wishlist $wishlist The magento's wishlist
|
| 317 |
+
*/
|
| 318 |
+
private function setTotalsForWishlist($wishlist) {
|
| 319 |
+
$totals = new Totals();
|
| 320 |
+
|
| 321 |
+
$totals->total = 0;
|
| 322 |
+
foreach ($wishlist->getItemCollection() as $item) {
|
| 323 |
+
$totals->total = $totals->total + $item->getProduct()->getFinalPrice() * $item->getData('qty');
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
$totals->subtotal = $totals->total;
|
| 327 |
+
$totals->currency = Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE);
|
| 328 |
+
|
| 329 |
+
$this->totals = $totals;
|
| 330 |
+
}
|
| 331 |
+
}
|
app/code/local/Intuiko/ConnectedStore/controllers/PingController.php
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Intuiko_ConnectedStore_PingController extends Mage_Core_Controller_Front_Action {
|
| 4 |
+
|
| 5 |
+
public function indexAction() {
|
| 6 |
+
if(!Mage::helper('connectedstore/ICSHelper')->isIcsModuleStatusEnabled()) {
|
| 7 |
+
$response = 'ICS connector is disabled.';
|
| 8 |
+
} else {
|
| 9 |
+
$pong = $this->pingAction();
|
| 10 |
+
if($pong != NULL) {
|
| 11 |
+
$response = "Success in " . $pong->timeElapsed . " ms! Tenant: " . $pong->tenantName . ", Profile: " . $pong->applicationProfile . ", Version: " . $pong->apiVersion;
|
| 12 |
+
} else {
|
| 13 |
+
$response = "Fail to connect to ICS, please check your configuration.";
|
| 14 |
+
}
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
$this->getResponse()->setBody($response);
|
| 18 |
+
$this->setFlag('', self::FLAG_NO_POST_DISPATCH, true);
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
public function pingAction() {
|
| 22 |
+
return Mage::helper('connectedstore/ICSHelper')->ping();
|
| 23 |
+
}
|
| 24 |
+
}
|
app/code/local/Intuiko/ConnectedStore/etc/adminhtml.xml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<config>
|
| 3 |
+
<acl>
|
| 4 |
+
<resources>
|
| 5 |
+
<admin>
|
| 6 |
+
<children>
|
| 7 |
+
<system>
|
| 8 |
+
<children>
|
| 9 |
+
<config>
|
| 10 |
+
<children>
|
| 11 |
+
<connectedstore_section translate="title">
|
| 12 |
+
<title>Ping</title>
|
| 13 |
+
<sort_order>100</sort_order>
|
| 14 |
+
</connectedstore_section>
|
| 15 |
+
</children>
|
| 16 |
+
</config>
|
| 17 |
+
</children>
|
| 18 |
+
</system>
|
| 19 |
+
</children>
|
| 20 |
+
</admin>
|
| 21 |
+
</resources>
|
| 22 |
+
</acl>
|
| 23 |
+
</config>
|
app/code/local/Intuiko/ConnectedStore/etc/config.xml
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<config>
|
| 3 |
+
<modules>
|
| 4 |
+
<Intuiko_ConnectedStore>
|
| 5 |
+
<version>1.0.0</version>
|
| 6 |
+
</Intuiko_ConnectedStore>
|
| 7 |
+
</modules>
|
| 8 |
+
|
| 9 |
+
<frontend>
|
| 10 |
+
<routers>
|
| 11 |
+
<ping>
|
| 12 |
+
<use>standard</use>
|
| 13 |
+
<args>
|
| 14 |
+
<module>Intuiko_ConnectedStore</module>
|
| 15 |
+
<frontName>ping</frontName>
|
| 16 |
+
</args>
|
| 17 |
+
</ping>
|
| 18 |
+
</routers>
|
| 19 |
+
|
| 20 |
+
<events>
|
| 21 |
+
<checkout_cart_save_after>
|
| 22 |
+
<observers>
|
| 23 |
+
<onSaveCart>
|
| 24 |
+
<type>singleton</type>
|
| 25 |
+
<class>Intuiko_ConnectedStore_Model_Observer</class>
|
| 26 |
+
<method>onSaveCart</method>
|
| 27 |
+
</onSaveCart>
|
| 28 |
+
</observers>
|
| 29 |
+
</checkout_cart_save_after>
|
| 30 |
+
|
| 31 |
+
<checkout_submit_all_after>
|
| 32 |
+
<observers>
|
| 33 |
+
<onSaveOrder>
|
| 34 |
+
<type>singleton</type>
|
| 35 |
+
<class>Intuiko_ConnectedStore_Model_Observer</class>
|
| 36 |
+
<method>onSaveOrder</method>
|
| 37 |
+
</onSaveOrder>
|
| 38 |
+
</observers>
|
| 39 |
+
</checkout_submit_all_after>
|
| 40 |
+
|
| 41 |
+
<wishlist_items_renewed>
|
| 42 |
+
<observers>
|
| 43 |
+
<onSaveWishlist>
|
| 44 |
+
<type>singleton</type>
|
| 45 |
+
<class>Intuiko_ConnectedStore_Model_Observer</class>
|
| 46 |
+
<method>onSaveWishlist</method>
|
| 47 |
+
</onSaveWishlist>
|
| 48 |
+
</observers>
|
| 49 |
+
</wishlist_items_renewed>
|
| 50 |
+
|
| 51 |
+
<customer_login>
|
| 52 |
+
<observers>
|
| 53 |
+
<onLogin>
|
| 54 |
+
<type>singleton</type>
|
| 55 |
+
<class>Intuiko_ConnectedStore_Model_Observer</class>
|
| 56 |
+
<method>onLogin</method>
|
| 57 |
+
</onLogin>
|
| 58 |
+
</observers>
|
| 59 |
+
</customer_login>
|
| 60 |
+
|
| 61 |
+
<customer_logout>
|
| 62 |
+
<observers>
|
| 63 |
+
<onLogout>
|
| 64 |
+
<type>singleton</type>
|
| 65 |
+
<class>Intuiko_ConnectedStore_Model_Observer</class>
|
| 66 |
+
<method>onLogout</method>
|
| 67 |
+
</onLogout>
|
| 68 |
+
</observers>
|
| 69 |
+
</customer_logout>
|
| 70 |
+
|
| 71 |
+
<customer_save_after>
|
| 72 |
+
<observers>
|
| 73 |
+
<onCustomerSaveAfter>
|
| 74 |
+
<type>singleton</type>
|
| 75 |
+
<class>Intuiko_ConnectedStore_Model_Observer</class>
|
| 76 |
+
<method>onCustomerSaveAfter</method>
|
| 77 |
+
</onCustomerSaveAfter>
|
| 78 |
+
</observers>
|
| 79 |
+
</customer_save_after>
|
| 80 |
+
|
| 81 |
+
<controller_action_predispatch>
|
| 82 |
+
<observers>
|
| 83 |
+
<synchroCart>
|
| 84 |
+
<type>singleton</type>
|
| 85 |
+
<class>Intuiko_ConnectedStore_Model_Observer</class>
|
| 86 |
+
<method>synchroBag</method>
|
| 87 |
+
</synchroCart>
|
| 88 |
+
</observers>
|
| 89 |
+
</controller_action_predispatch>
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
<controller_action_layout_generate_blocks_after>
|
| 93 |
+
<observers>
|
| 94 |
+
<synchroCart>
|
| 95 |
+
<type>singleton</type>
|
| 96 |
+
<class>Intuiko_ConnectedStore_Model_Observer</class>
|
| 97 |
+
<method>resetFlagSynchro</method>
|
| 98 |
+
</synchroCart>
|
| 99 |
+
</observers>
|
| 100 |
+
</controller_action_layout_generate_blocks_after>
|
| 101 |
+
|
| 102 |
+
</events>
|
| 103 |
+
|
| 104 |
+
</frontend>
|
| 105 |
+
|
| 106 |
+
<global>
|
| 107 |
+
|
| 108 |
+
<helpers>
|
| 109 |
+
<connectedstore>
|
| 110 |
+
<class>Intuiko_ConnectedStore_Helper</class>
|
| 111 |
+
</connectedstore>
|
| 112 |
+
</helpers>
|
| 113 |
+
|
| 114 |
+
<models>
|
| 115 |
+
<connectedstore>
|
| 116 |
+
<class>Intuiko_ConnectedStore_Model</class>
|
| 117 |
+
</connectedstore>
|
| 118 |
+
</models>
|
| 119 |
+
|
| 120 |
+
<blocks>
|
| 121 |
+
<connectedstore>
|
| 122 |
+
<class>Intuiko_ConnectedStore_Block</class>
|
| 123 |
+
</connectedstore>
|
| 124 |
+
</blocks>
|
| 125 |
+
|
| 126 |
+
</global>
|
| 127 |
+
|
| 128 |
+
<default>
|
| 129 |
+
<connectedstore_section>
|
| 130 |
+
<connectedstore_group>
|
| 131 |
+
<timeout_field>5000</timeout_field>
|
| 132 |
+
</connectedstore_group>
|
| 133 |
+
</connectedstore_section>
|
| 134 |
+
</default>
|
| 135 |
+
|
| 136 |
+
</config>
|
app/code/local/Intuiko/ConnectedStore/etc/system.xml
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<config>
|
| 3 |
+
<tabs>
|
| 4 |
+
<connectedstore_tab translate="label">
|
| 5 |
+
<label>Connected Store</label>
|
| 6 |
+
<sort_order>100</sort_order>
|
| 7 |
+
</connectedstore_tab>
|
| 8 |
+
</tabs>
|
| 9 |
+
<sections>
|
| 10 |
+
<connectedstore_section translate="label">
|
| 11 |
+
<label>Parameters</label>
|
| 12 |
+
<sort_order>200</sort_order>
|
| 13 |
+
<show_in_default>1</show_in_default>
|
| 14 |
+
<show_in_website>1</show_in_website>
|
| 15 |
+
<show_in_store>1</show_in_store>
|
| 16 |
+
<tab>connectedstore_tab</tab>
|
| 17 |
+
<groups>
|
| 18 |
+
<connectedstore_group translate="label">
|
| 19 |
+
<label>Connected Store</label>
|
| 20 |
+
<comment>Connection parameters</comment>
|
| 21 |
+
<sort_order>10</sort_order>
|
| 22 |
+
<show_in_default>1</show_in_default>
|
| 23 |
+
<show_in_website>1</show_in_website>
|
| 24 |
+
<show_in_store>1</show_in_store>
|
| 25 |
+
<fields>
|
| 26 |
+
<status_field translate="label tooltip">
|
| 27 |
+
<label>ICS Connector Status</label>
|
| 28 |
+
<tooltip>Activate or Deactivate the ICS connector</tooltip>
|
| 29 |
+
<show_in_default>1</show_in_default>
|
| 30 |
+
<show_in_website>1</show_in_website>
|
| 31 |
+
<show_in_store>1</show_in_store>
|
| 32 |
+
<frontend_type>select</frontend_type>
|
| 33 |
+
<source_model>Mage_Adminhtml_Model_System_Config_Source_Enabledisable</source_model>
|
| 34 |
+
<sort_order>1</sort_order>
|
| 35 |
+
</status_field>
|
| 36 |
+
<tenantid_field translate="label tooltip">
|
| 37 |
+
<label>Tenant Id</label>
|
| 38 |
+
<tooltip>Your tenant Id</tooltip>
|
| 39 |
+
<show_in_default>1</show_in_default>
|
| 40 |
+
<show_in_website>1</show_in_website>
|
| 41 |
+
<show_in_store>1</show_in_store>
|
| 42 |
+
<frontend_input>text</frontend_input>
|
| 43 |
+
<sort_order>2</sort_order>
|
| 44 |
+
</tenantid_field>
|
| 45 |
+
<urlservice_field translate="label tooltip">
|
| 46 |
+
<label>Url Service</label>
|
| 47 |
+
<tooltip>The url of the service</tooltip>
|
| 48 |
+
<show_in_default>1</show_in_default>
|
| 49 |
+
<show_in_website>1</show_in_website>
|
| 50 |
+
<show_in_store>1</show_in_store>
|
| 51 |
+
<frontend_input>text</frontend_input>
|
| 52 |
+
<sort_order>3</sort_order>
|
| 53 |
+
</urlservice_field>
|
| 54 |
+
<brandid_field translate="label tooltip">
|
| 55 |
+
<label>Brand Id</label>
|
| 56 |
+
<tooltip>Your Brand Id</tooltip>
|
| 57 |
+
<show_in_default>1</show_in_default>
|
| 58 |
+
<show_in_website>1</show_in_website>
|
| 59 |
+
<show_in_store>1</show_in_store>
|
| 60 |
+
<frontend_input>text</frontend_input>
|
| 61 |
+
<sort_order>4</sort_order>
|
| 62 |
+
</brandid_field>
|
| 63 |
+
<apikey_field translate="label tooltip">
|
| 64 |
+
<label>Api Key</label>
|
| 65 |
+
<tooltip>Your API Key</tooltip>
|
| 66 |
+
<show_in_default>1</show_in_default>
|
| 67 |
+
<show_in_website>1</show_in_website>
|
| 68 |
+
<show_in_store>0</show_in_store>
|
| 69 |
+
<frontend_input>text</frontend_input>
|
| 70 |
+
<sort_order>5</sort_order>
|
| 71 |
+
</apikey_field>
|
| 72 |
+
<mergemethod_field translate="label tooltip">
|
| 73 |
+
<label>Bag Merge Method</label>
|
| 74 |
+
<tooltip>Your bag merge method</tooltip>
|
| 75 |
+
<show_in_default>1</show_in_default>
|
| 76 |
+
<show_in_website>1</show_in_website>
|
| 77 |
+
<show_in_store>0</show_in_store>
|
| 78 |
+
<frontend_type>select</frontend_type>
|
| 79 |
+
<source_model>Intuiko_ConnectedStore_Model_MergeMethods</source_model>
|
| 80 |
+
<sort_order>6</sort_order>
|
| 81 |
+
</mergemethod_field>
|
| 82 |
+
<timeout_field translate="label tooltip">
|
| 83 |
+
<label>ICS API Calls Timeout (ms)</label>
|
| 84 |
+
<tooltip>value in millisecond(s)</tooltip>
|
| 85 |
+
<validate>validate-not-negative-number</validate>
|
| 86 |
+
<show_in_default>1</show_in_default>
|
| 87 |
+
<show_in_website>1</show_in_website>
|
| 88 |
+
<show_in_store>0</show_in_store>
|
| 89 |
+
<frontend_input>int</frontend_input>
|
| 90 |
+
<sort_order>7</sort_order>
|
| 91 |
+
</timeout_field>
|
| 92 |
+
<ping_field translate="label tooltip">
|
| 93 |
+
<!-- <tooltip><![CDATA[Do a ping in order to test your connection to the ICS API.<br/> Note: Do not forget to save your last modifications before running this test.]]></tooltip> -->
|
| 94 |
+
<label><![CDATA[Test your connection<br/> Note: Do not forget to save your last modifications before running this test.]]></label>
|
| 95 |
+
<show_in_default>1</show_in_default>
|
| 96 |
+
<show_in_website>1</show_in_website>
|
| 97 |
+
<show_in_store>0</show_in_store>
|
| 98 |
+
<frontend_input>button</frontend_input>
|
| 99 |
+
<sort_order>8</sort_order>
|
| 100 |
+
<frontend_model>connectedstore/button</frontend_model>
|
| 101 |
+
</ping_field>
|
| 102 |
+
</fields>
|
| 103 |
+
</connectedstore_group>
|
| 104 |
+
</groups>
|
| 105 |
+
</connectedstore_section>
|
| 106 |
+
</sections>
|
| 107 |
+
</config>
|
app/etc/modules/Intuiko_All.xml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<config>
|
| 3 |
+
<modules>
|
| 4 |
+
<Intuiko_ConnectedStore>
|
| 5 |
+
<active>true</active>
|
| 6 |
+
<codePool>local</codePool>
|
| 7 |
+
</Intuiko_ConnectedStore>
|
| 8 |
+
</modules>
|
| 9 |
+
</config>
|
package.xml
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0"?>
|
| 2 |
+
<package><name>ICS_Connector</name><version>1.3.1</version><stability>stable</stability><license>MPL</license><channel>community</channel><extends></extends><summary>The Magento Connector developed alongside Intuiko for Connected Store is a two-way connector.</summary><description>The Magento Connector developed alongside Intuiko for Connected Store is a two-way connector.&#xD;Intuiko has developed a module that allows you to manage carts and wishlists from a Magento webiste which uses the Intuiko for Connected Store API.&#xD;</description><notes>Version 1.3.1.</notes><authors><author><name>Intuiko</name><user>Intuiko</user><email>support.ics@intuiko.com</email></author></authors><date>2014-12-01</date><time>0:48:05</time><compatible></compatible><dependencies><required><php><min>5.0.0</min><max>6.0.0</max></php></required></dependencies><contents><target name="mage"><dir name="app"><dir name="etc"><dir name="modules"><file name="Intuiko_All.xml" hash="335ba38d9a767e0cb30c0dc69067652d"/></dir></dir><dir name="code"><dir name="local"><dir name="Intuiko"><dir name="ConnectedStore"><file name="Exception.php" hash="ff373acc5dbd57184595ed7ef2c99426"/><dir name="controllers"><file name="PingController.php" hash="d6fe17473922d65b49a9928a7a299d70"/></dir><dir name="Model"><file name="Bag.php" hash="4eee9a59f438c978e4457d895dd7df5c"/><file name="Cart.php" hash="ecc51597ff0558aae69d70195b033414"/><file name="Customer.php" hash="3338d954f9b67eaacc5d6d50c4d3bb03"/><file name="Entities.php" hash="2e7973982f97c7996219f247106e4665"/><file name="MergeMethods.php" hash="a56c244e7320557556ddf3d445f2ccc9"/><file name="Messages.php" hash="cec65dce8066fb0a16d7bc06585b269e"/><file name="Observer.php" hash="4e33b2276335b21e2331fb74b45acdf1"/><file name="Order.php" hash="758d1c4dcc51e773d05a67f9b2dc06ce"/><file name="Wishlist.php" hash="9475611fc24b04a4ae02d7cdf7083195"/><dir name="Resource"><file name="ICSResource.php" hash="df0d7c0cac29dfb09fa68ac4c055fed5"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="08bc5ce6d52b3d3dff3d00dc5e5e3b9d"/><file name="config.xml" hash="d2c80100bda8a1ebb66933fb3875bdd2"/><file name="system.xml" hash="031a4b2c1b93687d4e8f81a22a9fe9a9"/></dir><dir name="Helper"><file name="ICSHelper.php" hash="e22435138ab252ab6cb9e033b8f82562"/><file name="ICSTwitterHelper.php" hash="e0b970d299200a0987b853a6f7120d5c"/></dir><dir name="Block"><file name="Button.php" hash="b266514f04677886a8b23a3311338570"/></dir><dir name="Logger"><file name="ICSLogger.php" hash="8cf2fc0098040f94c5fdd158be269497"/></dir></dir></dir></dir></dir></dir></target></contents></package>
|
