add empik module

This commit is contained in:
2025-05-30 09:08:26 +02:00
parent 87a41f4cfc
commit 56aa2cdc2d
1466 changed files with 138249 additions and 146 deletions

View File

@@ -0,0 +1,395 @@
<?php
namespace Empik\Marketplace\API;
use Empik\Marketplace\Factory\HttpClientsFactory;
use Empik\Marketplace\Factory\HttpClientFactoryInterface;
use Empik\Marketplace\Exception\InvalidArgumentException;
class EmpikClient
{
const IMPORT_MODE_NORMAL = 'NORMAL';
const IMPORT_MODE_PARTIAL_UPDATE = 'PARTIAL_UPDATE';
const IMPORT_MODE_REPLACE = 'REPLACE';
/** @var string */
private $apiUrl;
/** @var string */
private $apiKey;
/** @var HttpClientInterface */
private $client;
/**
* @param $apiUrl
* @param $apiKey
* @param HttpClientFactoryInterface|null $httpClientFactory
* @throws \Exception
*/
public function __construct($apiUrl, $apiKey, HttpClientFactoryInterface $httpClientFactory = null)
{
if (!$httpClientFactory) {
$httpClientFactory = new HttpClientsFactory();
}
$this->apiUrl = $apiUrl;
$this->apiKey = $apiKey;
$this->client = $httpClientFactory->createHttpClient($apiUrl);
}
/**
* @param int|string $id
* @param array $headers
* @param array $body
*
* @return false|array
*/
private function post($id, array $headers = [], array $body = [])
{
return $this->sendRequest($id, $headers, $body, 'POST');
}
/**
* @param int|string $id
* @param array $headers
* @param array $body
*
* @return false|array
*/
private function put($id, array $headers = [], array $body = [])
{
return $this->sendRequest($id, $headers, $body, 'PUT');
}
/**
* @param int|string $id
* @param array $headers
* @param array $body
*
* @return false|array
*/
private function get($id, array $headers = [], array $body = [])
{
return $this->sendRequest($id, $headers, $body, 'GET');
}
/**
* @param int|string $id
* @param array $headers
* @param array $body
* @param string $method
*
* @return false|array|string
*/
private function sendRequest($id, array $headers, array $body, $method)
{
$headers['Authorization'] = $this->apiKey;
switch ($method)
{
case 'POST':
$response = $this->client->post(
$this->apiUrl . $id,
$headers,
$body
);
break;
case 'PUT':
$response = $this->client->put(
$this->apiUrl . $id,
$headers,
$body
);
break;
case 'GET':
$response = $this->client->get(
$this->apiUrl . $id,
$headers,
$body
);
break;
}
return $response;
}
/**
* @return array|bool|false
*/
public function getAccount()
{
return $this->get(
'/api/account'
);
}
/**
* P41 - Import products to the operator information
*
* @param string $csvPath
*
* @return array|false
* @throws InvalidArgumentException
*/
public function postProducts($csvPath)
{
if (!file_exists($csvPath)) {
throw new InvalidArgumentException(sprintf('CSV product file does not exists: %s', $csvPath));
}
return $this->post(
'/api/products/imports',
[],
[
'file' => [
'filename' => basename($csvPath),
'filepath' => $csvPath,
]
]
);
}
/**
* OF01 - Import a file to add offers
*
* @param string $csvPath
* @param string $importMode
*
* @return array|false
* @throws InvalidArgumentException
*/
public function postOffersImports($csvPath, $importMode = self::IMPORT_MODE_NORMAL)
{
if (!file_exists($csvPath)) {
throw new InvalidArgumentException(sprintf('CSV offer file does not exists: %s', $csvPath));
}
if (!in_array($importMode, [self::IMPORT_MODE_NORMAL, self::IMPORT_MODE_PARTIAL_UPDATE, self::IMPORT_MODE_REPLACE])) {
throw new InvalidArgumentException(sprintf('Unsupported import mode: %s', $importMode));
}
return $this->post(
'/api/offers/imports',
[],
[
'import_mode' => $importMode,
'file' => [
'filename' => basename($csvPath),
'filepath' => $csvPath,
]
]
);
}
/**
* OF24 - Create, update, or delete offers
*
* @param array $offers
*
* @return array|false
*/
public function postOffers(array $offers)
{
return $this->post(
'/api/offers',
[
'Content-Type' => 'application/json'
],
[
'offers' => $offers,
]
);
}
/**
* GET P42 - Get the import status for a product import
*
* @param int $importId
* @return array|bool|false
*/
public function getProductsImport($importId)
{
return $this->get(
'/api/products/imports/' . (int)$importId
);
}
/**
* GET OF02 - Get information and statistics about an offer import
*
* @param int $importId
* @return array|bool|false
*/
public function getOffersImport($importId)
{
return $this->get(
'/api/offers/imports/' . (int)$importId
);
}
/**
* GET SH21 - List all carriers
*
* @return array|bool|false
*/
public function getCarriers()
{
return $this->get(
'/api/shipping/carriers'
);
}
/**
* GET SH12 - List all active shipping methods
*
* @return array|bool|false
*/
public function getShippingTypes()
{
return $this->get(
'/api/shipping/types'
);
}
/**
* GET OR11 - List orders
*
* @param array $filterParams
* @return array|bool|false
*/
public function getOrders($filterParams = [])
{
$filterParams = array_merge([
'sort' => 'dateCreated',
'order' => 'desc',
'max' => '20',
], $filterParams);
$query = http_build_query($filterParams);
return $this->get(
'/api/orders' . '?' . $query
);
}
/**
* PUT OR21 - Accept or refuse order lines
*
* @param int|string $orderReference
* @param array $orderLines
* @return array|bool|false
*/
public function putOrderAccept($orderReference, array $orderLines)
{
$bodyParams['order_lines'] = $orderLines;
return $this->put(
'/api/orders/' . $orderReference . '/accept',
[
'Content-Type' => 'application/json'
],
$bodyParams
);
}
/**
* PUT OR24 - Validate the shipment of an order
*
* @param int|string $orderReference
* @return array|bool|false
*/
public function putOrderShip($orderReference)
{
return $this->put(
'/api/orders/' . $orderReference . '/ship',
[
'Content-Type' => 'application/json'
]
);
}
/**
* PUT OR23 - Update carrier tracking information for a specific order
*
* @param int|string $orderReference
* @param string $carrierCode
* @param string $carrierName
* @param string $carrierUrl
* @param string $trackingNumber
* @return array|false
*/
public function putOrderTracking(
$orderReference,
$carrierCode = null,
$carrierName = null,
$carrierUrl = null,
$trackingNumber = null
)
{
$bodyParams = [];
if ($carrierCode) {
$bodyParams['carrier_code'] = $carrierCode;
}
if ($carrierName) {
$bodyParams['carrier_name'] = $carrierName;
}
if ($carrierUrl) {
$bodyParams['carrier_url'] = $carrierUrl;
}
if ($trackingNumber) {
$bodyParams['tracking_number'] = $trackingNumber;
}
return $this->put(
'/api/orders/' . $orderReference . '/tracking',
[
'Content-Type' => 'application/json'
],
$bodyParams
);
}
/**
* GET P44 - Get the error report file for a product import
*
* @param string $importId
* @return array|bool|false
*/
public function getProductImportErrorReport($importId)
{
return $this->get(
'/api/products/imports/' . $importId . '/new_product_report'
);
}
/**
* GET P44 - Get the error report file for a product import
*
* @param string $importId
* @return array|bool|false
*/
public function getOfferImportErrorReport($importId)
{
return $this->get(
'/api/offers/imports/' . $importId . '/error_report'
);
}
/**
* GET SH31 - List all logistic classes
*
* @return array|bool|false
*/
public function getLogisticClasses()
{
return $this->get(
'/api/shipping/logistic_classes'
);
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Empik\Marketplace\API;
interface HttpClientInterface
{
public function post($id, array $headers = [], array $body = []);
public function put($id, array $headers = [], array $body = []);
public function get($id, array $headers = [], array $body = []);
}

View File

@@ -0,0 +1,101 @@
<?php
namespace Empik\Marketplace\API;
use CURLFile;
class HttpCurlClient implements HttpClientInterface
{
public function __construct($config = [])
{
}
public function post($id, array $headers = [], array $body = [])
{
if (isset($body['file'])) {
$curlFile = new CURLFile($body['file']['filepath'], 'text/plain', $body['file']['filename']);
$body['file'] = $curlFile;
}
$ch = $this->create($id, $headers);
curl_setopt($ch, CURLOPT_POST,1);
if (isset($headers['Content-Type']) && $headers['Content-Type'] == 'application/json') {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
} else {
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
$response = $this->execute($ch);
curl_close($ch);
return $response;
}
public function put($id, array $headers = [], array $body = [])
{
$ch = $this->create($id, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
$response = $this->execute($ch);
curl_close($ch);
return $response;
}
public function get($id, array $headers = [], array $body = [])
{
$ch = $this->create($id, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = $this->execute($ch);
curl_close($ch);
return $response;
}
protected function create($id, $headers = [])
{
$ch = curl_init($id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($headers) {
$headersString = [];
foreach ($headers as $key => $value) {
$headersString[] = $key . ': ' . $value;
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headersString);
}
return $ch;
}
protected function execute($ch)
{
$response = curl_exec($ch);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// is 2xx http code
if ($httpCode < 200 || $httpCode >= 300) {
throw new \Exception('Request failed with HTTP code ' . $httpCode . '.');
}
if ($contentType === 'application/json') {
$response = json_decode($response, true);
}
return $response;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,64 @@
<?php
namespace Empik\Marketplace\Adapter;
use Configuration;
use Context;
use Shop;
class ConfigurationAdapter
{
const CONF_ENVIRONMENT = 'EMPIK_ENVIRONMENT';
const CONF_API_KEY = 'EMPIK_API_KEY';
const CONF_AUTH_STATUS = 'EMPIK_AUTH_STATUS';
const CONF_SYNC_OFFERS = 'EMPIK_SYNC_OFFERS';
const CONF_SYNC_LOGISTIC_CLASS = 'EMPIK_SYNC_LOGISTIC_CLASS';
const CONF_OFFER_IDENTIFIER = 'EMPIK_OFFER_IDENTIFIER';
const CONF_SKU_TYPE = 'EMPIK_SKU_TYPE';
const CONF_LEAD_TIME_TO_SHIP = 'EMPIK_LEAD_TIME_TO_SHIP';
const CONF_PRICE_RATIO = 'EMPIK_PRICE_RATIO';
const CONF_ADD_TO_PRICE = 'EMPIK_ADD_TO_PRICE';
const CONF_REDUCE_STOCK = 'EMPIK_REDUCE_STOCK';
const CONF_IMPORT_ORDERS = 'EMPIK_IMPORT_ORDERS';
const CONF_AUTO_ACCEPT_ORDERS = 'EMPIK_AUTO_ACCEPT_ORDERS';
const CONF_NEW_ORDER_STATE = 'EMPIK_NEW_ORDER_STATE';
const CONF_SHIPPED_ORDER_STATE = 'EMPIK_SHIPPED_ORDER_STATE';
const CONF_CARRIER_MAP = 'EMPIK_CARRIER_MAP';
const CONF_ID_EMPLOYEE = 'EMPIK_ID_EMPLOYEE';
const ENV_TEST = 'https://stg1.marketplace.empik.com';
const ENV_PROD = 'https://marketplace.empik.com';
/** @var Shop */
private $shopId;
public function __construct($shopId = null)
{
$this->shopId = $shopId ? $shopId : Context::getContext()->shop->id;
}
public function get($key, $langId = null, $shopGroupId = null, $shopId = null, $default = false)
{
if ($shopId === null) {
$shopId = $this->shopId;
}
return Configuration::get($key, $langId, $shopGroupId, $shopId, $default);
}
public function updateValue($key, $values, $html = false, $shopGroupId = null, $shopId = null)
{
if ($shopId === null) {
$shopId = $this->shopId;
}
return Configuration::updateValue($key, $values, $html, $shopGroupId, $shopId);
}
public function deleteByName($key)
{
return Configuration::deleteByName($key);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Empik\Marketplace\Adapter;
use Empik\Marketplace\PrestaShopContext;
use Context;
use Link;
class LinkAdapter
{
/** @var Link */
protected $link;
/** @var PrestaShopContext */
protected $prestaShopContext;
public function __construct(PrestaShopContext $prestaShopContext)
{
$this->prestaShopContext = $prestaShopContext;
$this->link = Context::getContext()->link;
}
/**
* @param string $controller
* @param array $params
* @return string
*/
public function getAdminLink($controller, $params = [])
{
if ($this->prestaShopContext->is17()) {
return $this->link->getAdminLink($controller, true, [], $params);
} else {
$paramsQuery = $params ? '&' . http_build_query($params) : '';
return $this->link->getAdminLink($controller, true) . $paramsQuery;
}
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Empik\Marketplace\Adapter;
use PrestaShopLogger;
class LoggerAdapter
{
const LOG_SEVERITY_LEVEL_INFORMATIVE = 1;
const LOG_SEVERITY_LEVEL_WARNING = 2;
const LOG_SEVERITY_LEVEL_ERROR = 3;
const LOG_SEVERITY_LEVEL_MAJOR = 4;
/**
* @param string $message
* @param int $severity
* @return bool
*/
public function log($message, $severity = self::LOG_SEVERITY_LEVEL_INFORMATIVE)
{
return PrestaShopLogger::addLog($message, $severity);
}
/**
* @param string $message
* @return bool
*/
public function logInfo($message)
{
return $this->log($message, self::LOG_SEVERITY_LEVEL_INFORMATIVE);
}
/**
* @param string $message
* @return bool
*/
public function logWarning($message)
{
return $this->log($message, self::LOG_SEVERITY_LEVEL_WARNING);
}
/**
* @param string $message
* @return bool
*/
public function logError($message)
{
return $this->log($message, self::LOG_SEVERITY_LEVEL_ERROR);
}
/**
* @param string $message
* @return bool
*/
public function logMajor($message)
{
return $this->log($message, self::LOG_SEVERITY_LEVEL_MAJOR);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Empik\Marketplace\Adapter;
use Tools;
use Context;
class ToolsAdapter
{
protected $context;
public function __construct()
{
$this->context = Context::getContext();
}
public function hash($value)
{
if ($this->is176()) {
return Tools::hash($value);
}
return Tools::encrypt($value);
}
public function is17()
{
return version_compare(_PS_VERSION_, '1.7.0', '>=');
}
public function is176()
{
return version_compare(_PS_VERSION_, '1.7.6', '>=');
}
public static function is17static()
{
return version_compare(_PS_VERSION_, '1.7.0', '>=');
}
public static function is176static()
{
return version_compare(_PS_VERSION_, '1.7.6', '>=');
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace Empik\Marketplace\Adapter;
use Context;
use Exception;
use Module;
use Tools;
use Translate;
class TranslateAdapter
{
/**
* Adapter for getting module translation for a specific locale on PS 1.6
*
* @param Module|string $module Module instance or name
* @param string $originalString string to translate
* @param string $source source of the original string
* @param string|null $iso locale or language ISO code
*
* @return string
*
* @throws Exception
*/
public function getModuleTranslation(
$module,
$originalString,
$source,
$iso = null
) {
if (version_compare(_PS_VERSION_, '1.7', '>=')) {
return Translate::getModuleTranslation($module, $originalString, $source, null, false, $iso);
} elseif ($iso === null) {
return Translate::getModuleTranslation($module, $originalString, $source);
}
static $translations;
static $langCache = [];
static $translationsMerged = [];
$name = $module instanceof Module ? $module->name : $module;
if (empty($iso)) {
$iso = Context::getContext()->language->iso_code;
}
if (!isset($translationsMerged[$name][$iso])) {
$filesByPriority = [
// PrestaShop 1.5 translations
_PS_MODULE_DIR_ . $name . '/translations/' . $iso . '.php',
// PrestaShop 1.4 translations
_PS_MODULE_DIR_ . $name . '/' . $iso . '.php',
// Translations in theme
_PS_THEME_DIR_ . 'modules/' . $name . '/translations/' . $iso . '.php',
_PS_THEME_DIR_ . 'modules/' . $name . '/' . $iso . '.php',
];
foreach ($filesByPriority as $file) {
if (file_exists($file)) {
$_MODULE = null;
include $file;
if (isset($_MODULE)) {
$translations[$iso] = isset($translations[$iso])
? array_merge($translations[$iso], $_MODULE)
: $_MODULE;
}
}
}
$translationsMerged[$name][$iso] = true;
}
$string = preg_replace("/\\\*'/", "\'", $originalString);
$key = md5($string);
$cacheKey = $name . '|' . $string . '|' . $source . '|' . $iso;
if (!isset($langCache[$cacheKey])) {
if (!isset($translations[$iso])) {
return str_replace('"', '&quot;', $string);
}
$currentKey = Tools::strtolower('<{' . $name . '}' . _THEME_NAME_ . '>' . $source) . '_' . $key;
$defaultKey = Tools::strtolower('<{' . $name . '}prestashop>' . $source) . '_' . $key;
if ('controller' == Tools::substr($source, -10, 10)) {
$file = Tools::substr($source, 0, -10);
$currentKeyFile = Tools::strtolower('<{' . $name . '}' . _THEME_NAME_ . '>' . $file) . '_' . $key;
$defaultKeyFile = Tools::strtolower('<{' . $name . '}prestashop>' . $file) . '_' . $key;
}
if (isset($currentKeyFile) && !empty($translations[$iso][$currentKeyFile])) {
$ret = Tools::stripslashes($translations[$iso][$currentKeyFile]);
} elseif (isset($defaultKeyFile) && !empty($translations[$iso][$defaultKeyFile])) {
$ret = Tools::stripslashes($translations[$iso][$defaultKeyFile]);
} elseif (!empty($translations[$iso][$currentKey])) {
$ret = Tools::stripslashes($translations[$iso][$currentKey]);
} elseif (!empty($translations[$iso][$defaultKey])) {
$ret = Tools::stripslashes($translations[$iso][$defaultKey]);
} else {
$ret = Tools::stripslashes($string);
}
$langCache[$cacheKey] = htmlspecialchars($ret, ENT_COMPAT, 'UTF-8');
}
return $langCache[$cacheKey];
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,45 @@
<?php
namespace Empik\Marketplace\Cache;
use Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider;
class Cache
{
protected $cacheEnvironment;
protected $cacheNamespace;
protected $cacheDirectory;
public function __construct($cacheNamespace = 'empikmarketplace')
{
$this->cacheEnvironment = Configuration::get(ConfigurationAdapter::CONF_ENVIRONMENT);
$this->cacheNamespace = $cacheNamespace;
$this->cacheDirectory = new CacheDirectoryProvider(
_PS_VERSION_,
_PS_ROOT_DIR_,
_PS_MODE_DEV_
);
}
public function get($key, callable $callback, $ttl = 3600)
{
$cacheElem = sprintf('%s/%s_%s.tmp', rtrim($this->cacheDirectory->getPath(), '/'), $this->cacheNamespace, md5($key . $this->cacheEnvironment));
if (file_exists($cacheElem) && (time() - filemtime($cacheElem)) < $ttl) {
return unserialize(file_get_contents($cacheElem));
}
try {
$result = $callback();
} catch (\Exception $e) {
return false;
}
file_put_contents($cacheElem, serialize($result));
return $result;
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Empik\Marketplace\Cache;
use Module;
use PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider;
class CacheClearer
{
const CONTAINERS = [
'admin',
'front',
];
protected $module;
protected $cacheDirectory;
public function __construct(Module $module)
{
$this->module = $module;
$this->cacheDirectory = new CacheDirectoryProvider(
_PS_VERSION_,
_PS_ROOT_DIR_,
false
);
}
public function clear()
{
foreach (self::CONTAINERS as $containerName) {
$containerFilePath = sprintf(
'%s/%s%sContainer.php',
rtrim($this->cacheDirectory->getPath(), '/'),
ucfirst($this->module->name),
ucfirst($containerName)
);
if (file_exists($containerFilePath)) {
unlink($containerFilePath);
}
}
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace Empik\Marketplace\Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
class ExportConfiguration
{
const EXPORT_PRODUCT_FILENAME = 'PrestaShop_products.csv';
const EXPORT_OFFER_FILENAME = 'PrestaShop_offers.csv';
const EXPORT_DIR = '/modules/empikmarketplace/data/';
const EXPORT_PATH = _PS_ROOT_DIR_ . self::EXPORT_DIR;
const CSV_FIELD_SEPARATOR = ';';
const CSV_VALUE_SEPARATOR = '|';
const EXPORT_IMG_LIMIT = 10;
const EXPORT_NAME_MAX_LENGTH = 128;
const EXPORT_PRODUCTS_PER_PAGE = 10;
protected $configurationAdapter;
public function __construct(ConfigurationAdapter $configurationAdapter)
{
$this->configurationAdapter = $configurationAdapter;
}
public function getExportPath()
{
return self::EXPORT_PATH . self::EXPORT_PRODUCT_FILENAME;
}
public function getProductExportPath()
{
return self::EXPORT_PATH . self::EXPORT_PRODUCT_FILENAME;
}
public function getOfferExportPath()
{
return self::EXPORT_PATH . self::EXPORT_OFFER_FILENAME;
}
public function getCsvDelimiter()
{
return self::CSV_FIELD_SEPARATOR;
}
public function getProductIdType()
{
return $this->configurationAdapter->get('EMPIK_OFFER_IDENTIFIER');
}
public function getPriceRatio()
{
return (float)$this->configurationAdapter->get('EMPIK_PRICE_RATIO');
}
public function getAddToPrice()
{
return (float)$this->configurationAdapter->get('EMPIK_ADD_TO_PRICE');
}
public function getStockReduce()
{
return (float)$this->configurationAdapter->get('EMPIK_REDUCE_STOCK');
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Empik\Marketplace\Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
class ExportProductConfiguration
{
const EXPORT_PRODUCT_FILENAME = 'PrestaShop_products.csv';
const EXPORT_OFFER_FILENAME = 'PrestaShop_offers.csv';
const EXPORT_PATH = __DIR__ . '/../../data/';
const CSV_FIELD_SEPARATOR = ';';
const CSV_VALUE_SEPARATOR = '|';
protected $configurationAdapter;
public function __construct(ConfigurationAdapter $configurationAdapter)
{
$this->configurationAdapter = $configurationAdapter;
}
public function getExportPath()
{
return self::EXPORT_PATH . self::EXPORT_PRODUCT_FILENAME;
}
public function getProductExportPath()
{
return self::EXPORT_PATH . self::EXPORT_PRODUCT_FILENAME;
}
public function getOfferExportPath()
{
return self::EXPORT_PATH . self::EXPORT_OFFER_FILENAME;
}
public function getCsvDelimiter()
{
return self::CSV_FIELD_SEPARATOR;
}
public function getProductIdType()
{
return $this->configurationAdapter->get('EMPIK_OFFER_IDENTIFIER');
}
public function getPriceRatio()
{
return (float)$this->configurationAdapter->get('EMPIK_PRICE_RATIO');
}
public function getAddToPrice()
{
return (float)$this->configurationAdapter->get('EMPIK_ADD_TO_PRICE');
}
public function getStockReduce()
{
return (float)$this->configurationAdapter->get('EMPIK_REDUCE_STOCK');
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,46 @@
<?php
namespace Empik\Marketplace\DataProvider;
use Db;
use DbQuery;
use Context;
use Empik\Marketplace\Utils\Utils;
class CarriersDataProvider
{
/**
* @var Db
*/
protected $db;
/**
* @var Context
*/
protected $context;
/**
* @var int
*/
protected $countryId;
public function __construct()
{
$this->db = Db::getInstance();
$this->context = Context::getContext();
$this->countryId = Utils::getCountryId();
}
public function getCarriers()
{
$sql = new DbQuery();
$sql->select('c.*');
$sql->from('carrier', 'c');
$sql->where('c.deleted = 0');
$result = $this->db->executeS($sql);
return $result;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Empik\Marketplace\DataProvider;
use Context;
use Product;
class CombinationDataProvider
{
/** @var Context */
protected $context;
public function __construct()
{
$this->context = Context::getContext();
}
public function getCombinationsByProductId($id_product)
{
$product = new Product($id_product);
$combinations = $product->getAttributeCombinations($this->context->language->id);
$combinationsGrouped = [];
foreach ($combinations as $combination) {
if (!isset($combinationsGrouped[$combination['id_product_attribute']])) {
$combinationsGrouped[$combination['id_product_attribute']] = $combination;
}
$combinationsGrouped[$combination['id_product_attribute']]['attributes'][] = sprintf(
'%s: %s', $combination['group_name'], $combination['attribute_name']
);
$empikProduct = \EmpikProduct::getOrCreate($id_product, $combination['id_product_attribute']);
$combinationsGrouped[$combination['id_product_attribute']]['offer_price'] = $empikProduct->offer_price;
$combinationsGrouped[$combination['id_product_attribute']]['offer_price_reduced'] = $empikProduct->offer_price_reduced;
}
if (!empty($combinationsGrouped)) {
foreach ($combinationsGrouped as $idProductAttribute => $combination) {
$combinationsGrouped[$idProductAttribute]['attributes_list'] = implode(', ', $combination['attributes']);
}
}
return $combinationsGrouped;
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Empik\Marketplace\DataProvider;
use Empik\Marketplace\Exception\InvalidArgumentException;
use Empik\Marketplace\Repository\ProductRepository;
use Empik\Marketplace\Utils\IdentifierExtractor;
class OffersDataProvider
{
const STATE_CODE_NEW = 1;
const STATE_CODE_USED = 11;
/** @var ProductRepository */
protected $productRepository;
/** @var IdentifierExtractor */
protected $identifierExtractor;
public function __construct(
ProductRepository $productRepository,
IdentifierExtractor $identifierExtractor
) {
$this->productRepository = $productRepository;
$this->identifierExtractor = $identifierExtractor;
}
public function getOffersDataByProductIds(array $ids, $updateDeleteMode = 'delete')
{
if (!in_array($updateDeleteMode, ['update', 'delete'])) {
throw new InvalidArgumentException(sprintf('Invalid mode "%s"', $updateDeleteMode));
}
$offers = [];
$products = $this->productRepository->getOffersByIds($ids);
foreach ($products as $product) {
$offers[] = [
'description' => $product['description'],
'internal_description' => $product['id_product'],
'price' => $product['price'],
'product_id' => $this->identifierExtractor->extract($product),
'product_id_type' => $this->identifierExtractor->getIdentifierType(),
'shop_sku' => $product['reference'],
'state_code' => self::STATE_CODE_NEW,
'update_delete' => $updateDeleteMode,
];
}
return $offers;
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace Empik\Marketplace\DataProvider;
use Db;
use DbQuery;
use Context;
class ProductDataProvider
{
/** @var Db */
protected $db;
/** @var int */
protected $shopId;
/** @var int */
protected $langId;
public function __construct()
{
$this->db = Db::getInstance();
$this->shopId = Context::getContext()->shop->id;
$this->langId = Context::getContext()->language->id;
}
public function getOneBy($params = [])
{
$sql = new DbQuery();
$sql->select('
p.id_product,
p.cache_default_attribute AS id_product_attribute,
p.price,
p.wholesale_price,
p.reference,
p.supplier_reference,
p.ean13,
# p.isbn,
# p.mpn,
p.upc,
p.unity,
p.width,
p.height,
p.depth,
p.weight,
p.condition,
p.additional_shipping_cost,
p.available_date,
p.minimal_quantity,
p.active,
pl.name,
pl.description,
pl.description_short,
pl.link_rewrite,
pl.meta_description,
pl.meta_keywords,
pl.meta_title,
pl.available_now,
pl.available_later,
# pl.delivery_in_stock,
# pl.delivery_out_stock,
sav.quantity,
sav.depends_on_stock,
m.name AS manufacturer_name');
$sql->from('product', 'p');
$sql->leftJoin(
'manufacturer',
'm',
'm.id_manufacturer = p.id_manufacturer'
);
$sql->leftJoin(
'product_lang',
'pl',
'pl.id_product = p.id_product AND
pl.id_lang = ' . (int)$this->langId . ' AND
pl.id_shop = ' . (int)$this->shopId
);
// stock
$sql->leftJoin(
'stock_available',
'sav',
'sav.id_product = p.id_product AND
sav.id_product_attribute = 0 AND
sav.id_shop = ' . (int)$this->shopId . ' AND
sav.id_shop_group = 0'
);
foreach ($params as $param => $value) {
$sql->where(pSQL($param) . ' = ' . '"'.pSQL($value).'"');
}
$result = $this->db->getRow($sql);
return $result;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,60 @@
<?php
class EmpikAction extends ObjectModel
{
const ACTION_OTHER = 'OTHER';
const ACTION_PRODUCT_EXPORT = 'PRODUCT_EXPORT';
const ACTION_OFFER_EXPORT = 'OFFER_EXPORT';
const ACTION_PRODUCT_EXPORT_INCLUDE = 'PRODUCT_EXPORT_INCLUDE';
const ACTION_PRODUCT_EXPORT_EXCLUDE = 'PRODUCT_EXPORT_EXCLUDE';
const STATUS_NEW = 'NEW';
const STATUS_COMPLETED = 'COMPLETE';
public $id_shop;
public $action = self::ACTION_OTHER;
public $status = self::STATUS_NEW;
public $id_import;
public $import_count;
public $date_start;
public $date_end;
public static $definition = [
'table' => 'empik_action',
'primary' => 'id_empik_action',
'fields' => [
'id_shop' => [
'type' => self::TYPE_INT,
'validate' => 'isUnsignedInt',
'required' => true,
],
'action' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
],
'status' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
],
'id_import' => [
'type' => self::TYPE_INT,
'validate' => 'isCleanHtml',
],
'import_count' => [
'type' => self::TYPE_INT,
'validate' => 'isCleanHtml',
],
'date_start' => [
'type' => self::TYPE_DATE,
'validate' => 'isDate',
'required' => true,
],
'date_end' => [
'type' => self::TYPE_DATE,
'validate' => 'isDate',
'required' => true,
],
],
];
}

View File

@@ -0,0 +1,30 @@
<?php
class EmpikActionLog extends ObjectModel
{
public $id_empik_action;
public $message;
public $date_add;
public static $definition = [
'table' => 'empik_action',
'primary' => 'id_empik_action_log',
'fields' => [
'id_empik_action' => [
'type' => self::TYPE_INT,
'validate' => 'isUnsignedInt',
'required' => true,
],
'message' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
],
'date_add' => [
'type' => self::TYPE_DATE,
'validate' => 'isDate',
'required' => true,
],
],
];
}

View File

@@ -0,0 +1,87 @@
<?php
class EmpikOrder extends ObjectModel
{
public $id_order;
public $empik_order_reference;
public $empik_order_carrier;
public $empik_payment;
public $empik_carrier;
public $empik_pickup_point;
public $empik_vat_number;
public $date_add;
public static $definition = [
'table' => 'empik_orders',
'primary' => 'id_empik_order',
'fields' => [
'id_order' => [
'type' => self::TYPE_INT,
'validate' => 'isUnsignedInt',
'required' => true,
],
'empik_order_reference' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
],
'empik_order_carrier' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
],
'empik_payment' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
'required' => true,
],
'empik_carrier' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
'required' => true,
],
'empik_pickup_point' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
],
'empik_vat_number' => [
'type' => self::TYPE_STRING,
'validate' => 'isCleanHtml',
],
'date_add' => [
'type' => self::TYPE_DATE,
'validate' => 'isDate',
'required' => false,
],
],
];
public static function getEmpikOrderByOrderId($orderId)
{
$query = (new DbQuery())
->select('eo.*')
->from('empik_orders', 'eo')
->where('eo.id_order = "'.pSQL($orderId).'"');
return Db::getInstance()->getRow($query);
}
public static function getEmpikOrderReferenceByOrderId($orderId)
{
$query = (new DbQuery())
->select('eo.empik_order_reference')
->from('empik_orders', 'eo')
->where('eo.id_order = "'.pSQL($orderId).'"');
return Db::getInstance()->getValue($query);
}
public static function getOrderIdByEmpikOrderReference($empikOrderReference)
{
$query = (new DbQuery())
->select('eo.id_order')
->from('empik_orders', 'eo')
->where('eo.empik_order_reference = "'.pSQL($empikOrderReference).'"');
return Db::getInstance()->getValue($query);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Empik\Marketplace\Exception;
use Exception;
class InvalidActionException extends Exception
{
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Empik\Marketplace\Exception;
use Exception;
class InvalidArgumentException extends Exception
{
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Empik\Marketplace\Exception;
use Exception;
class LogicException extends Exception
{
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Empik\Marketplace\Exception;
use Exception;
class OrderProcessException extends Exception
{
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,26 @@
<?php
namespace Empik\Marketplace\Factory;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\API\EmpikClient;
class EmpikClientFactory
{
/** @var ConfigurationAdapter */
protected $configurationAdapter;
public function __construct(ConfigurationAdapter $configurationAdapter)
{
$this->configurationAdapter = $configurationAdapter;
}
public function createClient()
{
$apiUrl = $this->configurationAdapter->get(ConfigurationAdapter::CONF_ENVIRONMENT);
$apiKey = $this->configurationAdapter->get(ConfigurationAdapter::CONF_API_KEY);
return new EmpikClient($apiUrl, $apiKey);
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Empik\Marketplace\Factory;
use Empik\Marketplace\API\HttpClientInterface;
use Empik\Marketplace\API\HttpCurlClient;
class EmpikCurlHttpClientFactory implements HttpClientFactoryInterface
{
/**
* @param $apiUrl
* @return HttpClientInterface
*/
public function createClient($apiUrl)
{
return new HttpCurlClient(['base_url' => $apiUrl]);
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Empik\Marketplace\Factory;
use GuzzleHttp\Client;
class EmpikGuzzleHttpClientFactory implements HttpClientFactoryInterface
{
public function createClient($apiUrl)
{
return new Client(['base_url' => $apiUrl]);
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Empik\Marketplace\Factory;
use GuzzleHttp\Client;
interface HttpClientFactoryInterface
{
/**
* @param string $apiUrl
* @return Client
*/
public function createClient($apiUrl);
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Empik\Marketplace\Factory;
use Empik\Marketplace\API\HttpClientInterface;
use Empik\Marketplace\API\HttpCurlClient;
use Exception;
class HttpClientsFactory
{
/**
* @param null $handler
* @return HttpClientInterface
* @throws Exception
*/
public static function createHttpClient($handler = null)
{
return self::detectDefaultClient();
}
/**
* @return HttpClientInterface
* @throws Exception
*/
private static function detectDefaultClient()
{
if (function_exists('curl_version')) {
return new HttpCurlClient();
}
throw new Exception('Unable to detect default HTTP client.');
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,19 @@
<?php
namespace Empik\Marketplace\Formatter;
use Empik\Marketplace\Configuration\ExportConfiguration;
use Tools;
class ProductNameFormatter
{
/**
* @param string $name
* @param int|bool $length
* @return string
*/
public function format($name, $length = false)
{
return (string)Tools::substr($name, 0, $length ? $length : ExportConfiguration::EXPORT_NAME_MAX_LENGTH);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,107 @@
<?php
namespace Empik\Marketplace\Handler;
use Context;
use EmpikMarketplace;
use Empik\Marketplace\Adapter\ToolsAdapter;
use Empik\Marketplace\Processor\OrderProcessor;
use Empik\Marketplace\Processor\ExportProductProcessor;
use Empik\Marketplace\Processor\ExportOfferProcessor;
use Empik\Marketplace\Exception\InvalidActionException;
class CronJobsHandler
{
const ACTION_EXPORT_PRODUCTS = 'exportProducts';
const ACTION_EXPORT_OFFERS = 'exportOffers';
const ACTION_IMPORT_ORDERS = 'importOrders';
const ACTIONS = [
self::ACTION_EXPORT_PRODUCTS,
self::ACTION_EXPORT_OFFERS,
self::ACTION_IMPORT_ORDERS,
];
/** @var Context */
protected $context;
/** @var EmpikMarketplace */
protected $module;
/** @var ToolsAdapter */
protected $tools;
/** @var ExportProductProcessor */
protected $exportProductProcessor;
/** @var ExportOfferProcessor */
protected $exportOfferProcessor;
/** @var OrderProcessor */
protected $orderProcessor;
public function __construct(
EmpikMarketplace $module,
ToolsAdapter $tools,
ExportProductProcessor $exportProductProcessor,
ExportOfferProcessor $exportOfferProcessor,
OrderProcessor $orderProcessor
) {
$this->module = $module;
$this->tools = $tools;
$this->exportProductProcessor = $exportProductProcessor;
$this->exportOfferProcessor = $exportOfferProcessor;
$this->orderProcessor = $orderProcessor;
$this->context = Context::getContext();
}
public function handle($action)
{
set_time_limit(0);
switch ($action) {
case self::ACTION_EXPORT_PRODUCTS:
$this->exportProductProcessor->process();
break;
case self::ACTION_EXPORT_OFFERS:
$this->exportOfferProcessor->process();
break;
case self::ACTION_IMPORT_ORDERS:
$this->orderProcessor->process();
break;
default:
throw new InvalidActionException();
}
}
public function getAvailableActionsUrls()
{
$urls = [];
foreach (self::ACTIONS as $action) {
$urls[$action] = $this->getActionUrl($action);
}
return $urls;
}
public function checkToken($token)
{
return $token === $this->getToken();
}
protected function getActionUrl($action)
{
return $this->context->link->getModuleLink($this->module->name, 'cron', [
'action' => $action,
'token' => $this->getToken(),
]);
}
protected function getToken()
{
return $this->tools->hash($this->module->name . '_cron');
}
}

View File

@@ -0,0 +1,189 @@
<?php
namespace Empik\Marketplace\Handler;
use Context;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\Manager\CsvManager;
use Empik\Marketplace\Utils\SkuExtractor;
use Product;
use EmpikMarketplace;
use Empik\Marketplace\Configuration\ExportConfiguration;
use Empik\Marketplace\Repository\CategoryRepository;
use Empik\Marketplace\Repository\FeatureRepository;
use Empik\Marketplace\Repository\ImageRepository;
use Empik\Marketplace\Repository\ProductRepository;
use Empik\Marketplace\Repository\TaxRepository;
use Empik\Marketplace\Utils\CategoryPathBuilder;
use Empik\Marketplace\Utils\IdentifierExtractor;
use Empik\Marketplace\Formatter\ProductNameFormatter;
use Empik\Marketplace\Utils\OfferPriceCalculator;
use Empik\Marketplace\Utils\OfferQuantityCalculator;
class ExportOfferHandler
{
const STATE_CODE_NEW = 1;
const STATE_CODE_USED = 11;
/** @var EmpikMarketplace */
protected $module;
/** @var Context */
protected $context;
/** @var ExportConfiguration */
protected $exportConfig;
/** @var ProductRepository */
protected $productRepository;
/** @var FeatureRepository */
protected $featureRepository;
/** @var TaxRepository */
protected $taxRepository;
/** @var CategoryRepository */
protected $categoryRepository;
/** @var ImageRepository */
protected $imageRepository;
/** @var ProductNameFormatter */
protected $productNameFormatter;
/** @var CategoryPathBuilder */
protected $categoryPathBuilder;
/** @var IdentifierExtractor */
protected $identifierExtractor;
/** @var SkuExtractor */
protected $skuExtractor;
/** @var OfferPriceCalculator */
protected $offerPriceCalculator;
/** @var OfferQuantityCalculator */
protected $offerQuantityCalculator;
/** @var CsvManager */
protected $csvManager;
public function __construct(
EmpikMarketplace $module,
ExportConfiguration $exportConfig,
ProductRepository $productRepository,
FeatureRepository $featureRepository,
TaxRepository $taxRepository,
CategoryRepository $categoryRepository,
ImageRepository $imageRepository,
ProductNameFormatter $productNameFormatter,
CategoryPathBuilder $categoryPathBuilder,
IdentifierExtractor $identifierExtractor,
SkuExtractor $skuExtractor,
OfferPriceCalculator $offerPriceCalculator,
OfferQuantityCalculator $offerQuantityCalculator
) {
$this->module = $module;
$this->exportConfig = $exportConfig;
$this->productRepository = $productRepository;
$this->featureRepository = $featureRepository;
$this->taxRepository = $taxRepository;
$this->categoryRepository = $categoryRepository;
$this->imageRepository = $imageRepository;
$this->productNameFormatter = $productNameFormatter;
$this->categoryPathBuilder = $categoryPathBuilder;
$this->identifierExtractor = $identifierExtractor;
$this->skuExtractor = $skuExtractor;
$this->offerPriceCalculator = $offerPriceCalculator;
$this->offerQuantityCalculator = $offerQuantityCalculator;
$this->csvManager = new CsvManager(
$this->exportConfig->getOfferExportPath(),
ExportConfiguration::CSV_FIELD_SEPARATOR
);
$this->context = Context::getContext();
}
public function isLastPage($page)
{
$total = $this->productRepository->getProductsTotal(ProductRepository::SRC_OFFER);
return $page * ExportConfiguration::EXPORT_PRODUCTS_PER_PAGE > $total;
}
public function handle($page = null)
{
if (!$page && file_exists($this->exportConfig->getOfferExportPath())) {
$this->csvManager->remove();
}
$localPage = $page === null ? 0 : $page;
$leadTimeToShip = \Configuration::get(ConfigurationAdapter::CONF_LEAD_TIME_TO_SHIP);
$syncLogisticClass = \Configuration::get(ConfigurationAdapter::CONF_SYNC_LOGISTIC_CLASS);
do {
$products = $this->productRepository->getProductsPaginate(
$localPage,
ExportConfiguration::EXPORT_PRODUCTS_PER_PAGE,
ProductRepository::SRC_OFFER
);
foreach ($products as $i => $product) {
$offer = [];
$priceWithReduction = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2);
$priceWithoutReduction = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2, null, false, false);
$calculatedPriceWithReduction = $this->offerPriceCalculator->calculate($priceWithReduction);
$calculatedPriceWithoutReduction = $this->offerPriceCalculator->calculate($priceWithoutReduction);
$hasReduction = $calculatedPriceWithoutReduction > $calculatedPriceWithReduction;
$quantity = \StockAvailable::getQuantityAvailableByProduct($product['id_product'], $product['id_product_attribute']);
$calculatedQuantity = $this->offerQuantityCalculator->calculate($quantity);
$offer['product-id-type'] = $this->identifierExtractor->getIdentifierType();
$offer['product-id'] = $this->identifierExtractor->extract($product);
$offer['sku'] = $this->skuExtractor->extract($product);
$offer['state'] = !empty($product['empik_condition']) ? $product['empik_condition'] : self::STATE_CODE_NEW;
if ($product['offer_price'] > 0) {
$offer['price'] = $product['offer_price'];
} else {
$offer['price'] = $calculatedPriceWithoutReduction;
}
if ((int)$product['export_original_price'] > 0) {
if ($product['offer_price_reduced'] > 0) {
$offer['discount-price'] = $product['offer_price_reduced'];
} else {
$offer['discount-price'] = $hasReduction ? $calculatedPriceWithReduction : null;
}
} else {
$offer['discount-price'] = '';
}
$offer['quantity'] = $calculatedQuantity;
if ($leadTimeToShip && $leadTimeToShip >= 0) {
$offer['leadtime-to-ship'] = $leadTimeToShip;
}
if ($syncLogisticClass) {
$offer['logistic-class'] = $product['logistic_class'];
}
// add csv header
if ($i === 0 && ($page === 0 || $page === null && $localPage === 0)) {
$this->csvManager->addRow(array_keys($offer));
}
$this->csvManager->addRow($offer);
}
$localPage++;
} while ($products && $page === null);
}
}

View File

@@ -0,0 +1,259 @@
<?php
namespace Empik\Marketplace\Handler;
use Empik\Marketplace\Manager\CsvManager;
use Tools;
use Context;
use Product;
use StockAvailable;
use EmpikMarketplace;
use Empik\Marketplace\Configuration\ExportConfiguration;
use Empik\Marketplace\Repository\CategoryRepository;
use Empik\Marketplace\Repository\FeatureRepository;
use Empik\Marketplace\Repository\AttributeRepository;
use Empik\Marketplace\Repository\ImageRepository;
use Empik\Marketplace\Repository\ProductRepository;
use Empik\Marketplace\Repository\TaxRepository;
use Empik\Marketplace\Utils\CategoryPathBuilder;
use Empik\Marketplace\Utils\IdentifierExtractor;
use Empik\Marketplace\Formatter\ProductNameFormatter;
class ExportProductHandler
{
/** @var EmpikMarketplace */
protected $module;
/** @var Context */
protected $context;
/** @var ExportConfiguration */
protected $exportConfig;
/** @var ProductRepository */
protected $productRepository;
/** @var FeatureRepository */
protected $featureRepository;
/** @var AttributeRepository */
protected $attributeRepository;
/** @var TaxRepository */
protected $taxRepository;
/** @var CategoryRepository */
protected $categoryRepository;
/** @var ImageRepository */
protected $imageRepository;
/** @var ProductNameFormatter */
protected $productNameFormatter;
/** @var CategoryPathBuilder */
protected $categoryPathBuilder;
/** @var IdentifierExtractor */
protected $identifierExtractor;
/** @var CsvManager */
protected $csvManager;
public function __construct(
EmpikMarketplace $module,
ExportConfiguration $exportConfig,
ProductRepository $productRepository,
FeatureRepository $featureRepository,
AttributeRepository $attributeRepository,
TaxRepository $taxRepository,
CategoryRepository $categoryRepository,
ImageRepository $imageRepository,
ProductNameFormatter $productNameFormatter,
CategoryPathBuilder $categoryPathBuilder,
IdentifierExtractor $identifierExtractor
) {
$this->module = $module;
$this->exportConfig = $exportConfig;
$this->productRepository = $productRepository;
$this->featureRepository = $featureRepository;
$this->attributeRepository = $attributeRepository;
$this->taxRepository = $taxRepository;
$this->categoryRepository = $categoryRepository;
$this->imageRepository = $imageRepository;
$this->productNameFormatter = $productNameFormatter;
$this->categoryPathBuilder = $categoryPathBuilder;
$this->identifierExtractor = $identifierExtractor;
$this->csvManager = new CsvManager(
$this->exportConfig->getProductExportPath(),
ExportConfiguration::CSV_FIELD_SEPARATOR
);
$this->context = Context::getContext();
}
public function isLastPage($page)
{
$total = $this->productRepository->getProductsTotal(ProductRepository::SRC_PRODUCT);
return $page * ExportConfiguration::EXPORT_PRODUCTS_PER_PAGE > $total;
}
public function handle($page = null)
{
if (!$page && file_exists($this->exportConfig->getProductExportPath())) {
$this->csvManager->remove();
}
$localPage = $page === null ? 0 : $page;
do {
$products = $this->productRepository->getProductsPaginate(
$localPage,
ExportConfiguration::EXPORT_PRODUCTS_PER_PAGE,
ProductRepository::SRC_PRODUCT
);
foreach ($products as $i => $product) {
$product = $this->addName($product);
$product = $this->addPrices($product);
$product = $this->addQuantity($product);
$product = $this->addTax($product);
$product = $this->addCategories($product);
$product = $this->addFeatures($product);
$product = $this->addAttributes($product);
$product = $this->addImages($product);
// add csv header
if ($i === 0 && ($page === 0 || $page === null && $localPage === 0)) {
$this->csvManager->addRow(array_keys($product));
}
$this->csvManager->addRow($product);
}
$localPage++;
} while ($products && $page === null);
}
/**
* @param array $product
* @return array
*/
protected function addName($product)
{
$product['name'] = $this->productNameFormatter->format($product['name']);
return $product;
}
/**
* @param array $product
* @return array
*/
protected function addFeatures($product)
{
$features = $this->featureRepository->getFeatures($product['id_product']);
foreach ($features as $feature) {
$product[sprintf('feature[%s]', $feature['feature_name'])] = $feature['value'];
}
return $product;
}
/**
* @param array $product
* @return array
*/
protected function addAttributes($product)
{
$features = $this->attributeRepository->getAttributes($product['id_product'], $product['id_product_attribute']);
foreach ($features as $feature) {
$product[sprintf('attribute[%s]', $feature['name'])] = $feature['value'];
}
return $product;
}
/**
* @param array $product
* @return array
*/
protected function addPrices($product)
{
$product['price'] = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2);
$product['price_without_reduction'] = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2, null, false, false);
$product['reduction'] = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2, null, true);
return $product;
}
/**
* @param array $product
* @return array
*/
protected function addQuantity($product)
{
$quantity = StockAvailable::getQuantityAvailableByProduct(
$product['id_product'],
$product['id_product_attribute']
);
$product['quantity'] = (int)$quantity;
return $product;
}
/**
* @param array $product
* @return array
*/
protected function addTax($product)
{
$product['vat'] = $this->taxRepository->getTaxRateByProductId($product['id_product']);
return $product;
}
/**
* @param array $product
* @return array
*/
protected function addCategories($product)
{
$categories = $this->categoryRepository->getCategoriesByProductId($product['id_product']);
$path = $this->categoryPathBuilder->buildPath($categories);
$product['category'] = $path;
return $product;
}
/**
* @param array $product
* @return array
*/
protected function addImages($product)
{
$images = $this->imageRepository->getImages($product['id_product'], $product['id_product_attribute']);
for ($i = 0; $i < ExportConfiguration::EXPORT_IMG_LIMIT; $i++) {
$imageUrl = null;
if (isset($images[$i])) {
$imageUrl = $this->context->link->getImageLink(
Tools::link_rewrite($product['link_rewrite'] ? $product['link_rewrite'] : $product['name']),
$images[$i]['id_image']
);
}
$product[sprintf('image_%d', $i + 1)] = isset($imageUrl) ? $imageUrl : null;
}
return $product;
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Empik\Marketplace\Handler;
use Exception;
use Empik\Marketplace\API\EmpikClient;
use Empik\Marketplace\DataProvider\OffersDataProvider;
use Empik\Marketplace\Factory\EmpikClientFactory;
use Empik\Marketplace\Repository\ProductRepository;
use Empik\Marketplace\Traits\ErrorsTrait;
class UpdateDeleteOfferHandler
{
use ErrorsTrait;
/** @var EmpikClientFactory */
protected $empikClientFactory;
/** @var ProductRepository */
protected $productRepository;
/** @var OffersDataProvider */
protected $offersDataProvider;
/** @var EmpikClient */
protected $empikClient;
public function __construct(
EmpikClientFactory $empikClientFactory,
ProductRepository $productRepository,
OffersDataProvider $offersDataProvider
) {
$this->empikClientFactory = $empikClientFactory;
$this->productRepository = $productRepository;
$this->offersDataProvider = $offersDataProvider;
$this->empikClient = $this->empikClientFactory->createClient();
}
public function handle(array $ids)
{
try {
$offersData = $this->offersDataProvider->getOffersDataByProductIds($ids);
$this->empikClient->postOffers($offersData);
return true;
} catch (Exception $e) {
$this->addError($e->getMessage());
}
return false;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,258 @@
<?php
namespace Empik\Marketplace\Hook;
use Carrier;
use Configuration;
use Context;
use Module;
use Order;
use Product;
use OrderHistory;
use EmpikOrder;
use EmpikMarketplace;
use Empik\Marketplace\Adapter\LoggerAdapter;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\Factory\EmpikClientFactory;
use Empik\Marketplace\Handler\UpdateDeleteOfferHandler;
use Empik\Marketplace\Manager\CarrierMapManager;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn;
use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface;
use PrestaShop\PrestaShop\Core\Grid\Filter\Filter;
use PrestaShop\PrestaShop\Core\Search\Filters\OrderFilters;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Doctrine\ORM\QueryBuilder;
use Exception;
class HookAction
{
/** @var EmpikMarketplace */
protected $module;
/** @var Context */
protected $context;
/** @var CarrierMapManager */
protected $carrierMapManager;
public function __construct(CarrierMapManager $carrierMapManager)
{
$this->carrierMapManager = $carrierMapManager;
$this->module = Module::getInstanceByName('empikmarketplace');
$this->context = Context::getContext();
}
public function hookActionOrderGridDefinitionModifier(array $params)
{
/** @var GridDefinitionInterface $definition */
$definition = $params['definition'];
$definition
->getColumns()
->addAfter(
'reference',
(new DataColumn('empik_order_reference'))
->setName('Empik')
->setOptions(
[
'field' => 'empik_order_reference',
]
)
);
$definition->getFilters()->add(
(new Filter('empik_order_reference', TextType::class))
->setTypeOptions([
'required' => false,
])
->setAssociatedColumn('empik_order_reference')
);
}
public function hookActionOrderGridQueryBuilderModifier(array $params)
{
/** @var QueryBuilder[] $queryBuilders */
$queryBuilders = [
'search' => $params['search_query_builder'],
'count' => $params['count_query_builder'],
];
/** @var OrderFilters $searchCriteria */
$searchCriteria = $params['search_criteria'];
$filters = $searchCriteria->getFilters();
foreach ($queryBuilders as $queryBuilder) {
if (isset($filters['empik_order_reference'])) {
$queryBuilder
->andWhere('empik.empik_order_reference = :empik_order_reference')
->setParameter('empik_order_reference', $filters['empik_order_reference']);
}
}
foreach ($queryBuilders as $queryBuilder) {
$queryBuilder
->addSelect(
'empik.empik_order_reference'
)
->leftJoin(
'o',
_DB_PREFIX_.'empik_orders',
'empik',
'empik.id_order = o.id_order'
)
;
}
/** @var QueryBuilder $searchQueryBuilder */
$searchQueryBuilder = $params['search_query_builder'];
if ('empik_order_reference' === $searchCriteria->getOrderBy()) {
$searchQueryBuilder->orderBy('empik.empik_order_reference', $searchCriteria->getOrderWay());
}
}
public function hookActionOrderHistoryAddAfter(array $params)
{
/** @var OrderHistory $orderHistory */
$orderHistory = $params['order_history'];
$empikOrderId = EmpikOrder::getEmpikOrderReferenceByOrderId($orderHistory->id_order);
if (!$empikOrderId) {
return;
}
if ($orderHistory->id_order_state == Configuration::get(ConfigurationAdapter::CONF_SHIPPED_ORDER_STATE)) {
/** @var LoggerAdapter $logger */
$logger = $this->module->getService('empik.marketplace.adapter.loggerAdapter');
/** @var EmpikClientFactory $empikClientFactory */
$empikClientFactory = $this->module->getService('empik.marketplace.factory.empikClientFactory');
$empikClient = $empikClientFactory->createClient();
try {
$empikClient->putOrderShip($empikOrderId);
} catch (Exception $e) {
$logger->logError($e->getMessage());
}
}
}
public function hookActionAdminOrdersListingFieldsModifier($params)
{
if (isset($params['select'])) {
if (strpos('a.reference', $params['select']) === false) {
$params['select'] .= ',a.reference';
}
$params['select'] .= ',eo.empik_order_reference';
$params['join'] .= ' LEFT JOIN `'._DB_PREFIX_.'empik_orders` eo ON (eo.`id_order` = a.`id_order`)';
}
$params['fields']['empik_order_reference'] = [
'title' => $this->module->l('Empik'),
'align' => 'center',
];
}
public function hookDisplayAdminOrder($params)
{
$empikOrder = EmpikOrder::getEmpikOrderByOrderId($params['id_order']);
if (!$empikOrder) {
return null;
}
$this->context->smarty->assign(
[
'empik_order' => $empikOrder,
]
);
return $this->context->smarty->fetch(
$this->module->getLocalPath().'/views/templates/admin/hook/admin_order.tpl'
);
}
public function hookActionAdminOrdersTrackingNumberUpdate(array $params)
{
/** @var Order $order */
$order = $params['order'];
/** @var Carrier $carrier */
$carrier = $params['carrier'];
$trackingNumber = isset($_POST['update_order_shipping']['tracking_number'])
? $_POST['update_order_shipping']['tracking_number']
: $order->shipping_number
;
if ($trackingNumber) {
$empikOrder = EmpikOrder::getEmpikOrderByOrderId($order->id);
if (!$empikOrder) {
return;
}
/** @var EmpikClientFactory $empikClientFactory */
$empikClientFactory = $this->module->getService('empik.marketplace.factory.empikClientFactory');
$empikClient = $empikClientFactory->createClient();
/** @var LoggerAdapter $logger */
$logger = $this->module->getService('empik.marketplace.adapter.loggerAdapter');
$carrierName = null;
$carrierUrl = null;
$carrierCode = $this->carrierMapManager->getTypeByCode($empikOrder['empik_order_carrier']);
if (!$carrierCode) {
$carrierName = $carrier->name;
$carrierUrl = str_replace('@', $trackingNumber, $carrier->url);
}
try {
$empikClient->putOrderTracking(
$empikOrder['empik_order_reference'],
$carrierCode,
$carrierName,
$carrierUrl,
$trackingNumber
);
} catch (Exception $e) {
$logger->logError($e->getMessage());
}
}
}
public function hookActionObjectProductDeleteBefore($params)
{
/** @var Product $product */
$product = $params['object'];
if (!$this->module->getAuthStatus()) {
return;
}
/** @var UpdateDeleteOfferHandler $handler */
$handler = $this->module->getService('empik.marketplace.handler.updateDeleteOfferHandler');
/** @var LoggerAdapter $logger */
$logger = $this->module->getService('empik.marketplace.adapter.loggerAdapter');
if (!$handler->handle([$product->id])) {
foreach ($handler->getErrors() as $error) {
$logger->logError($error);
}
}
}
public function hookActionAdminControllerSetMedia($params)
{
$this->context->controller->addCSS($this->module->getPathUri() . '/views/css/admin/empik.css');
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,141 @@
<?php
namespace Empik\Marketplace\Install;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\PrestaShopContext;
use EmpikMarketplace;
use Exception;
use Configuration;
use Language;
use Context;
use Module;
use Tab;
use Db;
class Installer
{
/** @var Db */
protected $db;
/** @var EmpikMarketplace */
protected $module;
/** @var PrestaShopContext */
protected $prestaShopContext;
/** @var array */
protected $errors = [];
public function __construct(PrestaShopContext $prestaShopContext)
{
$this->prestaShopContext = $prestaShopContext;
$this->db = Db::getInstance();
$this->module = Module::getInstanceByName('empikmarketplace');
}
public function install()
{
$result = true;
$result &= $this->createTabs();
$result &= $this->crateTables();
$result &= $this->registerHooks();
$result &= $this->createConfig();
return (bool)$result;
}
public function createTabs()
{
$result = true;
foreach ($this->module->getAdminTabs() as $tab) {
$result &= $this->installTab(
$tab['className'],
$tab['parent'],
$tab['name'],
$tab['module'],
$tab['active'],
$tab['icon']
);
}
return $result;
}
public function crateTables()
{
try {
include __DIR__ . '/Sql/install.php';
} catch (Exception $e) {
$this->errors[] = $this->module->l('Failed to install database tables');
return false;
}
return true;
}
public function registerHooks()
{
$module = $this->module;
$hooksCommon = $module::HOOK_LIST_COMMON;
$hooks17 = $module::HOOK_LIST_17;
$hooks16 = $module::HOOK_LIST_16;
if ($this->prestaShopContext->is177()) {
$hooks = array_merge($hooksCommon, $hooks17);
} else {
$hooks = array_merge($hooksCommon, $hooks16);
}
return $this->module->registerHook(
$hooks
);
}
public function createConfig()
{
$result = true;
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_LEAD_TIME_TO_SHIP, -1);
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_PRICE_RATIO, 1);
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_ADD_TO_PRICE, 0);
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_SYNC_LOGISTIC_CLASS, 0);
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_REDUCE_STOCK, 0);
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_OFFER_IDENTIFIER, 'EAN');
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_SKU_TYPE, 'REFERENCE');
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_ID_EMPLOYEE, (int)Context::getContext()->employee->id);
$result &= Configuration::updateValue(ConfigurationAdapter::CONF_ENVIRONMENT, ConfigurationAdapter::ENV_TEST);
return $result;
}
protected function installTab($className, $parent, $name, $module, $active, $icon)
{
if (Tab::getIdFromClassName($className)) {
return true;
}
$parentId = is_int($parent) ? $parent : Tab::getIdFromClassName($parent);
$moduleTab = new Tab();
$moduleTab->class_name = $className;
$moduleTab->id_parent = $parentId;
$moduleTab->module = $module;
$moduleTab->active = $active;
if (property_exists($moduleTab, 'icon')) {
$moduleTab->icon = $icon;
}
$languages = Language::getLanguages(true);
foreach ($languages as $language) {
$moduleTab->name[$language['id_lang']] = $name;
}
return (bool)$moduleTab->add();
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,57 @@
<?php
$sql = [];
$sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'empik_action` (
`id_empik_action` INT(11) NOT NULL AUTO_INCREMENT,
`id_shop` INT(11) NOT NULL,
`action` VARCHAR(32) NOT NULL,
`status` VARCHAR(32) NOT NULL,
`id_import` INT(11),
`import_count` INT(11),
`date_start` DATETIME NOT NULL,
`date_end` DATETIME NOT NULL,
INDEX (`id_shop`),
PRIMARY KEY (`id_empik_action`)
)';
$sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'empik_action_log` (
`id_empik_action_log` INT(11) NOT NULL,
`message` TEXT NOT NULL,
`date_add` DATETIME NOT NULL,
INDEX (`id_empik_action_log`)
)';
$sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'empik_orders` (
`id_empik_order` INT(11) NOT NULL AUTO_INCREMENT,
`id_order` INT(11) NOT NULL,
`empik_order_reference` VARCHAR(32) NOT NULL,
`empik_order_carrier` VARCHAR(255) NOT NULL,
`empik_payment` VARCHAR(255) NOT NULL,
`empik_carrier` VARCHAR(255) NOT NULL,
`empik_pickup_point` VARCHAR(255) NOT NULL,
`empik_vat_number` VARCHAR(255) NOT NULL,
`date_add` DATETIME NOT NULL,
INDEX (`empik_order_reference`),
INDEX (`id_order`),
PRIMARY KEY (`id_empik_order`)
)';
$sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'empik_product` (
`id_empik_product` INT(11) NOT NULL AUTO_INCREMENT,
`id_product` INT(11) NOT NULL,
`id_product_attribute` INT(11) NOT NULL,
`logistic_class` INT(4) NOT NULL DEFAULT 2,
`product_export` INT(1) NOT NULL DEFAULT 0,
`offer_export` INT(1) NOT NULL DEFAULT 0,
`offer_price` DECIMAL(20, 2) NOT NULL DEFAULT 0,
`offer_price_reduced` DECIMAL(20, 2) NOT NULL DEFAULT 0,
UNIQUE (`id_product`, `id_product_attribute`),
PRIMARY KEY (`id_empik_product`)
)';
foreach ($sql as $query) {
if (Db::getInstance()->execute($query) == false) {
return false;
}
}
return true;

View File

@@ -0,0 +1,16 @@
<?php
$sql = [];
$sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'empik_action`;';
$sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'empik_action_log`;';
$sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'empik_orders`;';
$sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'empik_product`;';
foreach ($sql as $query) {
if (Db::getInstance()->execute($query) == false) {
return false;
}
}
return true;

View File

@@ -0,0 +1,95 @@
<?php
namespace Empik\Marketplace\Install;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use EmpikMarketplace;
use Exception;
use Configuration;
use Tab;
use Db;
class Uninstaller
{
/** @var Db */
protected $db;
/** @var EmpikMarketplace */
protected $module;
/** @var array */
protected $errors = [];
public function __construct()
{
$this->db = \Db::getInstance();
$this->module = \Module::getInstanceByName('empikmarketplace');
}
public function uninstall()
{
$result = true;
$result &= $this->dropTabs();
$result &= $this->dropTables();
$result &= $this->dropConfig();
return $result;
}
public function dropTabs()
{
$result = true;
/** @var Tab $tab */
foreach (Tab::getCollectionFromModule($this->module->name) as $tab) {
$result &= (bool)$tab->delete();
}
return $result;
}
public function dropTables()
{
try {
include __DIR__ . '/Sql/uninstall.php';
} catch (Exception $e) {
$this->errors[] = $this->module->l('Failed to uninstall database tables');
return false;
}
return true;
}
public function dropConfig()
{
$result = true;
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_ENVIRONMENT);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_API_KEY);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_AUTH_STATUS);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_SYNC_OFFERS);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_SYNC_LOGISTIC_CLASS);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_OFFER_IDENTIFIER);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_LEAD_TIME_TO_SHIP);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_PRICE_RATIO);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_ADD_TO_PRICE);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_REDUCE_STOCK);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_IMPORT_ORDERS);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_AUTO_ACCEPT_ORDERS);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_NEW_ORDER_STATE);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_SHIPPED_ORDER_STATE);
$result &= Configuration::deleteByName(ConfigurationAdapter::CONF_CARRIER_MAP);
return $result;
}
protected function uninstallTab($className)
{
$tab = new Tab(Tab::getIdFromClassName($className));
return (bool)$tab->delete();
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,110 @@
<?php
namespace Empik\Marketplace\Manager;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
class CarrierMapManager
{
/** @var ConfigurationAdapter */
protected $configurationAdapter;
/** @var array */
protected $map = [];
public function __construct(ConfigurationAdapter $configurationAdapter)
{
$this->configurationAdapter = $configurationAdapter;
$this->loadFromConfig();
}
/**
* @return array|mixed
*/
public function loadFromConfig()
{
$jsonString = $this->configurationAdapter->get(ConfigurationAdapter::CONF_CARRIER_MAP);
if ($jsonString) {
$this->map = json_decode($jsonString, true);
}
return $this->map;
}
/**
* @param $map
* @return bool
*/
public function setMap($map)
{
if ($this->validate($map)) {
$this->map = $map;
return true;
}
return false;
}
/**
* @param $map
* @return bool
*/
public function store($map)
{
if ($this->validate($map)) {
return $this->configurationAdapter->updateValue(
ConfigurationAdapter::CONF_CARRIER_MAP,
json_encode($map)
);
}
return true;
}
/**
* @param $code
* @return mixed
*/
public function getTypeByCode($code)
{
foreach ($this->map as $carrierCode => $carrier) {
if ($carrierCode === $code) {
return $carrier['type'];
}
}
return false;
}
/**
* @param $code
* @return mixed
*/
public function getIdByCode($code)
{
foreach ($this->map as $carrierCode => $carrier) {
if ($carrierCode === $code) {
return $carrier['id_carrier'];
}
}
return false;
}
/**
* @param $map
* @return bool
*/
protected function validate($map)
{
if (!is_array($map)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Empik\Marketplace\Manager;
use Empik\Marketplace\Exception\InvalidArgumentException;
class CsvManager
{
/** @var null|string */
protected $csvPath;
/** @var string */
protected $delimiter;
/** @var null|resource */
protected $fileHandle;
public function __construct($csvPath, $delimiter = ';')
{
$this->csvPath = $csvPath;
$this->delimiter = $delimiter;
}
function __destruct()
{
if ($this->fileHandle) {
fclose($this->fileHandle);
}
}
public function remove()
{
if (file_exists($this->csvPath)) {
return unlink($this->csvPath);
}
return true;
}
public function addRow(array $row)
{
if (!$this->fileHandle) {
$this->fileHandle = fopen($this->csvPath, 'a');
}
if (!$row) {
throw new InvalidArgumentException('Invalid CSV row');
}
return fputcsv($this->fileHandle, $row, $this->delimiter);
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Empik\Marketplace\Manager;
class OrderManager
{
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Empik\Marketplace\Manager;
use Context;
use DateTime;
use EmpikAction;
class ProcessManager
{
/** @var EmpikAction */
protected $processModel;
public function __construct()
{
$this->processModel = new EmpikAction();
$this->processModel->id_shop = Context::getContext()->shop->id;
}
public function start($action = null)
{
if ($action) {
$this->processModel->action = $action;
}
$this->setDateStart();
$this->setDateEnd();
}
public function end()
{
$this->setDateEnd();
$this->processModel->save();
}
public function setStatus($status)
{
$this->processModel->status = $status;
$this->processModel->save();
}
protected function setDateStart()
{
$time = new DateTime();
$this->processModel->date_start = $time->format('Y-m-d H:i:s');
}
protected function setDateEnd()
{
$time = new DateTime();
$this->processModel->date_end = $time->format('Y-m-d H:i:s');
}
public function updateFromResponse(array $response)
{
if (isset($response['import_id'])) {
$this->processModel->id_import = (int)$response['import_id'];
}
$this->processModel->save();
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,383 @@
<?php
namespace Empik\Marketplace\OrderFulfiller;
use Empik\Marketplace\Adapter\ToolsAdapter;
use Empik\Marketplace\DataProvider\ProductDataProvider;
use Order;
use OrderDetail;
use Address;
use Customer;
use OrderCarrier;
use OrderHistory;
use Cart;
class EmpikOrder
{
/** @var ProductDataProvider */
protected $productDataProvider;
/** @var array */
protected $data;
/** @var Order */
protected $order;
/** @var OrderDetail[] */
protected $orderDetails;
/** @var Customer */
protected $customer;
/** @var Address */
protected $shippingAddress;
/** @var Address */
protected $billingAddress;
/** @var OrderCarrier */
protected $carrier;
/** @var Cart */
protected $cart;
/** @var OrderHistory[] */
protected $orderHistory;
/** @var array */
protected $notes;
public function __construct($data)
{
$id = \EmpikOrder::getOrderIdByEmpikOrderReference($data['order_id']);
$order = new Order($id);
$this->setData($data);
$this->setOrder($order);
$this->productDataProvider = new ProductDataProvider();
}
/**
* @return bool
*/
public function exist()
{
$data = $this->getData();
return (bool)\EmpikOrder::getOrderIdByEmpikOrderReference($data['order_id']);
}
/**
* @return bool
*/
public function isAcceptable()
{
foreach ($this->getAcceptanceLines() as $orderLine) {
if (!$orderLine['accepted']) {
return false;
}
}
return true;
}
/**
* @return array
*/
public function getAcceptanceLines()
{
$return = [];
foreach ($this->getData()['order_lines'] as $orderLine) {
$pr = $this->productDataProvider->getOneBy([
'p.reference' => $orderLine['offer_sku'] // @todo
]);
$return[] = [
'id' => (string)$orderLine['order_line_id'],
'accepted' => $pr && $pr['active'] && $pr['quantity'] >= $orderLine['quantity'],
];
}
return $return;
}
public function add()
{
$context = \Context::getContext();
if ($this->customer && !$this->customer->id) {
$this->customer->id_shop = $context->shop->id;
$this->customer->id_shop_group = $context->shop->id_shop_group;
$this->customer->add();
}
if ($this->shippingAddress && !$this->shippingAddress->id) {
$this->shippingAddress->id_customer = $this->customer->id;
$this->shippingAddress->add();
}
if ($this->billingAddress && !$this->billingAddress->id) {
$this->shippingAddress->id_customer = $this->customer->id;
$this->billingAddress->add();
}
$this->cart->id_customer = $this->customer->id;
// $this->cart->add();
$this->order->id_address_delivery = $this->shippingAddress->id;
$this->order->id_address_invoice = $this->billingAddress->id;
$this->order->id_cart = $this->cart->id;
$this->order->id_currency = $context->currency->id;
$this->order->id_lang = $context->language->id;
$this->order->id_shop = $context->shop->id;
$this->order->id_shop_group = $context->shop->id_shop_group;
$this->order->id_customer = $this->customer->id;
$this->order->id_carrier = $this->carrier->id_carrier;
$this->order->payment = $this->data['payment_type'];
$this->order->module = 'empikmarketplace';
$this->order->total_paid = (float)$this->data['total_price'];
$this->order->total_paid_tax_incl = (float)$this->data['total_price'];
$this->order->total_paid_tax_excl = (float)$this->data['total_price'];
$this->order->total_paid_real = (float)$this->data['total_price'];
$this->order->total_products = (float)$this->data['price'];
$this->order->total_products_wt = (float)$this->data['price'];
$this->order->total_shipping = (float)$this->data['shipping_price'];
$this->order->total_shipping_tax_incl = (float)$this->data['shipping_price'];
$this->order->total_shipping_tax_excl = (float)$this->data['shipping_price'];
$this->order->conversion_rate = 1;
$this->order->secure_key = $this->customer->secure_key;
do {
$this->order->reference = Order::generateReference();
} while (Order::getByReference($this->order->reference)->count());
if ($this->orderHistory) {
$this->order->current_state = end($this->orderHistory)->id_order_state;
}
// foreach ($this->notes as $note) {
// $this->order->note .= !$this->order->note ? $note : "\r\n\r\n" . $note;
// }
// create order
$this->order->add();
// add message (ps 1.6)
// if ($this->order->note && !ToolsAdapter::is17static()) {
// $msg = new \Message();
// $msg->message = $this->order->note;
// $msg->id_cart = $this->cart->id;
// $msg->id_customer = $this->customer->id;
// $msg->id_order = $this->order->id;
// $msg->private = 1;
// $msg->add();
// }
// add order carrier
$this->carrier->id_order = $this->order->id;
$this->carrier->shipping_cost_tax_excl = $this->order->total_shipping_tax_excl;
$this->carrier->shipping_cost_tax_incl = $this->order->total_shipping_tax_incl;
$this->carrier->add();
foreach ($this->orderDetails as $orderDetail) {
$orderDetail->id_order = $this->order->id;
$orderDetail->add();
}
foreach ($this->orderHistory as $history) {
$history->id_order = $this->order->id;
$history->add();
}
// @todo
$empikOrder = new \EmpikOrder();
$empikOrder->id_order = $this->order->id;
$empikOrder->empik_order_reference = $this->data['order_id'];
$empikOrder->empik_order_carrier = $this->data['shipping_type_code'];
$empikOrder->empik_payment = $this->data['payment_type'];
$empikOrder->empik_carrier = $this->data['shipping_type_label'];
foreach ($this->data['order_additional_fields'] as $additionalField) {
if ($additionalField['code'] === 'delivery-point-name') {
$empikOrder->empik_pickup_point = $additionalField['value'];
}
if ($additionalField['code'] === 'nip') {
$empikOrder->empik_vat_number = $additionalField['value'];
}
}
$empikOrder->add();
}
/**
* @return Cart
*/
public function getCart()
{
return $this->cart;
}
/**
* @param Cart $cart
*/
public function setCart($cart)
{
$this->cart = $cart;
}
/**
* @return OrderHistory[]
*/
public function getOrderHistory()
{
return $this->orderHistory;
}
/**
* @param OrderHistory[] $orderHistory
*/
public function setOrderHistory($orderHistory)
{
$this->orderHistory = $orderHistory;
}
/**
* @return OrderCarrier
*/
public function getCarrier()
{
return $this->carrier;
}
/**
* @param OrderCarrier $carrier
*/
public function setCarrier($carrier)
{
$this->carrier = $carrier;
}
/**
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* @param array $data
*/
public function setData($data)
{
$this->data = $data;
}
/**
* @return Order
*/
public function getOrder()
{
return $this->order;
}
/**
* @param Order $order
*/
public function setOrder($order)
{
$this->order = $order;
}
/**
* @return OrderDetail[]
*/
public function getOrderDetails()
{
return $this->orderDetails;
}
/**
* @param OrderDetail[] $orderDetails
*/
public function setOrderDetails($orderDetails)
{
$this->orderDetails = $orderDetails;
}
/**
* @return Customer
*/
public function getCustomer()
{
return $this->customer;
}
/**
* @param Customer $customer
*/
public function setCustomer($customer)
{
$this->customer = $customer;
}
/**
* @return Address
*/
public function getShippingAddress()
{
return $this->shippingAddress;
}
/**
* @param Address $shippingAddress
*/
public function setShippingAddress($shippingAddress)
{
$this->shippingAddress = $shippingAddress;
}
/**
* @return Address
*/
public function getBillingAddress()
{
return $this->billingAddress;
}
/**
* @param Address $billingAddress
*/
public function setBillingAddress($billingAddress)
{
$this->billingAddress = $billingAddress;
}
/**
* @return array
*/
public function getNotes(): array
{
return $this->notes;
}
/**
* @param array $notes
*/
public function setNotes(array $notes): void
{
$this->notes = $notes;
}
}

View File

@@ -0,0 +1,394 @@
<?php
namespace Empik\Marketplace\OrderFulfiller;
use Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\DataProvider\ProductDataProvider;
use Empik\Marketplace\PrestaShopContext;
use Empik\Marketplace\Repository\ProductRepository;
use Empik\Marketplace\Utils\IdentifierExtractor;
use Order;
use OrderDetail;
use Address;
use Customer;
use OrderCarrier;
use OrderHistory;
use EmpikOrder;
use Cart;
use StockAvailable;
class EmpikOrderWrapper
{
/** @var ProductDataProvider */
protected $productDataProvider;
/** @var ProductRepository */
protected $productRepository;
/** @var IdentifierExtractor */
protected $identifierExtractor;
/** @var array */
protected $data;
/** @var Order */
protected $order;
/** @var OrderDetail[] */
protected $orderDetails;
/** @var Customer */
protected $customer;
/** @var Address */
protected $shippingAddress;
/** @var Address */
protected $billingAddress;
/** @var OrderCarrier */
protected $carrier;
/** @var Cart */
protected $cart;
/** @var OrderHistory[] */
protected $orderHistory;
public function __construct()
{
$this->productDataProvider = new ProductDataProvider();
$this->productRepository = new ProductRepository(
new PrestaShopContext()
);
$this->identifierExtractor = new IdentifierExtractor();
}
public function init($data)
{
$id = EmpikOrder::getOrderIdByEmpikOrderReference($data['order_id']);
$order = new Order($id);
$this->setData($data);
$this->setOrder($order);
}
/**
* @return bool
*/
public function exist()
{
$data = $this->getData();
return (bool)\EmpikOrder::getOrderIdByEmpikOrderReference($data['order_id']);
}
/**
* @return bool
*/
public function isAcceptable()
{
foreach ($this->getAcceptanceLines() as $orderLine) {
if (!$orderLine['accepted']) {
return false;
}
}
return true;
}
/**
* @return array
*/
public function getAcceptanceLines()
{
$skuType = Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE);
$return = [];
foreach ($this->getData()['order_lines'] as $orderLine) {
if ($skuType === 'ID') {
$product = $this->productRepository->getProductOrCombinationById($orderLine['offer_sku']);
} elseif ($skuType === 'EAN') {
$product = $this->productRepository->getProductOrCombinationByEan($orderLine['offer_sku']);
} elseif ($skuType === 'REFERENCE') {
$product = $this->productRepository->getProductOrCombinationBySku($orderLine['offer_sku']);
}
$return[] = [
'id' => (string)$orderLine['order_line_id'],
'accepted' => $product && $product['active'] && $product['quantity'] >= $orderLine['quantity'],
];
}
return $return;
}
public function add()
{
$context = \Context::getContext();
if ($this->customer && !$this->customer->id) {
$this->customer->id_shop = $context->shop->id;
$this->customer->id_shop_group = $context->shop->id_shop_group;
$this->customer->add();
}
if ($this->shippingAddress && !$this->shippingAddress->id) {
$this->shippingAddress->id_customer = $this->customer->id;
$this->shippingAddress->add();
}
if ($this->billingAddress && !$this->billingAddress->id) {
$this->billingAddress->id_customer = $this->customer->id;
$this->billingAddress->add();
}
$this->cart->id_customer = $this->customer->id;
$this->cart->id_address_delivery = $this->shippingAddress->id;
$this->cart->id_address_invoice = $this->billingAddress->id;
$this->cart->update();
$this->order->id_address_delivery = $this->shippingAddress->id;
$this->order->id_address_invoice = $this->billingAddress->id;
$this->order->id_cart = $this->cart->id;
$this->order->id_currency = $context->currency->id;
$this->order->id_lang = $context->language->id;
$this->order->id_shop = $context->shop->id;
$this->order->id_shop_group = $context->shop->id_shop_group;
$this->order->id_customer = $this->customer->id;
$this->order->id_carrier = $this->carrier->id_carrier;
$this->order->payment = $this->data['payment_type'];
$this->order->module = 'empikmarketplace';
$this->order->total_paid = (float)$this->data['total_price'];
$this->order->total_paid_tax_incl = (float)$this->data['total_price'];
$this->order->total_paid_tax_excl = (float)$this->data['total_price'];
$this->order->total_paid_real = (float)$this->data['total_price'];
$this->order->total_products = (float)$this->data['price'];
$this->order->total_products_wt = (float)$this->data['price'];
$this->order->total_shipping = (float)$this->data['shipping_price'];
$this->order->total_shipping_tax_incl = (float)$this->data['shipping_price'];
$this->order->total_shipping_tax_excl = (float)$this->data['shipping_price'];
$this->order->conversion_rate = 1;
$this->order->secure_key = $this->customer->secure_key;
do {
$this->order->reference = Order::generateReference();
} while (Order::getByReference($this->order->reference)->count());
if ($this->orderHistory) {
$this->order->current_state = end($this->orderHistory)->id_order_state;
}
// create order
$this->order->add();
// add order carrier
$this->carrier->id_order = $this->order->id;
$this->carrier->shipping_cost_tax_excl = $this->order->total_shipping_tax_excl;
$this->carrier->shipping_cost_tax_incl = $this->order->total_shipping_tax_incl;
$this->carrier->add();
foreach ($this->orderDetails as $orderDetail) {
$orderDetail->id_order = $this->order->id;
$orderDetail->add();
if ($this->order->current_state != Configuration::get('PS_OS_CANCELED')
&& $this->order->current_state != Configuration::get('PS_OS_ERROR')) {
if (!StockAvailable::dependsOnStock($orderDetail->product_id)) {
StockAvailable::updateQuantity(
$orderDetail->product_id,
$orderDetail->product_attribute_id,
-(int) $orderDetail->product_quantity,
$orderDetail->id_shop,
true
);
}
}
}
foreach ($this->orderHistory as $history) {
$history->id_order = $this->order->id;
$history->add();
}
$this->createEmpikOrder();
}
public function createEmpikOrder()
{
$empikOrder = new EmpikOrder();
$empikOrder->id_order = $this->order->id;
$empikOrder->empik_order_reference = $this->data['order_id'];
$empikOrder->empik_order_carrier = $this->data['shipping_type_code'];
$empikOrder->empik_payment = $this->data['payment_type'];
$empikOrder->empik_carrier = $this->data['shipping_type_label'];
foreach ($this->data['order_additional_fields'] as $additionalField) {
if ($additionalField['code'] === 'delivery-point-name') {
$empikOrder->empik_pickup_point = $additionalField['value'];
}
if ($additionalField['code'] === 'nip') {
$empikOrder->empik_vat_number = $additionalField['value'];
}
}
$empikOrder->add();
}
/**
* @return Cart
*/
public function getCart()
{
return $this->cart;
}
/**
* @param Cart $cart
*/
public function setCart($cart)
{
$this->cart = $cart;
}
/**
* @return OrderHistory[]
*/
public function getOrderHistory()
{
return $this->orderHistory;
}
/**
* @param OrderHistory[] $orderHistory
*/
public function setOrderHistory($orderHistory)
{
$this->orderHistory = $orderHistory;
}
/**
* @return OrderCarrier
*/
public function getCarrier()
{
return $this->carrier;
}
/**
* @param OrderCarrier $carrier
*/
public function setCarrier($carrier)
{
$this->carrier = $carrier;
}
/**
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* @param array $data
*/
public function setData($data)
{
$this->data = $data;
}
/**
* @return Order
*/
public function getOrder()
{
return $this->order;
}
/**
* @param Order $order
*/
public function setOrder($order)
{
$this->order = $order;
}
/**
* @return OrderDetail[]
*/
public function getOrderDetails()
{
return $this->orderDetails;
}
/**
* @param OrderDetail[] $orderDetails
*/
public function setOrderDetails($orderDetails)
{
$this->orderDetails = $orderDetails;
}
/**
* @return Customer
*/
public function getCustomer()
{
return $this->customer;
}
/**
* @param Customer $customer
*/
public function setCustomer($customer)
{
$this->customer = $customer;
}
/**
* @return Address
*/
public function getShippingAddress()
{
return $this->shippingAddress;
}
/**
* @param Address $shippingAddress
*/
public function setShippingAddress($shippingAddress)
{
$this->shippingAddress = $shippingAddress;
}
/**
* @return Address
*/
public function getBillingAddress()
{
return $this->billingAddress;
}
/**
* @param Address $billingAddress
*/
public function setBillingAddress($billingAddress)
{
$this->billingAddress = $billingAddress;
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace Empik\Marketplace\OrderFulfiller;
use Empik\Marketplace\Provider\Order\AddressProvider;
use Empik\Marketplace\Provider\Order\CarrierProvider;
use Empik\Marketplace\Provider\Order\CustomerProvider;
use Empik\Marketplace\Provider\Order\HistoryProvider;
use Empik\Marketplace\Provider\Order\CartProvider;
use Empik\Marketplace\Provider\Order\OrderLinesProvider;
use Empik\Marketplace\Exception\OrderProcessException;
class OrderFulfiller
{
/** @var AddressProvider */
protected $addressProvider;
/** @var CustomerProvider */
protected $customerProvider;
/** @var OrderLinesProvider */
protected $orderLinesProvider;
/** @var CarrierProvider */
protected $carrierProvider;
/** @var HistoryProvider */
protected $historyProvider;
/** @var CartProvider */
protected $cartProvider;
public function __construct(
AddressProvider $addressProvider,
CustomerProvider $customerProvider,
OrderLinesProvider $orderLinesProvider,
CarrierProvider $carrierProvider,
HistoryProvider $historyProvider,
CartProvider $cartProvider
) {
$this->addressProvider = $addressProvider;
$this->customerProvider = $customerProvider;
$this->orderLinesProvider = $orderLinesProvider;
$this->carrierProvider = $carrierProvider;
$this->historyProvider = $historyProvider;
$this->cartProvider = $cartProvider;
}
/**
* @param EmpikOrderWrapper $order
* @throws OrderProcessException
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
public function fulfill(EmpikOrderWrapper $order)
{
$data = $order->getData();
$this->validate($data);
// add customer
$prestaShopCustomer = $this->customerProvider->provide($data);
$order->setCustomer($prestaShopCustomer);
// add addresses
$billingAddress = isset($data['customer']['billing_address']) ? $data['customer']['billing_address'] : null;
$shippingAddress = isset($data['customer']['shipping_address']) ? $data['customer']['shipping_address'] : null;
$additionalFields = isset($data['order_additional_fields']) ? $data['order_additional_fields'] : [];
$prestaShopShippingAddress = $this->addressProvider->provide(
$shippingAddress,
$order->getCustomer()
);
$order->setShippingAddress($prestaShopShippingAddress);
$prestaShopBillingAddress = $this->addressProvider->provide(
$billingAddress,
$order->getCustomer(),
$additionalFields
);
$order->setBillingAddress($prestaShopBillingAddress);
// add cart
$cart = $this->cartProvider->provide($data);
$order->setCart($cart);
// add order lines
$orderLines = $this->orderLinesProvider->provide($data);
$order->setOrderDetails($orderLines);
// add carrier
$carrier = $this->carrierProvider->provide($data);
$order->setCarrier($carrier);
// add order status
$history = $this->historyProvider->provide($data);
$order->setOrderHistory($history);
$order->add();
}
/**
* @param array $data
* @throws OrderProcessException
*/
protected function validate($data)
{
if (
(
empty($data['customer']['shipping_address']) &&
empty($data['customer']['billing_address'])
) ||
empty($data['order_id']) ||
empty($data['order_lines']) ||
empty($data['order_state']) ||
empty($data['total_price'])
) {
throw new OrderProcessException(sprintf('Invalid order data for order: %s', $data['order_id']));
}
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,16 @@
<?php
namespace Empik\Marketplace;
class PrestaShopContext
{
public function is17()
{
return version_compare(_PS_VERSION_, '1.7', '>=');
}
public function is177()
{
return version_compare(_PS_VERSION_, '1.7.7', '>=');
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace Empik\Marketplace\Processor;
use Empik\Marketplace\Traits\ErrorsTrait;
use Empik\Marketplace\API\EmpikClient;
use Empik\Marketplace\Configuration\ExportConfiguration;
use Empik\Marketplace\Factory\EmpikClientFactory;
use Empik\Marketplace\Handler\ExportOfferHandler;
use Empik\Marketplace\Manager\ProcessManager;
use Exception;
class ExportOfferProcessor
{
use ErrorsTrait;
/** @var EmpikClientFactory */
private $empikClientFactory;
/** @var ExportOfferHandler */
protected $exportOfferHandler;
/** @var ExportConfiguration */
protected $exportConfiguration;
/** @var EmpikClient */
protected $empikClient;
/** @var ProcessManager */
protected $processManager;
protected $page = null;
public function __construct(
ProcessManager $processManager,
EmpikClientFactory $empikClientFactory,
ExportOfferHandler $exportOfferHandler,
ExportConfiguration $exportConfiguration
) {
$this->processManager = $processManager;
$this->empikClientFactory = $empikClientFactory;
$this->exportOfferHandler = $exportOfferHandler;
$this->exportConfiguration = $exportConfiguration;
$this->empikClient = $this->empikClientFactory->createClient();
}
public function setPage($page)
{
$this->page = $page;
}
public function process()
{
try {
$this->processManager->start(\EmpikAction::ACTION_OFFER_EXPORT);
// create CSV
$this->exportOfferHandler->handle(
$this->page
);
// post CSV
if ($this->isLastPage()) {
$response = $this->empikClient->postOffersImports(
$this->exportConfiguration->getOfferExportPath()
);
$this->processManager->updateFromResponse($response);
$this->processManager->end();
}
} catch (Exception $e) {
$this->addError($e->getMessage());
}
}
public function isLastPage()
{
return $this->page === null || $this->exportOfferHandler->isLastPage($this->page);
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace Empik\Marketplace\Processor;
use Empik\Marketplace\Traits\ErrorsTrait;
use Empik\Marketplace\API\EmpikClient;
use Empik\Marketplace\Configuration\ExportConfiguration;
use Empik\Marketplace\Factory\EmpikClientFactory;
use Empik\Marketplace\Handler\ExportProductHandler;
use Empik\Marketplace\Manager\ProcessManager;
use Exception;
class ExportProductProcessor
{
use ErrorsTrait;
/** @var EmpikClientFactory */
private $empikClientFactory;
/** @var ExportProductHandler */
protected $exportProductHandler;
/** @var ExportConfiguration */
protected $exportConfiguration;
/** @var EmpikClient */
protected $empikClient;
/** @var ProcessManager */
protected $processManager;
protected $page = null;
public function __construct(
ProcessManager $processManager,
EmpikClientFactory $empikClientFactory,
ExportProductHandler $exportProductHandler,
ExportConfiguration $exportConfiguration
) {
$this->processManager = $processManager;
$this->empikClientFactory = $empikClientFactory;
$this->exportProductHandler = $exportProductHandler;
$this->exportConfiguration = $exportConfiguration;
$this->empikClient = $this->empikClientFactory->createClient();
}
public function setPage($page)
{
$this->page = $page;
}
public function process()
{
try {
$this->processManager->start(\EmpikAction::ACTION_PRODUCT_EXPORT);
// create CSV
$this->exportProductHandler->handle(
$this->page
);
// post CSV
if ($this->isLastPage()) {
$response = $this->empikClient->postProducts(
$this->exportConfiguration->getProductExportPath()
);
$this->processManager->updateFromResponse($response);
$this->processManager->end();
}
} catch (Exception $e) {
$this->addError($e->getMessage());
}
}
public function isLastPage()
{
return $this->page === null || $this->exportProductHandler->isLastPage($this->page);
}
}

View File

@@ -0,0 +1,129 @@
<?php
namespace Empik\Marketplace\Processor;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\Adapter\LoggerAdapter;
use Empik\Marketplace\API\EmpikClient;
use Empik\Marketplace\OrderFulfiller\EmpikOrderWrapper;
use Empik\Marketplace\Factory\EmpikClientFactory;
use Empik\Marketplace\Manager\ProcessManager;
use Empik\Marketplace\OrderFulfiller\OrderFulfiller;
use GuzzleHttp\Exception\ClientException;
use Exception;
use Configuration;
use Db;
class OrderProcessor
{
const CODE_WAITING_ACCEPTANCE = 'WAITING_ACCEPTANCE';
const CODE_SHIPPING = 'SHIPPING';
/** @var EmpikClientFactory */
protected $empikClientFactory;
/** @var EmpikClient */
protected $empikClient;
/** @var ProcessManager */
protected $processManager;
/** @var OrderFulfiller */
protected $orderFulfiller;
/** @var LoggerAdapter */
protected $logger;
protected $allowAccept;
protected $allowImport;
public function __construct(
ProcessManager $processManager,
EmpikClientFactory $empikClientFactory,
OrderFulfiller $orderFulfiller,
LoggerAdapter $loggerAdapter
) {
$this->processManager = $processManager;
$this->empikClientFactory = $empikClientFactory;
$this->orderFulfiller = $orderFulfiller;
$this->logger = $loggerAdapter;
$this->empikClient = $this->empikClientFactory->createClient();
$this->allowAccept = (bool)Configuration::get(ConfigurationAdapter::CONF_AUTO_ACCEPT_ORDERS);
$this->allowImport = (bool)Configuration::get(ConfigurationAdapter::CONF_IMPORT_ORDERS);
}
public function process()
{
if (!$this->allowAccept && !$this->allowImport) {
return;
}
$response = $this->empikClient->getOrders([
'order_state_codes' => implode(',', $this->getOrderCodesForProcess()),
]);
foreach ($response['orders'] as $order) {
$empikOrder = new EmpikOrderWrapper();
$empikOrder->init($order);
if ($this->allowAccept && $empikOrder->isAcceptable() && !$empikOrder->exist()) {
$this->accept($empikOrder);
}
if ($this->allowImport) {
if (!$empikOrder->exist()) {
$this->import($empikOrder);
}
}
}
}
protected function import(EmpikOrderWrapper $empikOrder)
{
try {
Db::getInstance()->execute('START TRANSACTION');
$this->orderFulfiller->fulfill($empikOrder);
Db::getInstance()->execute('COMMIT');
} catch (Exception $e) {
Db::getInstance()->execute('ROLLBACK');
$this->logger->logError(sprintf('Error importing order [%s]', $e->getMessage()));
}
}
protected function accept(EmpikOrderWrapper $empikOrder)
{
$acceptLines = $empikOrder->getAcceptanceLines();
try {
$this->empikClient->putOrderAccept(
$empikOrder->getData()['order_id'],
$acceptLines
);
} catch (ClientException $e) {
$responseJson = $e->getResponse()->json();
$message = isset($responseJson['message']) ? $responseJson['message'] : null;
$this->logger->logError(sprintf('Error accepting order [%s]', $message));
} catch (Exception $e) {
$this->logger->logError(sprintf('Error accepting order [%s]', $e->getMessage()));
}
}
protected function getOrderCodesForProcess()
{
$codes = [];
if ($this->allowAccept) {
$codes[] = self::CODE_WAITING_ACCEPTANCE;
}
if ($this->allowImport) {
$codes[] = self::CODE_SHIPPING;
}
return $codes;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Empik\Marketplace\Processor;
use Empik\Marketplace\Manager\OrderManager;
use Empik\Marketplace\OrderFulfiller\OrderFulfiller;
use Empik\Marketplace\Repository\OrderRepository;
class OrdersProcessor
{
/** @var OrderRepository */
private $orderRepository;
/** @var OrderManager */
private $orderManager;
/** @var OrderFulfiller */
private $orderFulfiller;
public function __construct(
OrderRepository $orderRepository,
OrderManager $orderManager,
OrderFulfiller $orderFulfiller
)
{
$this->orderRepository = $orderRepository;
$this->orderManager = $orderManager;
$this->orderFulfiller = $orderFulfiller;
}
public function process($limit = 0, $step = 0)
{
$orders = $this->orderRepository->find($limit, $step);
foreach ($orders as $order) {
try {
$this->orderFulfiller->fulfill($order);
} catch (\Exception $e) {
}
}
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,13 @@
<?php
namespace Empik\Marketplace\Provider;
class BillingAddressProvider
{
public function provide($address)
{
return [];
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace Empik\Marketplace\Provider\Order;
use Address;
use Country;
use Customer;
use Configuration;
use Empik\Marketplace\Repository\AddressRepository;
class AddressProvider
{
const NAME_EMPTY = '--';
const NAME_PICKUP_POINT = 'PICKUP POINT';
/** @var AddressRepository */
protected $addressRepository;
public function __construct(AddressRepository $addressRepository)
{
$this->addressRepository = $addressRepository;
}
/**
* @param array $addressData
* @param Customer $customer
* @return Address
*/
public function provide(array $addressData, Customer $customer, array $additionalFields = [])
{
$address = $this->getAddress($addressData, $customer);
if ($address) {
return $address;
}
$isPickupPointAddress = false;
$isCompanyAddress = false;
if (empty($addressData['firstname']) && !empty($addressData['lastname']) && !empty($addressData['company'])) {
$isCompanyAddress = true;
} elseif (empty($addressData['firstname']) && !empty($addressData['lastname'])) {
$isPickupPointAddress = true;
}
$obj = new Address();
if ($isCompanyAddress) {
$obj->lastname = isset($addressData['lastname']) ? $addressData['lastname'] : self::NAME_EMPTY;
$obj->firstname = isset($addressData['firstname']) ? $addressData['firstname'] : self::NAME_EMPTY;
} elseif ($isPickupPointAddress) {
$obj->lastname = self::NAME_PICKUP_POINT;
$obj->firstname = self::NAME_PICKUP_POINT;
$obj->address2 = $addressData['lastname'];
} else {
$obj->lastname = $addressData['lastname'];
$obj->firstname = $addressData['firstname'];
$obj->address2 = $addressData['street_2'];
}
if ($additionalFields) {
foreach ($additionalFields as $additionalField) {
if ($additionalField['code'] === 'nip' && $additionalField['value']) {
$obj->vat_number = $additionalField['value'];
}
}
}
$obj->id_country = $this->getCountryId($addressData);
$obj->address1 = $addressData['street_1'];
$obj->city = $addressData['city'];
$obj->company = $addressData['company'];
$obj->postcode = $addressData['zip_code'];
$obj->phone = !empty($addressData['phone']) ? $addressData['phone'] : null;
$obj->other = !empty($addressData['additional_info']) ? $addressData['additional_info'] : null;
$obj->alias = mb_substr(
sprintf('%s - %s', $obj->city, $obj->address1),
0,
32
);
return $obj;
}
/**
* @param $addressData
* @param Customer $customer
* @return Address|bool
*/
protected function getAddress($addressData, Customer $customer)
{
$address = $this->addressRepository->getOneBy([
'id_customer' => (int)$customer->id,
'lastname' => !empty($addressData['lastname']) ? $addressData['lastname'] : self::NAME_EMPTY,
'firstname' => !empty($addressData['firstname']) ? $addressData['firstname'] : self::NAME_EMPTY,
'city' => $addressData['city'],
'address1' => $addressData['street_1'],
]);
if ($address) {
return new Address($address['id_address']);
}
return false;
}
/**
* @param array $address
* @return int
*/
protected function getCountryId(array $address)
{
$countryId = null;
$isoCode = $address['country_iso_code'];
if ($isoCode) {
$countryId = (int)Country::getByIso($isoCode);
}
if (!$countryId) {
$countryId = (int)Configuration::get('PS_COUNTRY_DEFAULT');
}
return $countryId;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Empik\Marketplace\Provider\Order;
use Carrier;
use OrderCarrier;
use Empik\Marketplace\Manager\CarrierMapManager;
use Empik\Marketplace\Exception\OrderProcessException;
class CarrierProvider
{
/** @var CarrierMapManager */
protected $carrierMapManager;
public function __construct(CarrierMapManager $carrierMapManager)
{
$this->carrierMapManager = $carrierMapManager;
}
/**
* @param array $data
* @return OrderCarrier
* @throws OrderProcessException
*/
function provide($data)
{
$obj = $this->getCarrier($data['shipping_type_code']);
if (!$obj || !\Validate::isLoadedObject($obj)) {
throw new OrderProcessException(
sprintf(
'Unmapped carrier (%s) for order: %s',
$data['shipping_type_code'],
$data['order_id']
)
);
}
$orderCarrier = new OrderCarrier();
$orderCarrier->id_carrier = $obj->id;
return $orderCarrier;
}
protected function getCarrier($carrierCode)
{
$carrierId = $this->carrierMapManager->getIdByCode($carrierCode);
return new Carrier($carrierId);
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Empik\Marketplace\Provider\Order;
use Configuration;
use Db;
use Cart;
use Context;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\Exception\OrderProcessException;
use Empik\Marketplace\Repository\ProductRepository;
use Empik\Marketplace\Utils\IdentifierExtractor;
class CartProvider
{
/** @var ProductRepository */
protected $productRepository;
/** @var IdentifierExtractor */
protected $identifierExtractor;
/** @var Context */
protected $context;
public function __construct(ProductRepository $productRepository, IdentifierExtractor $identifierExtractor)
{
$this->productRepository = $productRepository;
$this->identifierExtractor = $identifierExtractor;
$this->context = Context::getContext();
}
/**
* @param array $data
* @return Cart
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
function provide($data)
{
$cart = new Cart();
$cart->id_currency = $this->context->currency->id;
$cart->id_lang = $this->context->language->id;
$cart->add();
foreach ($data['order_lines'] as $orderLine) {
$productData = $this->getProductByRef($orderLine);
if (!$productData) {
throw new OrderProcessException(sprintf('Products "%s" not found', $orderLine['product_title']));
}
Db::getInstance()->insert('cart_product', [
'id_cart' => $cart->id,
'id_product' => $productData['id_product'],
'id_shop' => $this->context->shop->id,
'quantity' => (int)$orderLine['quantity'],
'date_add' => date('Y-m-d H:i:s'),
]);
}
return $cart;
}
/**
* @param $orderLine
* @return array|bool|false|object|null
*/
protected function getProductByRef($orderLine)
{
$skuType = Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE);
if ($skuType === 'ID') {
$product = $this->productRepository->getProductOrCombinationById($orderLine['offer_sku']);
} elseif ($skuType === 'EAN') {
$product = $this->productRepository->getProductOrCombinationByEan($orderLine['offer_sku']);
} elseif ($skuType === 'REFERENCE') {
$product = $this->productRepository->getProductOrCombinationBySku($orderLine['offer_sku']);
}
return !empty($product) ? $product : false;
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Empik\Marketplace\Provider\Order;
use Tools;
use Customer;
use Configuration;
use Empik\Marketplace\Exception\OrderProcessException;
class CustomerProvider
{
/**
* @param array $data
* @return Customer
* @throws OrderProcessException
*/
public function provide($data)
{
$email = null;
foreach ($data['order_additional_fields'] as $orderAdditionalField) {
if ($orderAdditionalField['code'] === 'customer-email') {
$email = $orderAdditionalField['value'];
break;
}
}
if (!$email) {
throw new OrderProcessException(sprintf('Empty email for order %s', $data['order_id']));
}
$customerId = $this->getCustomerIdByEmail($email);
if ($customerId) {
return new Customer($customerId);
}
$obj = new Customer();
$obj->lastname = !empty($data['customer']['lastname']) ? $data['customer']['lastname'] : '--';
$obj->firstname = !empty($data['customer']['firstname']) ? $data['customer']['firstname'] : '--';
$obj->email = $email;
$obj->passwd = md5(Tools::passwdGen());
$obj->secure_key = md5(microtime() . _COOKIE_KEY_);
$obj->is_guest = Configuration::get('PS_GUEST_CHECKOUT_ENABLED') ? 1 : 0;
return $obj;
}
/**
* @param string $email
* @return bool|int
*/
public function getCustomerIdByEmail($email)
{
return Customer::customerExists($email, true, false);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Empik\Marketplace\Provider\Order;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\Utils\Utils;
use Configuration;
use OrderHistory;
class HistoryProvider
{
/**
* @param array $data
* @return OrderHistory[]
*/
function provide($data)
{
$obj = new OrderHistory();
$obj->id_employee = Utils::getEmployeeId();
$obj->id_order_state = Configuration::get(ConfigurationAdapter::CONF_NEW_ORDER_STATE);
return [
$obj
];
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Empik\Marketplace\Provider\Order;
use Module;
use EmpikMarketplace;
class NotesProvider
{
/** @var EmpikMarketplace */
protected $module;
public function __construct()
{
$this->module = Module::getInstanceByName('empikmarketplace');
}
/**
* @param array $data
* @return array
*/
function provide($data)
{
$notes = [];
$notes[] = $this->module->l('Empik order reference:') . ' ' . $data['order_id'];
$notes[] = $this->module->l('Payment type:') . ' ' . $data['payment_type'];
$notes[] = $this->module->l('Shipping option name:') . ' ' . $data['shipping_type_label'];
foreach ($data['order_additional_fields'] as $additionalField) {
if ($additionalField['code'] === 'nip') {
$notes[] = $this->module->l('VAT number:') . ' ' . $additionalField['value'];
break;
}
}
foreach ($data['order_additional_fields'] as $additionalField) {
if ($additionalField['code'] === 'delivery-point-name') {
$notes[] = $this->module->l('Pickup point:') . ' ' . $additionalField['value'];
break;
}
}
return $notes;
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace Empik\Marketplace\Provider\Order;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\PrestaShopContext;
use Empik\Marketplace\Repository\ProductRepository;
use Empik\Marketplace\Utils\IdentifierExtractor;
use OrderDetail;
use Context;
use Configuration;
use Product;
use ProductSupplier;
use TaxRulesGroup;
use TaxCalculator;
class OrderLinesProvider
{
/** @var PrestaShopContext */
protected $prestaShopContext;
/** @var ProductRepository */
protected $productRepository;
/** @var IdentifierExtractor */
protected $identifierExtractor;
/** @var Context */
protected $context;
public function __construct(
PrestaShopContext $prestaShopContext,
ProductRepository $productRepository,
IdentifierExtractor $identifierExtractor
) {
$this->prestaShopContext = $prestaShopContext;
$this->productRepository = $productRepository;
$this->identifierExtractor = $identifierExtractor;
$this->context = Context::getContext();
}
function provide($data)
{
$lines = [];
foreach ($data['order_lines'] as $orderLine) {
$productData = $this->getProductByRef($orderLine);
if (!$productData) {
continue;
}
$obj = new OrderDetail();
$obj->id_warehouse = 0;
$obj->id_shop = $this->context->shop->id;
$obj->product_name = !empty($orderLine['product_title']) ? $orderLine['product_title'] : '--';
$obj->product_reference = !empty($orderLine['product_sku']) ? $orderLine['product_sku'] : null;
$obj->product_quantity = (int)$orderLine['quantity'];
if ($productData) {
$obj->product_id = $productData['id_product'];
$obj->product_ean13 = $productData['ean13'];
$obj->product_reference = $productData['reference'];
if ($this->prestaShopContext->is17()) {
$obj->product_isbn = isset($productData['isbn']) ? $productData['isbn'] : null;
$obj->product_upc = isset($productData['upc']) ? $productData['upc'] : null;
$obj->product_mpn = isset($productData['mpn']) ? $productData['mpn'] : null;
}
}
$obj->product_price = $orderLine['price_unit'];
$obj->unit_price_tax_incl = $orderLine['price_unit'];
$obj->total_price_tax_incl = $obj->unit_price_tax_incl * $obj->product_quantity;
$taxRate = $this->getProductTaxRateByDefaultCountry($productData);
$taxRateMultiplier = (100 + $taxRate) / 100;
$obj->total_price_tax_excl = round($obj->total_price_tax_incl / $taxRateMultiplier, 6);
$obj->unit_price_tax_excl = round($obj->unit_price_tax_incl / $taxRateMultiplier, 6);
$obj->original_product_price = Product::getPriceStatic(
$obj->product_id,
false,
(int) $obj->product_attribute_id,
6,
null,
false,
false,
1,
false,
null,
null,
null,
$null,
true,
true,
$this->context
);
$obj->tax_computation_method = TaxCalculator::COMBINE_METHOD;
$obj->purchase_supplier_price = (float) $productData['wholesale_price'];
if ($productData['id_supplier'] > 0 && ($supplierPrice = ProductSupplier::getProductPrice((int) $productData['id_supplier'], $productData['id_product'], $productData['id_product_attribute'], true)) > 0) {
$obj->purchase_supplier_price = (float) $supplierPrice;
}
$obj->tax_rate = $taxRate;
$obj->id_tax_rules_group = $productData['id_tax_rules_group'];
$lines[] = $obj;
}
return $lines;
}
/**
* @param $orderLine
* @return array|bool|false|object|null
*/
protected function getProductByRef($orderLine)
{
$skuType = Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE);
if ($skuType === 'ID') {
$product = $this->productRepository->getProductOrCombinationById($orderLine['offer_sku']);
} elseif ($skuType === 'EAN') {
$product = $this->productRepository->getProductOrCombinationByEan($orderLine['offer_sku']);
} elseif ($skuType === 'REFERENCE') {
$product = $this->productRepository->getProductOrCombinationBySku($orderLine['offer_sku']);
}
return !empty($product) ? $product : false;
}
/**
* @param $productData
* @return float
*/
protected function getProductTaxRateByDefaultCountry($productData)
{
$taxRate = 0.00;
$defaultCountryId = Configuration::get('PS_COUNTRY_DEFAULT');
$taxRates = TaxRulesGroup::getAssociatedTaxRatesByIdCountry($defaultCountryId);
if (!empty($taxRates)) {
$taxRate = reset($taxRates);
}
return $taxRate;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,32 @@
<?php
namespace Empik\Marketplace\Repository;
use Db;
use DbQuery;
class AddressRepository
{
/** @var Db */
protected $db;
public function __construct()
{
$this->db = Db::getInstance();
}
public function getOneBy($filter = [])
{
$sql = new DbQuery();
$sql->select('a.*');
$sql->from('address', 'a');
foreach ($filter as $name => $value) {
$sql->where('a.' . pSQL($name) . ' = ' . '"'.pSQL($value).'"');
}
$result = $this->db->getRow($sql);
return $result ? $result : [];
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Empik\Marketplace\Repository;
use Db;
use DbQuery;
use Empik\Marketplace\Utils\Utils;
class AttributeRepository
{
/** @var Db */
protected $db;
/** @var int */
protected $langId;
public function __construct()
{
$this->db = Db::getInstance();
$this->langId = Utils::getLangId();
}
public function getAttributes($productId, $productAttributeId)
{
$sql = new DbQuery();
$sql->select('al.name AS value, agl.public_name AS name');
$sql->from('attribute_group', 'ag');
$sql->leftJoin('attribute_group_lang', 'agl', 'agl.id_attribute_group = ag.id_attribute_group AND agl.id_lang = ' . (int)$this->langId);
$sql->leftJoin('product_attribute', 'pa', 'pa.id_product = ' . (int)$productId . ' AND pa.id_product_attribute = ' . (int)$productAttributeId);
$sql->leftJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pa.id_product_attribute');
$sql->leftJoin('attribute', 'a', 'a.id_attribute = pac.id_attribute AND ag.id_attribute_group = a.id_attribute_group');
$sql->leftJoin('attribute_lang', 'al', 'al.id_attribute = a.id_attribute AND al.id_lang = ' . (int)$this->langId);
$sql->orderBy('ag.id_attribute_group');
$result = $this->db->executeS($sql);
$resultGrouped = [];
foreach ($result as $item) {
if (!isset($resultGrouped[$item['name']]) || $item['value']) {
$resultGrouped[$item['name']] = $item;
}
}
return (array)$resultGrouped;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Empik\Marketplace\Repository;
use Db;
use DbQuery;
use Context;
use Empik\Marketplace\Utils\Utils;
class CategoryRepository
{
/** @var Db */
protected $db;
/** @var int */
protected $langId;
/** @var int */
protected $shopId;
public function __construct()
{
$this->db = Db::getInstance();
$this->shopId = Context::getContext()->shop->id;
$this->langId = Utils::getLangId();
}
public function getCategoriesByProductId($productId)
{
$sql = new DbQuery();
$sql->select('cp.id_category, c.id_parent, c.level_depth, cl.name');
$sql->from('category_product', 'cp');
$sql->leftJoin('category_lang', 'cl', 'cl.id_category = cp.id_category AND cl.id_shop = ' . (int)$this->shopId . ' AND cl.id_lang = ' . (int)$this->langId);
$sql->leftJoin('category', 'c', 'c.id_category = cp.id_category');
$sql->where('cp.id_product = ' . (int)$productId);
$sql->orderBy('c.level_depth ASC, c.position ASC');
$result = $this->db->executeS($sql);
return (array)$result;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Empik\Marketplace\Repository;
use Db;
use DbQuery;
use Empik\Marketplace\Utils\Utils;
class FeatureRepository
{
const SEPARATOR = '|';
/** @var Db */
protected $db;
/** @var int */
protected $langId;
public function __construct()
{
$this->db = Db::getInstance();
$this->langId = Utils::getLangId();
}
public function getFeatures($productId)
{
$sql = new DbQuery();
$sql->select('fl.name AS feature_name, f.id_feature, fp.id_product, GROUP_CONCAT(fvl.value SEPARATOR "'.pSQL(self::SEPARATOR).'") AS value');
$sql->from('feature', 'f');
$sql->leftJoin('feature_lang', 'fl', 'fl.id_feature = f.id_feature AND fl.id_lang = ' . (int)$this->langId);
$sql->leftJoin('feature_product', 'fp', 'fp.id_feature = f.id_feature AND fp.id_product = ' . (int)$productId);
$sql->leftJoin('feature_value_lang', 'fvl', 'fvl.id_feature_value = fp.id_feature_value AND fvl.id_lang = ' . (int)$this->langId);
$sql->orderBy('f.id_feature');
$sql->groupBy('f.id_feature');
$result = $this->db->executeS($sql);
return (array)$result;
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace Empik\Marketplace\Repository;
use Db;
use DbQuery;
use Context;
use Empik\Marketplace\Utils\Utils;
class ImageRepository
{
/**
* @var Db
*/
protected $db;
/**
* @var Context
*/
protected $context;
/**
* @var int
*/
protected $langId;
/**
* @var int
*/
protected $shopId;
public function __construct()
{
$this->db = Db::getInstance();
$this->context = Context::getContext();
$this->shopId = $this->context->shop->id;
$this->langId = Utils::getLangId();
}
public function getImages($productId, $productAttributeId = null)
{
$query = $this->getBaseQuery($productId);
if ($productAttributeId) {
$query->rightJoin(
'product_attribute_image',
'pai',
'pai.id_image = i.id_image AND pai.id_product_attribute = ' . (int)$productAttributeId
);
}
$result = $this->db->executeS($query);
if ($productAttributeId && count((array)$result) == 0) {
// If no images were found for given product attribute, perform query without product attribute
// condition to get all product images
$newQuery = $this->getBaseQuery($productId);
$result = $this->db->executeS($newQuery);
}
return (array)$result;
}
private function getBaseQuery($productId)
{
$sql = new DbQuery();
$sql->select('i.position, is.id_image, is.cover, il.legend');
$sql->from('image', 'i');
$sql->leftJoin(
'image_shop',
'is',
'i.id_image = is.id_image AND is.id_shop = ' . (int)$this->shopId
);
$sql->leftJoin(
'image_lang',
'il',
'i.id_image = il.id_image AND il.id_lang = ' . (int)$this->shopId
);
$sql->where('i.id_product = ' . (int)$productId);
$sql->orderBy('is.cover DESC, i.position ASC');
return $sql;
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Empik\Marketplace\Repository;
class OrderRepository
{
public function find($limit, $step)
{
}
}

View File

@@ -0,0 +1,209 @@
<?php
namespace Empik\Marketplace\Repository;
use Db;
use DbQuery;
use Context;
use Empik\Marketplace\Configuration\ExportConfiguration;
use Empik\Marketplace\PrestaShopContext;
use Empik\Marketplace\Utils\Utils;
class ProductRepository
{
const SRC_PRODUCT = 'product';
const SRC_OFFER = 'offer';
/** @var Db */
protected $db;
/** @var int */
protected $langId;
/** @var int */
protected $shopId;
/** @var PrestaShopContext */
protected $shopContext;
public function __construct(PrestaShopContext $shopContext)
{
$this->shopContext = $shopContext;
$this->db = Db::getInstance();
$this->shopId = Context::getContext()->shop->id;
$this->langId = Utils::getLangId();
}
protected function getProductsCommonSql()
{
$sql = new DbQuery();
$sql->select('SQL_CALC_FOUND_ROWS ps.id_product, ps.price, ps.id_tax_rules_group, ps.wholesale_price, p.id_supplier, p.active');
$sql->select('p.upc, p.unity, p.width, p.height, p.depth, p.condition, p.additional_shipping_cost');
$sql->select('
IFNULL(epb.logistic_class, 0) AS logistic_class,
IFNULL(epb.condition, 0) AS empik_condition,
IFNULL(epb.product_export, 0) AS product_export,
IFNULL(epb.offer_export, 0) AS offer_export,
IFNULL(ep.offer_price, 0) AS offer_price,
IFNULL(ep.offer_price_reduced, 0) AS offer_price_reduced,
IFNULL(ep.export_original_price, 0) AS export_original_price
');
// combinations / base product
$sql->select('IFNULL(pa.reference, p.reference) AS reference');
$sql->select('IFNULL(pa.supplier_reference, p.supplier_reference) AS supplier_reference');
$sql->select('IFNULL(pa.ean13, p.ean13) AS ean13');
$sql->select('IFNULL(pa.minimal_quantity, ps.minimal_quantity) AS minimal_quantity');
$sql->select('IFNULL(pa.weight, p.weight) AS weight');
$sql->select('IFNULL(pa.wholesale_price, p.wholesale_price) AS wholesale_price');
$sql->select('IFNULL(pa.price, (ps.price + pa.price)) AS price');
$sql->select('pl.name, pl.description, pl.description_short, pl.link_rewrite, pl.meta_description, pl.meta_keywords, pl.meta_title, pl.available_now, pl.available_later');
$sql->select('pa.id_product_attribute');
$sql->select('m.name AS manufacturer_name');
$sql->select('sav.depends_on_stock, sav.quantity');
if ($this->shopContext->is177()) {
$sql->select('p.isbn, p.mpn');
$sql->select('pl.delivery_in_stock, pl.delivery_out_stock');
}
$sql->from('product', 'p');
$sql->leftJoin('product_shop', 'ps', 'ps.id_product = p.id_product AND ps.id_shop = ' . (int)$this->shopId);
$sql->leftJoin('manufacturer', 'm', 'm.id_manufacturer = p.id_manufacturer');
$sql->leftJoin('product_lang', 'pl', 'pl.id_product = p.id_product AND pl.id_lang = ' . (int)$this->langId . ' AND pl.id_shop = ' . (int)$this->shopId);
// combinations
$sql->leftJoin('product_attribute', 'pa', 'pa.id_product = p.id_product');
$sql->leftJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pa.id_product_attribute');
$sql->leftJoin('attribute', 'a', 'a.id_attribute = pac.id_attribute');
$sql->leftJoin('attribute_lang', 'al', 'al.id_attribute = a.id_attribute AND al.id_lang = ' . (int)$this->langId);
$sql->leftJoin('attribute_group', 'ag', 'ag.id_attribute_group = a.id_attribute_group');
$sql->leftJoin('attribute_group_lang', 'agl', 'agl.id_attribute_group = ag.id_attribute_group AND agl.id_lang = ' . (int)$this->langId);
$sql->leftJoin('empik_product', 'epb', 'epb.id_product = p.id_product AND epb.id_product_attribute = 0');
$sql->leftJoin('empik_product', 'ep', 'ep.id_product = p.id_product AND ep.id_product_attribute = IFNULL(pa.id_product_attribute, 0)');
// stock
$sql->leftJoin('stock_available', 'sav', 'sav.id_product = p.id_product AND sav.id_product_attribute = IFNULL(pa.id_product_attribute, 0) AND sav.id_shop = ' . (int)$this->shopId . ' AND sav.id_shop_group = 0');
$sql->where('ps.active = 1');
$sql->groupBy('p.id_product, pa.id_product_attribute');
return $sql;
}
/**
* @param int $page
* @param int $productsPerPage
* @param null $src
* @return array
* @throws \PrestaShopDatabaseException
*/
public function getProductsPaginate($page = null, $productsPerPage = 10, $src = null)
{
$sql = $this->getProductsCommonSql();
if ($page !== null) {
$sql->limit((int)$productsPerPage, (int)($page * $productsPerPage));
}
if ($src === self::SRC_PRODUCT) {
$sql->where('epb.product_export = 1');
}
if ($src === self::SRC_OFFER) {
$sql->where('epb.offer_export = 1');
}
$result = $this->db->executeS($sql);
return (array)$result;
}
public function getProductsTotal($src = null)
{
$sql = $this->getProductsCommonSql();
if ($src === self::SRC_PRODUCT) {
$sql->where('epb.product_export = 1');
}
if ($src === self::SRC_OFFER) {
$sql->where('epb.offer_export = 1');
}
$sql->limit(1, 0);
$this->db->executeS($sql);
$result = $this->db->getValue('SELECT FOUND_ROWS()');
return (int)$result;
}
public function getProductOrCombinationByEan($ean)
{
$sql = $this->getProductsCommonSql();
$sql->where('p.ean13 = "'.pSQL($ean).'" OR pa.ean13 = "'.pSQL($ean).'"');
return $this->db->getRow($sql);
}
public function getProductOrCombinationBySku($sku)
{
$sql = $this->getProductsCommonSql();
$sql->where('p.reference = "'.pSQL($sku).'" OR pa.reference = "'.pSQL($sku).'"');
return $this->db->getRow($sql);
}
public function getProductOrCombinationById($id)
{
$sql = $this->getProductsCommonSql();
$id = explode('-', $id);
$productId = isset($id[0]) ? (int)$id[0] : 0;
$productAttributeId = isset($id[1]) ? (int)$id[1] : 0;
if ($productAttributeId) {
$sql->where('pa.id_product_attribute = "'.pSQL($productAttributeId).'"');
} else {
$sql->where('p.id_product = "'.pSQL($productId).'"');
}
return $this->db->getRow($sql);
}
public function getOffersByIds(array $ids)
{
$ids = array_map('intval', $ids);
$sql = $this->getProductsCommonSql();
if (count($ids)) {
$sql->where('ps.id_product IN ('.implode(',', $ids).')');
}
$result = $this->db->executeS($sql);
return (array)$result;
}
public function updateOfferPrice($productId, $productAttributeId, $price)
{
$empikProduct = \EmpikProduct::getOrCreate($productId, $productAttributeId);
$empikProduct->offer_price = (float)$price;
$empikProduct->save();
}
public function updateOfferPriceReduced($productId, $productAttributeId, $price)
{
$empikProduct = \EmpikProduct::getOrCreate($productId, $productAttributeId);
$empikProduct->offer_price_reduced = (float)$price;
$empikProduct->save();
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Empik\Marketplace\Repository;
use Db;
use DbQuery;
use Empik\Marketplace\Utils\Utils;
class TaxRepository
{
/** @var Db */
protected $db;
/** @var int */
protected $countryId;
public function __construct()
{
$this->db = Db::getInstance();
$this->countryId = Utils::getCountryId();
}
public function getTaxRateByProductId($productId)
{
$sql = new DbQuery();
$sql->select('t.rate');
$sql->from('product', 'p');
$sql->leftJoin('tax_rules_group', 'trg', 'p.id_tax_rules_group = trg.id_tax_rules_group');
$sql->leftJoin('tax_rule', 'tr', 'tr.id_tax_rules_group = trg.id_tax_rules_group AND tr.id_country = ' . (int)$this->countryId);
$sql->leftJoin('tax', 't', 't.id_tax = tr.id_tax');
$sql->where('t.active = 1');
$sql->where('t.deleted = 0');
$sql->where('p.id_product = ' . (int)$productId);
$result = $this->db->getValue($sql);
return (int)$result;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,39 @@
<?php
namespace Empik\Marketplace\Traits;
trait ErrorsTrait
{
protected $errors = [];
public function hasErrors()
{
return !empty($this->errors);
}
public function getErrors()
{
return $this->errors;
}
protected function resetErrors()
{
$this->errors = [];
return $this;
}
protected function addError($error)
{
$this->errors[] = $error;
return $this;
}
protected function setErrors(array $errors)
{
$this->errors = $errors;
return $this;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,29 @@
<?php
namespace Empik\Marketplace\Utils;
use Empik\Marketplace\Configuration\ExportConfiguration;
class CategoryPathBuilder
{
/** @var array */
protected $categories;
/**
* @param array $categories
* @return string
*/
public function buildPath(array $categories)
{
$this->categories = $categories;
$names = [];
foreach ($this->categories as $c) {
$names[] = $c['name'];
}
return implode(ExportConfiguration::CSV_VALUE_SEPARATOR, $names);
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace Empik\Marketplace\Utils;
use Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\Exception\LogicException;
class IdentifierExtractor
{
const IDENTIFIER_EAN = 'EAN';
const IDENTIFIER_SKU = 'SHOP_SKU';
/** @var string */
protected $identifierType;
public function __construct()
{
$this->identifierType = Configuration::get(ConfigurationAdapter::CONF_OFFER_IDENTIFIER);
}
/**
* @return bool|false|string
*/
public function getIdentifierType()
{
return $this->identifierType;
}
/**
* @return string
* @throws LogicException
*/
public function getFilterKey()
{
switch ($this->identifierType) {
case self::IDENTIFIER_EAN:
$key = 'p.ean13';
break;
case self::IDENTIFIER_SKU:
$key = 'p.reference';
break;
default:
throw new LogicException(sprintf('Unknown identifier type: "%s"', $this->identifierType));
}
return $key;
}
/**
* @param array $product
* @return mixed|string
* @throws LogicException
*/
public function extract(array $product)
{
switch ($this->identifierType) {
case self::IDENTIFIER_EAN:
$identifier = isset($product['ean13']) ? $product['ean13'] : '';
break;
case self::IDENTIFIER_SKU:
// $identifier = isset($product['reference']) ? $product['reference'] : '';
$skuExtractor = new SkuExtractor();
$identifier = $skuExtractor->extract($product);
break;
default:
throw new LogicException(sprintf('Unknown identifier type: "%s"', $this->identifierType));
}
return $identifier;
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Empik\Marketplace\Utils;
use Tools;
use Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
class OfferPriceCalculator
{
const ROUND_PRECISION = 2;
/** @var float */
protected $addToPrice;
/** @var float */
protected $priceRatio;
public function __construct()
{
$this->addToPrice = (float)Configuration::get(ConfigurationAdapter::CONF_ADD_TO_PRICE);
$this->priceRatio = (float)Configuration::get(ConfigurationAdapter::CONF_PRICE_RATIO);
}
/**
* @param $price
* @return float
*/
public function calculate($price)
{
$price = (float)$price;
if ($this->priceRatio != 1) {
$price *= $this->priceRatio;
}
if ($this->addToPrice != 0) {
$price += $this->addToPrice;
}
return Tools::ps_round($price, self::ROUND_PRECISION);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Empik\Marketplace\Utils;
use Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
class OfferQuantityCalculator
{
/** @var int */
protected $stockReduce;
public function __construct()
{
$this->stockReduce = (int)Configuration::get(ConfigurationAdapter::CONF_REDUCE_STOCK);
}
/**
* @param int $quantity
* @return float
*/
public function calculate($quantity)
{
$quantity = (int)$quantity;
$quantity = max($quantity - $this->stockReduce, 0);
return $quantity;
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Empik\Marketplace\Utils;
use Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Empik\Marketplace\Exception\LogicException;
class SkuExtractor
{
const SKU_REFERENCE = 'REFERENCE';
const SKU_EAN = 'EAN';
const SKU_ID = 'ID';
/** @var string */
protected $skuType;
public function __construct()
{
$this->skuType = Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE);
}
/**
* @return bool|false|string
*/
public function getSkuType()
{
return $this->skuType;
}
/**
* @param array $product
* @return mixed|string
* @throws LogicException
*/
public function extract(array $product)
{
switch ($this->skuType) {
case self::SKU_REFERENCE:
$identifier = isset($product['reference']) ? $product['reference'] : '';
break;
case self::SKU_EAN:
$identifier = isset($product['ean13']) ? $product['ean13'] : '';
break;
case self::SKU_ID:
$identifier = isset($product['id_product']) ? $product['id_product'] : '';
if (isset($product['id_product_attribute']) && $product['id_product_attribute'] > 0) {
$identifier .= '-' . $product['id_product_attribute'];
}
break;
default:
throw new LogicException(sprintf('Unknown SKU type: "%s"', $this->skuType));
}
return $identifier;
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace Empik\Marketplace\Utils;
use Configuration;
use Empik\Marketplace\Adapter\ConfigurationAdapter;
use Language;
use Country;
use Currency;
class Utils
{
/** @var int */
protected static $cacheLangId;
/** @var int */
protected static $cacheCountryId;
/** @var int */
protected static $cacheCurrencyId;
/** @var int */
protected static $cacheEmployeeId;
/**
* @return int
* @throws \PrestaShopException
*/
public static function getLangId()
{
if (!self::$cacheLangId) {
$langId = (int)Language::getIdByIso('pl');
if ($langId) {
self::$cacheLangId = $langId;
} else {
self::$cacheLangId = (int)Configuration::get('PS_LANG_DEFAULT');
}
}
return self::$cacheLangId;
}
/**
* @return int
*/
public static function getCountryId()
{
if (!self::$cacheCountryId) {
$countryId = (int)Country::getByIso('PL');
if ($countryId) {
self::$cacheCountryId = $countryId;
} else {
self::$cacheCountryId = (int)Configuration::get('PS_COUNTRY_DEFAULT');
}
}
return self::$cacheCountryId;
}
/**
* @return int
*/
public static function getCurrencyId()
{
$currencyId = (int)Currency::getIdByIsoCode('PLN');
if ($currencyId) {
self::$cacheCurrencyId = $currencyId;
} else {
self::$cacheCurrencyId = (int)Configuration::get('PS_CURRENCY_DEFAULT');
}
return self::$cacheCurrencyId;
}
/**
* @return int
*/
public static function getEmployeeId()
{
$employeeId = (int)Configuration::get(ConfigurationAdapter::CONF_ID_EMPLOYEE);
if ($employeeId) {
self::$cacheEmployeeId = $employeeId;
} else {
self::$cacheEmployeeId = (int)Configuration::get(ConfigurationAdapter::CONF_ID_EMPLOYEE);
}
return self::$cacheEmployeeId;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,42 @@
<?php
namespace Empik\Marketplace\Validator;
class Validator
{
public static function isValidApiKey($data)
{
return preg_match('/^[a-f0-9\-]{16,64}$/', $data);
}
public static function isValidEnvironment($data)
{
return preg_match('/^(https?:)?\/\/[$~:;#,%&_=\(\)\[\]\.\? \+\-@\/a-zA-Z0-9]+$/', $data);
}
public static function isOfferIdentifier($data)
{
return preg_match('/^[A-Z_]{1,16}$/', $data);
}
public static function isSkuType($data)
{
return preg_match('/^[A-Z_]{1,16}$/', $data);
}
public static function isBool($data)
{
return $data === null || is_bool($data) || preg_match('/^(0|1)$/', $data);
}
public static function isInt($data)
{
return (string) (int) $data === (string) $data || $data === false;
}
public static function isFloat($data)
{
return (string) ((float) $data) == (string) $data;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;