first commit

This commit is contained in:
2024-12-17 13:43:22 +01:00
commit 8e6cd8b410
21292 changed files with 3514826 additions and 0 deletions

11
modules/ps_eventbus/.env Normal file
View File

@@ -0,0 +1,11 @@
ACCOUNTS_SVC_API_URL="https://accounts-api.psessentials.net"
ACCOUNTS_SVC_UI_URL="https://accounts.psessentials.net"
BILLING_SVC_API_URL="https://billing-api.distribution.prestashop.net"
EVENT_BUS_PROXY_API_URL="https://eventbus-proxy.psessentials.net"
EVENT_BUS_SYNC_API_URL="https://eventbus-sync.psessentials.net"
FIREBASE_API_KEY="AIzaSyBEm26bA2KR893rY68enLdVGpqnkoW2Juo"
FIREBASE_AUTH_DOMAIN="prestashop-ready-prod.firebaseapp.com"
FIREBASE_PROJECT_ID="prestashop-ready-prod"
SSO_MANAGE_ACCOUNT="https://auth.prestashop.com/login"
SSO_RESEND_VERIFICATION_EMAIL="https://auth.prestashop.com/account/send-verification-email"
SENTRY_CREDENTIALS="https://4c7f6c8dd5aa405b8401a35f5cf26ada@o298402.ingest.sentry.io/5354585"

View File

@@ -0,0 +1,11 @@
ACCOUNTS_SVC_API_URL="https://accounts-api.psessentials.net"
ACCOUNTS_SVC_UI_URL="https://accounts.psessentials.net"
BILLING_SVC_API_URL="https://billing-api.distribution.prestashop.net"
EVENT_BUS_PROXY_API_URL="https://eventbus-proxy.psessentials.net"
EVENT_BUS_SYNC_API_URL="https://eventbus-sync.psessentials.net"
FIREBASE_API_KEY="AIzaSyBEm26bA2KR893rY68enLdVGpqnkoW2Juo"
FIREBASE_AUTH_DOMAIN="prestashop-ready-prod.firebaseapp.com"
FIREBASE_PROJECT_ID="prestashop-ready-prod"
SSO_MANAGE_ACCOUNT="https://auth.prestashop.com/login"
SSO_RESEND_VERIFICATION_EMAIL="https://auth.prestashop.com/account/send-verification-email"
SENTRY_CREDENTIALS="https://4c7f6c8dd5aa405b8401a35f5cf26ada@o298402.ingest.sentry.io/5354585"

View File

@@ -0,0 +1,12 @@
<?php
$config = new PrestaShop\CodingStandards\CsFixer\Config();
$config
->setUsingCache(true)
->getFinder()
->in(__DIR__)
->exclude('translations')
->exclude('vendor');
return $config;

View File

@@ -0,0 +1,3 @@
# ps_eventbus
Module companion for EventBus

View File

@@ -0,0 +1,34 @@
{
"config": {
"preferred-install": "dist",
"platform": {
"php": "5.6"
},
"optimize-autoloader": true,
"prepend-autoloader": false
},
"autoload": {
"psr-4": {
"PrestaShop\\Module\\PsEventbus\\": "src/"
},
"classmap": [
"ps_eventbus.php",
"controllers/"
]
},
"require": {
"php": ">=5.6",
"symfony/dotenv": "^3.4",
"phpseclib/phpseclib": "^2.0",
"ext-json": "*",
"guzzlehttp/guzzle": "~5.0",
"monolog/monolog": "1.25.3",
"prestashop/prestashop-accounts-auth": "^2.2.0",
"prestashop/module-lib-service-container": "^1.2"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"prestashop/php-dev-tools": "3.*",
"friendsofphp/php-cs-fixer": "^2.16"
}
}

4107
modules/ps_eventbus/composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>ps_eventbus</name>
<displayName><![CDATA[PrestaShop Eventbus]]></displayName>
<version><![CDATA[1.3.7]]></version>
<description><![CDATA[Link your PrestaShop account to synchronize your shop&#039;s data to the partners you want . Don&#039;t uninstall this module if you are already using a service, as it will prevent it from working.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[administration]]></tab>
<confirmUninstall><![CDATA[This action will prevent immediately your PrestaShop services and Community services from working as they are using PrestaShop EventBus module for syncing.]]></confirmUninstall>
<is_configurable>0</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,4 @@
imports:
- { resource: ../common.yml }
- { resource: ../front/repository.yml }
- { resource: ../front/services.yml }

View File

@@ -0,0 +1,12 @@
services:
ps_eventbus.db:
class: Db
factory: [ 'Db', 'getInstance' ]
ps_eventbus.context:
class: Context
factory: [ 'Context', 'getContext' ]
ps_eventbus.link:
class: Link
factory: [ 'PrestaShop\Module\PsEventbus\Factory\Link', 'get' ]

View File

@@ -0,0 +1,11 @@
services:
PrestaShop\Module\PsEventbus\Api\EventBusSyncClient:
class: PrestaShop\Module\PsEventbus\Api\EventBusSyncClient
arguments:
- '@ps_eventbus.link'
PrestaShop\Module\PsEventbus\Api\EventBusProxyClient:
class: PrestaShop\Module\PsEventbus\Api\EventBusProxyClient
arguments:
- '@ps_eventbus.link'

View File

@@ -0,0 +1,12 @@
services:
PrestaShop\Module\PsEventbus\Decorator\ProductDecorator:
class: PrestaShop\Module\PsEventbus\Decorator\ProductDecorator
arguments:
- '@ps_eventbus.context'
- '@PrestaShop\Module\PsEventbus\Repository\LanguageRepository'
- '@PrestaShop\Module\PsEventbus\Repository\ProductRepository'
- '@PrestaShop\Module\PsEventbus\Repository\CategoryRepository'
- '@PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter'
PrestaShop\Module\PsEventbus\Decorator\CategoryDecorator:
class: PrestaShop\Module\PsEventbus\Decorator\CategoryDecorator

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,41 @@
services:
PrestaShop\Module\PsEventbus\Provider\ModuleDataProvider:
class: PrestaShop\Module\PsEventbus\Provider\ModuleDataProvider
arguments:
- '@PrestaShop\Module\PsEventbus\Repository\ModuleRepository'
PrestaShop\Module\PsEventbus\Provider\ProductDataProvider:
class: PrestaShop\Module\PsEventbus\Provider\ProductDataProvider
arguments:
- '@PrestaShop\Module\PsEventbus\Repository\ProductRepository'
- '@PrestaShop\Module\PsEventbus\Decorator\ProductDecorator'
- '@PrestaShop\Module\PsEventbus\Repository\LanguageRepository'
- '@PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter'
PrestaShop\Module\PsEventbus\Provider\CategoryDataProvider:
class: PrestaShop\Module\PsEventbus\Provider\CategoryDataProvider
arguments:
- '@PrestaShop\Module\PsEventbus\Repository\CategoryRepository'
- '@PrestaShop\Module\PsEventbus\Decorator\CategoryDecorator'
- '@PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter'
PrestaShop\Module\PsEventbus\Provider\OrderDataProvider:
class: PrestaShop\Module\PsEventbus\Provider\OrderDataProvider
arguments:
- '@ps_eventbus.context'
- '@PrestaShop\Module\PsEventbus\Repository\OrderRepository'
- '@PrestaShop\Module\PsEventbus\Repository\OrderDetailsRepository'
- '@PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter'
PrestaShop\Module\PsEventbus\Provider\CartDataProvider:
class: PrestaShop\Module\PsEventbus\Provider\CartDataProvider
arguments:
- '@PrestaShop\Module\PsEventbus\Repository\CartRepository'
- '@PrestaShop\Module\PsEventbus\Repository\CartProductRepository'
- '@PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter'
PrestaShop\Module\PsEventbus\Provider\GoogleTaxonomyDataProvider:
class: PrestaShop\Module\PsEventbus\Provider\GoogleTaxonomyDataProvider
arguments:
- '@PrestaShop\Module\PsEventbus\Repository\GoogleTaxonomyRepository'
- '@ps_eventbus.context'

View File

@@ -0,0 +1,101 @@
services:
PrestaShop\Module\PsEventbus\Repository\CurrencyRepository:
class: PrestaShop\Module\PsEventbus\Repository\CurrencyRepository
PrestaShop\Module\PsEventbus\Repository\LanguageRepository:
class: PrestaShop\Module\PsEventbus\Repository\LanguageRepository
PrestaShop\Module\PsEventbus\Repository\ConfigurationRepository:
class: PrestaShop\Module\PsEventbus\Repository\ConfigurationRepository
PrestaShop\Module\PsEventbus\Repository\EventbusSyncRepository:
class: PrestaShop\Module\PsEventbus\Repository\EventbusSyncRepository
arguments:
- '@ps_eventbus.db'
- '@ps_eventbus.context'
PrestaShop\Module\PsEventbus\Repository\CategoryRepository:
class: PrestaShop\Module\PsEventbus\Repository\CategoryRepository
arguments:
- '@ps_eventbus.db'
- '@ps_eventbus.context'
PrestaShop\Module\PsEventbus\Repository\ImageRepository:
class: PrestaShop\Module\PsEventbus\Repository\ImageRepository
arguments:
- '@ps_eventbus.db'
PrestaShop\Module\PsEventbus\Repository\ModuleRepository:
class: PrestaShop\Module\PsEventbus\Repository\ModuleRepository
arguments:
- '@ps_eventbus.db'
PrestaShop\Module\PsEventbus\Repository\ProductRepository:
class: PrestaShop\Module\PsEventbus\Repository\ProductRepository
arguments:
- '@ps_eventbus.db'
- '@ps_eventbus.context'
- '@PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter'
PrestaShop\Module\PsEventbus\Repository\ServerInformationRepository:
class: PrestaShop\Module\PsEventbus\Repository\ServerInformationRepository
arguments:
- '@ps_eventbus.context'
- '@ps_eventbus.db'
- '@PrestaShop\Module\PsEventbus\Repository\CurrencyRepository'
- '@PrestaShop\Module\PsEventbus\Repository\LanguageRepository'
- '@PrestaShop\Module\PsEventbus\Repository\ConfigurationRepository'
- '@PrestaShop\Module\PsEventbus\Repository\ShopRepository'
- '@PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter'
PrestaShop\Module\PsEventbus\Repository\ThemeRepository:
class: PrestaShop\Module\PsEventbus\Repository\ThemeRepository
arguments:
- '@ps_eventbus.context'
- '@ps_eventbus.db'
PrestaShop\Module\PsEventbus\Repository\OrderRepository:
class: PrestaShop\Module\PsEventbus\Repository\OrderRepository
arguments:
- '@ps_eventbus.db'
PrestaShop\Module\PsEventbus\Repository\OrderDetailsRepository:
class: PrestaShop\Module\PsEventbus\Repository\OrderDetailsRepository
arguments:
- '@ps_eventbus.db'
- '@ps_eventbus.context'
PrestaShop\Module\PsEventbus\Repository\CartRepository:
class: PrestaShop\Module\PsEventbus\Repository\CartRepository
arguments:
- '@ps_eventbus.db'
- '@ps_eventbus.context'
PrestaShop\Module\PsEventbus\Repository\CartProductRepository:
class: PrestaShop\Module\PsEventbus\Repository\CartProductRepository
arguments:
- '@ps_eventbus.db'
- '@ps_eventbus.context'
PrestaShop\Module\PsEventbus\Repository\GoogleTaxonomyRepository:
class: PrestaShop\Module\PsEventbus\Repository\GoogleTaxonomyRepository
arguments:
- '@ps_eventbus.db'
PrestaShop\Module\PsEventbus\Repository\DeletedObjectsRepository:
class: PrestaShop\Module\PsEventbus\Repository\DeletedObjectsRepository
arguments:
- '@ps_eventbus.db'
- '@ps_eventbus.context'
PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository:
class: PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository
arguments:
- '@ps_eventbus.db'
- '@ps_eventbus.context'
PrestaShop\Module\PsEventbus\Repository\ShopRepository:
class: PrestaShop\Module\PsEventbus\Repository\ShopRepository
arguments:
- '@ps_eventbus.context'
- '@ps_eventbus.db'

View File

@@ -0,0 +1,44 @@
imports:
- { resource: ../common.yml }
- { resource: api.yml }
- { resource: decorator.yml }
- { resource: provider.yml }
- { resource: repository.yml }
services:
PrestaShop\Module\PsEventbus\Formatter\JsonFormatter:
class: PrestaShop\Module\PsEventbus\Formatter\JsonFormatter
PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter:
class: PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter
PrestaShop\Module\PsEventbus\Service\CompressionService:
class: PrestaShop\Module\PsEventbus\Service\CompressionService
arguments:
- '@PrestaShop\Module\PsEventbus\Formatter\JsonFormatter'
PrestaShop\Module\PsEventbus\Service\ProxyService:
class: PrestaShop\Module\PsEventbus\Service\ProxyService
arguments:
- '@PrestaShop\Module\PsEventbus\Api\EventBusProxyClient'
- '@PrestaShop\Module\PsEventbus\Formatter\JsonFormatter'
PrestaShop\Module\PsEventbus\Service\ApiAuthorizationService:
class: PrestaShop\Module\PsEventbus\Service\ApiAuthorizationService
arguments:
- '@PrestaShop\Module\PsEventbus\Repository\EventbusSyncRepository'
- '@PrestaShop\Module\PsEventbus\Api\EventBusSyncClient'
PrestaShop\Module\PsEventbus\Service\DeletedObjectsService:
class: PrestaShop\Module\PsEventbus\Service\DeletedObjectsService
arguments:
- '@ps_eventbus.context'
- '@PrestaShop\Module\PsEventbus\Repository\DeletedObjectsRepository'
- '@PrestaShop\Module\PsEventbus\Service\ProxyService'
PrestaShop\Module\PsEventbus\Service\SynchronizationService:
class: PrestaShop\Module\PsEventbus\Service\SynchronizationService
arguments:
- '@PrestaShop\Module\PsEventbus\Repository\EventbusSyncRepository'
- '@PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository'
- '@PrestaShop\Module\PsEventbus\Service\ProxyService'

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>ps_eventbus</name>
<displayName><![CDATA[PrestaShop Eventbus]]></displayName>
<version><![CDATA[1.3.7]]></version>
<description><![CDATA[Link your PrestaShop account to synchronize your shop&#039;s data to the partners you want . Don&amp;#039;t uninstall this module if you are already using a service, as it will prevent it from working.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[administration]]></tab>
<confirmUninstall><![CDATA[This action will prevent immediately your PrestaShop services and Community services from working as they are using PrestaShop Eventbus module for syncing.]]></confirmUninstall>
<is_configurable>0</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,23 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Provider\CartDataProvider;
class ps_EventbusApiCartsModuleFrontController extends AbstractApiController
{
public $type = 'carts';
/**
* @throws PrestaShopException
*
* @return void
*/
public function postProcess()
{
$cartDataProvider = $this->module->getService(CartDataProvider::class);
$response = $this->handleDataSync($cartDataProvider);
$this->exitWithResponse($response);
}
}

View File

@@ -0,0 +1,23 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Provider\CategoryDataProvider;
class ps_EventbusApiCategoriesModuleFrontController extends AbstractApiController
{
public $type = 'categories';
/**
* @throws PrestaShopException
*
* @return void
*/
public function postProcess()
{
$categoryDataProvider = $this->module->getService(CategoryDataProvider::class);
$response = $this->handleDataSync($categoryDataProvider);
$this->exitWithResponse($response);
}
}

View File

@@ -0,0 +1,30 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
use PrestaShop\Module\PsEventbus\Service\DeletedObjectsService;
class ps_EventbusApiDeletedObjectsModuleFrontController extends AbstractApiController
{
public $type = 'deleted';
/**
* @return void
*/
public function postProcess()
{
$jobId = Tools::getValue('job_id', '');
/** @var DeletedObjectsService $deletedObjectsService */
$deletedObjectsService = $this->module->getService(DeletedObjectsService::class);
try {
$response = $deletedObjectsService->handleDeletedObjectsSync($jobId);
$this->exitWithResponse($response);
} catch (PrestaShopDatabaseException $exception) {
$this->exitWithExceptionMessage($exception);
} catch (EnvVarException $exception) {
$this->exitWithExceptionMessage($exception);
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
use PrestaShop\Module\PsEventbus\Config\Config;
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Provider\GoogleTaxonomyDataProvider;
class ps_EventbusApiGoogleTaxonomiesModuleFrontController extends AbstractApiController
{
public $type = 'taxonomies';
/**
* @throws PrestaShopException
*
* @return void
*/
public function postProcess()
{
if (!Module::isInstalled('ps_facebook')) {
$this->exitWithExceptionMessage(new Exception('Facebook module is not installed', Config::PS_FACEBOOK_NOT_INSTALLED));
}
$categoryDataProvider = $this->module->getService(GoogleTaxonomyDataProvider::class);
$response = $this->handleDataSync($categoryDataProvider);
$this->exitWithResponse($response);
}
}

View File

@@ -0,0 +1,26 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Repository\ServerInformationRepository;
class ps_EventbusApiHealthCheckModuleFrontController extends AbstractApiController
{
public $type = 'shops';
public function init()
{
}
/**
* @return void
*/
public function postProcess()
{
/** @var ServerInformationRepository $serverInformationRepository */
$serverInformationRepository = $this->module->getService(ServerInformationRepository::class);
$status = $serverInformationRepository->getHealthCheckData();
$this->exitWithResponse($status);
}
}

View File

@@ -0,0 +1,44 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
use PrestaShop\Module\PsEventbus\Repository\ServerInformationRepository;
class ps_EventbusApiInfoModuleFrontController extends AbstractApiController
{
public $type = 'shops';
/**
* @throws PrestaShopException
*
* @return void
*/
public function postProcess()
{
$response = [];
$jobId = Tools::getValue('job_id');
$serverInformationRepository = $this->module->getService(ServerInformationRepository::class);
$serverInfo = $serverInformationRepository->getServerInformation(Tools::getValue('lang_iso', null));
try {
$response = $this->proxyService->upload($jobId, $serverInfo, $this->startTime);
} catch (EnvVarException $exception) {
$this->exitWithExceptionMessage($exception);
} catch (Exception $exception) {
$this->exitWithExceptionMessage($exception);
}
$this->exitWithResponse(
array_merge(
[
'remaining_objects' => 0,
'total_objects' => 1,
],
$response
)
);
}
}

View File

@@ -0,0 +1,26 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Provider\ModuleDataProvider;
use PrestaShop\Module\PsEventbus\Repository\ModuleRepository;
class ps_EventbusApiModulesModuleFrontController extends AbstractApiController
{
public $type = 'modules';
/**
* @throws PrestaShopException
*
* @return void
*/
public function postProcess()
{
$moduleDataProvider = new ModuleDataProvider(
new ModuleRepository(Db::getInstance())
);
$response = $this->handleDataSync($moduleDataProvider);
$this->exitWithResponse($response);
}
}

View File

@@ -0,0 +1,23 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Provider\OrderDataProvider;
class ps_EventbusApiOrdersModuleFrontController extends AbstractApiController
{
public $type = 'orders';
/**
* @throws PrestaShopException
*
* @return void
*/
public function postProcess()
{
$orderDataProvider = $this->module->getService(OrderDataProvider::class);
$response = $this->handleDataSync($orderDataProvider);
$this->exitWithResponse($response);
}
}

View File

@@ -0,0 +1,23 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Provider\ProductDataProvider;
class ps_EventbusApiProductsModuleFrontController extends AbstractApiController
{
public $type = 'products';
/**
* @throws PrestaShopException
*
* @return void
*/
public function postProcess()
{
$productDataProvider = $this->module->getService(ProductDataProvider::class);
$response = $this->handleDataSync($productDataProvider);
$this->exitWithResponse($response);
}
}

View File

@@ -0,0 +1,42 @@
<?php
use PrestaShop\Module\PsEventbus\Controller\AbstractApiController;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
use PrestaShop\Module\PsEventbus\Repository\ThemeRepository;
class ps_EventbusApiThemesModuleFrontController extends AbstractApiController
{
public $type = 'themes';
/**
* @return void
*/
public function postProcess()
{
$response = [];
$jobId = Tools::getValue('job_id');
$themeRepository = $this->module->getService(ThemeRepository::class);
$themeInfo = $themeRepository->getThemes();
try {
$response = $this->proxyService->upload($jobId, $themeInfo, $this->startTime);
} catch (EnvVarException $exception) {
$this->exitWithExceptionMessage($exception);
} catch (Exception $exception) {
$this->exitWithExceptionMessage($exception);
}
$this->exitWithResponse(
array_merge(
[
'remaining_objects' => 0,
'total_objects' => count($themeInfo),
],
$response
)
);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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 @@
version: '2'
services:
mysql:
image: mysql:5.7
container_name: ps17_mysql
ports:
- "3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: psreference
reference-release:
image: prestashop/prestashop:1.7
container_name: ps17_php
volumes:
- ./:/var/www/html/modules/ps_facebook
environment:
DB_SERVER: mysql
DB_PASSWD: root
DB_NAME: psreference
PS_DOMAIN: localhost:8001
PS_DEV_MODE: 0
PS_INSTALL_AUTO: 1
PS_ERASE_DB: 1
PS_FOLDER_ADMIN: admin-dev
PS_FOLDER_INSTALL: install-dev
PS_LANGUAGE: fr
PS_COUNTRY: fr
depends_on:
- mysql
ports:
- "8001:80"

View File

@@ -0,0 +1,17 @@
version: '2'
services:
php:
image: phpdockerio/php72-cli
volumes:
- ./:/var/www/html
working_dir: /var/www/html
environment:
_PS_ROOT_DIR_: /var/www/html
node:
image: node:10.16
volumes:
- ./:/var/www/html
working_dir: /var/www/html
environment:
PATH: /var/www/html/_dev/node_modules/.bin/:$PATH

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php" colors="true" stopOnFailure="false">
<testsuites>
<testsuite name="Ps eventbus Tests">
<directory suffix="Test.php">./tests/unit</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@@ -0,0 +1,405 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_')) {
exit;
}
require_once __DIR__ . '/vendor/autoload.php';
class Ps_eventbus extends Module
{
/**
* @var array
*/
public $adminControllers;
/**
* @var string
*/
const VERSION = '1.3.7';
/**
* @var array
*/
const REQUIRED_TABLES = [
'eventbus_type_sync',
'eventbus_job',
'eventbus_deleted_objects',
'eventbus_incremental_sync',
];
/**
* @var string
*/
public $version;
/**
* List of hook to install at the installation of the module
*
* @var array
*/
private $hookToInstall = [
'actionObjectProductAddAfter',
'actionObjectProductUpdateAfter',
'actionObjectProductDeleteAfter',
'actionObjectCategoryAddAfter',
'actionObjectCategoryUpdateAfter',
'actionObjectCategoryDeleteAfter',
'actionObjectOrderAddAfter',
'actionObjectOrderUpdateAfter',
'actionObjectCartAddAfter',
'actionObjectCartUpdateAfter',
];
/**
* @var \PrestaShop\ModuleLibServiceContainer\DependencyInjection\ServiceContainer
*/
private $serviceContainer;
/**
* __construct.
*/
public function __construct()
{
$this->name = 'ps_eventbus';
$this->tab = 'administration';
$this->author = 'PrestaShop';
$this->need_instance = 0;
$this->bootstrap = true;
$this->version = '1.3.7';
$this->module_key = '7d76e08a13331c6c393755886ec8d5ce';
parent::__construct();
$this->displayName = $this->l('PrestaShop Eventbus');
$this->description = $this->l('Link your PrestaShop account to synchronize your shop\'s data to the partners you want . Don&#039;t uninstall this module if you are already using a service, as it will prevent it from working.');
$this->confirmUninstall = $this->l('This action will prevent immediately your PrestaShop services and Community services from working as they are using PrestaShop Eventbus module for syncing.');
$this->ps_versions_compliancy = ['min' => '1.6', 'max' => _PS_VERSION_];
$this->adminControllers = [];
$this->serviceContainer = new \PrestaShop\ModuleLibServiceContainer\DependencyInjection\ServiceContainer(
$this->name,
$this->getLocalPath()
);
$this->loadEnv();
}
/**
* @return void
*/
private function loadEnv()
{
$dotEnv = new Symfony\Component\Dotenv\Dotenv();
$dotEnv->load(_PS_MODULE_DIR_ . 'ps_eventbus/.env.dist');
if (file_exists(_PS_MODULE_DIR_ . 'ps_eventbus/.env')) {
$dotEnv->load(_PS_MODULE_DIR_ . 'ps_eventbus/.env');
}
}
/**
* @return \Context
*/
public function getContext()
{
return $this->context;
}
/**
* @return array
*/
public function getAdminControllers()
{
return $this->adminControllers;
}
/**
* @return bool
*/
public function install()
{
$installer = new PrestaShop\Module\PsEventbus\Module\Install($this, Db::getInstance());
return $installer->installInMenu()
&& $installer->installDatabaseTables()
&& parent::install()
&& $this->registerHook($this->hookToInstall);
}
/**
* @return bool
*/
public function uninstall()
{
$uninstaller = new PrestaShop\Module\PsEventbus\Module\Uninstall($this, Db::getInstance());
return $uninstaller->uninstallMenu()
&& $uninstaller->uninstallDatabaseTables()
&& parent::uninstall();
}
/**
* @param string $serviceName
*
* @return mixed
*/
public function getService($serviceName)
{
return $this->serviceContainer->getService($serviceName);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectProductDeleteAfter($parameters)
{
$product = $parameters['object'];
$this->insertDeletedObject(
$product->id,
'products',
date(DATE_ATOM),
$this->context->shop->id
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectProductAddAfter($parameters)
{
$product = $parameters['object'];
$this->insertIncrementalSyncObject(
$product->id,
'products',
date(DATE_ATOM),
$this->context->shop->id,
true
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectProductUpdateAfter($parameters)
{
$product = $parameters['object'];
$this->insertIncrementalSyncObject(
$product->id,
'products',
date(DATE_ATOM),
$this->context->shop->id,
true
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectCategoryAddAfter($parameters)
{
$category = $parameters['object'];
$this->insertIncrementalSyncObject(
$category->id,
'categories',
date(DATE_ATOM),
$this->context->shop->id,
true
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectCategoryUpdateAfter($parameters)
{
$category = $parameters['object'];
$this->insertIncrementalSyncObject(
$category->id,
'categories',
date(DATE_ATOM),
$this->context->shop->id,
true
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectCategoryDeleteAfter($parameters)
{
$category = $parameters['object'];
$this->insertDeletedObject(
$category->id,
'categories',
date(DATE_ATOM),
$this->context->shop->id
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectCartAddAfter($parameters)
{
$cart = $parameters['object'];
$this->insertIncrementalSyncObject(
$cart->id,
'carts',
date(DATE_ATOM),
$this->context->shop->id
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectCartUpdateAfter($parameters)
{
$cart = $parameters['object'];
$this->insertIncrementalSyncObject(
$cart->id,
'carts',
date(DATE_ATOM),
$this->context->shop->id
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectOrderAddAfter($parameters)
{
$order = $parameters['object'];
$this->insertIncrementalSyncObject(
$order->id,
'orders',
date(DATE_ATOM),
$this->context->shop->id
);
}
/**
* @param array $parameters
*
* @return void
*/
public function hookActionObjectOrderUpdateAfter($parameters)
{
$order = $parameters['object'];
$this->insertIncrementalSyncObject(
$order->id,
'orders',
date(DATE_ATOM),
$this->context->shop->id
);
}
/**
* @param int $objectId
* @param string $type
* @param string $date
* @param int $shopId
* @param bool $hasMultiLang
*
* @return void
*/
private function insertIncrementalSyncObject($objectId, $type, $date, $shopId, $hasMultiLang = false)
{
/** @var \PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository $incrementalSyncRepository */
$incrementalSyncRepository = $this->getService(
\PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository::class
);
/** @var \PrestaShop\Module\PsEventbus\Repository\LanguageRepository $languageRepository */
$languageRepository = $this->getService(
\PrestaShop\Module\PsEventbus\Repository\LanguageRepository::class
);
if ($hasMultiLang) {
$languagesIsoCodes = $languageRepository->getLanguagesIsoCodes();
foreach ($languagesIsoCodes as $languagesIsoCode) {
$incrementalSyncRepository->insertIncrementalObject($objectId, $type, $date, $shopId, $languagesIsoCode);
}
} else {
$languagesIsoCode = $languageRepository->getDefaultLanguageIsoCode();
$incrementalSyncRepository->insertIncrementalObject($objectId, $type, $date, $shopId, $languagesIsoCode);
}
}
/**
* @param int $id
* @param string $type
* @param string $date
* @param int $shopId
*
* @return void
*/
private function insertDeletedObject($id, $type, $date, $shopId)
{
/** @var \PrestaShop\Module\PsEventbus\Repository\DeletedObjectsRepository $deletedObjectsRepository */
$deletedObjectsRepository = $this->getService(
\PrestaShop\Module\PsEventbus\Repository\DeletedObjectsRepository::class
);
/** @var \PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository $incrementalSyncRepository */
$incrementalSyncRepository = $this->getService(
\PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository::class
);
$deletedObjectsRepository->insertDeletedObject($id, $type, $date, $shopId);
$incrementalSyncRepository->removeIncrementalSyncObject($type, $id);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,38 @@
CREATE TABLE IF NOT EXISTS `PREFIX_eventbus_type_sync`
(
`type` VARCHAR(50) NOT NULL,
`offset` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`id_shop` INT(10) UNSIGNED NOT NULL,
`lang_iso` VARCHAR(3),
`full_sync_finished` TINYINT(1) NOT NULL DEFAULT 0,
`last_sync_date` DATETIME NOT NULL
) ENGINE = ENGINE_TYPE
DEFAULT CHARSET = utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_eventbus_job`
(
`job_id` VARCHAR(200) NOT NULL,
`created_at` DATETIME NOT NULL
) ENGINE = ENGINE_TYPE
DEFAULT CHARSET = utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_eventbus_deleted_objects`
(
`type` VARCHAR(50) NOT NULL,
`id_object` INT(10) UNSIGNED NOT NULL,
`id_shop` INT(10) UNSIGNED NOT NULL,
`created_at` DATETIME NOT NULL,
PRIMARY KEY (`type`, `id_object`, `id_shop`)
) ENGINE = ENGINE_TYPE
DEFAULT CHARSET = utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_eventbus_incremental_sync`
(
`type` VARCHAR(50) NOT NULL,
`id_object` INT(10) UNSIGNED NOT NULL,
`id_shop` INT(10) UNSIGNED NOT NULL,
`lang_iso` VARCHAR(3),
`created_at` DATETIME NOT NULL,
PRIMARY KEY (`type`, `id_object`, `id_shop`, `lang_iso`)
) ENGINE = ENGINE_TYPE
DEFAULT CHARSET = utf8;

View File

@@ -0,0 +1,13 @@
INSERT INTO `PREFIX_eventbus_type_sync`
SELECT * FROM `PREFIX_accounts_type_sync`;
INSERT INTO `PREFIX_eventbus_deleted_objects`
SELECT * FROM `PREFIX_accounts_deleted_objects`;
INSERT INTO `PREFIX_eventbus_incremental_sync`
SELECT * FROM `PREFIX_accounts_incremental_sync`;
DROP TABLE IF EXISTS `PREFIX_accounts_type_sync`;
DROP TABLE IF EXISTS `PREFIX_accounts_deleted_objects`;
DROP TABLE IF EXISTS `PREFIX_accounts_incremental_sync`;
DROP TABLE IF EXISTS `PREFIX_accounts_sync`;

View File

@@ -0,0 +1,4 @@
DROP TABLE IF EXISTS `PREFIX_eventbus_type_sync`;
DROP TABLE IF EXISTS `PREFIX_eventbus_job`;
DROP TABLE IF EXISTS `PREFIX_eventbus_deleted_objects`;
DROP TABLE IF EXISTS `PREFIX_eventbus_incremental_sync`;

View File

@@ -0,0 +1,144 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Api;
use GuzzleHttp\Client;
use GuzzleHttp\Post\PostFile;
use Link;
use PrestaShop\AccountsAuth\Api\Client\GenericClient;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\Module\PsEventbus\Config\Config;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
/**
* Construct the client used to make call to Segment API
*/
class EventBusProxyClient extends GenericClient
{
public function __construct(Link $link, Client $client = null)
{
parent::__construct();
$this->setLink($link);
$psAccountsService = new PsAccountsService();
$token = $psAccountsService->getOrRefreshToken();
if (null === $client) {
$client = new Client([
'base_url' => $_ENV['EVENT_BUS_PROXY_API_URL'],
'defaults' => [
'timeout' => 60,
'exceptions' => $this->catchExceptions,
'headers' => [
'Authorization' => "Bearer $token",
],
],
]);
}
$this->setClient($client);
}
/**
* @param string $jobId
* @param string $data
* @param int $scriptStartTime
*
* @return array
*
* @throws EnvVarException
*/
public function upload($jobId, $data, $scriptStartTime)
{
if (!isset($_ENV['EVENT_BUS_PROXY_API_URL'])) {
throw new EnvVarException('EVENT_BUS_PROXY_API_URL is not defined');
}
$timeout = Config::PROXY_TIMEOUT - (time() - $scriptStartTime);
$route = $_ENV['EVENT_BUS_PROXY_API_URL'] . "/upload/$jobId";
$this->setRoute($route);
$file = new PostFile(
'file',
$data,
'file'
);
$response = $this->post([
'headers' => [
'Content-Type' => 'binary/octet-stream',
],
'body' => [
'file' => $file,
],
'timeout' => $timeout,
]);
if (is_array($response)) {
$response['upload_url'] = $route;
}
return $response;
}
/**
* @param string $jobId
* @param string $compressedData
*
* @return array
*
* @throws EnvVarException
*/
public function delete($jobId, $compressedData)
{
if (!isset($_ENV['EVENT_BUS_PROXY_API_URL'])) {
throw new EnvVarException('EVENT_BUS_PROXY_API_URL is not defined');
}
$route = $_ENV['EVENT_BUS_PROXY_API_URL'] . "/delete/$jobId";
$this->setRoute($route);
$file = new PostFile(
'file',
$compressedData,
'file.gz'
);
$response = $this->post([
'headers' => [
'Content-Type' => 'binary/octet-stream',
],
'body' => [
'file' => $file,
],
]);
if (is_array($response)) {
$response['upload_url'] = $route;
}
return $response;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace PrestaShop\Module\PsEventbus\Api;
use GuzzleHttp\Client;
use PrestaShop\AccountsAuth\Api\Client\GenericClient;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
class EventBusSyncClient extends GenericClient
{
public function __construct(\Link $link, Client $client = null)
{
parent::__construct();
$this->setLink($link);
$psAccountsService = new PsAccountsService();
$token = $psAccountsService->getOrRefreshToken();
if (null === $client) {
$client = new Client([
'base_url' => $_ENV['EVENT_BUS_SYNC_API_URL'],
'defaults' => [
'timeout' => $this->timeout,
'exceptions' => $this->catchExceptions,
'headers' => [
'Accept' => 'application/json',
'Authorization' => "Bearer $token",
],
],
]);
}
$this->setClient($client);
}
/**
* @param string $jobId
*
* @return array|bool
*
* @throws EnvVarException
*/
public function validateJobId($jobId)
{
if (!isset($_ENV['EVENT_BUS_SYNC_API_URL'])) {
throw new EnvVarException('EVENT_BUS_SYNC_API_URL is not defined');
}
$this->setRoute($_ENV['EVENT_BUS_SYNC_API_URL'] . "/job/$jobId");
return $this->get();
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,23 @@
<?php
namespace PrestaShop\Module\PsEventbus\Config;
class Config
{
const PROXY_TIMEOUT = 30;
const REFRESH_TOKEN_ERROR_CODE = 452;
const ENV_MISCONFIGURED_ERROR_CODE = 453;
const DATABASE_QUERY_ERROR_CODE = 454;
const DATABASE_INSERT_ERROR_CODE = 455;
const PS_FACEBOOK_NOT_INSTALLED = 456;
const INVALID_URL_QUERY = 458;
const HTTP_STATUS_MESSAGES = [
self::REFRESH_TOKEN_ERROR_CODE => 'Cannot refresh token',
self::ENV_MISCONFIGURED_ERROR_CODE => 'Environment misconfigured',
self::DATABASE_QUERY_ERROR_CODE => 'Database syntax error',
self::DATABASE_INSERT_ERROR_CODE => 'Failed to write to database',
self::PS_FACEBOOK_NOT_INSTALLED => 'Cannot sync Taxonomies without Facebook module',
self::INVALID_URL_QUERY => 'Invalid URL query',
];
}

View File

@@ -0,0 +1,277 @@
<?php
namespace PrestaShop\Module\PsEventbus\Controller;
use DateTime;
use Exception;
use ModuleFrontController;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\Module\PsEventbus\Config\Config;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
use PrestaShop\Module\PsEventbus\Exception\FirebaseException;
use PrestaShop\Module\PsEventbus\Exception\QueryParamsException;
use PrestaShop\Module\PsEventbus\Provider\PaginatedApiDataProviderInterface;
use PrestaShop\Module\PsEventbus\Repository\EventbusSyncRepository;
use PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository;
use PrestaShop\Module\PsEventbus\Repository\LanguageRepository;
use PrestaShop\Module\PsEventbus\Service\ApiAuthorizationService;
use PrestaShop\Module\PsEventbus\Service\ProxyService;
use PrestaShop\Module\PsEventbus\Service\SynchronizationService;
use PrestaShopDatabaseException;
use PrestaShopException;
use Ps_eventbus;
use Tools;
abstract class AbstractApiController extends ModuleFrontController
{
/**
* Endpoint name
*
* @var string
*/
public $type = '';
/**
* Timestamp when script started
*
* @var int
*/
public $startTime;
/**
* @var ApiAuthorizationService
*/
protected $authorizationService;
/**
* @var ProxyService
*/
protected $proxyService;
/**
* @var EventbusSyncRepository
*/
protected $eventbusSyncRepository;
/**
* @var LanguageRepository
*/
private $languageRepository;
/**
* @var PsAccountsService
*/
private $psAccountsService;
/**
* @var IncrementalSyncRepository
*/
protected $incrementalSyncRepository;
/**
* @var SynchronizationService
*/
private $synchronizationService;
/**
* @var Ps_eventbus
*/
public $module;
public function __construct()
{
parent::__construct();
$this->controller_type = 'module';
$this->proxyService = $this->module->getService(ProxyService::class);
$this->authorizationService = $this->module->getService(ApiAuthorizationService::class);
$this->eventbusSyncRepository = $this->module->getService(EventbusSyncRepository::class);
$this->languageRepository = $this->module->getService(LanguageRepository::class);
$this->psAccountsService = new PsAccountsService();
$this->incrementalSyncRepository = $this->module->getService(IncrementalSyncRepository::class);
$this->synchronizationService = $this->module->getService(SynchronizationService::class);
}
/**
* @return void
*/
public function init()
{
$this->startTime = time();
try {
$this->authorize();
} catch (PrestaShopDatabaseException $exception) {
$this->exitWithExceptionMessage($exception);
} catch (EnvVarException $exception) {
$this->exitWithExceptionMessage($exception);
} catch (FirebaseException $exception) {
$this->exitWithExceptionMessage($exception);
}
}
/**
* @return void
*
* @throws PrestaShopDatabaseException|EnvVarException|FirebaseException
*/
private function authorize()
{
$jobId = Tools::getValue('job_id', 'empty_job_id');
$authorizationResponse = $this->authorizationService->authorizeCall($jobId);
if (is_array($authorizationResponse)) {
$this->exitWithResponse($authorizationResponse);
} elseif (!$authorizationResponse) {
throw new PrestaShopDatabaseException('Failed saving job id to database');
}
try {
$token = $this->psAccountsService->getOrRefreshToken();
} catch (Exception $exception) {
throw new FirebaseException($exception->getMessage());
}
if (!$token) {
throw new FirebaseException('Invalid token');
}
}
/**
* @param PaginatedApiDataProviderInterface $dataProvider
*
* @return array
*/
protected function handleDataSync(PaginatedApiDataProviderInterface $dataProvider)
{
$jobId = Tools::getValue('job_id');
$langIso = Tools::getValue('lang_iso', $this->languageRepository->getDefaultLanguageIsoCode());
$limit = (int) Tools::getValue('limit', 50);
if ($limit < 0) {
$this->exitWithExceptionMessage(new QueryParamsException('Invalid URL Parameters', Config::INVALID_URL_QUERY));
}
$initFullSync = (int) Tools::getValue('full', 0) == 1;
$dateNow = (new DateTime())->format(DateTime::ATOM);
$offset = 0;
$incrementalSync = false;
$response = [];
try {
$typeSync = $this->eventbusSyncRepository->findTypeSync($this->type, $langIso);
if ($typeSync !== false && is_array($typeSync)) {
$offset = (int) $typeSync['offset'];
if ((int) $typeSync['full_sync_finished'] === 1 && !$initFullSync) {
$incrementalSync = true;
} elseif ($initFullSync) {
$offset = 0;
$this->eventbusSyncRepository->updateTypeSync($this->type, $offset, $dateNow, false, $langIso);
}
} else {
$this->eventbusSyncRepository->insertTypeSync($this->type, $offset, $dateNow, $langIso);
}
if ($incrementalSync) {
$response = $this->synchronizationService->handleIncrementalSync($dataProvider, $this->type, $jobId, $limit, $langIso, $this->startTime);
} else {
$response = $this->synchronizationService->handleFullSync($dataProvider, $this->type, $jobId, $langIso, $offset, $limit, $dateNow, $this->startTime);
}
return array_merge(
[
'job_id' => $jobId,
'object_type' => $this->type,
],
$response
);
} catch (PrestaShopDatabaseException $exception) {
$this->exitWithExceptionMessage($exception);
} catch (EnvVarException $exception) {
$this->exitWithExceptionMessage($exception);
} catch (FirebaseException $exception) {
$this->exitWithExceptionMessage($exception);
} catch (Exception $exception) {
$this->exitWithExceptionMessage($exception);
}
return $response;
}
/**
* @param array|null $value
* @param string|null $controller
* @param string|null $method
*
* @return void
*
* @throws PrestaShopException
*/
public function ajaxDie($value = null, $controller = null, $method = null)
{
parent::ajaxDie(json_encode($value), $controller, $method);
}
/**
* @param array $response
*
* @return void
*/
protected function exitWithResponse(array $response)
{
$httpCode = isset($response['httpCode']) ? (int) $response['httpCode'] : 200;
$this->dieWithResponse($response, $httpCode);
}
/**
* @param Exception $exception
*
* @return void
*/
protected function exitWithExceptionMessage(Exception $exception)
{
$code = $exception->getCode() == 0 ? 500 : $exception->getCode();
if ($exception instanceof PrestaShopDatabaseException) {
$code = Config::DATABASE_QUERY_ERROR_CODE;
} elseif ($exception instanceof EnvVarException) {
$code = Config::ENV_MISCONFIGURED_ERROR_CODE;
} elseif ($exception instanceof FirebaseException) {
$code = Config::REFRESH_TOKEN_ERROR_CODE;
} elseif ($exception instanceof QueryParamsException) {
$code = Config::INVALID_URL_QUERY;
}
$response = [
'object_type' => $this->type,
'status' => false,
'httpCode' => $code,
'message' => $exception->getMessage(),
];
$this->dieWithResponse($response, (int) $code);
}
/**
* @param array $response
* @param int $code
*
* @return void
*/
private function dieWithResponse(array $response, $code)
{
$httpStatusText = "HTTP/1.1 $code";
if (array_key_exists((int) $code, Config::HTTP_STATUS_MESSAGES)) {
$httpStatusText .= ' ' . Config::HTTP_STATUS_MESSAGES[(int) $code];
} elseif (isset($response['body']['statusText'])) {
$httpStatusText .= ' ' . $response['body']['statusText'];
}
$response['httpCode'] = (int) $code;
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/json;charset=utf-8');
header($httpStatusText);
echo json_encode($response, JSON_UNESCAPED_SLASHES);
exit;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,40 @@
<?php
namespace PrestaShop\Module\PsEventbus\Decorator;
class CategoryDecorator
{
/**
* @param array $categories
*
* @return void
*/
public function decorateCategories(array &$categories)
{
foreach ($categories as &$category) {
$this->castPropertyValues($category);
$this->formatDescription($category);
}
}
/**
* @param array $category
*
* @return void
*/
private function castPropertyValues(array &$category)
{
$category['id_category'] = (int) $category['id_category'];
$category['id_parent'] = (int) $category['id_parent'];
}
/**
* @param array $category
*
* @return void
*/
private function formatDescription(array &$category)
{
$category['description'] = md5($category['description']);
}
}

View File

@@ -0,0 +1,287 @@
<?php
namespace PrestaShop\Module\PsEventbus\Decorator;
use Context;
use PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter;
use PrestaShop\Module\PsEventbus\Repository\CategoryRepository;
use PrestaShop\Module\PsEventbus\Repository\LanguageRepository;
use PrestaShop\Module\PsEventbus\Repository\ProductRepository;
use PrestaShopException;
class ProductDecorator
{
/**
* @var Context
*/
private $context;
/**
* @var LanguageRepository
*/
private $languageRepository;
/**
* @var ProductRepository
*/
private $productRepository;
/**
* @var CategoryRepository
*/
private $categoryRepository;
/**
* @var ArrayFormatter
*/
private $arrayFormatter;
public function __construct(
Context $context,
LanguageRepository $languageRepository,
ProductRepository $productRepository,
CategoryRepository $categoryRepository,
ArrayFormatter $arrayFormatter
) {
$this->context = $context;
$this->languageRepository = $languageRepository;
$this->productRepository = $productRepository;
$this->categoryRepository = $categoryRepository;
$this->arrayFormatter = $arrayFormatter;
}
/**
* @param array $products
* @param string $langIso
* @param int $langId
*
* @throws \PrestaShopDatabaseException
*
* @return void
*/
public function decorateProducts(array &$products, $langIso, $langId)
{
$this->addFeatureValues($products, $langId);
$this->addAttributeValues($products, $langId);
$this->addImages($products);
foreach ($products as &$product) {
$this->addLanguageIsoCode($product, $langIso);
$this->addUniqueId($product);
$this->addAttributeId($product);
$this->addLink($product);
$this->addProductPrices($product);
$this->formatDescriptions($product);
$this->addCategoryTree($product);
$this->castPropertyValues($product);
}
}
/**
* @param array $product
*
* @return void
*/
private function addLink(array &$product)
{
try {
$product['link'] = $this->context->link->getProductLink(
$product,
null,
null,
null,
$this->languageRepository->getLanguageIdByIsoCode($product['iso_code']),
$this->context->shop->id,
$product['id_attribute']
);
} catch (PrestaShopException $e) {
$product['link'] = '';
}
}
/**
* @param array $product
*
* @return void
*/
private function addProductPrices(array &$product)
{
$product['price_tax_excl'] = (float) $product['price_tax_excl'];
$product['price_tax_incl'] =
(float) $this->productRepository->getPriceTaxIncluded($product['id_product'], $product['id_attribute']);
$product['sale_price_tax_excl'] =
(float) $this->productRepository->getSalePriceTaxExcluded($product['id_product'], $product['id_attribute']);
$product['sale_price_tax_incl'] =
(float) $this->productRepository->getSalePriceTaxIncluded($product['id_product'], $product['id_attribute']);
$product['tax'] = $product['price_tax_incl'] - $product['price_tax_excl'];
$product['sale_tax'] = $product['sale_price_tax_incl'] - $product['sale_price_tax_excl'];
$product['sale_date'] = $this->productRepository->getSaleDate($product['id_product'], $product['id_attribute']);
}
/**
* @param array $product
*
* @return void
*/
private function formatDescriptions(array &$product)
{
$product['description'] = base64_encode($product['description']);
$product['description_short'] = base64_encode($product['description_short']);
}
/**
* @param array $product
*
* @return void
*/
private function addCategoryTree(array &$product)
{
$categoryPaths = $this->categoryRepository->getCategoryPaths(
$product['id_category_default'],
$this->languageRepository->getLanguageIdByIsoCode($product['iso_code']),
$this->context->shop->id
);
$product['category_path'] = $categoryPaths['category_path'];
$product['category_id_path'] = $categoryPaths['category_id_path'];
}
/**
* @param array $product
*
* @return void
*/
private function castPropertyValues(array &$product)
{
$product['id_product'] = (int) $product['id_product'];
$product['id_attribute'] = (int) $product['id_attribute'];
$product['id_category_default'] = (int) $product['id_category_default'];
$product['quantity'] = (int) $product['quantity'];
$product['weight'] = (float) $product['weight'];
$product['active'] = $product['active'] == '1';
$product['manufacturer'] = (string) $product['manufacturer'];
$product['default_category'] = (string) $product['default_category'];
$product['isbn'] = isset($product['isbn']) ? (string) $product['isbn'] : '';
$product['ean'] = (string) $product['ean'];
$product['upc'] = (string) $product['upc'];
$product['is_default_attribute'] = $product['id_attribute'] === 0 ? true : $product['is_default_attribute'] === '1';
}
/**
* @param array $product
*
* @return void
*/
private function addUniqueId(array &$product)
{
$product['unique_product_id'] = "{$product['id_product']}-{$product['id_attribute']}-{$product['iso_code']}";
}
/**
* @param array $product
*
* @return void
*/
private function addAttributeId(array &$product)
{
$product['id_product_attribute'] = "{$product['id_product']}-{$product['id_attribute']}";
}
/**
* @param array $product
* @param string $langiso
*
* @return void
*/
private function addLanguageIsoCode(&$product, $langiso)
{
$product['iso_code'] = $langiso;
}
/**
* @param array $products
* @param int $langId
*
* @throws \PrestaShopDatabaseException
*
* @return void
*/
private function addFeatureValues(array &$products, $langId)
{
$productIds = $this->arrayFormatter->formatValueArray($products, 'id_product', true);
$features = $this->productRepository->getProductFeatures($productIds, $langId);
foreach ($products as &$product) {
$product['features'] = isset($features[$product['id_product']]) ? $features[$product['id_product']] : '';
}
}
/**
* @param array $products
* @param int $langId
*
* @throws \PrestaShopDatabaseException
*
* @return void
*/
private function addAttributeValues(array &$products, $langId)
{
$attributeIds = $this->arrayFormatter->formatValueArray($products, 'id_attribute', true);
$attributes = $this->productRepository->getProductAttributeValues($attributeIds, $langId);
foreach ($products as &$product) {
$product['attributes'] = isset($attributes[$product['id_attribute']]) ? $attributes[$product['id_attribute']] : '';
}
}
/**
* @param array $products
*
* @throws \PrestaShopDatabaseException
*
* @return void
*/
private function addImages(array &$products)
{
$productIds = $this->arrayFormatter->formatValueArray($products, 'id_product', true);
$attributeIds = $this->arrayFormatter->formatValueArray($products, 'id_attribute', true);
$images = $this->productRepository->getProductImages($productIds);
$attributeImages = $this->productRepository->getAttributeImages($attributeIds);
foreach ($products as &$product) {
$coverImageId = '0';
$productImages = array_filter($images, function ($image) use ($product) {
return $image['id_product'] === $product['id_product'];
});
foreach ($productImages as $productImage) {
if ($productImage['cover'] === '1') {
$coverImageId = $productImage['id_image'];
break;
}
}
if ($product['id_attribute'] === '0') {
$productImageIds = $this->arrayFormatter->formatValueArray($productImages, 'id_image');
} else {
$productAttributeImages = array_filter($attributeImages, function ($image) use ($product) {
return $image['id_product_attribute'] === $product['id_attribute'];
});
$productImageIds = $this->arrayFormatter->formatValueArray($productAttributeImages, 'id_image');
}
$productImageIds = array_diff($productImageIds, [$coverImageId]);
$product['images'] = $this->arrayFormatter->arrayToString(
array_map(function ($imageId) use ($product) {
return $this->context->link->getImageLink($product['link_rewrite'], (string) $imageId);
}, $productImageIds)
);
$product['cover'] = $coverImageId == '0' ?
'' :
$this->context->link->getImageLink($product['link_rewrite'], (string) $coverImageId);
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Exception;
class ApiException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Exception;
class EnvVarException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Exception;
class FirebaseException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Exception;
class HmacException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Exception;
class PsAccountsRsaSignDataEmptyException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Exception;
class QueryParamsException extends \Exception
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace PrestaShop\Module\PsEventbus\Exception;
class UnauthorizedException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Exception;
class WebhookException extends \Exception
{
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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 PrestaShop\Module\PsEventbus\Factory;
use Context;
class Link
{
/**
* @return \Link
*/
public static function get()
{
return Context::getContext()->link;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,59 @@
<?php
namespace PrestaShop\Module\PsEventbus\Formatter;
class ArrayFormatter
{
/**
* @param array $data
* @param string $separator
*
* @return string
*/
public function arrayToString(array $data, $separator = ';')
{
return implode($separator, $data);
}
/**
* @param array $data
* @param string|int $key
* @param bool $unique
*
* @return array
*/
public function formatValueArray(array $data, $key, $unique = false)
{
$result = array_map(function ($dataItem) use ($key) {
return $dataItem[$key];
}, $data);
if ($unique) {
return $this->unique($result);
}
return $result;
}
/**
* @param array $data
*
* @return array
*/
private function unique(array $data)
{
return array_unique($data);
}
/**
* @param array $data
* @param string|int $key
* @param string $separator
*
* @return string
*/
public function formatValueString(array $data, $key, $separator = ';')
{
return implode($separator, $this->formatValueArray($data, $key));
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace PrestaShop\Module\PsEventbus\Formatter;
class JsonFormatter
{
/**
* @param array $data
*
* @return string
*/
public function formatNewlineJsonString($data)
{
$jsonArray = array_map(function ($dataItem) {
return json_encode($dataItem, JSON_UNESCAPED_SLASHES);
}, $data);
return implode("\r\n", $jsonArray);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Module;
use Tools;
class Install
{
const PARENT_TAB_NAME = -1;
const TAB_ACTIVE = 0;
/**
* @var \Ps_eventbus
*/
private $module;
/**
* @var \Db
*/
private $db;
public function __construct(\Ps_eventbus $module, \Db $db)
{
$this->module = $module;
$this->db = $db;
}
/**
* installInMenu.
*
* @return bool
*/
public function installInMenu()
{
foreach ($this->module->adminControllers as $controllerName) {
$tabId = (int) \Tab::getIdFromClassName($controllerName);
if (!$tabId) {
$tabId = null;
}
$tab = new \Tab($tabId);
$tab->active = (bool) self::TAB_ACTIVE;
$tab->class_name = $controllerName;
$tab->name = [];
foreach (\Language::getLanguages(true) as $lang) {
$tab->name[$lang['id_lang']] = $this->module->displayName;
}
$tab->id_parent = -1 == self::PARENT_TAB_NAME ? (int) \Tab::getIdFromClassName((string) self::PARENT_TAB_NAME) : -1;
$tab->module = $this->module->name;
$tab->save();
}
return true;
}
/**
* Installs database tables
*
* @return bool
*/
public function installDatabaseTables()
{
$dbInstallFile = "{$this->module->getLocalPath()}/sql/install.sql";
if (!file_exists($dbInstallFile)) {
return false;
}
$sql = Tools::file_get_contents($dbInstallFile);
if (empty($sql) || !is_string($sql)) {
return false;
}
$sql = str_replace(['PREFIX_', 'ENGINE_TYPE'], [_DB_PREFIX_, _MYSQL_ENGINE_], $sql);
$sql = preg_split("/;\s*[\r\n]+/", trim($sql));
if (!empty($sql)) {
foreach ($sql as $query) {
if (!$this->db->execute($query)) {
return false;
}
}
}
$this->copyDataFromPsAccounts();
return true;
}
/**
* @return void
*/
private function copyDataFromPsAccounts()
{
$dbInstallFile = "{$this->module->getLocalPath()}/sql/migrate.sql";
if (!file_exists($dbInstallFile)) {
return;
}
$sql = Tools::file_get_contents($dbInstallFile);
if (empty($sql) || !is_string($sql)) {
return;
}
$sql = str_replace(['PREFIX_', 'ENGINE_TYPE'], [_DB_PREFIX_, _MYSQL_ENGINE_], $sql);
$sql = preg_split("/;\s*[\r\n]+/", trim($sql));
if (!empty($sql)) {
foreach ($sql as $query) {
try {
$this->db->execute($query);
} catch (\Exception $exception) {
}
}
}
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\PsEventbus\Module;
use Tools;
class Uninstall
{
/**
* @var \Ps_eventbus
*/
private $module;
/**
* @var \Db
*/
private $db;
public function __construct(\Ps_eventbus $module, \Db $db)
{
$this->module = $module;
$this->db = $db;
}
/**
* uninstallMenu.
*
* @return bool
*/
public function uninstallMenu()
{
// foreach( ['configure', 'hmac', 'ajax'] as $aliasController){
foreach ($this->module->adminControllers as $controllerName) {
$tabId = (int) \Tab::getIdFromClassName($controllerName);
if (!$tabId) {
return true;
}
$tab = new \Tab($tabId);
return $tab->delete();
}
return true;
}
/**
* @return bool
*/
public function uninstallDatabaseTables()
{
$dbUninstallFile = "{$this->module->getLocalPath()}/sql/uninstall.sql";
if (!file_exists($dbUninstallFile)) {
return false;
}
$sql = Tools::file_get_contents($dbUninstallFile);
if (empty($sql) || !is_string($sql)) {
return false;
}
$sql = str_replace(['PREFIX_', 'ENGINE_TYPE'], [_DB_PREFIX_, _MYSQL_ENGINE_], $sql);
$sql = preg_split("/;\s*[\r\n]+/", trim($sql));
if (!empty($sql)) {
foreach ($sql as $query) {
if (!$this->db->execute($query)) {
return false;
}
}
}
return true;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,175 @@
<?php
namespace PrestaShop\Module\PsEventbus\Provider;
use PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter;
use PrestaShop\Module\PsEventbus\Repository\CartProductRepository;
use PrestaShop\Module\PsEventbus\Repository\CartRepository;
class CartDataProvider implements PaginatedApiDataProviderInterface
{
/**
* @var CartRepository
*/
private $cartRepository;
/**
* @var CartProductRepository
*/
private $cartProductRepository;
/**
* @var ArrayFormatter
*/
private $arrayFormatter;
/**
* @param CartRepository $cartRepository
* @param CartProductRepository $cartProductRepository
* @param ArrayFormatter $arrayFormatter
*/
public function __construct(
CartRepository $cartRepository,
CartProductRepository $cartProductRepository,
ArrayFormatter $arrayFormatter
) {
$this->cartRepository = $cartRepository;
$this->cartProductRepository = $cartProductRepository;
$this->arrayFormatter = $arrayFormatter;
}
public function getFormattedData($offset, $limit, $langIso)
{
$carts = $this->cartRepository->getCarts($offset, $limit);
if (!is_array($carts)) {
return [];
}
$cartProducts = $this->getCartProducts($carts);
$this->castCartValues($carts);
$carts = array_map(function ($cart) {
return [
'id' => $cart['id_cart'],
'collection' => 'carts',
'properties' => $cart,
];
}, $carts);
return array_merge($carts, $cartProducts);
}
/**
* @param int $offset
* @param string $langIso
*
* @return int
*/
public function getRemainingObjectsCount($offset, $langIso)
{
return (int) $this->cartRepository->getRemainingCartsCount($offset);
}
/**
* @param array $carts
*
* @return void
*/
private function castCartValues(array &$carts)
{
foreach ($carts as &$cart) {
$cart['id_cart'] = (string) $cart['id_cart'];
}
}
/**
* @param array $cartProducts
*
* @return void
*/
private function castCartProductValues(array &$cartProducts)
{
foreach ($cartProducts as &$cartProduct) {
$cartProduct['id_cart_product'] = (string) "{$cartProduct['id_cart']}-{$cartProduct['id_product']}-{$cartProduct['id_product_attribute']}";
$cartProduct['id_cart'] = (string) $cartProduct['id_cart'];
$cartProduct['id_product'] = (string) $cartProduct['id_product'];
$cartProduct['id_product_attribute'] = (string) $cartProduct['id_product_attribute'];
$cartProduct['quantity'] = (int) $cartProduct['quantity'];
}
}
public function getFormattedDataIncremental($limit, $langIso)
{
$carts = $this->cartRepository->getCartsIncremental($limit);
if (!is_array($carts) || empty($carts)) {
return [
'ids' => [],
'data' => [],
];
}
$cartIds = $this->separateCartIds($carts);
$cartProducts = $this->getCartProducts($carts);
$this->castCartValues($carts);
$carts = array_map(function ($cart) {
return [
'id' => $cart['id_cart'],
'collection' => 'carts',
'properties' => $cart,
];
}, $carts);
return [
'ids' => $cartIds,
'data' => array_merge($carts, $cartProducts),
];
}
/**
* @param array $carts
*
* @return array
*
* @throws \PrestaShopDatabaseException
*/
private function getCartProducts(array $carts)
{
$cartIds = array_map(function ($cart) {
return (string) $cart['id_cart'];
}, $carts);
$cartProducts = $this->cartProductRepository->getCartProducts($cartIds);
if (!is_array($cartProducts) || empty($cartProducts)) {
return [];
}
$this->castCartProductValues($cartProducts);
if (is_array($cartProducts)) {
return array_map(function ($cartProduct) {
return [
'id' => "{$cartProduct['id_cart']}-{$cartProduct['id_product']}-{$cartProduct['id_product_attribute']}",
'collection' => 'cart_products',
'properties' => $cartProduct,
];
}, $cartProducts);
}
return [];
}
/**
* @param array $carts
*
* @return array
*/
private function separateCartIds(array $carts)
{
return $this->arrayFormatter->formatValueArray($carts, 'id_order', true);
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace PrestaShop\Module\PsEventbus\Provider;
use PrestaShop\Module\PsEventbus\Decorator\CategoryDecorator;
use PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter;
use PrestaShop\Module\PsEventbus\Repository\CategoryRepository;
class CategoryDataProvider implements PaginatedApiDataProviderInterface
{
/**
* @var CategoryRepository
*/
private $categoryRepository;
/**
* @var CategoryDecorator
*/
private $categoryDecorator;
/**
* @var ArrayFormatter
*/
private $arrayFormatter;
public function __construct(CategoryRepository $categoryRepository, CategoryDecorator $categoryDecorator, ArrayFormatter $arrayFormatter)
{
$this->categoryRepository = $categoryRepository;
$this->categoryDecorator = $categoryDecorator;
$this->arrayFormatter = $arrayFormatter;
}
/**
* @param int $offset
* @param int $limit
* @param string $langIso
*
* @return array
*
* @throws \PrestaShopDatabaseException
*/
public function getFormattedData($offset, $limit, $langIso)
{
$categories = $this->categoryRepository->getCategories($offset, $limit, $langIso);
if (!is_array($categories)) {
return [];
}
$this->categoryDecorator->decorateCategories($categories);
return array_map(function ($category) {
return [
'id' => "{$category['id_category']}-{$category['iso_code']}",
'collection' => 'categories',
'properties' => $category,
];
}, $categories);
}
/**
* @param int $offset
* @param string $langIso
*
* @return int
*/
public function getRemainingObjectsCount($offset, $langIso)
{
return (int) $this->categoryRepository->getRemainingCategoriesCount($offset, $langIso);
}
public function getFormattedDataIncremental($limit, $langIso)
{
$categories = $this->categoryRepository->getCategoriesIncremental($limit, $langIso);
if (!is_array($categories)) {
return [];
}
$categoryIds = $this->separateCategoryIds($categories);
$this->categoryDecorator->decorateCategories($categories);
$categories = array_map(function ($category) {
return [
'id' => "{$category['id_category']}-{$category['iso_code']}",
'collection' => 'categories',
'properties' => $category,
];
}, $categories);
return [
'data' => $categories,
'ids' => $categoryIds,
];
}
/**
* @param array $categories
*
* @return array
*/
private function separateCategoryIds(array $categories)
{
return $this->arrayFormatter->formatValueArray($categories, 'id_category', true);
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace PrestaShop\Module\PsEventbus\Provider;
use Context;
use PrestaShop\Module\PsEventbus\Repository\GoogleTaxonomyRepository;
class GoogleTaxonomyDataProvider implements PaginatedApiDataProviderInterface
{
/**
* @var GoogleTaxonomyRepository
*/
private $googleTaxonomyRepository;
/**
* @var Context
*/
private $context;
public function __construct(GoogleTaxonomyRepository $googleTaxonomyRepository, Context $context)
{
$this->googleTaxonomyRepository = $googleTaxonomyRepository;
$this->context = $context;
}
public function getFormattedData($offset, $limit, $langIso)
{
$data = $this->googleTaxonomyRepository->getTaxonomyCategories($offset, $limit, $this->context->shop->id);
if (!is_array($data)) {
return [];
}
return array_map(function ($googleTaxonomy) {
$uniqueId = "{$googleTaxonomy['id_category']}-{$googleTaxonomy['id_category']}";
$googleTaxonomy['taxonomy_id'] = $uniqueId;
return [
'id' => $uniqueId,
'collection' => 'taxonomies',
'properties' => $googleTaxonomy,
];
}, $data);
}
public function getRemainingObjectsCount($offset, $langIso)
{
return (int) $this->googleTaxonomyRepository->getRemainingTaxonomyRepositories($offset, $this->context->shop->id);
}
public function getFormattedDataIncremental($limit, $langIso)
{
return [
'ids' => [],
'data' => [],
];
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace PrestaShop\Module\PsEventbus\Provider;
use PrestaShop\Module\PsEventbus\Repository\ModuleRepository;
use PrestaShopDatabaseException;
class ModuleDataProvider implements PaginatedApiDataProviderInterface
{
/**
* @var ModuleRepository
*/
private $moduleRepository;
public function __construct(ModuleRepository $moduleRepository)
{
$this->moduleRepository = $moduleRepository;
}
/**
* @param int $offset
* @param int $limit
* @param string $langIso
*
* @return array
*/
public function getFormattedData($offset, $limit, $langIso)
{
try {
$modules = $this->moduleRepository->getModules($offset, $limit);
} catch (PrestaShopDatabaseException $e) {
return [];
}
if (!is_array($modules)) {
return [];
}
return array_map(function ($module) {
$moduleId = (string) $module['module_id'];
$module['active'] = $module['active'] == '1';
return [
'id' => $moduleId,
'collection' => 'modules',
'properties' => $module,
];
}, $modules);
}
/**
* @param int $offset
* @param string $langIso
*
* @return int
*/
public function getRemainingObjectsCount($offset, $langIso)
{
return (int) $this->moduleRepository->getRemainingModules($offset);
}
public function getFormattedDataIncremental($limit, $langIso = null)
{
return [
'ids' => [],
'data' => [],
];
}
}

View File

@@ -0,0 +1,214 @@
<?php
namespace PrestaShop\Module\PsEventbus\Provider;
use Context;
use PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter;
use PrestaShop\Module\PsEventbus\Repository\OrderDetailsRepository;
use PrestaShop\Module\PsEventbus\Repository\OrderRepository;
use PrestaShopDatabaseException;
class OrderDataProvider implements PaginatedApiDataProviderInterface
{
/**
* @var OrderRepository
*/
private $orderRepository;
/**
* @var Context
*/
private $context;
/**
* @var ArrayFormatter
*/
private $arrayFormatter;
/**
* @var OrderDetailsRepository
*/
private $orderDetailsRepository;
public function __construct(
Context $context,
OrderRepository $orderRepository,
OrderDetailsRepository $orderDetailsRepository,
ArrayFormatter $arrayFormatter
) {
$this->orderRepository = $orderRepository;
$this->context = $context;
$this->arrayFormatter = $arrayFormatter;
$this->orderDetailsRepository = $orderDetailsRepository;
}
/**
* @param int $offset
* @param int $limit
* @param string $langIso
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getFormattedData($offset, $limit, $langIso)
{
$orders = $this->orderRepository->getOrders($offset, $limit, $this->context->shop->id);
if (!is_array($orders)) {
return [];
}
$this->castOrderValues($orders);
$orderDetails = $this->getOrderDetails($orders, $this->context->shop->id);
$orders = array_map(function ($order) {
return [
'id' => $order['id_order'],
'collection' => 'orders',
'properties' => $order,
];
}, $orders);
return array_merge($orders, $orderDetails);
}
/**
* @param int $offset
* @param string $langIso
*
* @return int
*/
public function getRemainingObjectsCount($offset, $langIso)
{
return (int) $this->orderRepository->getRemainingOrderCount($offset, $this->context->shop->id);
}
/**
* @param array $orders
* @param int $shopId
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
private function getOrderDetails(array $orders, $shopId)
{
if (empty($orders)) {
return [];
}
$orderIds = $this->arrayFormatter->formatValueArray($orders, 'id_order');
$orderDetails = $this->orderDetailsRepository->getOrderDetails($orderIds, $shopId);
if (!is_array($orderDetails) || empty($orderDetails)) {
return [];
}
$this->castOrderDetailValues($orderDetails);
$orderDetails = array_map(function ($orderDetail) {
return [
'id' => $orderDetail['id_order_detail'],
'collection' => 'order_details',
'properties' => $orderDetail,
];
}, $orderDetails);
return $orderDetails;
}
/**
* @param array $orders
*
* @return void
*/
public function castOrderValues(array &$orders)
{
foreach ($orders as &$order) {
$order['id_order'] = (int) $order['id_order'];
$order['id_customer'] = (int) $order['id_customer'];
$order['current_state'] = (int) $order['current_state'];
$order['conversion_rate'] = (float) $order['conversion_rate'];
$order['total_paid_tax_incl'] = (float) $order['total_paid_tax_incl'];
$order['total_paid_tax_excl'] = (float) $order['total_paid_tax_excl'];
$order['refund'] = (float) $order['refund'];
$order['refund_tax_excl'] = (float) $order['refund_tax_excl'];
$order['new_customer'] = $order['new_customer'] === '1';
$order['is_paid'] = (float) $order['total_paid_real'] >= (float) $order['total_paid_tax_incl'];
$order['shipping_cost'] = (float) $order['shipping_cost'];
$order['total_paid_tax'] = $order['total_paid_tax_incl'] - $order['total_paid_tax_excl'];
}
}
/**
* @param array $orderDetails
*
* @return void
*/
private function castOrderDetailValues(array &$orderDetails)
{
foreach ($orderDetails as &$orderDetail) {
$orderDetail['id_order_detail'] = (int) $orderDetail['id_order_detail'];
$orderDetail['id_order'] = (int) $orderDetail['id_order'];
$orderDetail['product_id'] = (int) $orderDetail['product_id'];
$orderDetail['product_attribute_id'] = (int) $orderDetail['product_attribute_id'];
$orderDetail['product_quantity'] = (int) $orderDetail['product_quantity'];
$orderDetail['unit_price_tax_incl'] = (float) $orderDetail['unit_price_tax_incl'];
$orderDetail['unit_price_tax_excl'] = (float) $orderDetail['unit_price_tax_excl'];
$orderDetail['refund'] = (float) $orderDetail['refund'] > 0 ? -1 * (float) $orderDetail['refund'] : 0;
$orderDetail['refund_tax_excl'] = (float) $orderDetail['refund_tax_excl'] > 0 ? -1 * (float) $orderDetail['refund_tax_excl'] : 0;
$orderDetail['category'] = (int) $orderDetail['category'];
$orderDetail['unique_product_id'] = "{$orderDetail['product_id']}-{$orderDetail['product_attribute_id']}-{$orderDetail['iso_code']}";
$orderDetail['conversion_rate'] = (float) $orderDetail['conversion_rate'];
}
}
/**
* @param int $limit
* @param string $langIso
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getFormattedDataIncremental($limit, $langIso)
{
$orders = $this->orderRepository->getOrdersIncremental($limit, $this->context->shop->id);
if (!is_array($orders) || empty($orders)) {
return [
'ids' => [],
'data' => [],
];
}
$orderIds = $this->separateOrderIds($orders);
$this->castOrderValues($orders);
$orderDetails = $this->getOrderDetails($orders, $this->context->shop->id);
$orders = array_map(function ($order) {
return [
'id' => $order['id_order'],
'collection' => 'orders',
'properties' => $order,
];
}, $orders);
return [
'data' => array_merge($orders, $orderDetails),
'ids' => $orderIds,
];
}
/**
* @param array $orders
*
* @return array
*/
private function separateOrderIds(array $orders)
{
return $this->arrayFormatter->formatValueArray($orders, 'id_order', true);
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace PrestaShop\Module\PsEventbus\Provider;
use PrestaShopDatabaseException;
interface PaginatedApiDataProviderInterface
{
/**
* @param int $offset
* @param int $limit
* @param string $langIso
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getFormattedData($offset, $limit, $langIso);
/**
* @param int $offset
* @param string $langIso
*
* @return int
*
* @throws PrestaShopDatabaseException
*/
public function getRemainingObjectsCount($offset, $langIso);
/**
* @param int $limit
* @param string $langIso
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getFormattedDataIncremental($limit, $langIso);
}

View File

@@ -0,0 +1,132 @@
<?php
namespace PrestaShop\Module\PsEventbus\Provider;
use PrestaShop\Module\PsEventbus\Decorator\ProductDecorator;
use PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter;
use PrestaShop\Module\PsEventbus\Repository\LanguageRepository;
use PrestaShop\Module\PsEventbus\Repository\ProductRepository;
class ProductDataProvider implements PaginatedApiDataProviderInterface
{
/**
* @var ProductRepository
*/
private $productRepository;
/**
* @var ProductDecorator
*/
private $productDecorator;
/**
* @var LanguageRepository
*/
private $languageRepository;
/**
* @var ArrayFormatter
*/
private $arrayFormatter;
public function __construct(
ProductRepository $productRepository,
ProductDecorator $productDecorator,
LanguageRepository $languageRepository,
ArrayFormatter $arrayFormatter
) {
$this->productRepository = $productRepository;
$this->productDecorator = $productDecorator;
$this->languageRepository = $languageRepository;
$this->arrayFormatter = $arrayFormatter;
}
/**
* @param int $offset
* @param int $limit
* @param string $langIso
*
* @return array
*
* @throws \PrestaShopDatabaseException
*/
public function getFormattedData($offset, $limit, $langIso)
{
$langId = $this->languageRepository->getLanguageIdByIsoCode($langIso);
$products = $this->productRepository->getProducts($offset, $limit, $langId);
$this->productDecorator->decorateProducts($products, $langIso, $langId);
return array_map(function ($product) {
return [
'id' => $product['unique_product_id'],
'collection' => 'products',
'properties' => $product,
];
}, $products);
}
/**
* @param int $offset
* @param string $langIso
*
* @return int
*
* @throws \PrestaShopDatabaseException
*/
public function getRemainingObjectsCount($offset, $langIso)
{
$langId = $this->languageRepository->getLanguageIdByIsoCode($langIso);
return (int) $this->productRepository->getRemainingProductsCount($offset, $langId);
}
/**
* @param int $limit
* @param string $langIso
*
* @return array
*
* @throws \PrestaShopDatabaseException
*/
public function getFormattedDataIncremental($limit, $langIso)
{
$langId = $this->languageRepository->getLanguageIdByIsoCode($langIso);
$products = $this->productRepository->getProductsIncremental($limit, $langIso, $langId);
$productIds = $this->separateProductIds($products, count($products) < $limit);
if (!empty($products)) {
$this->productDecorator->decorateProducts($products, $langIso, $langId);
}
$data = array_map(function ($product) {
return [
'id' => $product['unique_product_id'],
'collection' => 'products',
'properties' => $product,
];
}, $products);
return [
'data' => $data,
'ids' => $productIds,
];
}
/**
* @param array $products
* @param bool $includeLast
*
* @return array
*/
private function separateProductIds($products, $includeLast)
{
$productIds = $this->arrayFormatter->formatValueArray($products, 'id_product', true);
if (!$includeLast) {
array_pop($productIds);
}
return $productIds;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,58 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
class CartProductRepository
{
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
/**
* @return DbQuery
*/
public function getBaseQuery()
{
$query = new DbQuery();
$query->from('cart_product', 'cp')
->where('cp.id_shop = ' . (int) $this->context->shop->id);
return $query;
}
/**
* @param array $cartIds
*
* @return array|bool|\mysqli_result|\PDOStatement|resource|null
*
* @throws \PrestaShopDatabaseException
*/
public function getCartProducts(array $cartIds)
{
$query = $this->getBaseQuery();
$query->select('cp.id_cart, cp.id_product, cp.id_product_attribute, cp.quantity, cp.date_add as created_at');
if (!empty($cartIds)) {
$query->where('cp.id_cart IN (' . implode(',', array_map('intval', $cartIds)) . ')');
}
return $this->db->executeS($query);
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
use mysqli_result;
use PDOStatement;
use PrestaShopDatabaseException;
class CartRepository
{
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
/**
* @return DbQuery
*/
private function getBaseQuery()
{
$query = new DbQuery();
$query->from('cart', 'c')
->where('c.id_shop = ' . (int) $this->context->shop->id);
return $query;
}
/**
* @param int $offset
* @param int $limit
*
* @return array|bool|mysqli_result|PDOStatement|resource|null
*
* @throws PrestaShopDatabaseException
*/
public function getCarts($offset, $limit)
{
$query = $this->getBaseQuery();
$this->addSelectParameters($query);
$query->limit($limit, $offset);
return $this->db->executeS($query);
}
/**
* @param int $offset
*
* @return int
*/
public function getRemainingCartsCount($offset)
{
$query = $this->getBaseQuery();
$query->select('(COUNT(c.id_cart) - ' . (int) $offset . ') as count');
return (int) $this->db->getValue($query);
}
/**
* @param int $limit
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getCartsIncremental($limit)
{
$query = $this->getBaseQuery();
$this->addSelectParameters($query);
$query->innerJoin(
IncrementalSyncRepository::INCREMENTAL_SYNC_TABLE,
'aic',
'aic.id_object = c.id_cart AND aic.id_shop = c.id_shop AND aic.type = "carts"'
)
->limit($limit);
$result = $this->db->executeS($query);
return is_array($result) ? $result : [];
}
/**
* @param DbQuery $query
*
* @return void
*/
private function addSelectParameters(DbQuery $query)
{
$query->select('c.id_cart, date_add as created_at, date_upd as updated_at');
}
}

View File

@@ -0,0 +1,217 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
use mysqli_result;
use PDOStatement;
use PrestaShopDatabaseException;
class CategoryRepository
{
/**
* @var Db
*/
private $db;
/**
* @var array
*/
private $categoryLangCache;
/**
* @var Context
*/
private $context;
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
/**
* @param int $shopId
* @param string $langIso
*
* @return DbQuery
*/
public function getBaseQuery($shopId, $langIso)
{
$query = new DbQuery();
$query->from('category_shop', 'cs')
->innerJoin('category', 'c', 'cs.id_category = c.id_category')
->leftJoin('category_lang', 'cl', 'cl.id_category = cs.id_category')
->leftJoin('lang', 'l', 'l.id_lang = cl.id_lang')
->where('cs.id_shop = ' . (int) $shopId)
->where('cl.id_shop = cs.id_shop')
->where('l.iso_code = "' . pSQL($langIso) . '"');
return $query;
}
/**
* @param int $topCategoryId
* @param int $langId
* @param int $shopId
*
* @return array
*/
public function getCategoryPaths($topCategoryId, $langId, $shopId)
{
if ((int) $topCategoryId === 0) {
return [
'category_path' => '',
'category_id_path' => '',
];
}
$categories = [];
try {
$categoriesWithParentsInfo = $this->getCategoriesWithParentInfo($langId, $shopId);
} catch (PrestaShopDatabaseException $e) {
return [
'category_path' => '',
'category_id_path' => '',
];
}
$this->buildCategoryPaths($categoriesWithParentsInfo, $topCategoryId, $categories);
$categories = array_reverse($categories);
return [
'category_path' => implode(' > ', array_map(function ($category) {
return $category['name'];
}, $categories)),
'category_id_path' => implode(' > ', array_map(function ($category) {
return $category['id_category'];
}, $categories)),
];
}
/**
* @param array $categoriesWithParentsInfo
* @param int $currentCategoryId
* @param array $categories
*
* @return void
*/
private function buildCategoryPaths($categoriesWithParentsInfo, $currentCategoryId, &$categories)
{
foreach ($categoriesWithParentsInfo as $category) {
if ($category['id_category'] == $currentCategoryId) {
$categories[] = $category;
$this->buildCategoryPaths($categoriesWithParentsInfo, $category['id_parent'], $categories);
}
}
}
/**
* @param int $langId
* @param int $shopId
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getCategoriesWithParentInfo($langId, $shopId)
{
if (!isset($this->categoryLangCache[$langId])) {
$query = new DbQuery();
$query->select('c.id_category, cl.name, c.id_parent')
->from('category', 'c')
->leftJoin(
'category_lang',
'cl',
'cl.id_category = c.id_category AND cl.id_shop = ' . (int) $shopId
)
->where('cl.id_lang = ' . (int) $langId)
->orderBy('cl.id_category');
$result = $this->db->executeS($query);
if (is_array($result)) {
$this->categoryLangCache[$langId] = $result;
} else {
throw new PrestaShopDatabaseException('No categories found');
}
}
return $this->categoryLangCache[$langId];
}
/**
* @param int $offset
* @param int $limit
* @param string $langIso
*
* @return array|bool|mysqli_result|PDOStatement|resource|null
*
* @throws PrestaShopDatabaseException
*/
public function getCategories($offset, $limit, $langIso)
{
$query = $this->getBaseQuery($this->context->shop->id, $langIso);
$this->addSelectParameters($query);
$query->limit($limit, $offset);
return $this->db->executeS($query);
}
/**
* @param int $offset
* @param string $langIso
*
* @return int
*/
public function getRemainingCategoriesCount($offset, $langIso)
{
$query = $this->getBaseQuery($this->context->shop->id, $langIso)
->select('(COUNT(cs.id_category) - ' . (int) $offset . ') as count');
return (int) $this->db->getValue($query);
}
/**
* @param int $limit
* @param string $langIso
*
* @return array|bool|mysqli_result|PDOStatement|resource|null
*
* @throws PrestaShopDatabaseException
*/
public function getCategoriesIncremental($limit, $langIso)
{
$query = $this->getBaseQuery($this->context->shop->id, $langIso);
$this->addSelectParameters($query);
$query->innerJoin(
IncrementalSyncRepository::INCREMENTAL_SYNC_TABLE,
'aic',
'aic.id_object = cs.id_category AND aic.id_shop = cs.id_shop AND aic.type = "categories" and aic.lang_iso = "' . pSQL($langIso) . '"'
)
->limit($limit);
return $this->db->executeS($query);
}
/**
* @param DbQuery $query
*
* @return void
*/
private function addSelectParameters(DbQuery $query)
{
$query->select('CONCAT(cs.id_category, "-", l.iso_code) as unique_category_id, cs.id_category,
c.id_parent, cl.name, cl.description, cl.link_rewrite, cl.meta_title, cl.meta_keywords, cl.meta_description,
l.iso_code, c.date_add as created_at, c.date_upd as updated_at');
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Configuration;
class ConfigurationRepository
{
/**
* We wrap Configuration::get function in here to be able to mock static functions
*
* @param string $key
*
* @return bool|string
*/
public function get($key)
{
return Configuration::get($key);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Currency;
class CurrencyRepository
{
/**
* @return array
*/
public function getCurrenciesIsoCodes()
{
$currencies = Currency::getCurrencies();
return array_map(function ($currency) {
return $currency['iso_code'];
}, $currencies);
}
/**
* @return string
*/
public function getDefaultCurrencyIsoCode()
{
$currency = Currency::getDefaultCurrency();
return $currency instanceof Currency ? $currency->iso_code : '';
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
class DeletedObjectsRepository
{
const DELETED_OBJECTS_TABLE = 'eventbus_deleted_objects';
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
/**
* @param int $shopId
*
* @return array
*
* @throws \PrestaShopDatabaseException
*/
public function getDeletedObjectsGrouped($shopId)
{
$query = new DbQuery();
$query->select('type, GROUP_CONCAT(id_object SEPARATOR ";") as ids')
->from(self::DELETED_OBJECTS_TABLE)
->where('id_shop = ' . (int) $shopId)
->groupBy('type');
$result = $this->db->executeS($query);
return is_array($result) ? $result : [];
}
/**
* @param int $objectId
* @param string $objectType
* @param string $date
* @param int $shopId
*
* @return bool
*/
public function insertDeletedObject($objectId, $objectType, $date, $shopId)
{
try {
return $this->db->insert(
self::DELETED_OBJECTS_TABLE,
[
'id_shop' => $shopId,
'id_object' => $objectId,
'type' => $objectType,
'created_at' => $date,
],
false,
true,
Db::ON_DUPLICATE_KEY
);
} catch (\PrestaShopDatabaseException $e) {
return false;
}
}
/**
* @param string $type
* @param array $objectIds
* @param int $shopId
*
* @return bool
*/
public function removeDeletedObjects($type, $objectIds, $shopId)
{
return $this->db->delete(
self::DELETED_OBJECTS_TABLE,
'type = "' . pSQL($type) . '"
AND id_shop = ' . $shopId . '
AND id_object IN(' . implode(',', $objectIds) . ')'
);
}
}

View File

@@ -0,0 +1,156 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
use PrestaShop\Module\PsEventbus\Config\Config;
use PrestaShopDatabaseException;
class EventbusSyncRepository
{
const TYPE_SYNC_TABLE_NAME = 'eventbus_type_sync';
const JOB_TABLE_NAME = 'eventbus_job';
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
/**
* @param string $type
* @param int $offset
* @param string $lastSyncDate
* @param string $langIso
*
* @return bool
*
* @throws \PrestaShopDatabaseException
*/
public function insertTypeSync($type, $offset, $lastSyncDate, $langIso = null)
{
$result = $this->db->insert(
self::TYPE_SYNC_TABLE_NAME,
[
'id_shop' => (int) $this->context->shop->id,
'type' => pSQL((string) $type),
'offset' => (int) $offset,
'last_sync_date' => pSQL((string) $lastSyncDate),
'lang_iso' => pSQL((string) $langIso),
]
);
if (!$result) {
throw new PrestaShopDatabaseException('Failed to insert type sync', Config::DATABASE_INSERT_ERROR_CODE);
}
return $result;
}
/**
* @param string $jobId
* @param string $date
*
* @return bool
*
* @throws \PrestaShopDatabaseException
*/
public function insertJob($jobId, $date)
{
return $this->db->insert(
self::JOB_TABLE_NAME,
[
'job_id' => pSQL($jobId),
'created_at' => pSQL($date),
]
);
}
/**
* @param string $jobId
*
* @return array|bool|false|object|null
*/
public function findJobById($jobId)
{
$query = new DbQuery();
$query->select('*')
->from(self::JOB_TABLE_NAME)
->where('job_id = "' . pSQL($jobId) . '"');
return $this->db->getRow($query);
}
/**
* @param string $type
* @param string $langIso
*
* @return array|bool|object|null
*/
public function findTypeSync($type, $langIso = null)
{
$query = new DbQuery();
$query->select('*')
->from(self::TYPE_SYNC_TABLE_NAME)
->where('type = "' . pSQL($type) . '"')
->where('lang_iso = "' . pSQL((string) $langIso) . '"')
->where('id_shop = ' . (int) $this->context->shop->id);
return $this->db->getRow($query);
}
/**
* @param string $type
* @param int $offset
* @param string $date
* @param bool $fullSyncFinished
* @param string $langIso
*
* @return bool
*/
public function updateTypeSync($type, $offset, $date, $fullSyncFinished, $langIso = null)
{
return $this->db->update(
self::TYPE_SYNC_TABLE_NAME,
[
'offset' => (int) $offset,
'full_sync_finished' => (int) $fullSyncFinished,
'last_sync_date' => pSQL($date),
],
'type = "' . pSQL($type) . '"
AND lang_iso = "' . pSQL((string) $langIso) . '"
AND id_shop = ' . $this->context->shop->id
);
}
/**
* @param string $type
* @param bool $fullSyncFinished
* @param string $langIso
*
* @return bool
*/
public function updateFullSyncStatus($type, $fullSyncFinished, $langIso = null)
{
return $this->db->update(
self::TYPE_SYNC_TABLE_NAME,
[
'full_sync_finished' => (int) $fullSyncFinished,
],
'type = "' . pSQL($type) . '"
AND lang_iso = "' . pSQL((string) $langIso) . '"
AND id_shop = ' . $this->context->shop->id
);
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Db;
use DbQuery;
class GoogleTaxonomyRepository
{
/**
* @var Db
*/
private $db;
public function __construct(Db $db)
{
$this->db = $db;
}
/**
* @param int $shopId
*
* @return DbQuery
*/
public function getBaseQuery($shopId)
{
$query = new DbQuery();
$query->from('fb_category_match', 'cm')
->where('cm.id_shop = ' . (int) $shopId);
return $query;
}
/**
* @param int $offset
* @param int $limit
* @param int $shopId
*
* @return array|bool|\mysqli_result|\PDOStatement|resource|null
*
* @throws \PrestaShopDatabaseException
*/
public function getTaxonomyCategories($offset, $limit, $shopId)
{
$query = $this->getBaseQuery($shopId);
$query->select('cm.id_category, cm.google_category_id')
->limit($limit, $offset);
return $this->db->executeS($query);
}
/**
* @param int $offset
* @param int $shopId
*
* @return int
*/
public function getRemainingTaxonomyRepositories($offset, $shopId)
{
$query = $this->getBaseQuery($shopId);
$query->select('(COUNT(cm.id_category) - ' . (int) $offset . ') as count');
return (int) $this->db->getValue($query);
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Db;
use DbQuery;
class ImageRepository
{
/**
* @var Db
*/
private $db;
public function __construct(Db $db)
{
$this->db = $db;
}
/**
* @param int $productId
* @param int $shopId
*
* @return false|string|null
*/
public function getProductCoverImage($productId, $shopId)
{
$query = new DbQuery();
$query->select('imgs.id_image')
->from('image_shop', 'imgs')
->where('imgs.cover = 1')
->where('imgs.id_shop = ' . (int) $shopId)
->where('imgs.id_product = ' . (int) $productId);
return $this->db->getValue($query);
}
/**
* @param int $productId
* @param int $attributeId
* @param int $shopId
* @param bool $includeCover
*
* @return array|bool|\mysqli_result|\PDOStatement|resource|null
*
* @throws \PrestaShopDatabaseException
*/
public function getProductImages($productId, $attributeId, $shopId, $includeCover = false)
{
$query = new DbQuery();
$query->select('imgs.id_image')
->from('image_shop', 'imgs')
->leftJoin('image', 'img', 'imgs.id_image = img.id_image')
->where('imgs.id_shop = ' . (int) $shopId)
->where('imgs.id_product = ' . (int) $productId)
->orderBy('img.position ASC');
if ((int) $attributeId !== 0) {
$query->innerJoin(
'product_attribute_image',
'pai',
'imgs.id_image = pai.id_image AND pai.id_product_attribute = ' . (int) $attributeId
);
}
if (!$includeCover) {
$query->where('(imgs.cover IS NULL OR imgs.cover = 0)');
}
return $this->db->executeS($query);
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
class IncrementalSyncRepository
{
const INCREMENTAL_SYNC_TABLE = 'eventbus_incremental_sync';
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
/**
* @param int $objectId
* @param string $objectType
* @param string $date
* @param int $shopId
* @param string $langIso
*
* @return bool
*/
public function insertIncrementalObject($objectId, $objectType, $date, $shopId, $langIso)
{
try {
return $this->db->insert(
self::INCREMENTAL_SYNC_TABLE,
[
'id_shop' => $shopId,
'id_object' => $objectId,
'type' => $objectType,
'created_at' => $date,
'lang_iso' => $langIso,
],
false,
true,
Db::ON_DUPLICATE_KEY
);
} catch (\PrestaShopDatabaseException $e) {
return false;
}
}
/**
* @param string $type
* @param array $objectIds
* @param string $langIso
*
* @return bool
*/
public function removeIncrementalSyncObjects($type, $objectIds, $langIso)
{
return $this->db->delete(
self::INCREMENTAL_SYNC_TABLE,
'type = "' . pSQL($type) . '"
AND id_shop = ' . $this->context->shop->id . '
AND id_object IN(' . implode(',', $objectIds) . ')
AND lang_iso = "' . pSQL($langIso) . '"'
);
}
/**
* @param string $type
* @param string $langIso
*
* @return int
*/
public function getRemainingIncrementalObjects($type, $langIso)
{
$query = new DbQuery();
$query->select('COUNT(id_object) as count')
->from(self::INCREMENTAL_SYNC_TABLE)
->where('lang_iso = "' . pSQL($langIso) . '"')
->where('type = "' . pSQL($type) . '"');
return (int) $this->db->getValue($query);
}
/**
* @param string $type
* @param int $objectId
*
* @return bool
*/
public function removeIncrementalSyncObject($type, $objectId)
{
return $this->db->delete(
self::INCREMENTAL_SYNC_TABLE,
'type = "' . pSQL($type) . '"
AND id_shop = ' . $this->context->shop->id . '
AND id_object = ' . (int) $objectId
);
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Configuration;
use Language;
class LanguageRepository
{
/**
* @return array
*/
public function getLanguagesIsoCodes()
{
$languages = Language::getLanguages();
return array_map(function ($language) {
return $language['iso_code'];
}, $languages);
}
/**
* @return string
*/
public function getDefaultLanguageIsoCode()
{
$language = Language::getLanguage((int) Configuration::get('PS_LANG_DEFAULT'));
if (is_array($language)) {
return $language['iso_code'];
}
return '';
}
/**
* @param string $isoCode
*
* @return int
*/
public function getLanguageIdByIsoCode($isoCode)
{
return (int) Language::getIdByIso($isoCode);
}
/**
* @return array
*/
public function getLanguages()
{
return Language::getLanguages();
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Db;
use DbQuery;
class ModuleRepository
{
const MODULE_TABLE = 'module';
/**
* @var Db
*/
private $db;
public function __construct(Db $db)
{
$this->db = $db;
}
/**
* @return DbQuery
*/
public function getBaseQuery()
{
$query = new DbQuery();
$query->from(self::MODULE_TABLE, 'm');
return $query;
}
/**
* @param int $offset
* @param int $limit
*
* @return array|bool|false|\mysqli_result|\PDOStatement|resource|null
*
* @throws \PrestaShopDatabaseException
*/
public function getModules($offset, $limit)
{
$query = $this->getBaseQuery();
$query->select('id_module as module_id, name, version as module_version, active')
->limit($limit, $offset);
return $this->db->executeS($query);
}
/**
* @param int $offset
*
* @return int
*/
public function getRemainingModules($offset)
{
$query = $this->getBaseQuery();
$query->select('(COUNT(id_module) - ' . (int) $offset . ') as count');
return (int) $this->db->getValue($query);
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
class OrderDetailsRepository
{
const TABLE_NAME = 'order_detail';
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
public function __construct(Db $db, Context $context)
{
$this->context = $context;
$this->db = $db;
}
/**
* @return DbQuery
*/
public function getBaseQuery()
{
$query = new DbQuery();
$query->from(self::TABLE_NAME, 'od')
->where('od.id_shop = ' . (int) $this->context->shop->id);
return $query;
}
/**
* @param array $orderIds
* @param int $shopId
*
* @return array|bool|\mysqli_result|\PDOStatement|resource|null
*
* @throws \PrestaShopDatabaseException
*/
public function getOrderDetails(array $orderIds, $shopId)
{
$query = $this->getBaseQuery();
$query->select('od.id_order_detail, od.id_order, od.product_id, od.product_attribute_id,
od.product_quantity, od.unit_price_tax_incl, od.unit_price_tax_excl, SUM(osd.total_price_tax_incl) as refund,
SUM(osd.total_price_tax_excl) as refund_tax_excl, c.iso_code as currency, ps.id_category_default as category,
l.iso_code, o.conversion_rate as conversion_rate, o.date_add as created_at, o.date_upd as updated_at')
->leftJoin('order_slip_detail', 'osd', 'od.id_order_detail = osd.id_order_detail')
->leftJoin('product_shop', 'ps', 'od.product_id = ps.id_product AND ps.id_shop = ' . (int) $shopId)
->innerJoin('orders', 'o', 'od.id_order = o.id_order')
->leftJoin('currency', 'c', 'c.id_currency = o.id_currency')
->leftJoin('lang', 'l', 'o.id_lang = l.id_lang')
->where('od.id_order IN (' . implode(',', array_map('intval', $orderIds)) . ')')
->groupBy('od.id_order_detail');
return $this->db->executeS($query);
}
}

View File

@@ -0,0 +1,118 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Db;
use DbQuery;
use PrestaShopDatabaseException;
class OrderRepository
{
const ORDERS_TABLE = 'orders';
/**
* @var Db
*/
private $db;
public function __construct(Db $db)
{
$this->db = $db;
}
/**
* @param int $shopId
*
* @return DbQuery
*/
public function getBaseQuery($shopId)
{
$query = new DbQuery();
$query->from(self::ORDERS_TABLE, 'o')
->leftJoin('currency', 'c', 'o.id_currency = c.id_currency')
->leftJoin('order_slip', 'os', 'o.id_order = os.id_order')
->where('o.id_shop = ' . (int) $shopId)
->groupBy('o.id_order');
return $query;
}
/**
* @param int $offset
* @param int $limit
* @param int $shopId
*
* @return array|bool|\mysqli_result|\PDOStatement|resource|null
*
* @throws PrestaShopDatabaseException
*/
public function getOrders($offset, $limit, $shopId)
{
$query = $this->getBaseQuery($shopId);
$this->addSelectParameters($query);
$query->limit((int) $limit, (int) $offset);
return $this->db->executeS($query);
}
/**
* @param int $offset
* @param int $shopId
*
* @return int
*/
public function getRemainingOrderCount($offset, $shopId)
{
$query = new DbQuery();
$query->select('(COUNT(o.id_order) - ' . (int) $offset . ') as count')
->from(self::ORDERS_TABLE, 'o')
->where('o.id_shop = ' . (int) $shopId);
return (int) $this->db->getValue($query);
}
/**
* @param int $limit
* @param int $shopId
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getOrdersIncremental($limit, $shopId)
{
$query = $this->getBaseQuery($shopId);
$this->addSelectParameters($query);
$query->innerJoin(
IncrementalSyncRepository::INCREMENTAL_SYNC_TABLE,
'aic',
'aic.id_object = o.id_order AND aic.id_shop = o.id_shop AND aic.type = "orders"'
)
->limit($limit);
$result = $this->db->executeS($query);
return is_array($result) ? $result : [];
}
/**
* @param DbQuery $query
*
* @return void
*/
private function addSelectParameters(DbQuery $query)
{
$query->select('o.id_order, o.reference, o.id_customer, o.id_cart, o.current_state,
o.conversion_rate, o.total_paid_tax_excl, o.total_paid_tax_incl,
IF((SELECT so.id_order FROM `' . _DB_PREFIX_ . 'orders` so WHERE so.id_customer = o.id_customer AND so.id_order < o.id_order LIMIT 1) > 0, 0, 1) as new_customer,
c.iso_code as currency, SUM(os.total_products_tax_incl + os.total_shipping_tax_incl) as refund,
SUM(os.total_products_tax_excl + os.total_shipping_tax_excl) as refund_tax_excl, o.module as payment_module,
o.payment as payment_mode, o.total_paid_real, o.total_shipping as shipping_cost, o.date_add as created_at,
o.date_upd as updated_at');
}
}

View File

@@ -0,0 +1,338 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use DateTime;
use Db;
use DbQuery;
use Employee;
use Exception;
use PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter;
use PrestaShopDatabaseException;
use Product;
use SpecificPrice;
class ProductRepository
{
/**
* @var Context
*/
private $context;
/**
* @var Db
*/
private $db;
/**
* @var ArrayFormatter
*/
private $arrayFormatter;
public function __construct(Db $db, Context $context, ArrayFormatter $arrayFormatter)
{
$this->db = $db;
$this->context = $context;
if (!$this->context->employee instanceof Employee) {
if (($employees = Employee::getEmployees()) !== false) {
$this->context->employee = new Employee($employees[0]['id_employee']);
}
}
$this->arrayFormatter = $arrayFormatter;
}
/**
* @param int $shopId
* @param int $langId
*
* @return DbQuery
*/
private function getBaseQuery($shopId, $langId)
{
$query = new DbQuery();
$query->from('product', 'p')
->innerJoin('product_shop', 'ps', 'ps.id_product = p.id_product AND ps.id_shop = ' . (int) $shopId)
->innerJoin('product_lang', 'pl', 'pl.id_product = ps.id_product AND pl.id_shop = ps.id_shop AND pl.id_lang = ' . (int) $langId)
->leftJoin('product_attribute_shop', 'pas', 'pas.id_product = p.id_product AND pas.id_shop = ps.id_shop')
->leftJoin('product_attribute', 'pa', 'pas.id_product_attribute = pa.id_product_attribute')
->leftJoin('category_lang', 'cl', 'ps.id_category_default = cl.id_category AND ps.id_shop = cl.id_shop AND cl.id_lang = ' . (int) $langId)
->leftJoin('stock_available', 'sa', 'sa.id_product = p.id_product AND sa.id_product_attribute = IFNULL(pas.id_product_attribute, 0) AND sa.id_shop = ps.id_shop')
->leftJoin('manufacturer', 'm', 'p.id_manufacturer = m.id_manufacturer');
return $query;
}
/**
* @param int $offset
* @param int $limit
* @param int $langId
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getProducts($offset, $limit, $langId)
{
$query = $this->getBaseQuery($this->context->shop->id, $langId);
$this->addSelectParameters($query);
$query->limit($limit, $offset);
$result = $this->db->executeS($query);
return is_array($result) ? $result : [];
}
/**
* @param int $offset
* @param int $langId
*
* @return int
*
* @throws PrestaShopDatabaseException
*/
public function getRemainingProductsCount($offset, $langId)
{
$products = $this->getProducts($offset, 1, $langId);
if (!is_array($products) || empty($products)) {
return 0;
}
return count($products);
}
/**
* @param array $attributeIds
* @param int $langId
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getProductAttributeValues(array $attributeIds, $langId)
{
$query = new DbQuery();
$query->select('pas.id_product_attribute, IFNULL(GROUP_CONCAT(DISTINCT agl.name, ":", al.name SEPARATOR ";"), "") as value')
->from('product_attribute_shop', 'pas')
->leftJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pas.id_product_attribute')
->leftJoin('attribute', 'a', 'a.id_attribute = pac.id_attribute')
->leftJoin('attribute_group_lang', 'agl', 'agl.id_attribute_group = a.id_attribute_group AND agl.id_lang = ' . (int) $langId)
->leftJoin('attribute_lang', 'al', 'al.id_attribute = pac.id_attribute AND al.id_lang = agl.id_lang')
->where('pas.id_product_attribute IN (' . $this->arrayFormatter->arrayToString($attributeIds, ',') . ') AND pas.id_shop = ' . (int) $this->context->shop->id)
->groupBy('pas.id_product_attribute');
$attributes = $this->db->executeS($query);
if (is_array($attributes)) {
$resultArray = [];
foreach ($attributes as $attribute) {
$resultArray[$attribute['id_product_attribute']] = $attribute['value'];
}
return $resultArray;
}
return [];
}
/**
* @param array $productIds
* @param int $langId
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getProductFeatures(array $productIds, $langId)
{
$query = new DbQuery();
$query->select('fp.id_product, IFNULL(GROUP_CONCAT(DISTINCT fl.name, ":", fvl.value SEPARATOR ";"), "") as value')
->from('feature_product', 'fp')
->leftJoin('feature_lang', 'fl', 'fl.id_feature = fp.id_feature AND fl.id_lang = ' . (int) $langId)
->leftJoin('feature_value_lang', 'fvl', 'fvl.id_feature_value = fp.id_feature_value AND fvl.id_lang = fl.id_lang')
->where('fp.id_product IN (' . $this->arrayFormatter->arrayToString($productIds, ',') . ')')
->groupBy('fp.id_product');
$features = $this->db->executeS($query);
if (is_array($features)) {
$resultArray = [];
foreach ($features as $feature) {
$resultArray[$feature['id_product']] = $feature['value'];
}
return $resultArray;
}
return [];
}
/**
* @param array $productIds
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getProductImages(array $productIds)
{
$query = new DbQuery();
$query->select('imgs.id_product, imgs.id_image, IFNULL(imgs.cover, 0) as cover')
->from('image_shop', 'imgs')
->where('imgs.id_shop = ' . (int) $this->context->shop->id . ' AND imgs.id_product IN (' . $this->arrayFormatter->arrayToString($productIds, ',') . ')');
$result = $this->db->executeS($query);
return is_array($result) ? $result : [];
}
/**
* @param array $attributeIds
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getAttributeImages(array $attributeIds)
{
$query = new DbQuery();
$query->select('id_product_attribute, id_image')
->from('product_attribute_image', 'pai')
->where('pai.id_product_attribute IN (' . $this->arrayFormatter->arrayToString($attributeIds, ',') . ')');
$result = $this->db->executeS($query);
return is_array($result) ? $result : [];
}
/**
* @param int $productId
* @param int $attributeId
*
* @return float
*/
public function getPriceTaxExcluded($productId, $attributeId)
{
return Product::getPriceStatic($productId, false, $attributeId, 6, null, false, false);
}
/**
* @param int $productId
* @param int $attributeId
*
* @return float
*/
public function getPriceTaxIncluded($productId, $attributeId)
{
return Product::getPriceStatic($productId, true, $attributeId, 6, null, false, false);
}
/**
* @param int $productId
* @param int $attributeId
*
* @return float
*/
public function getSalePriceTaxExcluded($productId, $attributeId)
{
return Product::getPriceStatic($productId, false, $attributeId, 6);
}
/**
* @param int $productId
* @param int $attributeId
*
* @return float
*/
public function getSalePriceTaxIncluded($productId, $attributeId)
{
return Product::getPriceStatic($productId, true, $attributeId, 6);
}
/**
* @param int $productId
* @param int $attributeId
*
* @return string
*/
public function getSaleDate($productId, $attributeId)
{
$specific_price = SpecificPrice::getSpecificPrice(
(int) $productId,
$this->context->shop->id,
0,
0,
0,
1,
$attributeId
);
try {
if (is_array($specific_price) && array_key_exists('to', $specific_price)) {
$from = new DateTime($specific_price['from']);
$to = new DateTime($specific_price['to']);
return $from->format('Y-m-dTh:i-Z') . '/' . $to->format('Y-m-dTh:i-Z');
}
} catch (Exception $exception) {
return '';
}
return '';
}
/**
* @param int $limit
* @param string $langIso
* @param int $langId
*
* @return array
*
* @throws PrestaShopDatabaseException
*/
public function getProductsIncremental($limit, $langIso, $langId)
{
$query = $this->getBaseQuery($this->context->shop->id, $langId);
$this->addSelectParameters($query);
$query->innerJoin(IncrementalSyncRepository::INCREMENTAL_SYNC_TABLE,
'aic',
'aic.id_object = p.id_product AND aic.id_shop = ps.id_shop AND aic.type = "products" and aic.lang_iso = "' . pSQL($langIso) . '"'
)
->limit($limit);
$result = $this->db->executeS($query);
return is_array($result) ? $result : [];
}
/**
* @param DbQuery $query
*
* @return void
*/
private function addSelectParameters(DbQuery $query)
{
$query->select('p.id_product, IFNULL(pas.id_product_attribute, 0) as id_attribute, pas.default_on as is_default_attribute,
pl.name, pl.description, pl.description_short, pl.link_rewrite, cl.name as default_category,
ps.id_category_default, IFNULL(pa.reference, p.reference) as reference, IFNULL(pa.upc, p.upc) as upc,
IFNULL(pa.ean13, p.ean13) as ean, ps.condition, ps.visibility, ps.active, sa.quantity, m.name as manufacturer,
(p.weight + IFNULL(pas.weight, 0)) as weight, (ps.price + IFNULL(pas.price, 0)) as price_tax_excl,
p.date_add as created_at, p.date_upd as updated_at');
if (version_compare(_PS_VERSION_, '1.7', '>=')) {
$query->select('IFNULL(pa.isbn, p.isbn) as isbn');
}
}
}

View File

@@ -0,0 +1,154 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
use Exception;
use Language;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\Module\PsEventbus\Formatter\ArrayFormatter;
use PrestaShopDatabaseException;
use Ps_eventbus;
class ServerInformationRepository
{
/**
* @var CurrencyRepository
*/
private $currencyRepository;
/**
* @var LanguageRepository
*/
private $languageRepository;
/**
* @var ConfigurationRepository
*/
private $configurationRepository;
/**
* @var Context
*/
private $context;
/**
* @var Db
*/
private $db;
/**
* @var ArrayFormatter
*/
private $arrayFormatter;
/**
* @var ShopRepository
*/
private $shopRepository;
public function __construct(
Context $context,
Db $db,
CurrencyRepository $currencyRepository,
LanguageRepository $languageRepository,
ConfigurationRepository $configurationRepository,
ShopRepository $shopRepository,
ArrayFormatter $arrayFormatter
) {
$this->currencyRepository = $currencyRepository;
$this->languageRepository = $languageRepository;
$this->configurationRepository = $configurationRepository;
$this->shopRepository = $shopRepository;
$this->context = $context;
$this->db = $db;
$this->arrayFormatter = $arrayFormatter;
}
/**
* @param null $langIso
*
* @return array
*/
public function getServerInformation($langIso = null)
{
$langId = $langIso != null ? (int) Language::getIdByIso($langIso) : null;
return [
[
'id' => '1',
'collection' => 'shops',
'properties' => [
'created_at' => date(DATE_ATOM),
'cms_version' => _PS_VERSION_,
'url_is_simplified' => $this->configurationRepository->get('PS_REWRITING_SETTINGS') == '1',
'cart_is_persistent' => $this->configurationRepository->get('PS_CART_FOLLOWING') == '1',
'default_language' => $this->languageRepository->getDefaultLanguageIsoCode(),
'languages' => implode(';', $this->languageRepository->getLanguagesIsoCodes()),
'default_currency' => $this->currencyRepository->getDefaultCurrencyIsoCode(),
'currencies' => implode(';', $this->currencyRepository->getCurrenciesIsoCodes()),
'weight_unit' => $this->configurationRepository->get('PS_WEIGHT_UNIT'),
'timezone' => $this->configurationRepository->get('PS_TIMEZONE'),
'is_order_return_enabled' => $this->configurationRepository->get('PS_ORDER_RETURN') == '1',
'order_return_nb_days' => (int) $this->configurationRepository->get('PS_ORDER_RETURN_NB_DAYS'),
'php_version' => phpversion(),
'http_server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '',
'url' => $this->context->link->getPageLink('index', null, $langId),
'ssl' => $this->configurationRepository->get('PS_SSL_ENABLED') == '1',
'multi_shop_count' => $this->shopRepository->getMultiShopCount(),
],
],
];
}
/**
* @return array
*/
public function getHealthCheckData()
{
$tokenValid = true;
$allTablesInstalled = true;
$phpVersion = '';
$psAccountsService = new PsAccountsService();
try {
$token = $psAccountsService->getOrRefreshToken();
if (!$token) {
$tokenValid = false;
}
} catch (Exception $e) {
$tokenValid = false;
}
foreach (Ps_eventbus::REQUIRED_TABLES as $requiredTable) {
$query = new DbQuery();
$query->select('*')
->from($requiredTable)
->limit(1);
try {
$this->db->executeS($query);
} catch (PrestaShopDatabaseException $e) {
$allTablesInstalled = false;
break;
}
}
if (defined('PHP_VERSION') && defined('PHP_EXTRA_VERSION')) {
$phpVersion = str_replace(PHP_EXTRA_VERSION, '', PHP_VERSION);
} else {
$phpVersion = (string) explode('-', (string) phpversion())[0];
}
return [
'prestashop_version' => _PS_VERSION_,
'ps_eventbus_version' => Ps_eventbus::VERSION,
'php_version' => $phpVersion,
'ps_account' => $tokenValid,
'ps_eventbus' => $allTablesInstalled,
'env' => [
'EVENT_BUS_PROXY_API_URL' => isset($_ENV['EVENT_BUS_PROXY_API_URL']) ? $_ENV['EVENT_BUS_PROXY_API_URL'] : null,
'EVENT_BUS_SYNC_API_URL' => isset($_ENV['EVENT_BUS_SYNC_API_URL']) ? $_ENV['EVENT_BUS_SYNC_API_URL'] : null,
],
];
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use DbQuery;
class ShopRepository
{
/**
* @var Context
*/
private $context;
/**
* @var Db
*/
private $db;
public function __construct(Context $context, Db $db)
{
$this->context = $context;
$this->db = $db;
}
/**
* @return int
*/
public function getMultiShopCount()
{
$query = new DbQuery();
$query->select('COUNT(id_shop)')
->from('shop')
->where('active = 1 and deleted = 0');
return (int) $this->db->getValue($query);
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace PrestaShop\Module\PsEventbus\Repository;
use Context;
use Db;
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder;
use Theme;
class ThemeRepository
{
/**
* @var Context
*/
private $context;
/**
* @var Db
*/
private $db;
public function __construct(Context $context, Db $db)
{
$this->context = $context;
$this->db = $db;
}
/**
* @return array|mixed|null
*/
public function getThemes()
{
if (version_compare(_PS_VERSION_, '1.7', '>')) {
$themeRepository = (new ThemeManagerBuilder($this->context, $this->db))
->buildRepository($this->context->shop);
$currentTheme = $this->context->shop->theme;
$themes = $themeRepository->getList();
return array_map(function ($key, $theme) use ($currentTheme) {
return [
'id' => md5((string) $key),
'collection' => 'themes',
'properties' => [
'theme_id' => md5((string) $key),
'name' => (string) $theme->getName(),
'theme_version' => (string) $theme->get('version'),
'active' => $theme->getName() == $currentTheme->getName(),
],
];
}, array_keys($themes), $themes);
} else {
/* @phpstan-ignore-next-line */
$themes = Theme::getAvailable(false);
return array_map(function ($theme) {
/* @phpstan-ignore-next-line */
$themeObj = Theme::getByDirectory($theme);
$themeData = [
'id' => md5($theme),
'collection' => 'themes',
'properties' => [],
];
/* @phpstan-ignore-next-line */
if ($themeObj instanceof Theme) {
/* @phpstan-ignore-next-line */
$themeInfo = Theme::getThemeInfo($themeObj->id);
$themeData['properties'] = [
'theme_id' => md5($theme),
'name' => isset($themeInfo['theme_name']) ? $themeInfo['theme_name'] : '',
'theme_version' => isset($themeInfo['theme_version']) ? $themeInfo['theme_version'] : '',
'active' => isset($themeInfo['theme_version']) ? false : (string) $this->context->theme->id == (string) $themeInfo['theme_id'],
];
} else {
$themeData['properties'] = [
'theme_id' => md5($theme),
'name' => $theme,
'theme_version' => '',
'active' => false,
];
}
return $themeData;
}, $themes);
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,54 @@
<?php
namespace PrestaShop\Module\PsEventbus\Service;
use PrestaShop\Module\PsEventbus\Api\EventBusSyncClient;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
use PrestaShop\Module\PsEventbus\Repository\EventbusSyncRepository;
use PrestaShopDatabaseException;
class ApiAuthorizationService
{
/**
* @var EventbusSyncRepository
*/
private $eventbusSyncStateRepository;
/**
* @var EventBusSyncClient
*/
private $eventBusSyncClient;
public function __construct(
EventbusSyncRepository $eventbusSyncStateRepository,
EventBusSyncClient $eventBusSyncClient
) {
$this->eventbusSyncStateRepository = $eventbusSyncStateRepository;
$this->eventBusSyncClient = $eventBusSyncClient;
}
/**
* Authorizes if the call to endpoint is legit and creates sync state if needed
*
* @param string $jobId
*
* @return array|bool
*
* @throws PrestaShopDatabaseException|EnvVarException
*/
public function authorizeCall($jobId)
{
$job = $this->eventbusSyncStateRepository->findJobById($jobId);
if ($job) {
return true;
}
$jobValidationResponse = $this->eventBusSyncClient->validateJobId($jobId);
if (is_array($jobValidationResponse) && (int) $jobValidationResponse['httpCode'] === 201) {
return $this->eventbusSyncStateRepository->insertJob($jobId, date(DATE_ATOM));
}
return $jobValidationResponse;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace PrestaShop\Module\PsEventbus\Service;
use Exception;
use PrestaShop\Module\PsEventbus\Formatter\JsonFormatter;
class CompressionService
{
/**
* @var JsonFormatter
*/
private $jsonFormatter;
public function __construct(JsonFormatter $jsonFormatter)
{
$this->jsonFormatter = $jsonFormatter;
}
/**
* Compresses data with gzip
*
* @param array $data
*
* @return string
*
* @throws Exception
*/
public function gzipCompressData($data)
{
if (!extension_loaded('zlib')) {
throw new Exception('Zlib extension for PHP is not enabled');
}
$dataJson = $this->jsonFormatter->formatNewlineJsonString($data);
if (!$encodedData = gzencode($dataJson)) {
throw new Exception('Failed encoding data to GZIP');
}
return $encodedData;
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace PrestaShop\Module\PsEventbus\Service;
use Context;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
use PrestaShop\Module\PsEventbus\Repository\DeletedObjectsRepository;
use PrestaShopDatabaseException;
class DeletedObjectsService
{
/**
* @var Context
*/
private $context;
/**
* @var DeletedObjectsRepository
*/
private $deletedObjectsRepository;
/**
* @var ProxyService
*/
private $proxyService;
public function __construct(Context $context, DeletedObjectsRepository $deletedObjectsRepository, ProxyService $proxyService)
{
$this->context = $context;
$this->deletedObjectsRepository = $deletedObjectsRepository;
$this->proxyService = $proxyService;
}
/**
* @param string $jobId
*
* @return array
*
* @throws PrestaShopDatabaseException|EnvVarException
*/
public function handleDeletedObjectsSync($jobId)
{
$deletedObjects = $this->deletedObjectsRepository->getDeletedObjectsGrouped($this->context->shop->id);
if (empty($deletedObjects)) {
return [
'total_objects' => 0,
];
}
$data = $this->formatData($deletedObjects);
$response = $this->proxyService->delete($jobId, $data);
if ($response['httpCode'] == 200) {
foreach ($data as $dataItem) {
$this->deletedObjectsRepository->removeDeletedObjects(
$dataItem['collection'],
$dataItem['deleteIds'],
$this->context->shop->id
);
}
}
return array_merge(
[
'job_id' => $jobId,
'total_objects' => count($data),
],
$response
);
}
/**
* @param array $data
*
* @return array
*/
private function formatData(array $data)
{
return array_map(function ($dataItem) {
return [
'collection' => $dataItem['type'],
'deleteIds' => explode(';', $dataItem['ids']),
];
}, $data);
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace PrestaShop\Module\PsEventbus\Service;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Ring\Exception\ConnectException;
use PrestaShop\Module\PsEventbus\Api\EventBusProxyClient;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
use PrestaShop\Module\PsEventbus\Formatter\JsonFormatter;
class ProxyService
{
/**
* @var EventBusProxyClient
*/
private $eventBusProxyClient;
/**
* @var JsonFormatter
*/
private $jsonFormatter;
public function __construct(EventBusProxyClient $eventBusProxyClient, JsonFormatter $jsonFormatter)
{
$this->eventBusProxyClient = $eventBusProxyClient;
$this->jsonFormatter = $jsonFormatter;
}
/**
* @param string $jobId
* @param array $data
* @param int $scriptStartTime
*
* @return array
*
* @throws EnvVarException
*/
public function upload($jobId, $data, $scriptStartTime)
{
$dataJson = $this->jsonFormatter->formatNewlineJsonString($data);
try {
$response = $this->eventBusProxyClient->upload($jobId, $dataJson, $scriptStartTime);
} catch (ClientException $exception) {
return ['error' => $exception->getMessage()];
} catch (ConnectException $exception) {
return ['error' => $exception->getMessage()];
}
return $response;
}
/**
* @param string $jobId
* @param array $data
*
* @return array
*
* @throws EnvVarException
*/
public function delete($jobId, $data)
{
$dataJson = $this->jsonFormatter->formatNewlineJsonString($data);
try {
$response = $this->eventBusProxyClient->delete($jobId, $dataJson);
} catch (ClientException $exception) {
return ['error' => $exception->getMessage()];
}
return $response;
}
}

View File

@@ -0,0 +1,131 @@
<?php
namespace PrestaShop\Module\PsEventbus\Service;
use PrestaShop\Module\PsEventbus\Exception\ApiException;
use PrestaShop\Module\PsEventbus\Exception\EnvVarException;
use PrestaShop\Module\PsEventbus\Provider\PaginatedApiDataProviderInterface;
use PrestaShop\Module\PsEventbus\Repository\EventbusSyncRepository;
use PrestaShop\Module\PsEventbus\Repository\IncrementalSyncRepository;
use PrestaShopDatabaseException;
class SynchronizationService
{
/**
* @var EventbusSyncRepository
*/
private $eventbusSyncRepository;
/**
* @var IncrementalSyncRepository
*/
private $incrementalSyncRepository;
/**
* @var ProxyService
*/
private $proxyService;
public function __construct(EventbusSyncRepository $eventbusSyncRepository, IncrementalSyncRepository $incrementalSyncRepository, ProxyService $proxyService)
{
$this->eventbusSyncRepository = $eventbusSyncRepository;
$this->incrementalSyncRepository = $incrementalSyncRepository;
$this->proxyService = $proxyService;
}
/**
* @param PaginatedApiDataProviderInterface $dataProvider
* @param string $type
* @param string $jobId
* @param string $langIso
* @param int $offset
* @param int $limit
* @param string $dateNow
* @param int $scriptStartTime
*
* @return array
*
* @throws PrestaShopDatabaseException|EnvVarException|ApiException
*/
public function handleFullSync(PaginatedApiDataProviderInterface $dataProvider, $type, $jobId, $langIso, $offset, $limit, $dateNow, $scriptStartTime)
{
$response = [];
$data = $dataProvider->getFormattedData($offset, $limit, $langIso);
if (!empty($data)) {
$response = $this->proxyService->upload($jobId, $data, $scriptStartTime);
if ($response['httpCode'] == 201) {
$offset += $limit;
}
}
$remainingObjects = (int) $dataProvider->getRemainingObjectsCount($offset, $langIso);
if ($remainingObjects <= 0) {
$remainingObjects = 0;
$offset = 0;
}
$this->eventbusSyncRepository->updateTypeSync($type, $offset, $dateNow, $remainingObjects == 0, $langIso);
return array_merge([
'total_objects' => count($data),
'has_remaining_objects' => $remainingObjects > 0,
'remaining_objects' => $remainingObjects,
'md5' => $this->getPayloadMd5($data),
], $response);
}
/**
* @param PaginatedApiDataProviderInterface $dataProvider
* @param string $type
* @param string $jobId
* @param int $limit
* @param string $langIso
* @param int $scriptStartTime
*
* @return array
*
* @throws PrestaShopDatabaseException|EnvVarException
*/
public function handleIncrementalSync(PaginatedApiDataProviderInterface $dataProvider, $type, $jobId, $limit, $langIso, $scriptStartTime)
{
$response = [];
$incrementalData = $dataProvider->getFormattedDataIncremental($limit, $langIso);
$objectIds = $incrementalData['ids'];
$data = $incrementalData['data'];
if (!empty($data)) {
$response = $this->proxyService->upload($jobId, $data, $scriptStartTime);
if ($response['httpCode'] == 201 && !empty($objectIds)) {
$this->incrementalSyncRepository->removeIncrementalSyncObjects($type, $objectIds, $langIso);
}
}
$remainingObjects = $this->incrementalSyncRepository->getRemainingIncrementalObjects($type, $langIso);
return array_merge([
'total_objects' => count($data),
'has_remaining_objects' => $remainingObjects > 0,
'remaining_objects' => $remainingObjects,
'md5' => $this->getPayloadMd5($data),
], $response);
}
/**
* @param array $payload
*
* @return string
*/
private function getPayloadMd5($payload)
{
return md5(
implode(' ', array_map(function ($payloadItem) {
return $payloadItem['id'];
}, $payload))
);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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;

Some files were not shown because too many files have changed in this diff Show More