amazonus.php (15340B)
1 <?php 2 namespace openbay; 3 4 final class Amazonus { 5 private $token; 6 private $encryption_key; 7 private $encryption_iv; 8 private $url = 'https://us-amazon.openbaypro.com/'; 9 private $registry; 10 11 public function __construct($registry) { 12 $this->registry = $registry; 13 $this->token = $this->config->get('openbay_amazonus_token'); 14 15 $this->setEncryptionKey($this->config->get('openbay_amazonus_encryption_key')); 16 $this->setEncryptionIv($this->config->get('openbay_amazonus_encryption_iv')); 17 } 18 19 public function __get($name) { 20 return $this->registry->get($name); 21 } 22 23 public function getEncryptionKey() { 24 return $this->encryption_key; 25 } 26 27 public function setEncryptionKey($key) { 28 $this->encryption_key = $key; 29 } 30 31 public function getEncryptionIv() { 32 return $this->encryption_iv; 33 } 34 35 public function setEncryptionIv($encryption_iv) { 36 $this->encryption_iv = $encryption_iv; 37 } 38 39 public function call($method, $data = array(), $use_json = true) { 40 if (!empty($data)) { 41 if ($use_json) { 42 $string = json_encode($data); 43 } else { 44 $string = $data; 45 } 46 47 $encrypted = $this->openbay->encrypt($string, $this->getEncryptionKey(), $this->getEncryptionIv(), false); 48 } else { 49 $encrypted = ''; 50 } 51 52 $post_data = array( 53 'token' => $this->token, 54 'data' => rawurlencode(base64_encode($encrypted)), 55 'opencart_version' => VERSION 56 ); 57 58 $headers = array(); 59 $headers[] = 'X-Endpoint-Version: 2'; 60 61 $defaults = array( 62 CURLOPT_HEADER => 0, 63 CURLOPT_HTTPHEADER => $headers, 64 CURLOPT_POST => 1, 65 CURLOPT_URL => $this->url . $method, 66 CURLOPT_USERAGENT => 'OpenBay Pro for Amazonus/Opencart', 67 CURLOPT_FRESH_CONNECT => 1, 68 CURLOPT_RETURNTRANSFER => 1, 69 CURLOPT_FORBID_REUSE => 1, 70 CURLOPT_TIMEOUT => 30, 71 CURLOPT_SSL_VERIFYPEER => 0, 72 CURLOPT_SSL_VERIFYHOST => 0, 73 CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"), 74 ); 75 76 $curl = curl_init(); 77 78 curl_setopt_array($curl, $defaults); 79 80 $response = curl_exec($curl); 81 82 curl_close($curl); 83 84 return $response; 85 } 86 87 public function callNoResponse($method, $data = array(), $use_json = true) { 88 if (!empty($data)) { 89 if ($use_json) { 90 $string = json_encode($data); 91 } else { 92 $string = $data; 93 } 94 95 $encrypted = $this->openbay->encrypt($string, $this->getEncryptionKey(), $this->getEncryptionIv(), false); 96 } else { 97 $encrypted = ''; 98 } 99 100 $post_data = array( 101 'token' => $this->token, 102 'data' => rawurlencode(base64_encode($encrypted)), 103 'opencart_version' => VERSION 104 ); 105 106 $headers = array(); 107 $headers[] = 'X-Endpoint-Version: 2'; 108 109 $defaults = array( 110 CURLOPT_HEADER => 0, 111 CURLOPT_HTTPHEADER => $headers, 112 CURLOPT_POST => 1, 113 CURLOPT_URL => $this->url . $method, 114 CURLOPT_USERAGENT => 'OpenBay Pro for Amazonus/Opencart', 115 CURLOPT_FRESH_CONNECT => 1, 116 CURLOPT_RETURNTRANSFER => 1, 117 CURLOPT_FORBID_REUSE => 1, 118 CURLOPT_TIMEOUT => 2, 119 CURLOPT_SSL_VERIFYPEER => 0, 120 CURLOPT_SSL_VERIFYHOST => 0, 121 CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"), 122 ); 123 $curl = curl_init(); 124 125 curl_setopt_array($curl, $defaults); 126 127 curl_exec($curl); 128 129 curl_close($curl); 130 } 131 132 public function getServer() { 133 return $this->url; 134 } 135 136 public function productUpdateListen($product_id, $data = array()) { 137 $logger = new \Log('amazonus_stocks.log'); 138 $logger->write('productUpdateListen(), product ID: ' . $product_id); 139 140 $product = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "' LIMIT 1")->row; 141 142 if ($this->openbay->addonLoad('openstock') && (isset($product['has_option']) && $product['has_option'] == 1)) { 143 $this->load->model('extension/module/openstock'); 144 $logger->write('Variant item'); 145 146 $quantity_data = array(); 147 148 // check if post data['variant'], if not then call db to get variants 149 if (!isset($data['variant'])) { 150 $variants = $this->model_extension_module_openstock->getVariants($product_id); 151 } else { 152 $variants = $data['variant']; 153 } 154 155 foreach ($variants as $variant) { 156 $amazon_sku_rows = $this->db->query("SELECT `amazonus_sku` FROM `" . DB_PREFIX . "amazonus_product_link` WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($variant['sku']) . "'")->rows; 157 158 foreach($amazon_sku_rows as $amazon_sku_row) { 159 $quantity_data[$amazon_sku_row['amazonus_sku']] = $variant['stock']; 160 } 161 } 162 163 if(!empty($quantity_data)) { 164 $logger->write('Updating with: ' . print_r($quantity_data, true)); 165 $this->updateQuantities($quantity_data); 166 } else { 167 $logger->write('Not required.'); 168 } 169 } else { 170 $this->putStockUpdateBulk(array($product_id)); 171 } 172 173 $logger->write('productUpdateListen() - finished'); 174 } 175 176 public function bulkUpdateOrders($orders) { 177 // Is the module enabled and called from admin? 178 if ($this->config->get('openbay_amazonus_status') != 1 || !defined('HTTPS_CATALOG')) { 179 return; 180 } 181 $this->load->model('extension/openbay/amazonus'); 182 183 $log = new \Log('amazonus.log'); 184 $log->write('Called bulkUpdateOrders method'); 185 186 $request = array( 187 'orders' => array(), 188 ); 189 190 foreach ($orders as $order) { 191 $amazon_order = $this->getOrder($order['order_id']); 192 $amazon_order_products = $this->model_extension_openbay_amazonus->getAmazonusOrderedProducts($order['order_id']); 193 194 $products = array(); 195 196 foreach ($amazon_order_products as $amazon_order_product) { 197 $products[] = array( 198 'amazon_order_item_id' => $amazon_order_product['amazonus_order_item_id'], 199 'quantity' => $amazon_order_product['quantity'], 200 ); 201 } 202 203 $order_info = array( 204 'amazon_order_id' => $amazon_order['amazonus_order_id'], 205 'status' => $order['status'], 206 'products' => $products, 207 ); 208 209 if ($order['status'] == 'shipped' && !empty($order['carrier'])) { 210 if ($order['carrier_from_list']) { 211 $order_info['carrier_id'] = $order['carrier']; 212 } else { 213 $order_info['carrier_name'] = $order['carrier']; 214 } 215 216 $order_info['tracking'] = $order['tracking']; 217 } 218 219 $request['orders'][] = $order_info; 220 } 221 222 $log->write('order/bulkUpdate call: ' . print_r($request, 1)); 223 224 $response = $this->call('order/bulkUpdate', $request); 225 226 $log->write('order/bulkUpdate response: ' . $response); 227 } 228 229 public function updateOrder($order_id, $order_status_string, $courier_id = '', $courier_from_list = true, $tracking_no = '') { 230 231 if ($this->config->get('openbay_amazonus_status') != 1) { 232 return; 233 } 234 235 /* Is called from admin? */ 236 if (!defined('HTTPS_CATALOG')) { 237 return; 238 } 239 240 $amazonus_order = $this->getOrder($order_id); 241 242 if(!$amazonus_order) { 243 return; 244 } 245 246 $amazonus_order_id = $amazonus_order['amazonus_order_id']; 247 248 $log = new \Log('amazonus.log'); 249 $log->write("Order's $amazonus_order_id status changed to $order_status_string"); 250 251 $this->load->model('extension/openbay/amazonus'); 252 $amazonus_order_products = $this->model_extension_openbay_amazonus->getAmazonusOrderedProducts($order_id); 253 254 $request_node = new \SimpleXMLElement('<Request/>'); 255 256 $request_node->addChild('AmazonusOrderId', $amazonus_order_id); 257 $request_node->addChild('Status', $order_status_string); 258 259 if(!empty($courier_id)) { 260 if($courier_from_list) { 261 $request_node->addChild('CourierId', $courier_id); 262 } else { 263 $request_node->addChild('CourierOther', $courier_id); 264 } 265 $request_node->addChild('TrackingNo', $tracking_no); 266 } 267 268 $order_items_node = $request_node->addChild('OrderItems'); 269 270 foreach ($amazonus_order_products as $product) { 271 $new_order_item = $order_items_node->addChild('OrderItem'); 272 $new_order_item->addChild('ItemId', htmlspecialchars($product['amazonus_order_item_id'])); 273 $new_order_item->addChild('Quantity', (int)$product['quantity']); 274 } 275 276 $doc = new \DOMDocument('1.0'); 277 $doc->preserveWhiteSpace = false; 278 $doc->loadXML($request_node->asXML()); 279 $doc->formatOutput = true; 280 281 $this->model_extension_openbay_amazonus->updateAmazonusOrderTracking($order_id, $courier_id, $courier_from_list, !empty($courier_id) ? $tracking_no : ''); 282 $log->write('Request: ' . $doc->saveXML()); 283 $response = $this->call('order/update2', $doc->saveXML(), false); 284 $log->write("Response for Order's status update: $response"); 285 } 286 287 public function getCategoryTemplates() { 288 $result = $this->call("productv2/RequestTemplateList"); 289 if(isset($result)) { 290 return (array)json_decode($result); 291 } else { 292 return array(); 293 } 294 } 295 296 public function registerInsertion($data) { 297 $result = $this->call("productv2/RegisterInsertionRequest", $data); 298 if(isset($result)) { 299 return (array)json_decode($result); 300 } else { 301 return array(); 302 } 303 } 304 305 public function insertProduct($data) { 306 $result = $this->call("productv2/InsertProductRequest", $data); 307 if(isset($result)) { 308 return (array)json_decode($result); 309 } else { 310 return array(); 311 } 312 } 313 314 public function updateQuantities($data) { 315 $result = $this->call("product/UpdateQuantityRequest", $data); 316 if(isset($result)) { 317 return (array)json_decode($result); 318 } else { 319 return array(); 320 } 321 } 322 323 public function getStockUpdatesStatus($data) { 324 $result = $this->call("status/StockUpdates", $data); 325 if(isset($result)) { 326 return $result; 327 } else { 328 return false; 329 } 330 } 331 332 public function putStockUpdateBulk($product_id_array, $end_inactive = false){ 333 $logger = new \Log('amazonus_stocks.log'); 334 $logger->write('putStockUpdateBulk(), End inactive: ' . $end_inactive . ', ids: ' . json_encode($product_id_array)); 335 336 $quantity_data = array(); 337 338 foreach($product_id_array as $product_id) { 339 $linked_skus = $this->db->query("SELECT `amazonus_sku` FROM `" . DB_PREFIX . "amazonus_product_link` WHERE `product_id` = '" . (int)$product_id . "'")->rows; 340 341 if (!empty($linked_skus)) { 342 foreach($linked_skus as $sku) { 343 $product = $this->db->query("SELECT quantity, status FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "'")->row; 344 345 if(!empty($product)) { 346 if($end_inactive && $product['status'] == '0') { 347 $quantity_data[$sku['amazonus_sku']] = 0; 348 } else { 349 $quantity_data[$sku['amazonus_sku']] = $product['quantity']; 350 } 351 } 352 } 353 } else { 354 $logger->write('No linked SKU'); 355 } 356 } 357 358 if(!empty($quantity_data)) { 359 $logger->write('New Qty:' . print_r($quantity_data, true)); 360 361 $response = $this->updateQuantities($quantity_data); 362 363 $logger->write('API Response: ' . print_r($response, true)); 364 } else { 365 $logger->write('No update needed'); 366 } 367 } 368 369 public function getOrderdProducts($order_id) { 370 return $this->db->query("SELECT `op`.`product_id`, `p`.`quantity` as `quantity_left` FROM `" . DB_PREFIX . "order_product` as `op` LEFT JOIN `" . DB_PREFIX . "product` as `p` ON `p`.`product_id` = `op`.`product_id` WHERE `op`.`order_id` = '" . (int)$order_id . "'")->rows; 371 } 372 373 public function validate() { 374 if ($this->config->get('openbay_amazonus_status') != 0 && 375 $this->config->get('openbay_amazonus_token') != '' && 376 $this->config->get('openbay_amazonus_encryption_key') != '' && 377 $this->config->get('openbay_amazonus_encryption_iv') != '') { 378 return true; 379 } else { 380 return false; 381 } 382 } 383 384 public function deleteProduct($product_id){ 385 $this->db->query("DELETE FROM `" . DB_PREFIX . "amazonus_product_link` WHERE `product_id` = '" . (int)$product_id . "'"); 386 } 387 388 public function orderDelete($order_id){ 389 /** 390 * @todo 391 */ 392 } 393 394 public function getOrder($order_id) { 395 $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazonus_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1"); 396 397 if ($qry->num_rows > 0) { 398 return $qry->row; 399 } else { 400 return false; 401 } 402 } 403 404 public function getCarriers() { 405 return array( 406 "Blue Package", 407 "Canada Post", 408 "City Link", 409 "DHL", 410 "DHL Global Mail", 411 "Fastway", 412 "FedEx", 413 "FedEx SmartPost", 414 "GLS", 415 "GO!", 416 "Hermes Logistik Gruppe", 417 "Newgistics", 418 "NipponExpress", 419 "OSM", 420 "OnTrac", 421 "Parcelforce", 422 "Royal Mail", 423 "SagawaExpress", 424 "Streamlite", 425 "TNT", 426 "Target", 427 "UPS", 428 "UPS Mail Innovations", 429 "USPS", 430 "YamatoTransport", 431 ); 432 } 433 434 public function parseCategoryTemplate($xml) { 435 $simplexml = null; 436 437 libxml_use_internal_errors(true); 438 if(($simplexml = simplexml_load_string($xml)) == false) { 439 return false; 440 } 441 442 $category = (string)$simplexml->filename; 443 444 $tabs = array(); 445 foreach($simplexml->tabs->tab as $tab) { 446 $attributes = $tab->attributes(); 447 $tabs[] = array( 448 'id' => (string)$attributes['id'], 449 'name' => (string)$tab->name, 450 ); 451 } 452 453 $fields = array(); 454 $field_types = array('required', 'desired', 'optional'); 455 foreach ($field_types as $type) { 456 foreach ($simplexml->fields->$type->field as $field) { 457 $attributes = $field->attributes(); 458 $fields[] = array( 459 'name' => (string)$attributes['name'], 460 'title' => (string)$field->title, 461 'definition' => (string)$field->definition, 462 'accepted' => (array)$field->accepted, 463 'type' => (string)$type, 464 'child' => false, 465 'order' => (isset($attributes['order'])) ? (string)$attributes['order'] : '', 466 'tab' => (string)$attributes['tab'], 467 ); 468 } 469 foreach ($simplexml->fields->$type->childfield as $field) { 470 $attributes = $field->attributes(); 471 $fields[] = array( 472 'name' => (string)$attributes['name'], 473 'title' => (string)$field->title, 474 'definition' => (string)$field->definition, 475 'accepted' => (array)$field->accepted, 476 'type' => (string)$type, 477 'child' => true, 478 'parent' => (array)$field->parent, 479 'order' => (isset($attributes['order'])) ? (string)$attributes['order'] : '', 480 'tab' => (string)$attributes['tab'], 481 ); 482 } 483 } 484 485 foreach($fields as $index => $field) { 486 $fields[$index]['unordered_index'] = $index; 487 } 488 489 usort($fields, array('openbay\Amazonus','compareFields')); 490 491 return array( 492 'category' => $category, 493 'fields' => $fields, 494 'tabs' => $tabs, 495 ); 496 } 497 498 private static function compareFields($field1, $field2) { 499 if($field1['order'] == $field2['order']) { 500 return ($field1['unordered_index'] < $field2['unordered_index']) ? -1 : 1; 501 } else if(!empty($field1['order']) && empty($field2['order'])) { 502 return -1; 503 } else if(!empty($field2['order']) && empty($field1['order'])) { 504 return 1; 505 } else { 506 return ($field1['order'] < $field2['order']) ? -1 : 1; 507 } 508 } 509 }