Introduce ContainerWrapper
Container wrapper wraps both premium and free containers and adds ability for free plugin to use premium plugin services directly. [PREMIUM-99]
This commit is contained in:
@ -2,9 +2,9 @@
|
||||
|
||||
namespace MailPoet\API;
|
||||
|
||||
use MailPoet\DI\ContainerWrapper;
|
||||
use MailPoetVendor\Psr\Container\ContainerInterface;
|
||||
use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use MailPoet\DI\ContainerFactory;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
@ -37,8 +37,7 @@ class API {
|
||||
*/
|
||||
private static function ensureContainerIsLoaded() {
|
||||
if(!self::$container) {
|
||||
$factory = new ContainerFactory();
|
||||
self::$container = $factory->getContainer();
|
||||
self::$container = ContainerWrapper::getInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ namespace MailPoet\API\JSON;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoetVendor\Psr\Container\ContainerInterface;
|
||||
use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Util\Helpers;
|
||||
use MailPoet\Util\Security;
|
||||
@ -143,13 +142,7 @@ class API {
|
||||
throw new \Exception(__('Invalid API endpoint.', 'mailpoet'));
|
||||
}
|
||||
|
||||
try {
|
||||
$endpoint = $this->container->get($this->_request_endpoint_class);
|
||||
} catch (ServiceNotFoundException $e) {
|
||||
// Hotfix for Premium plugin which adds endpoints which are not registered in DI container
|
||||
$endpoint = new $this->_request_endpoint_class();
|
||||
}
|
||||
|
||||
if(!method_exists($endpoint, $this->_request_method)) {
|
||||
throw new \Exception(__('Invalid API endpoint method.', 'mailpoet'));
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ namespace MailPoet\Config;
|
||||
|
||||
use MailPoet\API;
|
||||
use MailPoet\Cron\CronTrigger;
|
||||
use MailPoet\DI\ContainerFactory;
|
||||
use MailPoet\DI\ContainerWrapper;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Router;
|
||||
use MailPoet\Util\ConflictResolver;
|
||||
@ -97,8 +97,7 @@ class Initializer {
|
||||
}
|
||||
|
||||
function loadContainer() {
|
||||
$container_factory = new ContainerFactory(WP_DEBUG);
|
||||
$this->container = $container_factory->getContainer();
|
||||
$this->container = ContainerWrapper::getInstance(WP_DEBUG);
|
||||
API\API::injectContainer($this->container);
|
||||
}
|
||||
|
||||
|
62
lib/DI/ContainerWrapper.php
Normal file
62
lib/DI/ContainerWrapper.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\DI;
|
||||
|
||||
use MailPoetVendor\Psr\Container\ContainerInterface;
|
||||
use MailPoetVendor\Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class ContainerWrapper implements ContainerInterface {
|
||||
|
||||
/** @var ContainerInterface */
|
||||
private $free_container;
|
||||
|
||||
/** @var ContainerInterface|null */
|
||||
private $premium_container;
|
||||
|
||||
/** @var ContainerWrapper */
|
||||
private static $instance;
|
||||
|
||||
public function __construct(ContainerInterface $free_container, ContainerInterface $premium_container = null) {
|
||||
$this->free_container = $free_container;
|
||||
$this->premium_container = $premium_container;
|
||||
}
|
||||
|
||||
function get($id) {
|
||||
try {
|
||||
return $this->free_container->get($id);
|
||||
} catch (NotFoundExceptionInterface $e) {
|
||||
if(!$this->premium_container) {
|
||||
throw $e;
|
||||
}
|
||||
return $this->premium_container->get($id);
|
||||
}
|
||||
}
|
||||
|
||||
function has($id) {
|
||||
return $this->free_container->has($id) || ($this->premium_container && $this->premium_container->has($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ContainerInterface|null
|
||||
*/
|
||||
function getPremiumContainer() {
|
||||
return $this->premium_container;
|
||||
}
|
||||
|
||||
static function getInstance($debug = false) {
|
||||
if(self::$instance) {
|
||||
return self::$instance;
|
||||
}
|
||||
$free_container_factory = new ContainerFactory(new ContainerConfigurator(), $debug);
|
||||
$free_container = $free_container_factory->getContainer();
|
||||
$premium_container = null;
|
||||
if(class_exists(\MailPoet\Premium\DI\ContainerConfigurator::class)) {
|
||||
$premium_container_factory = new ContainerFactory(new \MailPoet\Premium\DI\ContainerConfigurator($free_container), $debug);
|
||||
$premium_container = $premium_container_factory->getContainer();
|
||||
$premium_container->set(IContainerConfigurator::FREE_CONTAINER_SERVICE_SLUG, $free_container);
|
||||
$free_container->set(IContainerConfigurator::PREMIUM_CONTAINER_SERVICE_SLUG, $premium_container);
|
||||
}
|
||||
self::$instance = new ContainerWrapper($free_container, $premium_container);
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
87
tests/unit/DI/ContainerWrapperTest.php
Normal file
87
tests/unit/DI/ContainerWrapperTest.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
namespace MailPoet\Test\DI;
|
||||
|
||||
use Codeception\Stub;
|
||||
use MailPoet\DI\ContainerWrapper;
|
||||
use MailPoetVendor\Symfony\Component\DependencyInjection\Container;
|
||||
use MailPoetVendor\Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use MailPoetVendor\Psr\Container\ContainerInterface;
|
||||
use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
|
||||
class ContainerWrapperTest extends \MailPoetUnitTest {
|
||||
function testItCanConstruct() {
|
||||
$instance = new ContainerWrapper(new ContainerBuilder());
|
||||
expect($instance)->isInstanceOf(ContainerWrapper::class);
|
||||
expect($instance)->isInstanceOf(ContainerInterface::class);
|
||||
|
||||
$instance = new ContainerWrapper(new ContainerBuilder(), new ContainerBuilder());
|
||||
expect($instance)->isInstanceOf(ContainerWrapper::class);
|
||||
expect($instance)->isInstanceOf(ContainerInterface::class);
|
||||
}
|
||||
|
||||
function testItProvidesPremiumContainerIfAvailable() {
|
||||
$instance = new ContainerWrapper(new ContainerBuilder());
|
||||
expect($instance->getPremiumContainer())->null();
|
||||
|
||||
$instance = new ContainerWrapper(new ContainerBuilder(), new ContainerBuilder());
|
||||
expect($instance->getPremiumContainer())->isInstanceOf(ContainerBuilder::class);
|
||||
}
|
||||
|
||||
function testItProvidesFreePluginServices() {
|
||||
$free_container_stub = Stub::make(Container::class, [
|
||||
'get' => function () {
|
||||
return 'service';
|
||||
}
|
||||
]);
|
||||
$instance = new ContainerWrapper($free_container_stub);
|
||||
$service = $instance->get('service_id');
|
||||
expect($service)->equals('service');
|
||||
}
|
||||
|
||||
function testItThrowsFreePluginServices() {
|
||||
$free_container_stub = Stub::make(Container::class, [
|
||||
'get' => function ($id) {
|
||||
throw new ServiceNotFoundException($id);
|
||||
}
|
||||
]);
|
||||
$instance = new ContainerWrapper($free_container_stub);
|
||||
$exception = null;
|
||||
try {
|
||||
$instance->get('service');
|
||||
} catch (ServiceNotFoundException $e) {
|
||||
$exception = $e;
|
||||
}
|
||||
expect($exception)->isInstanceOf(ServiceNotFoundException::class);
|
||||
}
|
||||
|
||||
function testItReturnServiceFromPremium() {
|
||||
$free_container_stub = Stub::make(Container::class, [
|
||||
'get' => function ($id) {
|
||||
throw new ServiceNotFoundException($id);
|
||||
}
|
||||
]);
|
||||
$premium_container_stub = Stub::make(Container::class, [
|
||||
'get' => function () {
|
||||
return 'service_1';
|
||||
}
|
||||
]);
|
||||
$instance = new ContainerWrapper($free_container_stub, $premium_container_stub);
|
||||
expect($instance->get('service'))->equals('service_1');
|
||||
}
|
||||
|
||||
function testItThrowsIfServiceNotFoundInBothContainers() {
|
||||
$container_stub = Stub::make(Container::class, [
|
||||
'get' => function ($id) {
|
||||
throw new ServiceNotFoundException($id);
|
||||
}
|
||||
]);
|
||||
$instance = new ContainerWrapper($container_stub, $container_stub);
|
||||
$exception = null;
|
||||
try {
|
||||
$instance->get('service');
|
||||
} catch (ServiceNotFoundException $e) {
|
||||
$exception = $e;
|
||||
}
|
||||
expect($exception)->isInstanceOf(ServiceNotFoundException::class);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user