etsy.php (15168B)
1 <?php 2 namespace openbay; 3 4 final class Etsy { 5 private $token; 6 private $encryption_key; 7 private $encryption_iv; 8 private $url = 'https://api.openbaypro.io/'; 9 private $registry; 10 private $logger; 11 private $max_log_size = 50; //max log size in Mb 12 13 public function __construct($registry) { 14 $this->registry = $registry; 15 $this->token = $this->config->get('etsy_token'); 16 $this->logging = $this->config->get('etsy_logging'); 17 18 if ($this->logging == 1) { 19 $this->setLogger(); 20 } 21 22 $this->setEncryptionKey($this->config->get('etsy_encryption_key')); 23 $this->setEncryptionIv($this->config->get('etsy_encryption_iv')); 24 } 25 26 public function __get($name) { 27 return $this->registry->get($name); 28 } 29 30 public function getEncryptionKey() { 31 return $this->encryption_key; 32 } 33 34 public function setEncryptionKey($key) { 35 $this->encryption_key = $key; 36 } 37 38 public function getEncryptionIv() { 39 return $this->encryption_iv; 40 } 41 42 public function setEncryptionIv($encryption_iv) { 43 $this->encryption_iv = $encryption_iv; 44 } 45 46 public function resetConfig($token, $encryption_key) { 47 $this->token = $token; 48 $this->setEncryptionKey($encryption_key); 49 } 50 51 public function call($uri, $method, $data = array()) { 52 if($this->config->get('etsy_status') == 1) { 53 $headers = array (); 54 $headers[] = 'X-Auth-Token: ' . $this->token; 55 $headers[] = 'X-Endpoint-Version: 2'; 56 $headers[] = 'Content-Type: application/json'; 57 //$headers[] = 'Content-Length: '.strlen(json_encode($data)); 58 59 $defaults = array( 60 CURLOPT_HEADER => 0, 61 CURLOPT_HTTPHEADER => $headers, 62 CURLOPT_URL => $this->url . $uri, 63 CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1", 64 CURLOPT_FRESH_CONNECT => 1, 65 CURLOPT_RETURNTRANSFER => 1, 66 CURLOPT_FORBID_REUSE => 1, 67 CURLOPT_TIMEOUT => 10, 68 CURLOPT_SSL_VERIFYPEER => 0, 69 CURLOPT_SSL_VERIFYHOST => 0, 70 //CURLOPT_VERBOSE => true, 71 //CURLOPT_STDERR => fopen(DIR_LOGS . 'curl_verbose.log', "w+") 72 ); 73 74 if ($method == 'POST') { 75 $defaults[CURLOPT_POST] = 1; 76 $defaults[CURLOPT_POSTFIELDS] = json_encode($data); 77 } 78 79 $curl = curl_init(); 80 curl_setopt_array($curl, $defaults); 81 82 $response = array(); 83 84 if (! $result = curl_exec($curl)) { 85 $this->log('call() - Curl Failed ' . curl_error($curl) . ' ' . curl_errno($curl)); 86 87 return false; 88 } else { 89 $this->log('call() - Result of : "' . print_r($result, true) . '"'); 90 91 $encoding = mb_detect_encoding($result); 92 93 if($encoding == 'UTF-8') { 94 $result = preg_replace('/[^(\x20-\x7F)]*/', '', $result); 95 } 96 97 $result = json_decode($result, 1); 98 99 $response['header_code'] = curl_getinfo($curl, CURLINFO_HTTP_CODE); 100 101 if(!empty($result)) { 102 $response['data'] = $result; 103 } else { 104 $response['data'] = ''; 105 } 106 } 107 108 curl_close($curl); 109 110 return $response; 111 } else { 112 $this->log('call() - OpenBay Pro / Etsy not active'); 113 114 return false; 115 } 116 } 117 118 private function setLogger() { 119 if (file_exists(DIR_LOGS . 'etsylog.log')) { 120 if (filesize(DIR_LOGS . 'etsylog.log') > ($this->max_log_size * 1000000)) { 121 rename(DIR_LOGS . 'etsylog.log', DIR_LOGS . '_etsylog_' . date('Y-m-d_H-i-s') . '.log'); 122 } 123 } 124 125 $this->logger = new \Log('etsylog.log'); 126 } 127 128 public function log($data, $write = true) { 129 if ($this->logging == 1) { 130 if (function_exists('getmypid')) { 131 $process_id = getmypid(); 132 $data = $process_id . ' - ' . print_r($data, true); 133 } 134 135 $this->logger->write($data); 136 } 137 } 138 139 public function getServer() { 140 return $this->url; 141 } 142 143 public function settingsUpdate() { 144 $this->log("settingsUpdate() - start"); 145 146 $response = $this->call('v1/etsy/data/type/getSetup/', 'GET'); 147 148 if (isset($response['data']) && is_array($response['data'])) { 149 foreach ($response['data'] as $key => $options) { 150 $this->db->query("DELETE FROM `" . DB_PREFIX . "etsy_setting_option` WHERE `key` = '" . $this->db->escape($key) . "' LIMIT 1"); 151 152 $this->db->query("INSERT INTO `" . DB_PREFIX . "etsy_setting_option` SET `data` = '" . $this->db->escape(json_encode($options)) . "', `key` = '" . $this->db->escape($key) . "', `last_updated` = now()"); 153 154 $this->log("settingsUpdate() - updated option: " . $key); 155 } 156 157 $this->log("settingsUpdate() - complete"); 158 } else { 159 $this->log("settingsUpdate() - failed - no data response"); 160 } 161 } 162 163 public function getSetting($key) { 164 $this->log("getSetting() - " . $key); 165 166 $qry = $this->db->query("SELECT `data` FROM `" . DB_PREFIX . "etsy_setting_option` WHERE `key` = '" . $this->db->escape($key) . "' LIMIT 1"); 167 168 if($qry->num_rows > 0) { 169 $this->log("getSetting() - Found setting"); 170 171 return json_decode($qry->row['data']); 172 } else { 173 return false; 174 } 175 } 176 177 public function getLinks($product_id, $status = 0, $limit = null) { 178 $this->log("getLinks() - Product_id: " . $product_id . " status: " . $status . " limit:" . $limit); 179 180 if ($limit != null) { 181 $sql_limit = ' LIMIT 1'; 182 } else { 183 $sql_limit = ''; 184 } 185 186 $qry = $this->db->query("SELECT `el`.*, `p`.`quantity` FROM `" . DB_PREFIX . "etsy_listing` `el` LEFT JOIN `" . DB_PREFIX . "product` `p` ON `el`.`product_id` = `p`.`product_id` WHERE `el`.`product_id` = '" . (int)$product_id . "' AND `el`.`status` = '" . (int)$status . "' ORDER BY `el`.`created` DESC" . $sql_limit); 187 188 if ($qry->num_rows) { 189 $this->log("getLinks() - " . $qry->num_rows . " found"); 190 191 $links = array(); 192 193 foreach ($qry->rows as $row) { 194 $links[] = $row; 195 } 196 197 return $links; 198 } else { 199 $this->log("getLinks() - no links found"); 200 201 return false; 202 } 203 } 204 205 public function getLinkedProduct($etsy_item_id) { 206 $this->log("getLinkedProduct() - etsy_item_id: " . $etsy_item_id); 207 208 $qry = $this->db->query("SELECT `p`.`quantity`, `p`.`product_id`, `p`.`model`, `el`.`etsy_listing_id`, `el`.`status` AS `link_status` FROM `" . DB_PREFIX . "etsy_listing` `el` LEFT JOIN `" . DB_PREFIX . "product` `p` ON `p`.`product_id` = `el`.`product_id` WHERE `el`.`etsy_item_id` = '" . (int)$etsy_item_id . "' AND `el`.`status` = 1"); 209 210 if($qry->num_rows) { 211 $this->log("getLinkedProduct() - " . $qry->num_rows . " found"); 212 213 return $qry->row; 214 } else { 215 $this->log("getLinkedProduct() - no link found"); 216 217 return false; 218 } 219 } 220 221 public function updateListingStock($etsy_item_id, $new_stock, $status) { 222 $this->log("updateListingStock() - ItemID: " . $etsy_item_id . ", new stock: " . $new_stock . ", status: " . $status); 223 224 if ($new_stock > 0) { 225 $this->log("updateListingStock() - stock > 0 - update stock"); 226 227 if ($status == 'edit') { 228 $status = 'inactive'; 229 } 230 231 $response = $this->call('v1/etsy/product/listing/' . (int)$etsy_item_id . '/updateStock/', 'POST', array('quantity' => $new_stock, 'state' => $status)); 232 233 if (isset($response['data']['error'])) { 234 return $response; 235 } else { 236 return true; 237 } 238 } else { 239 $this->log("updateListingStock() - stock > 0 - set to inactive"); 240 241 $this->deleteLink(null, $etsy_item_id); 242 243 $response = $this->call('v1/etsy/product/listing/' . (int)$etsy_item_id . '/inactive/', 'POST'); 244 245 if (isset($response['data']['error'])) { 246 $this->log("updateListingStock() - Error: " . json_encode($response)); 247 248 return $response; 249 } else { 250 $this->log("updateListingStock() - Item ended OK"); 251 252 return true; 253 } 254 } 255 } 256 257 public function deleteProduct($product_id) { 258 $this->log("deleteProduct() - Product ID: " . $product_id); 259 260 $this->db->query("DELETE FROM `" . DB_PREFIX . "etsy_listing` WHERE `product_id` = '" . (int)$product_id . "'"); 261 } 262 263 public function deleteLink($etsy_listing_id = null, $etsy_item_id = null) { 264 $this->log("deleteLink() - Listing ID: " . $etsy_listing_id . ", item ID" . $etsy_item_id); 265 266 if ($etsy_listing_id != null) { 267 $this->log("deleteLink() - Listing ID is not null"); 268 269 $this->db->query("UPDATE `" . DB_PREFIX . "etsy_listing` SET `status` = 0 WHERE `etsy_listing_id` = '" . (int)$etsy_listing_id . "' LIMIT 1"); 270 } elseif ($etsy_item_id != null) { 271 $this->log("deleteLink() - Item ID is not null"); 272 273 $this->db->query("UPDATE `" . DB_PREFIX . "etsy_listing` SET `status` = 0 WHERE `etsy_item_id` = '" . (int)$etsy_item_id . "' LIMIT 1"); 274 } 275 } 276 277 public function productUpdateListen($product_id, $data = array()) { 278 $this->log("productUpdateListen() - " . $product_id . ", Data: " . json_encode($data)); 279 280 $links = $this->getLinks($product_id, 1); 281 282 if (!empty($links)) { 283 foreach ($links as $link) { 284 $this->log("productUpdateListen() - Item ID: " . $link['etsy_item_id']); 285 286 $etsy_listing = $this->getEtsyItem($link['etsy_item_id']); 287 288 if ($etsy_listing != false && isset($etsy_listing['state']) && ($etsy_listing['state'] == 'active' || $etsy_listing['state'] == 'private' || $etsy_listing['state'] == 'draft' || $etsy_listing['state'] == 'edit')) { 289 $this->log("productUpdateListen() - Listing state seems valid"); 290 291 if ($etsy_listing['quantity'] != $link['quantity']) { 292 $this->log("productUpdateListen() - Stock is different, do update"); 293 294 $this->updateListingStock($link['etsy_item_id'], $link['quantity'], $etsy_listing['state']); 295 } else { 296 $this->log("productUpdateListen() - Stock is the same: " . $etsy_listing['quantity'] . " " . $link['quantity']); 297 } 298 } else { 299 $this->log("productUpdateListen() - Listing state seems invalid"); 300 $this->log("productUpdateListen() - " . json_encode($etsy_listing)); 301 302 $this->deleteLink($link['etsy_listing_id']); 303 } 304 } 305 } else { 306 $this->log("productUpdateListen() - No links"); 307 } 308 } 309 310 public function orderFind($order_id = null, $receipt_id = null) { 311 $this->log("orderFind() - OrderID: " . $order_id . ", Receipt ID: " . $receipt_id); 312 313 if ($order_id != null) { 314 $this->log("orderFind() - Order ID is not null"); 315 316 $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "etsy_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1"); 317 318 if($query->num_rows > 0) { 319 $this->log('orderFind() - Found'); 320 return $query->row; 321 } else { 322 $this->log('orderFind() - Not found'); 323 return false; 324 } 325 } elseif ($receipt_id != null) { 326 $this->log("orderFind() - Receipt ID is not null"); 327 328 $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "etsy_order` WHERE `receipt_id` = '" . (int)$receipt_id . "' LIMIT 1"); 329 330 if($query->num_rows > 0) { 331 $this->log('orderFind() - Found'); 332 return $query->row; 333 } else { 334 $this->log('orderFind() - Not found'); 335 return false; 336 } 337 } 338 } 339 340 public function orderDelete($order_id) { 341 $this->log("orderDelete() - ID: " . $order_id); 342 343 if(!$this->orderFind($order_id)) { 344 $query = $this->db->query("SELECT `p`.`product_id` FROM `" . DB_PREFIX . "order_product` `op` LEFT JOIN `" . DB_PREFIX . "product` `p` ON `op`.`product_id` = `p`.`product_id` WHERE `op`.`order_id` = '" . (int)$order_id . "'"); 345 346 if($query->num_rows > 0) { 347 $this->log("orderDelete() - " . $query->num_rows . " products"); 348 349 foreach ($query->rows as $product) { 350 $this->log("orderDelete() - Processing ID: " . $product['product_id']); 351 352 $this->productUpdateListen((int)$product['product_id']); 353 } 354 } else { 355 $this->log("orderDelete() - No products in order"); 356 } 357 } else { 358 $this->log("orderDelete() - Not an Etsy order"); 359 } 360 } 361 362 public function orderUpdatePaid($receipt_id, $status) { 363 $this->log("orderUpdatePaid() - Receipt ID: " . $receipt_id . ", Status: " . $status); 364 365 $response = $this->openbay->etsy->call('v1/etsy/order/update/payment/', 'POST', array('receipt_id' => $receipt_id, 'status' => $status)); 366 367 if (isset($response['data']['error'])) { 368 $this->log("orderUpdatePaid() - Error: " . json_encode($response)); 369 370 return $response; 371 } else { 372 $this->log("orderUpdatePaid() - OK"); 373 374 return true; 375 } 376 } 377 378 public function orderUpdateShipped($receipt_id, $status) { 379 $this->log("orderUpdateShipped() - Receipt ID: " . $receipt_id . ", Status: " . $status); 380 381 $response = $this->openbay->etsy->call('v1/etsy/order/update/shipping/', 'POST', array('receipt_id' => $receipt_id, 'status' => $status)); 382 383 if (isset($response['data']['error'])) { 384 $this->log("orderUpdateShipped() - Error: " . json_encode($response)); 385 386 return $response; 387 } else { 388 $this->log("orderUpdateShipped() - OK"); 389 390 return true; 391 } 392 } 393 394 public function putStockUpdateBulk($product_id_array, $end_inactive) { 395 $this->log("putStockUpdateBulk() - ok"); 396 $this->log("putStockUpdateBulk() - Item count: " . count($product_id_array)); 397 398 foreach($product_id_array as $product_id) { 399 $this->log("putStockUpdateBulk() - Product ID: " . $product_id); 400 401 $links = $this->getLinks($product_id, 1); 402 403 if (!empty($links)) { 404 $this->log("putStockUpdateBulk() - Links found: " . count($links)); 405 406 foreach ($links as $link) { 407 $etsy_listing = $this->getEtsyItem($link['etsy_item_id']); 408 409 if ($etsy_listing != false && isset($etsy_listing['state']) && ($etsy_listing['state'] == 'active' || $etsy_listing['state'] == 'private' || $etsy_listing['state'] == 'draft' || $etsy_listing['state'] == 'edit')) { 410 $this->log("putStockUpdateBulk() - Listing state seems valid"); 411 412 if ($etsy_listing['quantity'] != $link['quantity']) { 413 $this->log("putStockUpdateBulk() - Stock is different, do update"); 414 415 $this->updateListingStock($link['etsy_item_id'], $link['quantity'], $etsy_listing['state']); 416 } else { 417 $this->log("putStockUpdateBulk() - Stock is the same: " . $etsy_listing['quantity'] . " " . $link['quantity']); 418 } 419 } else { 420 $this->log("putStockUpdateBulk() - Listing state seems invalid"); 421 $this->log("putStockUpdateBulk() - " . json_encode($etsy_listing)); 422 423 $this->deleteLink($link['etsy_listing_id']); 424 } 425 } 426 } else { 427 $this->log("putStockUpdateBulk() - No link found"); 428 } 429 } 430 } 431 432 public function getEtsyItem($listing_id) { 433 $this->log("getEtsyItem(): " . $listing_id); 434 435 $response = $this->openbay->etsy->call('v1/etsy/product/listing/' . $listing_id . '/', 'GET'); 436 437 if (isset($response['data']['error'])) { 438 $this->log("getEtsyItem() error: ". $response['data']['error']); 439 440 return $response; 441 } else { 442 $this->log("getEtsyItem() - OK : " . json_encode($response)); 443 444 return $response['data']['results'][0]; 445 } 446 } 447 448 public function validate() { 449 if ($this->config->get('etsy_token') && $this->config->get('etsy_encryption_key') && $this->config->get('etsy_encryption_iv')) { 450 $this->log("Etsy details valid"); 451 452 return true; 453 } else { 454 $this->log("Etsy details are not valid"); 455 456 return false; 457 } 458 } 459 }