Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/origin/master' into 1.9
Browse files Browse the repository at this point in the history
  • Loading branch information
rgrebenchuk committed Feb 12, 2016
2 parents 618c0b9 + f1595e3 commit 6e45c54
Show file tree
Hide file tree
Showing 164 changed files with 5,167 additions and 604 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class ActivityAssociationRouteOptionsResolver implements RouteOptionsResolverInt
/** @var EntityAliasResolver */
protected $entityAliasResolver;

/** @var array */
private $supportedActivities;

/**
* @param ConfigProvider $groupingConfigProvider
* @param EntityAliasResolver $entityAliasResolver
Expand All @@ -50,7 +53,25 @@ public function resolve(Route $route, RouteCollectionAccessor $routes)
}

if ($this->hasAttribute($route, self::ACTIVITY_PLACEHOLDER)) {
$activities = array_map(
$activities = $this->getSupportedActivities();
if (!empty($activities)) {
$this->adjustRoutes($route, $routes, $activities);
}

$this->completeRouteRequirements($route);
$route->setOption('hidden', true);
} elseif ($this->hasAttribute($route, self::ENTITY_PLACEHOLDER)) {
$this->completeRouteRequirements($route);
}
}

/**
* @return string[]
*/
protected function getSupportedActivities()
{
if (null === $this->supportedActivities) {
$this->supportedActivities = array_map(
function (ConfigInterface $config) {
// convert to entity alias
return $this->entityAliasResolver->getPluralAlias(
Expand All @@ -68,15 +89,9 @@ function (ConfigInterface $config) {
}
)
);

if (!empty($activities)) {
$this->adjustRoutes($route, $routes, $activities);
$route->setRequirement(self::ACTIVITY_ATTRIBUTE, implode('|', $activities));
}
$this->completeRouteRequirements($route);
} elseif ($this->hasAttribute($route, self::ENTITY_PLACEHOLDER)) {
$this->completeRouteRequirements($route);
}

return $this->supportedActivities;
}

/**
Expand Down Expand Up @@ -126,6 +141,11 @@ protected function adjustRoutes(Route $route, RouteCollectionAccessor $routes, $
*/
protected function completeRouteRequirements(Route $route)
{
if (null === $route->getRequirement(self::ACTIVITY_ATTRIBUTE)
&& $this->hasAttribute($route, self::ACTIVITY_PLACEHOLDER)
) {
$route->setRequirement(self::ACTIVITY_ATTRIBUTE, '\w+');
}
if (null === $route->getRequirement(self::ACTIVITY_ID_ATTRIBUTE)
&& $this->hasAttribute($route, self::ACTIVITY_ID_PLACEHOLDER)
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public function testResolve()
$this->routeOptionsResolver->resolve($route, $this->routeCollectionAccessor);

$this->assertEquals(
['activity' => 'emails|calls|tasks|events'],
['activity' => '\w+'],
$route->getRequirements()
);

Expand All @@ -130,7 +130,7 @@ public function testResolve()
);

$this->assertEquals(
'emails|calls|tasks|events',
'\w+',
$this->routeCollection->get('tested_route')->getRequirement('activity')
);
$this->assertEquals(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
oro_api:
entities:
Oro\Bundle\ActivityListBundle\Entity\ActivityList: ~
Oro\Bundle\ActivityListBundle\Entity\ActivityOwner: ~
2 changes: 1 addition & 1 deletion src/Oro/Bundle/AddressBundle/Entity/AbstractAddress.php
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ public function beforeSave()

/**
* @param ExecutionContextInterface $context
* @deprecated Use \Oro\Bundle\AddressBundle\Validator\Constraints\ValidRegionValidator instead
* @deprecated since 1.9 Use \Oro\Bundle\AddressBundle\Validator\Constraints\ValidRegionValidator instead
*/
public function isRegionValid(ExecutionContextInterface $context)
{
Expand Down
3 changes: 3 additions & 0 deletions src/Oro/Bundle/AddressBundle/Resources/config/oro/api.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
oro_api:
entities:
Oro\Bundle\AddressBundle\Entity\Address: ~

relations:
Oro\Bundle\AddressBundle\Entity\AbstractAddress:
definition:
Expand Down
4 changes: 2 additions & 2 deletions src/Oro/Bundle/AddressBundle/Resources/config/validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ Oro\Bundle\AddressBundle\Entity\AbstractAddress:

# Prevent required values for all child of AbstractAddress
Oro\Bundle\AddressBundle\Entity\Address:
constraints:
- Oro\Bundle\AddressBundle\Validator\Constraints\ValidRegion: { groups: ['RequirePeriod'] }
properties:
street:
- NotBlank: ~
city:
- NotBlank: ~
postalCode:
- NotBlank: ~
constraints:
- Oro\Bundle\AddressBundle\Validator\Constraints\ValidRegion: ~

Oro\Bundle\AddressBundle\Entity\AbstractEmail:
properties:
Expand Down
24 changes: 21 additions & 3 deletions src/Oro/Bundle/ApiBundle/Command/DebugCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableSeparator;
Expand All @@ -12,6 +13,7 @@
use Oro\Component\ChainProcessor\ChainApplicableChecker;
use Oro\Component\ChainProcessor\Context;
use Oro\Component\ChainProcessor\ProcessorBagInterface;
use Oro\Bundle\ApiBundle\Request\RequestType;

class DebugCommand extends ContainerAwareCommand
{
Expand All @@ -27,6 +29,12 @@ protected function configure()
'action',
InputArgument::OPTIONAL,
'Shows a list of processors for a specified action in the order they are executed'
)
->addOption(
'request-type',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'API request type'
);
}

Expand All @@ -39,7 +47,7 @@ public function execute(InputInterface $input, OutputInterface $output)
if (empty($action)) {
$this->dumpActions($output);
} else {
$this->dumpProcessors($output, $action);
$this->dumpProcessors($output, $action, $input->getOption('request-type'));
}
}

Expand Down Expand Up @@ -77,9 +85,12 @@ protected function dumpActions(OutputInterface $output)
/**
* @param OutputInterface $output
* @param string $action
* @param string[] $requestType
*/
protected function dumpProcessors(OutputInterface $output, $action)
protected function dumpProcessors(OutputInterface $output, $action, array $requestType)
{
$output->writeln('The processors are displayed in order they are executed.');

/** @var ProcessorBagInterface $processorBag */
$processorBag = $this->getContainer()->get('oro_api.processor_bag');

Expand All @@ -88,8 +99,15 @@ protected function dumpProcessors(OutputInterface $output, $action)

$context = new Context();
$context->setAction($action);
if (!empty($requestType)) {
$context->set('requestType', $requestType);
}
$processors = $processorBag->getProcessors($context);
$processors->setApplicableChecker(new ChainApplicableChecker());

$applicableChecker = new ChainApplicableChecker();
$applicableChecker->addChecker(new RequestTypeApplicableChecker());
$processors->setApplicableChecker($applicableChecker);

$i = 0;
foreach ($processors as $processor) {
if ($i > 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/Oro/Bundle/ApiBundle/Command/DumpConfigCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function execute(InputInterface $input, OutputInterface $output)
/** @var EntityClassNameHelper $entityClassNameHelper */
$entityClassNameHelper = $this->getContainer()->get('oro_entity.entity_class_name_helper');

$entityClass = $entityClassNameHelper->resolveEntityClass($input->getArgument('entity'));
$entityClass = $entityClassNameHelper->resolveEntityClass($input->getArgument('entity'), true);
$requestType = $input->getOption('request-type');
// @todo: API version is not supported for now
//$version = $input->getArgument('version');
Expand Down
2 changes: 1 addition & 1 deletion src/Oro/Bundle/ApiBundle/Command/DumpMetadataCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function execute(InputInterface $input, OutputInterface $output)
/** @var EntityClassNameHelper $entityClassNameHelper */
$entityClassNameHelper = $this->getContainer()->get('oro_entity.entity_class_name_helper');

$entityClass = $entityClassNameHelper->resolveEntityClass($input->getArgument('entity'));
$entityClass = $entityClassNameHelper->resolveEntityClass($input->getArgument('entity'), true);
$requestType = $input->getOption('request-type');
// @todo: API version is not supported for now
//$version = $input->getArgument('version');
Expand Down
122 changes: 122 additions & 0 deletions src/Oro/Bundle/ApiBundle/Command/DumpPublicResourcesCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

namespace Oro\Bundle\ApiBundle\Command;

use Oro\Bundle\ApiBundle\Request\PublicResource;
use Oro\Bundle\EntityBundle\ORM\EntityAliasResolver;
use Oro\Bundle\EntityBundle\Provider\EntityClassNameProviderInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

use Oro\Bundle\ApiBundle\Provider\PublicResourcesLoader;
use Oro\Bundle\ApiBundle\Request\RequestType;
use Oro\Bundle\ApiBundle\Request\Version;

class DumpPublicResourcesCommand extends ContainerAwareCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('oro:api:resources:dump')
->setDescription('Dumps all public API resources.')
// @todo: API version is not supported for now
//->addArgument(
// 'version',
// InputArgument::OPTIONAL,
// 'API version',
// Version::LATEST
//)
->addOption(
'request-type',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'API request type',
[RequestType::REST, RequestType::JSON_API]
);
}

/**
* {@inheritdoc}
*/
public function execute(InputInterface $input, OutputInterface $output)
{
$requestType = $input->getOption('request-type');
// @todo: API version is not supported for now
//$version = $input->getArgument('version');
$version = Version::LATEST;

/** @var PublicResourcesLoader $resourcesLoader */
$resourcesLoader = $this->getContainer()->get('oro_api.public_resources_loader');
$resources = $resourcesLoader->getResources($version, $requestType);

$table = new Table($output);
$table->setHeaders(['Entity', 'Attributes']);

$i = 0;
foreach ($resources as $resource) {
if ($i > 0) {
$table->addRow(new TableSeparator());
}
$table->addRow(
[
$resource->getEntityClass(),
$this->convertResourceAttributesToString($this->getResourceAttributes($resource))
]
);
$i++;
}

$table->render();
}

/**
* @param PublicResource $resource
*
* @return array
*/
protected function getResourceAttributes(PublicResource $resource)
{
$result = [];

$entityClass = $resource->getEntityClass();

/** @var EntityAliasResolver $entityAliasResolver */
$entityAliasResolver = $this->getContainer()->get('oro_entity.entity_alias_resolver');
$result['Alias'] = $entityAliasResolver->getPluralAlias($entityClass);

/** @var EntityClassNameProviderInterface $entityClassNameProvider */
$entityClassNameProvider = $this->getContainer()->get('oro_entity.entity_class_name_provider');
$result['Name'] = $entityClassNameProvider->getEntityClassName($entityClass);
$result['Plural Name'] = $entityClassNameProvider->getEntityClassPluralName($entityClass);

return $result;
}

/**
* @param array $attributes
*
* @return string
*/
protected function convertResourceAttributesToString(array $attributes)
{
$result = '';

$i = 0;
foreach ($attributes as $name => $value) {
if ($i > 0) {
$result .= PHP_EOL;
}
$result .= sprintf('%s: %s', $name, $value);
$i++;
}

return $result;
}
}
44 changes: 44 additions & 0 deletions src/Oro/Bundle/ApiBundle/Command/RequestTypeApplicableChecker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Oro\Bundle\ApiBundle\Command;

use Oro\Component\ChainProcessor\ApplicableCheckerInterface;
use Oro\Component\ChainProcessor\ContextInterface;

class RequestTypeApplicableChecker implements ApplicableCheckerInterface
{
/**
* {@inheritdoc}
*/
public function isApplicable(ContextInterface $context, array $processorAttributes)
{
$result = self::ABSTAIN;
$attrName = 'requestType';
if (!empty($processorAttributes[$attrName]) && $context->has($attrName)) {
if (!$this->isMatch($processorAttributes[$attrName], $context->get($attrName))) {
$result = self::NOT_APPLICABLE;
}
}

return $result;
}

/**
* Checks if a value of a processor attribute matches a corresponding value from the context
*
* @param mixed $value
* @param mixed $contextValue
*
* @return bool
*/
protected function isMatch($value, $contextValue)
{
if (is_array($contextValue)) {
return is_array($value)
? count(array_intersect($value, $contextValue)) === count($value)
: in_array($value, $contextValue, true);
}

return $contextValue === $value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ConfigurationCompilerPass implements CompilerPassInterface
const ACTION_PROCESSOR_BAG_SERVICE_ID = 'oro_api.action_processor_bag';
const PROCESSOR_BAG_SERVICE_ID = 'oro_api.processor_bag';
const FILTER_FACTORY_TAG = 'oro.api.filter_factory';
const FILTER_FACTORY_SERVICE_ID = 'oro.api.filter_factory';
const FILTER_FACTORY_SERVICE_ID = 'oro_api.filter_factory';
const EXCLUSION_PROVIDER_TAG = 'oro_entity.exclusion_provider.api';
const EXCLUSION_PROVIDER_SERVICE_ID = 'oro_api.entity_exclusion_provider';
const VIRTUAL_FIELD_PROVIDER_TAG = 'oro_entity.virtual_field_provider.api';
Expand Down
Loading

0 comments on commit 6e45c54

Please sign in to comment.