Files
grzanieplus.pl/plugins/stAllegroPlugin/lib/stAllegroApi.class.php
2025-03-12 17:06:23 +01:00

833 lines
23 KiB
PHP

<?php
class stAllegroApi
{
const ALLEGRO_URL = 'https://allegro.pl';
const ALLEGRO_ARCHIVE_URL = 'https://archiwum.allegro.pl';
const ALLEGRO_SANDBOX_URL = 'https://allegro.pl.allegrosandbox.pl';
/**
* offer is visible on site and available for purchase, occurs when offer status changes from ACTIVATING to ACTIVE.
*/
const OFFER_ACTIVATED = 'OFFER_ACTIVATED';
/**
* occurs when offer's fields has been changed e.g. description or photos.
*/
const OFFER_CHANGED = 'OFFER_CHANGED';
/**
* offer is no longer available for purchase, occurs when offer status changes from ACTIVE to ENDED.
*/
const OFFER_ENDED = 'OFFER_ENDED';
/**
* stock in an offer was changed either via purchase or by seller.
*/
const OFFER_STOCK_CHANGED = 'OFFER_STOCK_CHANGED';
/**
* occurs when price in an offer was changed.
*/
const OFFER_PRICE_CHANGED = 'OFFER_PRICE_CHANGED';
/**
* offer is no longer available on listing and has been archived
*/
const OFFER_ARCHIVED = 'OFFER_ARCHIVED';
/**
* bid was placed on the offer
*/
const OFFER_BID_PLACED = 'OFFER_BID_PLACED';
/**
* bid for offer was canceled
*/
const OFFER_BID_CANCELED = 'OFFER_BID_CANCELED';
const FILTER_SINGLE = 'SINGLE';
const FILTER_MULTI = 'MULTI';
const FILTER_NUMERIC = 'NUMERIC';
const FILTER_NUMERIC_SINGLE = 'NUMERIC_SINGLE';
const STATUS_INACTIVE = "INACTIVE";
const STATUS_ACTIVATING = "ACTIVATING";
const STATUS_ACTIVE = "ACTIVE";
const STATUS_ENDED = "ENDED";
protected static $instance = null;
/**
* AllegroRestApi instance
*
* @var AllegroRestApi
*/
protected $api = null;
/**
* stConfig instance
*
* @var stConfig
*/
protected $config = null;
/**
* Bazowy język wystawianej oferty
*
* @var string
*/
protected $language;
/**
* Get stAllegroApi instance
*
* @return self
*/
public static function getInstance()
{
if (null === self::$instance)
{
self::$instance = new static();
self::$instance->initialize();
}
return self::$instance;
}
public static function redirectAuthUri()
{
return sfContext::getInstance()->getController()->genUrl('@stAllegroPlugin?action=config', true);
}
public function initialize()
{
$this->config = stConfig::getInstance('stAllegroBackend');
try
{
$this->refreshToken();
}
catch(stAllegroException $e)
{
$this->api = new AllegroRestApi($this->config->get('access_token'), $this->config->get('sandbox'));
throw $e;
}
$this->api = new AllegroRestApi($this->config->get('access_token'), $this->config->get('sandbox'));
$this->language = stLanguage::getOptLanguage() == 'pl_PL' ? 'pl-PL' : 'en-EN';
}
public function refreshToken()
{
if (time() >= $this->config->get('expires'))
{
$response = AllegroRestApi::refreshToken($this->config->get('refresh_token'), $this->config->get('client_id'), $this->config->get('client_secret'), self::redirectAuthUri(), $this->config->get('sandbox'));
if ($response)
{
if (isset($response->error))
{
throw new stAllegroException($response->error);
}
$this->config->set('access_token', $response->access_token);
$this->config->set('refresh_token', $response->refresh_token);
$this->config->set('expires', $response->expires_in + time());
$this->config->set('seller_id', $response->seller_id);
$this->config->save(true);
}
}
}
public function getBasicInfoAboutUser()
{
return $this->apiCall('get', '/me');
}
public function getDeliveryMethods()
{
$response = $this->apiCall('get', '/sale/delivery-methods?marketplace=allegro-pl');
if ($response)
{
return $response->deliveryMethods;
}
return null;
}
public function getShippingRates()
{
$response = $this->apiCall('get', '/sale/shipping-rates?seller.id=' . $this->config->get('seller_id'));
if (isset($response->shippingRates))
{
return $response->shippingRates;
}
return null;
}
public function getShippingRate($id)
{
$response = $this->apiCall('get', '/sale/shipping-rates/'.$id);
if ($response)
{
$rates = array();
foreach ($response->rates as $rate)
{
$rates[$rate->deliveryMethod->id] = $rate;
}
$response->rates = $rates;
}
return $response;
}
public function updateShippingRate($id, $data)
{
$rates = array();
foreach ($data['rates'] as $methodId => $rate)
{
$rates[] = array(
'deliveryMethod' => array('id' => $methodId),
'maxQuantityPerPackage' => $rate['max_quantity_per_package'],
'firstItemRate' => $rate['first_item_rate'],
'nextItemRate' => $rate['next_item_rate'],
);
}
$request = array(
'id' => $id,
'name' => $data['name'],
'rates' => $rates,
);
return $this->apiCall('put', '/sale/shipping-rates/'.$id, $request);
}
public function createShippingRate($data)
{
$rates = array();
if ($data['rates'])
{
foreach ($data['rates'] as $methodId => $rate)
{
$rates[] = array(
'deliveryMethod' => array('id' => $methodId),
'maxQuantityPerPackage' => $rate['max_quantity_per_package'],
'firstItemRate' => $rate['first_item_rate'],
'nextItemRate' => $rate['next_item_rate'],
);
}
}
$request = array(
'name' => $data['name'],
'rates' => $rates,
);
return $this->apiCall('post', '/sale/shipping-rates', $request);
}
public function getProducts(array $params)
{
$filterquerystring = array();
if (isset($params['filters']))
{
foreach ($params['filters'] as $name => $filter)
{
switch ($filter['type'])
{
case self::FILTER_SINGLE:
case self::FILTER_NUMERIC_SINGLE:
$filterquerystring[] = $name . '=' . rawurlencode($filter['value']);
break;
case self::FILTER_MULTI:
foreach ($filter['value'] as $name => $value)
{
$filterquerystring[] = $name . '=' . rawurlencode($value);
}
break;
case self::FILTER_NUMERIC:
$filterquerystring[] = $name . '.from=' . rawurlencode($filter['value']['from']);
$filterquerystring[] = $name . '.to=' . rawurlencode($filter['value']['to']);
break;
}
}
unset($params['filters']);
}
$query = $params ? '?' . http_build_query($params, '', '&') : '';
if ($filterquerystring)
{
$query = $query ? '&'.implode("&", $filterquerystring) : '?'.implode("&", $filterquerystring);
}
return $this->apiCall('get', '/sale/products' . $query);
}
public function getProduct($id)
{
return $this->apiCall('get', '/sale/products/' . rawurlencode($id));
}
public function getOffers($params = array())
{
$externalId = [];
$params['publication.marketplace'] = 'allegro-pl';
if (isset($params['external.id']) && is_array($params['external.id'])) {
foreach ($params['external.id'] as $id)
{
$externalId[] = 'external.id='.$id;
}
unset($params['external.id']);
}
$query = $params ? '?' . http_build_query($params, '', '&') : '';
return $this->apiCall('get', '/sale/offers'.$query.($query ? '&'.implode("&", $externalId) : '?'.implode("&", $externalId)));
}
public function getOffer($id)
{
$response = $this->apiCall('get', '/sale/offers/'.$id);
if ($response->parameters)
{
$parameters = array();
foreach ($response->parameters as $parameter)
{
$parameters[$parameter->id] = $parameter;
}
$response->parameters = $parameters;
}
return $response;
}
public function getCategoryParameters($categoryId)
{
$response = $this->apiCall('get', '/sale/categories/' . $categoryId . '/parameters');
return $response->parameters;
}
public function getCategories($parentId = null)
{
if ($parentId)
{
$response = $this->apiCall('get', '/sale/categories?parent.id=' . $parentId);
}
else
{
$response = $this->apiCall('get', '/sale/categories');
}
if ($response)
{
return $response->categories;
}
return array();
}
public function getCategory($categoryId)
{
return $this->apiCall('get', '/sale/categories/'.$categoryId);
}
public function getMatchingCategories($searchPhrase)
{
$query = http_build_query(array(
'name' => $searchPhrase
), null, '&');
$response = $this->apiCall('get', '/sale/matching-categories?'.$query);
return $response ? $response->matchingCategories : array();
}
public function getCategoryPath($parentId)
{
$path = array();
$response = $this->getCategory($parentId);
$path[] = $response;
while($response && null !== $response->parent)
{
$response = $this->getCategory($response->parent->id);
$path[] = $response;
}
return $path ? array_reverse($path) : array();
}
public function deleteDraftOffer($id)
{
return $this->apiCall('delete', '/sale/offers/'.$id);
}
public static function getOfferUrl($offerNumber)
{
return self::getAllegroUrl() . '/oferta/' . $offerNumber;
}
public static function getArchiveOfferUrl($offerNumber)
{
return self::ALLEGRO_ARCHIVE_URL . '/oferta/' . $offerNumber;
}
public static function getOrderUrl($checkoutFormId)
{
return self::getAllegroUrl() . '/moje-allegro/sprzedaz/zamowienia/' . $checkoutFormId;
}
public static function getAllegroUrl()
{
$config = stConfig::getInstance('stAllegroBackend');
return $config->get('sandbox') ? self::ALLEGRO_SANDBOX_URL : self::ALLEGRO_URL;
}
public function updateOffer($id, stdClass $offer)
{
if (property_exists($offer, 'ean'))
{
unset($offer->ean);
}
if (!isset($offer->language) || empty($offer->language) && $offer->publication->status == self::STATUS_INACTIVE)
{
$offer->language = $this->language;
}
$data = self::objectToArray($offer);
$data['parameters'] = array_values($data['parameters']);
return $this->apiCall('put', '/sale/offers/'.$id, $data);
}
public function createOffer(stdClass $offer)
{
if (!isset($offer->language) || empty($offer->language))
{
$offer->language = $this->language;
}
$data = self::objectToArray($offer);
foreach ($data as $name => $value)
{
if (null === $value)
{
unset($data[$name]);
}
}
$data['parameters'] = array_values($data['parameters']);
// throw new Exception("<pre>".var_export($data, true)."</pre>");
$response = $this->apiCall('post', '/sale/offers', $data);
// throw new Exception("<pre>".var_export($response, true)."</pre>");
if ($response->parameters)
{
$parameters = array();
foreach ($response->parameters as $parameter)
{
$parameters[$parameter->id] = $parameter;
}
$response->parameters = $parameters;
}
return $response;
}
public function addParcelTrackingNumber($checkoutFormId, $carrierId, $trackingNumber, array $lineItems = [])
{
$params = [
'carrierId' => $carrierId,
'waybill' => $trackingNumber,
];
if (!empty($lineItems))
{
$params['lineItems'] = array_map(function($value) {
return ['id' => $value];
}, $lineItems);
}
return $this->api->post("/order/checkout-forms/$checkoutFormId/shipments", $params);
}
public function getAvailableShippingCarriers()
{
$response = $this->api->get('/order/carriers');
return $response ? $response->carriers : array();
}
public function getAccountAdditionalEmails()
{
return $this->apiCall('get', '/account/additional-emails/');
}
public function getImpliedWarranties()
{
$response = $this->apiCall('get', '/after-sales-service-conditions/implied-warranties?seller.id=' . $this->config->get('seller_id'));
return $response && $response->impliedWarranties ? $response->impliedWarranties : array();
}
public function getWarranties()
{
$response = $this->apiCall('get', '/after-sales-service-conditions/warranties?seller.id=' . $this->config->get('seller_id'));
return $response && $response->warranties ? $response->warranties : array();
}
public function getReturnPolicies()
{
$response = $this->apiCall('get', '/after-sales-service-conditions/return-policies?seller.id=' . $this->config->get('seller_id'));
return $response && $response->returnPolicies ? $response->returnPolicies : array();
}
public function uploadImage($imageFile)
{
$fileMimeType = mime_content_type($imageFile);
$data = file_get_contents($imageFile);
return $this->apiCall('post', $this->api->getUploadUrl() . '/sale/images', $data, array(
'Content-Type' => $fileMimeType,
));
}
public function getPricingFeePreview(array $params)
{
return $this->apiCall('post', '/pricing/fee-preview', $params);
}
public function getOfferQuotes($id)
{
return $this->apiCall('get', '/pricing/offer-quotes?offer.id=' . $id);
}
public function publishOffers(array $offers, $activate = true)
{
$params = array('offerCriteria' => array(array(
'offers' => array_map(function($id) {
return array('id' => intval($id));
}, $offers),
'type' => 'CONTAINS_OFFERS',
)),
'publication' => array(
'action' => $activate ? 'ACTIVATE' : 'END',
));
$response = $this->apiCall('put', '/sale/offer-publication-commands/' . $this->api->getUuid(), $params);
return $response;
}
public function getPublishOffersReport($commandId)
{
$response = $this->apiCall('get', "/sale/offer-publication-commands/$commandId/tasks");
if ($response)
{
return $response->tasks;
}
return null;
}
public function getPaymentMapping($paymentId)
{
$response = $this->apiCall('get', '/payments/payment-id-mappings?paymentId=' . $paymentId);
if ($response)
{
return $response->transactionId;
}
return null;
}
public function getOrderCheckoutForms($offset = null, $fromDate = null, $type = "READY_FOR_PROCESSING", $limit = 10)
{
$params = array(
'status' => $type,
'limit' => $limit,
'marketplace.id' => 'allegro-pl'
);
if (null !== $fromDate)
{
$params['updatedAt.gte'] = $fromDate;
}
if (null !== $offset)
{
$params['offset'] = $offset;
}
$query = http_build_query($params, null, '&');
return $this->apiCall('get', "/order/checkout-forms?" . $query);
}
public function getOrderCheckoutForm($checkoutFormId)
{
return $this->api->get("/order/checkout-forms/$checkoutFormId");
}
public function getOfferEvents($from = null, $type = null, $limit = 100)
{
$params = array(
'limit' => $limit,
);
if (null !== $from)
{
$params['from'] = $from;
}
$query = http_build_query($params, null, '&');
if (null !== $type)
{
$query .= is_array($type) ? '&type='.implode('&type=', $type) : '&type='.$type;
}
$response = $this->api->get("/sale/offer-events?".$query);
return $response ? $response->offerEvents : array();
}
public function getOrderEvents($from = null, $type = "READY_FOR_PROCESSING", $limit = 10)
{
$params = array(
'status' => $type,
'limit' => $limit,
);
if (null !== $from)
{
$params['offset'] = $from;
}
$query = http_build_query($params, null, '&');
$response = $this->apiCall('get', "/order/events?" . $query);
if ($response && isset($response->events))
{
return $response->events;
}
return null;
}
public function getOrderEventStats()
{
$response = $this->apiCall('get', "/order/event-stats");
if ($response && isset($response->latestEvent))
{
return $response->latestEvent;
}
return null;
}
/**
* Wywołuje adres zasobu API
*
* @param string $method Metoda GET, POST, PUT, DELETE
* @param string $url Adres zasobu
* @param array|string $data Dane
* @param array $headers Dodatkowe nagłówki
* @return void
*/
public function apiCall(string $method, string $url, $data = array(), array $headers = array())
{
$this->refreshToken();
return $this->api->sendRequest($url, $method, $data, $headers);
}
public static function objectToArray($data) {
if (is_object($data)) {
// Gets the properties of the given object
// with get_object_vars function
$data = get_object_vars($data);
}
if (is_array($data)) {
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
return array_map(array('stAllegroApi', 'objectToArray'), $data);
}
else {
// Return array
return $data;
}
}
public static function arrayToObject($data, $camelize = false)
{
if (is_array($data))
{
if (!isset($data[0]) && !empty($data))
{
$results = array();
foreach ($data as $index => $value)
{
$results[$camelize ? lcfirst(sfInflector::camelize($index)) : $index] = self::arrayToObject($value, $camelize);
}
return (object)$results;
}
else
{
$results = array();
foreach ($data as $index => $value)
{
$results[$index] = self::arrayToObject($value, $camelize);
}
return $results;
}
}
else {
// Return object
return !empty($data) ? $data : null;
}
}
public static function getErrorByHttpCode($code)
{
$errors = array(
400 => 'Wysłano niepoprawne dane JSON.',
401 => 'Użytkownik nie jest uwierzytelniony - Proszę ponownie zalogować się w Allegro.',
403 => 'Nie masz praw dostępu do danego zasobu.',
404 => 'Odpytywany zasób nie istnieje w API.',
406 => 'W nagłówku Accept przekazany został nieobsługiwany przez zasób typ danych.',
415 => 'W nagłówku Accept przekazany został nieobsługiwany przez zasób typ danych.',
422 => 'Wysłano niepoprawne wartości pól, np. walidacja obiektu zwróciła błąd, albo któreś z pól nie spełnia kryteriów nałożonych na nie przez zasób.',
429 => 'Klient przekroczył limit liczby żądań.',
503 => 'Połączenie z serwisem nie jest możliwe.',
);
return isset($errors[$code]) ? $errors[$code] : null;
}
public static function getDeliveryTimes()
{
return array(
'PT0S' => 'natychmiast',
'PT24H' => '24 godziny',
'PT48H' => '2 dni',
'PT72H' => '3 dni',
'PT96H' => '4 dni',
'PT120H' => '5 dni',
'PT168H' => '7 dni',
'PT240H' => '10 dni',
'PT336H' => '14 dni',
'PT504H' => '21 dni',
'PT720H' => '30 dni',
'PT1440H' => '60 dni',
);
}
public static function getDurationTimes()
{
return array(
'' => 'Do wyczerpania przedmiotów',
'PT72H' => '3 dni',
'PT120H' => '5 dni',
'PT168H' => '7 dni',
'PT240H' => '10 dni',
'PT480H' => '20 dni',
'PT720H' => '30 dni',
);
}
public static function getStatusList()
{
return array(
self::STATUS_INACTIVE => "Szkic",
self::STATUS_ACTIVE => "Aktywna",
self::STATUS_ACTIVATING => "W trakcie aktywacji",
self::STATUS_ENDED => "Zakończona",
);
}
public static function getPaymentInvoiceList()
{
return array(
"NO_INVOICE" => "Nie wystawiam faktury",
"VAT" => "Faktura VAT",
"VAT_MARGIN" => "Faktura VAT-marża",
"WITHOUT_VAT" => "Faktura bez VAT",
);
}
public static function getIntervalToDays($interval)
{
$interval = new DateInterval($interval);
$seconds = ($interval->d * 24 * 60 * 60) +
($interval->h * 60 * 60) +
($interval->i * 60) +
$interval->s;
return $seconds / (60 * 60 * 24);
}
public static function formatDate($date, $format = "d-m-Y")
{
$time = strtotime($date);
return date($format, $time);
}
public static function getLastErrors()
{
return AllegroRestApi::getLastErrors();
}
public static function getLastErrorsAsString($delimiter = "\n")
{
return AllegroRestApi::getLastErrorsAsString($delimiter);
}
public static function getLastHttpCode()
{
return AllegroRestApi::getLastHttpCode();
}
}