Permalink
Browse files

OXDEV-1580 Introduce shop aware services

  • Loading branch information...
MantasVaitkunas committed Oct 16, 2018
1 parent e0a520e commit 2efabe3f22e831379acdf514b0376d2de232bbfc
@@ -9,12 +9,12 @@
namespace OxidEsales\EshopCommunity\Internal\Application;
use OxidEsales\EshopCommunity\Core\Registry;
use OxidEsales\EshopCommunity\Internal\Console\ConsoleCommandPass;
use OxidEsales\EshopCommunity\Internal\Application\Dao\ProjectYamlDao;
use OxidEsales\EshopCommunity\Internal\Application\Service\ProjectYamlImportService;
use OxidEsales\EshopCommunity\Internal\Utility\Context;
use OxidEsales\Facts\Facts;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder as SymfonyContainerBuilder;
@@ -53,7 +53,7 @@ public function getContainer(): Container
{
$symfonyContainer = new SymfonyContainerBuilder();
$symfonyContainer->addCompilerPass(new RegisterListenersPass());
$symfonyContainer->addCompilerPass(new AddConsoleCommandPass('console.command_loader', 'console.command'));
$symfonyContainer->addCompilerPass(new ConsoleCommandPass());
$this->loadServiceFiles($symfonyContainer);
if ($this->facts->isProfessional()) {
$this->loadEditionServices($symfonyContainer, $this->facts->getProfessionalEditionRootPath());
@@ -7,7 +7,6 @@
namespace OxidEsales\EshopCommunity\Internal\Application\Events;
use OxidEsales\EshopCommunity\Internal\Utility\ContextInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
@@ -0,0 +1,19 @@
<?php declare(strict_types=1);
/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/
namespace OxidEsales\EshopCommunity\Internal\Console;
use OxidEsales\EshopCommunity\Internal\Application\Events\ShopAwareInterface;
use OxidEsales\EshopCommunity\Internal\Application\Events\ShopAwareServiceTrait;
use Symfony\Component\Console\Command\Command;
/**
* Class is being used to detect if command active for active shop.
*/
abstract class AbstractShopAwareCommand extends Command implements ShopAwareInterface
{
use ShopAwareServiceTrait;
}
@@ -6,6 +6,9 @@
namespace OxidEsales\EshopCommunity\Internal\Console\CommandsProvider;
use OxidEsales\EshopCommunity\Internal\Console\AbstractShopAwareCommand;
use OxidEsales\EshopCommunity\Internal\Console\ConsoleCommandPass;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -19,6 +22,11 @@ class ServicesCommandsProvider implements CommandsProviderInterface
*/
private $container;
/**
* @var array
*/
private $commands = [];
/**
* @param ContainerInterface $container
*/
@@ -32,12 +40,37 @@ public function __construct(ContainerInterface $container)
*/
public function getCommands(): array
{
$commands = [];
if ($this->container->hasParameter('console.command.ids')) {
foreach ($this->container->getParameter('console.command.ids') as $id) {
$commands[] = $this->container->get($id);
if ($this->container->hasParameter(ConsoleCommandPass::COMMANDS_PARAMETER_NAME)) {
foreach ($this->container->getParameter(ConsoleCommandPass::COMMANDS_PARAMETER_NAME) as $id) {
$service = $this->container->get($id);
$this->setShopAwareCommands($service);
$this->setNonShopAwareCommands($service);
}
}
return $commands;
return $this->commands;
}
/**
* Set commands for modules.
*
* @param Command $service
*/
private function setShopAwareCommands(Command $service)
{
if ($service instanceof AbstractShopAwareCommand && $service->isActive()) {
$this->commands[] = $service;
}
}
/**
* Sets commands which should be shown independently from active shop.
*
* @param Command $service
*/
private function setNonShopAwareCommands(Command $service)
{
if (!$service instanceof AbstractShopAwareCommand && $service instanceof Command) {
$this->commands[] = $service;
}
}
}
@@ -0,0 +1,49 @@
<?php declare(strict_types=1);
/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/
namespace OxidEsales\EshopCommunity\Internal\Console;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Registers tagged services.
* @internal
*/
class ConsoleCommandPass implements CompilerPassInterface
{
const COMMANDS_PARAMETER_NAME = 'console.command.ids';
const COMMAND_TAG = 'console.command';
/**
* @param ContainerBuilder $container
* @throws \ReflectionException
*/
public function process(ContainerBuilder $container)
{
$commandServices = $container->findTaggedServiceIds(static::COMMAND_TAG, true);
$serviceIds = [];
foreach ($commandServices as $id => $tags) {
$serviceIds[] = $id;
$definition = $container->getDefinition($id);
$class = $container->getParameterBag()->resolveValue($definition->getClass());
if (isset($tags[0]['command'])) {
$commandName = $tags[0]['command'];
} else {
if (!$r = $container->getReflectionClass($class)) {
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
}
$commandName = $class::getDefaultName();
}
$definition->addMethodCall('setName', array($commandName));
}
$container->setParameter(static::COMMANDS_PARAMETER_NAME, $serviceIds);
}
}
@@ -6,12 +6,8 @@
namespace OxidEsales\EshopCommunity\Internal\Console;
use OxidEsales\EshopCommunity\Internal\Adapter\ShopAdapterInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
@@ -47,9 +43,7 @@ public function __construct(
*/
public function execute(InputInterface $input = null, OutputInterface $output = null)
{
foreach ($this->commandsCollectionBuilder->build()->toArray() as $command) {
$this->application->add($command);
}
$this->application->addCommands($this->commandsCollectionBuilder->build()->toArray());
$this->application->run($input, $output);
}
}
@@ -9,10 +9,6 @@ services:
symfony.component.console.application:
class: Symfony\Component\Console\Application
public: false
calls:
- method: setCommandLoader
arguments:
- '@console.command_loader'
Symfony\Component\Console\Output\ConsoleOutputInterface:
class: Symfony\Component\Console\Output\ConsoleOutput
@@ -23,12 +19,23 @@ services:
arguments:
- '@console.commands_provider.component_commands_provider'
- '@console.commands_provider.module_commands_provider'
- '@console.commands_provider.services_commands_provider'
console.commands_provider.component_commands_provider:
class: OxidEsales\EshopCommunity\Internal\Console\CommandsProvider\ComponentCommandsProvider
public: false
arguments: ['@Composer\Repository\WritableRepositoryInterface']
console.commands_provider.module_commands_provider:
class: OxidEsales\EshopCommunity\Internal\Console\CommandsProvider\ModuleCommandsProvider
public: false
autowire: true
console.commands_provider.services_commands_provider:
class: OxidEsales\EshopCommunity\Internal\Console\CommandsProvider\ServicesCommandsProvider
public: false
autowire: true
composer.composer:
class: Composer\Composer
public: true
@@ -52,11 +59,6 @@ services:
factory: 'composer.repository.manager:getLocalRepository'
public: false
console.commands_provider.module_commands_provider:
class: OxidEsales\EshopCommunity\Internal\Console\CommandsProvider\ModuleCommandsProvider
public: false
autowire: true
symfony.component.console.input.argv_input:
class: Symfony\Component\Console\Input\ArgvInput
public: false
@@ -1,12 +1,9 @@
parameters:
utility_path: OxidEsales\EshopCommunity\Internal\Utility
services:
OxidEsales\Eshop\Core\Config:
class: OxidEsales\Eshop\Core\Config
factory: ['OxidEsales\Eshop\Core\Registry', getConfig]
public: false
OxidEsales\EshopCommunity\Internal\Utility\ContextInterface:
class: %utility_path%\Context
class: OxidEsales\EshopCommunity\Internal\Utility\Context
autowire: true
public: false
@@ -28,40 +28,54 @@ class ExecutorTest extends TestCase
public function testIfRegisteredCommandInList()
{
$commands = $this->getMockBuilder(CommandsProvidableInterface::class)->getMock();
$commands->method('getCommands')->willReturn([new TestCommand()]);
$commandsCollectionBuilder = new CommandsCollectionBuilder($commands);
$consoleOutput = $this->execute(
$this->getApplication(),
$commandsCollectionBuilder,
new ArrayInput(['command' => 'list'])
);
$executor = $this->makeExecutor();
$output = new StreamOutput(fopen('php://memory', 'w', false));
$executor->execute(new ArrayInput(['command' => 'list']), $output);
$this->assertRegexp('/oe:tests:test-command/', $consoleOutput);
$this->assertRegexp('/oe:tests:test-command/', $this->getOutputFromStream($output));
}
public function testCommandExecution()
{
$commands = $this->getMockBuilder(CommandsProvidableInterface::class)->getMock();
$commands->method('getCommands')->willReturn([new TestCommand()]);
$commandsCollectionBuilder = new CommandsCollectionBuilder($commands);
$consoleOutput = $this->execute(
$this->getApplication(),
$commandsCollectionBuilder,
new ArrayInput(['command' => 'oe:tests:test-command'])
);
$executor = $this->makeExecutor();
$output = new StreamOutput(fopen('php://memory', 'w', false));
$executor->execute(new ArrayInput(['command' => 'oe:tests:test-command']), $output);
$this->assertSame('Command have been executed!'.PHP_EOL, $consoleOutput);
$this->assertSame('Command have been executed!'.PHP_EOL, $this->getOutputFromStream($output));
}
public function testCommandWithChangedNameExecution()
{
$executor = $this->makeExecutor();
$output = new StreamOutput(fopen('php://memory', 'w', false));
$executor->execute(new ArrayInput(['command' => 'oe:tests:test-command-changed-name']), $output);
$this->assertSame('Command have been executed!'.PHP_EOL, $this->getOutputFromStream($output));
}
/**
* @return Application
* @return ExecutorInterface
*/
private function getApplication(): Application
private function makeExecutor(): ExecutorInterface
{
$application = $this->get('symfony.component.console.application');
$application->setAutoExit(false);
$facts = $this->getMockBuilder(Facts::class)->setMethods(['getSourcePath'])->getMock();
$facts->method('getSourcePath')->willReturn(__DIR__ . '/Fixtures');
$containerBuilder = new ContainerBuilder($facts);
$container = $containerBuilder->getContainer();
$container->compile();
$executor = $container->get(ExecutorInterface::class);
return $executor;
}
return $application;
/**
* @param StreamOutput $output
* @return bool|string
*/
private function getOutputFromStream($output)
{
$stream = $output->getStream();
rewind($stream);
$display = stream_get_contents($stream);
return $display;
}
}

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,21 @@
services:
oxid_esales.tests.integration.internal.console.fixtures.test_command:
class: OxidEsales\EshopCommunity\Tests\Integration\Internal\Console\Fixtures\TestCommand
public: true
tags:
- { name: 'console.command', command: 'oe:tests:test-command' }
oxid_esales.tests.integration.internal.console.fixtures.test_command_change_name:
class: OxidEsales\EshopCommunity\Tests\Integration\Internal\Console\Fixtures\TestCommand
public: true
tags:
- { name: 'console.command', command: 'oe:tests:test-command-changed-name' }
symfony.component.console.application:
class: Symfony\Component\Console\Application
public: false
calls:
- method: setAutoExit
arguments:
- false
Oops, something went wrong.

0 comments on commit 2efabe3

Please sign in to comment.