php 7.3 support, better architecture
This commit is contained in:
parent
f1d0ecaa39
commit
93e6ab06c3
@ -5,13 +5,14 @@ cache:
|
||||
- $HOME/.composer/cache
|
||||
|
||||
php:
|
||||
- '7.3'
|
||||
- '7.4'
|
||||
|
||||
before_script:
|
||||
- flags="-o"
|
||||
- composer install $flags
|
||||
|
||||
script: php ./vendor/phpunit/phpunit/phpunit -c phpunit.xml.dist
|
||||
script: composer run-script phpunit
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
@ -17,13 +17,12 @@
|
||||
"psr-4": { "RetailCrm\\": "src/" }
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4.0",
|
||||
"php": ">=7.3.0",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"psr/http-client": "^1.0",
|
||||
"symfony/serializer": "^5.1",
|
||||
"symfony/validator": "^5.1",
|
||||
"devanych/di-container": "^2.1",
|
||||
"doctrine/annotations": "^1.10",
|
||||
"doctrine/cache": "^1.10",
|
||||
"symfony/property-access": "^5.1"
|
||||
@ -32,7 +31,15 @@
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"phpmd/phpmd": "^2.9",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"guzzlehttp/guzzle": "^7.1"
|
||||
"guzzlehttp/guzzle": "^7.1",
|
||||
"phpcompatibility/php-compatibility": "*",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0"
|
||||
},
|
||||
"scripts": {
|
||||
"phpunit": "./vendor/bin/phpunit -c phpunit.xml.dist",
|
||||
"phpcs": "./vendor/bin/phpcs -p src --runtime-set testVersion 7.3",
|
||||
"phpcbf": "./vendor/bin/phpcbf -p src"
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
|
@ -1,36 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.5/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="false"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
backupStaticAttributes="false"
|
||||
convertErrorsToExceptions="false"
|
||||
convertNoticesToExceptions="false"
|
||||
convertWarningsToExceptions="false"
|
||||
processIsolation="true"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
stopOnIncomplete="false"
|
||||
stopOnSkipped="false"
|
||||
stopOnRisky="false"
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="false"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
backupStaticAttributes="false"
|
||||
convertErrorsToExceptions="false"
|
||||
convertNoticesToExceptions="false"
|
||||
convertWarningsToExceptions="false"
|
||||
processIsolation="true"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
stopOnIncomplete="false"
|
||||
stopOnSkipped="false"
|
||||
stopOnRisky="false"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-clover" target="coverage.xml"/>
|
||||
<log type="junit" target="test-report.xml"/>
|
||||
</logging>
|
||||
</phpunit>
|
||||
<coverage>
|
||||
<include>
|
||||
<directory>src</directory>
|
||||
</include>
|
||||
<report>
|
||||
<clover outputFile="coverage.xml"/>
|
||||
</report>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<logging>
|
||||
<junit outputFile="test-report.xml"/>
|
||||
</logging>
|
||||
</phpunit>
|
||||
|
280
src/Component/DependencyInjection/Container.php
Normal file
280
src/Component/DependencyInjection/Container.php
Normal file
@ -0,0 +1,280 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category Container
|
||||
* @package RetailCrm\Component\DependencyInjection
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
namespace RetailCrm\Component\DependencyInjection;
|
||||
|
||||
use Closure;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use RetailCrm\Component\DependencyInjection\Exception\ContainerException;
|
||||
use RetailCrm\Component\DependencyInjection\Exception\NotFoundException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class Container
|
||||
* This implementation took an inspiration from devanych/di-container. It's almost the same, but for PHP 7.3.
|
||||
*
|
||||
* @category Container
|
||||
* @package RetailCrm\Component\DependencyInjection
|
||||
* @author Evgeniy Zyubin <mail@devanych.ru>
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
class Container implements ContainerInterface
|
||||
{
|
||||
/**
|
||||
* @var array $instances
|
||||
*/
|
||||
public $instances = [];
|
||||
|
||||
/**
|
||||
* @var array $definitions
|
||||
*/
|
||||
public $definitions = [];
|
||||
|
||||
/**
|
||||
* Container constructor.
|
||||
*
|
||||
* @param array $definitions
|
||||
*/
|
||||
public function __construct(array $definitions = [])
|
||||
{
|
||||
$this->setGroup($definitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets definition to the container.
|
||||
*
|
||||
* @param string $id
|
||||
* @param mixed $definition
|
||||
*/
|
||||
public function set(string $id, $definition): void
|
||||
{
|
||||
if ($this->instantiated($id)) {
|
||||
unset($this->instances[$id]);
|
||||
}
|
||||
|
||||
$this->definitions[$id] = $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets group of definitions at once.
|
||||
*
|
||||
* @param array<string, mixed> $definitions
|
||||
*/
|
||||
public function setGroup(array $definitions): void
|
||||
{
|
||||
foreach ($definitions as $id => $definition) {
|
||||
self::isString($id);
|
||||
$this->set($id, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an entry of the container by its identifier and returns it.
|
||||
*
|
||||
* @param string $id Identifier of the entry to look for.
|
||||
*
|
||||
* @return mixed Entry.
|
||||
* @throws ContainerExceptionInterface Error while retrieving the entry.
|
||||
*
|
||||
* @throws NotFoundExceptionInterface No entry was found for **this** identifier.
|
||||
*/
|
||||
public function get($id)
|
||||
{
|
||||
self::isString($id);
|
||||
|
||||
if ($this->instantiated($id)) {
|
||||
return $this->instances[$id];
|
||||
}
|
||||
|
||||
$this->instances[$id] = $this->createInstance($id);
|
||||
|
||||
return $this->instances[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the container can return an entry for the given identifier.
|
||||
* Returns false otherwise.
|
||||
*
|
||||
* `has($id)` returning true does not mean that `get($id)` will not throw an exception.
|
||||
* It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
|
||||
*
|
||||
* @param string $id Identifier of the entry to look for.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($id): bool
|
||||
{
|
||||
return (is_string($id) && array_key_exists($id, $this->definitions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create instance by definition from the container by ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return mixed
|
||||
* @throws NotFoundException
|
||||
* @throws ContainerException
|
||||
*/
|
||||
private function createInstance(string $id)
|
||||
{
|
||||
if (!$this->has($id)) {
|
||||
if (self::isClassName($id)) {
|
||||
return $this->createObject($id);
|
||||
}
|
||||
|
||||
throw new NotFoundException(sprintf('`%s` is not set in container and is not a class name.', $id));
|
||||
}
|
||||
|
||||
if (self::isClassName($this->definitions[$id])) {
|
||||
return $this->createObject($this->definitions[$id]);
|
||||
}
|
||||
|
||||
if ($this->definitions[$id] instanceof Closure) {
|
||||
return $this->definitions[$id]($this);
|
||||
}
|
||||
|
||||
return $this->definitions[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create object by class name.
|
||||
*
|
||||
* @param string $className
|
||||
* @return object
|
||||
* @throws ContainerException If unable to create object.
|
||||
*/
|
||||
private function createObject(string $className): object
|
||||
{
|
||||
try {
|
||||
$reflection = new ReflectionClass($className);
|
||||
} catch (ReflectionException $e) {
|
||||
throw new ContainerException(sprintf('Unable to create object `%s`.', $className), 0, $e);
|
||||
}
|
||||
|
||||
if (in_array(FactoryInterface::class, $reflection->getInterfaceNames(), true)) {
|
||||
try {
|
||||
/*** @var FactoryInterface $factory */
|
||||
$factory = $this->getObjectFromReflection($reflection);
|
||||
return $factory->create($this);
|
||||
} catch (ContainerException $e) {
|
||||
throw $e;
|
||||
} catch (Throwable $e) {
|
||||
throw new ContainerException(sprintf('Unable to create object `%s`.', $className), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->getObjectFromReflection($reflection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create object from reflection.
|
||||
*
|
||||
* If the object has dependencies in the constructor, it tries to create them too.
|
||||
*
|
||||
* @param ReflectionClass $reflection
|
||||
* @return object
|
||||
* @throws ContainerException If unable to create object.
|
||||
*/
|
||||
private function getObjectFromReflection(ReflectionClass $reflection): object
|
||||
{
|
||||
if (($constructor = $reflection->getConstructor()) === null) {
|
||||
return $reflection->newInstance();
|
||||
}
|
||||
|
||||
$arguments = [];
|
||||
|
||||
foreach ($constructor->getParameters() as $parameter) {
|
||||
if ($type = $parameter->getType()) {
|
||||
$typeName = $type->getName();
|
||||
|
||||
if (!$type->isBuiltin() && ($this->has($typeName) || self::isClassName($typeName))) {
|
||||
$arguments[] = $this->get($typeName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($typeName === 'array' && $type->isBuiltin() && !$parameter->isDefaultValueAvailable()) {
|
||||
$arguments[] = [];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($parameter->isDefaultValueAvailable()) {
|
||||
try {
|
||||
$arguments[] = $parameter->getDefaultValue();
|
||||
continue;
|
||||
} catch (ReflectionException $e) {
|
||||
throw new ContainerException(
|
||||
sprintf(
|
||||
'Unable to create object `%s`. Unable to get default value of constructor parameter: `%s`.',
|
||||
$reflection->getName(),
|
||||
$parameter->getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ContainerException(
|
||||
sprintf(
|
||||
'Unable to create object `%s`. Unable to process a constructor parameter: `%s`.',
|
||||
$reflection->getName(),
|
||||
$parameter->getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $reflection->newInstanceArgs($arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if definition was instantiated, false otherwise.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function instantiated(string $id): bool
|
||||
{
|
||||
return array_key_exists($id, $this->instances);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if provided parameter is class name, false otherwise.
|
||||
*
|
||||
* @param mixed $className
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isClassName($className): bool
|
||||
{
|
||||
return (is_string($className) && class_exists($className));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate provided ID
|
||||
*
|
||||
* @param mixed $id
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
private static function isString($id): void
|
||||
{
|
||||
if (!is_string($id)) {
|
||||
throw new NotFoundException(sprintf('Invalid id. Expects string, `%s` provided.', gettype($id)));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category ContainerException
|
||||
* @package RetailCrm\Component\DependencyInjection\Exception
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
namespace RetailCrm\Component\DependencyInjection\Exception;
|
||||
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use LogicException;
|
||||
|
||||
/**
|
||||
* Class ContainerException
|
||||
*
|
||||
* @category ContainerException
|
||||
* @package RetailCrm\Component\DependencyInjection\Exception
|
||||
* @author Evgeniy Zyubin <mail@devanych.ru>
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
class ContainerException extends LogicException implements ContainerExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category NotFoundException
|
||||
* @package RetailCrm\Component\DependencyInjection\Exception
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
namespace RetailCrm\Component\DependencyInjection\Exception;
|
||||
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Class NotFoundException
|
||||
*
|
||||
* @category NotFoundException
|
||||
* @package RetailCrm\Component\DependencyInjection\Exception
|
||||
* @author Evgeniy Zyubin <mail@devanych.ru>
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
class NotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface
|
||||
{
|
||||
}
|
36
src/Component/DependencyInjection/FactoryInterface.php
Normal file
36
src/Component/DependencyInjection/FactoryInterface.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category FactoryInterface
|
||||
* @package RetailCrm\Component\DependencyInjection
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
namespace RetailCrm\Component\DependencyInjection;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Interface FactoryInterface
|
||||
*
|
||||
* @category FactoryInterface
|
||||
* @package RetailCrm\Component\DependencyInjection
|
||||
* @author Evgeniy Zyubin <mail@devanych.ru>
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
interface FactoryInterface
|
||||
{
|
||||
/**
|
||||
* @param \Psr\Container\ContainerInterface $container
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function create(ContainerInterface $container): object;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category Environment
|
||||
* @package RetailCrm\Component
|
||||
@ -12,10 +12,6 @@
|
||||
*/
|
||||
namespace RetailCrm\Component;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use RetailCrm\Factory\ClientFactory;
|
||||
use RetailCrm\TopClient\Client;
|
||||
|
||||
/**
|
||||
* Class Environment
|
||||
*
|
||||
@ -31,36 +27,4 @@ class Environment
|
||||
public const PROD = 'PROD';
|
||||
public const DEV = 'DEV';
|
||||
public const TEST = 'TEST';
|
||||
|
||||
private ContainerInterface $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Psr\Container\ContainerInterface
|
||||
*/
|
||||
public function getContainer(): ContainerInterface
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $serviceUrl
|
||||
*
|
||||
* @return \RetailCrm\TopClient\Client
|
||||
* @throws \RetailCrm\Component\Exception\ValidationException
|
||||
*/
|
||||
public function createClient(string $serviceUrl): Client
|
||||
{
|
||||
$factory = $this->container->get(ClientFactory::class);
|
||||
|
||||
if (!($factory instanceof ClientFactory)) {
|
||||
throw new \RuntimeException('Invalid factory definition in the provided container');
|
||||
}
|
||||
|
||||
return $factory->create($serviceUrl);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category ValidationException
|
||||
* @package RetailCrm\Component\Exception
|
||||
@ -27,7 +27,10 @@ use Throwable;
|
||||
*/
|
||||
class ValidationException extends \Exception
|
||||
{
|
||||
private ?ConstraintViolationListInterface $violations;
|
||||
/**
|
||||
* @var \Symfony\Component\Validator\ConstraintViolationListInterface|null
|
||||
*/
|
||||
private $violations;
|
||||
|
||||
/**
|
||||
* ValidationException constructor.
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category ClientFactory
|
||||
* @package RetailCrm\Factory
|
||||
@ -12,13 +12,11 @@
|
||||
*/
|
||||
namespace RetailCrm\Factory;
|
||||
|
||||
use RetailCrm\Interfaces\HttpClientAwareInterface;
|
||||
use RetailCrm\Interfaces\ValidatorAwareInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use RetailCrm\Interfaces\ContainerAwareInterface;
|
||||
use RetailCrm\Interfaces\FactoryInterface;
|
||||
use RetailCrm\TopClient\Client;
|
||||
use RetailCrm\Traits\HttpClientAwareTrait;
|
||||
use RetailCrm\Traits\ValidatorAwareTrait;
|
||||
use Symfony\Component\Serializer\SerializerAwareInterface;
|
||||
use Symfony\Component\Serializer\SerializerAwareTrait;
|
||||
use RetailCrm\Traits\ContainerAwareTrait;
|
||||
|
||||
/**
|
||||
* Class ClientFactory
|
||||
@ -30,24 +28,47 @@ use Symfony\Component\Serializer\SerializerAwareTrait;
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
class ClientFactory implements HttpClientAwareInterface, SerializerAwareInterface, ValidatorAwareInterface
|
||||
class ClientFactory implements ContainerAwareInterface, FactoryInterface
|
||||
{
|
||||
use HttpClientAwareTrait;
|
||||
use SerializerAwareTrait;
|
||||
use ValidatorAwareTrait;
|
||||
use ContainerAwareTrait;
|
||||
|
||||
/** @var string $serviceUrl */
|
||||
private $serviceUrl;
|
||||
|
||||
/**
|
||||
* @param \Psr\Container\ContainerInterface $container
|
||||
*
|
||||
* @return \RetailCrm\Factory\ClientFactory
|
||||
*/
|
||||
public static function withContainer(ContainerInterface $container): ClientFactory
|
||||
{
|
||||
$factory = new self();
|
||||
$factory->setContainer($container);
|
||||
|
||||
return $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $serviceUrl
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setServiceUrl(string $serviceUrl): ClientFactory
|
||||
{
|
||||
$this->serviceUrl = $serviceUrl;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RetailCrm\TopClient\Client
|
||||
* @throws \RetailCrm\Component\Exception\ValidationException
|
||||
*/
|
||||
public function create(string $serviceUrl): Client
|
||||
public function create(): Client
|
||||
{
|
||||
$client = new Client($serviceUrl);
|
||||
$client->setHttpClient($this->httpClient);
|
||||
$client->setSerializer($this->serializer);
|
||||
$client->setValidator($this->validator);
|
||||
$client = new Client($this->serviceUrl);
|
||||
$client->setHttpClient($this->container->get('httpClient'));
|
||||
$client->setSerializer($this->container->get('serializer'));
|
||||
$client->setValidator($this->container->get('validator'));
|
||||
$client->validateSelf();
|
||||
|
||||
return $client;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category EnvironmentFactory
|
||||
* @package RetailCrm\Factory
|
||||
@ -12,17 +12,16 @@
|
||||
*/
|
||||
namespace RetailCrm\Factory;
|
||||
|
||||
use Devanych\Di\Container;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use RetailCrm\TopClient\Client;
|
||||
use RetailCrm\Component\DependencyInjection\Container;
|
||||
use RetailCrm\Component\Environment;
|
||||
use RetailCrm\Interfaces\FactoryInterface;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
use Symfony\Component\Serializer\Encoder\XmlEncoder;
|
||||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
use Symfony\Component\Serializer\SerializerAwareTrait;
|
||||
use Symfony\Component\Validator\Validation;
|
||||
use RetailCrm\Component\Environment;
|
||||
use Symfony\Component\Validator\Validator\TraceableValidator;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
@ -36,17 +35,24 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
class EnvironmentFactory implements EnvironmentAwareFactoryInterface
|
||||
class ContainerFactory implements FactoryInterface
|
||||
{
|
||||
public string $env;
|
||||
public ClientInterface $httpClient;
|
||||
/**
|
||||
* @var string $env
|
||||
*/
|
||||
public $env;
|
||||
|
||||
/**
|
||||
* @var \Psr\Http\Client\ClientInterface $httpClient
|
||||
*/
|
||||
public $httpClient;
|
||||
|
||||
/**
|
||||
* @param string $environmentType
|
||||
*
|
||||
* @return \RetailCrm\Factory\EnvironmentAwareFactoryInterface
|
||||
* @return ContainerFactory
|
||||
*/
|
||||
public static function withEnv(string $environmentType = Environment::DEV): EnvironmentAwareFactoryInterface
|
||||
public static function withEnv(string $environmentType = Environment::DEV): ContainerFactory
|
||||
{
|
||||
$factory = new self();
|
||||
$factory->env = $environmentType;
|
||||
@ -57,28 +63,35 @@ class EnvironmentFactory implements EnvironmentAwareFactoryInterface
|
||||
/**
|
||||
* @param \Psr\Http\Client\ClientInterface $httpClient
|
||||
*
|
||||
* @return \RetailCrm\Component\Environment
|
||||
* @return \RetailCrm\Factory\ContainerFactory
|
||||
*/
|
||||
public function create(ClientInterface $httpClient): Environment
|
||||
public function withClient(ClientInterface $httpClient): ContainerFactory
|
||||
{
|
||||
$this->httpClient = $httpClient;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Psr\Container\ContainerInterface
|
||||
*/
|
||||
public function create(): ContainerInterface
|
||||
{
|
||||
$container = new Container();
|
||||
|
||||
switch ($this->env) {
|
||||
case Environment::PROD:
|
||||
$this->setProdServices($container);
|
||||
break;
|
||||
case Environment::DEV:
|
||||
case Environment::TEST:
|
||||
$this->setProdServices($container);
|
||||
$this->setDevServices($container);
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException(sprintf('Invalid environment type: %s', $this->env));
|
||||
case Environment::PROD:
|
||||
$this->setProdServices($container);
|
||||
break;
|
||||
case Environment::DEV:
|
||||
case Environment::TEST:
|
||||
$this->setProdServices($container);
|
||||
$this->setDevServices($container);
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException(sprintf('Invalid environment type: %s', $this->env));
|
||||
}
|
||||
|
||||
return new Environment($container);
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,18 +101,12 @@ class EnvironmentFactory implements EnvironmentAwareFactoryInterface
|
||||
{
|
||||
$container->set('httpClient', $this->httpClient);
|
||||
$container->set('validator', Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator());
|
||||
$container->set('serializer', new Serializer(
|
||||
[new ObjectNormalizer()],
|
||||
[new XmlEncoder(), new JsonEncoder()]
|
||||
));
|
||||
$container->set(ClientFactory::class, function (ContainerInterface $container): ClientFactory {
|
||||
$factory = new ClientFactory();
|
||||
$factory->setHttpClient($container->get('httpClient'));
|
||||
$factory->setSerializer($container->get('serializer'));
|
||||
$factory->setValidator($container->get('validator'));
|
||||
|
||||
return $factory;
|
||||
});
|
||||
$container->set(
|
||||
'serializer', new Serializer(
|
||||
[new ObjectNormalizer()],
|
||||
[new XmlEncoder(), new JsonEncoder()]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
*
|
||||
* @category EnvironmentAwareFactoryInterface
|
||||
* @package RetailCrm\Factory
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Factory;
|
||||
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use RetailCrm\Component\Environment;
|
||||
|
||||
/**
|
||||
* Interface EnvironmentAwareFactoryInterface
|
||||
*
|
||||
* @category EnvironmentAwareFactoryInterface
|
||||
* @package RetailCrm\Factory
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
interface EnvironmentAwareFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @param string $environmentType
|
||||
*
|
||||
* @return \RetailCrm\Factory\EnvironmentAwareFactoryInterface
|
||||
*/
|
||||
public static function withEnv(string $environmentType = Environment::DEV): EnvironmentAwareFactoryInterface;
|
||||
|
||||
/**
|
||||
* @return \RetailCrm\Component\Environment
|
||||
*/
|
||||
public function create(ClientInterface $httpClient): Environment;
|
||||
}
|
41
src/Interfaces/ContainerAwareInterface.php
Normal file
41
src/Interfaces/ContainerAwareInterface.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category ContainerAwareInterface
|
||||
* @package RetailCrm\Interfaces
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Interfaces;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Interface ContainerAwareInterface
|
||||
*
|
||||
* @category ContainerAwareInterface
|
||||
* @package RetailCrm\Interfaces
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
interface ContainerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @param \Psr\Container\ContainerInterface $container
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function setContainer(ContainerInterface $container): void;
|
||||
|
||||
/**
|
||||
* @return \Psr\Container\ContainerInterface
|
||||
*/
|
||||
public function getContainer(): ContainerInterface;
|
||||
}
|
32
src/Interfaces/FactoryInterface.php
Normal file
32
src/Interfaces/FactoryInterface.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category FactoryInterface
|
||||
* @package RetailCrm\Interfaces
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Interfaces;
|
||||
|
||||
/**
|
||||
* Interface FactoryInterface
|
||||
*
|
||||
* @category FactoryInterface
|
||||
* @package RetailCrm\Interfaces
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
interface FactoryInterface
|
||||
{
|
||||
/**
|
||||
* @return object
|
||||
*/
|
||||
public function create();
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category ClientAwareInterface
|
||||
* @package RetailCrm\Interfaces
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category ValidatorAwareInterface
|
||||
* @package RetailCrm\Interfaces
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category Client
|
||||
* @package RetailCrm\TopClient
|
||||
@ -16,9 +16,9 @@ use RetailCrm\Component\Exception\ValidationException;
|
||||
use RetailCrm\Interfaces\HttpClientAwareInterface;
|
||||
use RetailCrm\Interfaces\ValidatorAwareInterface;
|
||||
use RetailCrm\Traits\HttpClientAwareTrait;
|
||||
use RetailCrm\Traits\SerializerAwareTrait;
|
||||
use RetailCrm\Traits\ValidatorAwareTrait;
|
||||
use Symfony\Component\Serializer\SerializerAwareInterface;
|
||||
use Symfony\Component\Serializer\SerializerAwareTrait;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
@ -42,10 +42,11 @@ class Client implements SerializerAwareInterface, HttpClientAwareInterface, Vali
|
||||
public const AVAILABLE_ENDPOINTS = [self::OVERSEAS_ENDPOINT, self::CHINESE_ENDPOINT];
|
||||
|
||||
/**
|
||||
* @var string $serviceUrl
|
||||
* @Assert\Url()
|
||||
* @Assert\Choice(choices=Client::AVAILABLE_ENDPOINTS, message="Choose a valid endpoint.")
|
||||
*/
|
||||
protected string $serviceUrl;
|
||||
protected $serviceUrl;
|
||||
|
||||
/**
|
||||
* Client constructor.
|
||||
@ -62,11 +63,7 @@ class Client implements SerializerAwareInterface, HttpClientAwareInterface, Vali
|
||||
*/
|
||||
public function validateSelf(): void
|
||||
{
|
||||
$violations = $this->validator->validate($this);
|
||||
|
||||
if ($violations->count()) {
|
||||
throw new ValidationException("Invalid client data", $violations);
|
||||
}
|
||||
$this->validate($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,7 +76,7 @@ class Client implements SerializerAwareInterface, HttpClientAwareInterface, Vali
|
||||
$violations = $this->validator->validate($item);
|
||||
|
||||
if ($violations->count()) {
|
||||
throw new ValidationException("Invalid data", $item);
|
||||
throw new ValidationException("Invalid data", $violations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
52
src/Traits/ContainerAwareTrait.php
Normal file
52
src/Traits/ContainerAwareTrait.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category ContainerAwareTrait
|
||||
* @package RetailCrm\Traits
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Traits;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* Trait ContainerAwareTrait
|
||||
*
|
||||
* @category ContainerAwareTrait
|
||||
* @package RetailCrm\Traits
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
trait ContainerAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface $container
|
||||
* @Assert\NotNull(message="Container should be provided")
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @param \Psr\Container\ContainerInterface $container
|
||||
*/
|
||||
public function setContainer(ContainerInterface $container): void
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Psr\Container\ContainerInterface
|
||||
*/
|
||||
public function getContainer(): ContainerInterface
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category HttpClientAwareTrait
|
||||
* @package RetailCrm\Traits
|
||||
@ -29,9 +29,10 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
trait HttpClientAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var ClientInterface $httpClient
|
||||
* @Assert\NotNull(message="HTTP client should be provided")
|
||||
*/
|
||||
protected ClientInterface $httpClient;
|
||||
protected $httpClient;
|
||||
|
||||
/**
|
||||
* @param \Psr\Http\Client\ClientInterface $httpClient
|
||||
|
45
src/Traits/SerializerAwareTrait.php
Normal file
45
src/Traits/SerializerAwareTrait.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category SerializerAwareTrait
|
||||
* @package RetailCrm\Traits
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Traits;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
/**
|
||||
* Trait SerializerAwareTrait
|
||||
*
|
||||
* @category SerializerAwareTrait
|
||||
* @package RetailCrm\Traits
|
||||
* @author Joel Wurtz <joel.wurtz@gmail.com>
|
||||
* @author RetailDriver LLC <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see https://help.retailcrm.ru
|
||||
*/
|
||||
trait SerializerAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var SerializerInterface $serializer
|
||||
* @Assert\NotNull(message="Serializer should be provided")
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\Serializer\SerializerInterface $serializer
|
||||
*/
|
||||
public function setSerializer(SerializerInterface $serializer): void
|
||||
{
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.4
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @category ValidatorAwareTrait
|
||||
* @package RetailCrm\Traits
|
||||
@ -29,9 +29,10 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
trait ValidatorAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var ValidatorInterface $validator
|
||||
* @Assert\NotNull(message="Validator should be provided")
|
||||
*/
|
||||
protected ValidatorInterface $validator;
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\Validator\Validator\ValidatorInterface $validator
|
||||
|
@ -12,9 +12,10 @@
|
||||
*/
|
||||
namespace Component;
|
||||
|
||||
use GuzzleHttp\Client as HttpClient;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use RetailCrm\Factory\EnvironmentFactory;
|
||||
use RetailCrm\Component\Environment;
|
||||
use RetailCrm\Factory\ClientFactory;
|
||||
use RetailCrm\Factory\ContainerFactory;
|
||||
use RetailCrm\TopClient\Client;
|
||||
|
||||
/**
|
||||
@ -31,9 +32,11 @@ class EnvironmentTest extends TestCase
|
||||
{
|
||||
public function testCreateClient()
|
||||
{
|
||||
$client = EnvironmentFactory::withEnv()
|
||||
->create(new HttpClient())
|
||||
->createClient(Client::OVERSEAS_ENDPOINT);
|
||||
$client = ClientFactory::withContainer(
|
||||
ContainerFactory::withEnv(Environment::DEV)
|
||||
->withClient(new \GuzzleHttp\Client())
|
||||
->create()
|
||||
)->setServiceUrl(Client::OVERSEAS_ENDPOINT)->create();
|
||||
|
||||
self::assertInstanceOf(Client::class, $client);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user