Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ Thumbs.db

Tests/Fixtures/TestProject/web/bundles
Tests/Fixtures/TestProject/var
Tests/Fixtures/TestProject/config/reference.php
Tests/Fixtures/TestProject/ProjectBundle/DataFixtures
Tests/Fixtures/TestProject/ProjectBundle/Entity
1 change: 1 addition & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
'vendor',
'Tests/Fixtures/TestProject/var',
])
->notPath('Tests/Fixtures/TestProject/config/reference.php')
->in(__DIR__)
)
;
4 changes: 2 additions & 2 deletions Command/ResourceDebugCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function __construct(ConfigurationRepository $repository)
parent::__construct();
}

protected function configure()
protected function configure(): void
{
$this
->setName('imatic:controller:resource-debug')
Expand All @@ -32,7 +32,7 @@ protected function configure()
->addArgument('action', InputArgument::OPTIONAL, 'Action to debug');
}

protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$resourceName = $input->getArgument('resource');
$io = new SymfonyStyle($input, $output);
Expand Down
2 changes: 1 addition & 1 deletion Controller/Api/Command/BatchCommandApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function batchCommand($allowedCommands)
$this->command->addCommandParameters([
'selected' => $request->request->all()['selected'] ?? [],
'selectedAll' => $request->request->get('selectedAll', false),
'query' => $request->get('query', '[]'),
'query' => $request->request->get('query', $request->query->get('query', '[]')),
]);

return $this;
Expand Down
2 changes: 1 addition & 1 deletion Controller/Api/Form/FormApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function namedForm($name, $type, $emptyValue = null, array $options = [])
return $this;
}

public function edit(QueryObjectInterface $queryObject, \Closure $closure = null)
public function edit(QueryObjectInterface $queryObject, ?\Closure $closure = null)
{
$item = $this->data->query('item', $queryObject);
$this->response->throwNotFoundUnless($item);
Expand Down
2 changes: 1 addition & 1 deletion Controller/Api/Listing/ListingApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function __construct(
$this->displayCriteriaReader = $displayCriteriaReader;
}

public function listing(QueryObjectInterface $queryObject, DisplayCriteriaInterface $displayCriteria = null)
public function listing(QueryObjectInterface $queryObject, ?DisplayCriteriaInterface $displayCriteria = null)
{
$this->displayCriteria = $displayCriteria;
$this->queryObject = $queryObject;
Expand Down
12 changes: 6 additions & 6 deletions Controller/Feature/Data/DataFeature.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function __construct(QueryExecutorInterface $queryExecutor)
*
* @return mixed
*/
public function query($name, QueryObjectInterface $queryObject, DisplayCriteriaInterface $displayCriteria = null)
public function query($name, QueryObjectInterface $queryObject, ?DisplayCriteriaInterface $displayCriteria = null)
{
$result = $this->doQuery($queryObject, $displayCriteria);
$this->data[$name] = $result;
Expand All @@ -39,7 +39,7 @@ public function query($name, QueryObjectInterface $queryObject, DisplayCriteriaI
*
* @return int
*/
public function count($name, QueryObjectInterface $queryObject, DisplayCriteriaInterface $displayCriteria = null)
public function count($name, QueryObjectInterface $queryObject, ?DisplayCriteriaInterface $displayCriteria = null)
{
$count = $this->doCount($queryObject, $displayCriteria);
$this->data[$name] = $count;
Expand All @@ -55,7 +55,7 @@ public function count($name, QueryObjectInterface $queryObject, DisplayCriteriaI
*
* @return array result, count
*/
public function queryAndCount($resultName, $countName, QueryObjectInterface $queryObject, DisplayCriteriaInterface $displayCriteria = null)
public function queryAndCount($resultName, $countName, QueryObjectInterface $queryObject, ?DisplayCriteriaInterface $displayCriteria = null)
{
list($result, $count) = $this->doQueryAndCount($queryObject, $displayCriteria);

Expand Down Expand Up @@ -87,17 +87,17 @@ public function set($name, $value)
$this->data[$name] = $value;
}

protected function doQuery(QueryObjectInterface $queryObject, DisplayCriteriaInterface $displayCriteria = null)
protected function doQuery(QueryObjectInterface $queryObject, ?DisplayCriteriaInterface $displayCriteria = null)
{
return $this->queryExecutor->execute($queryObject, $displayCriteria);
}

protected function doCount(QueryObjectInterface $queryObject, DisplayCriteriaInterface $displayCriteria = null)
protected function doCount(QueryObjectInterface $queryObject, ?DisplayCriteriaInterface $displayCriteria = null)
{
return $this->queryExecutor->count($queryObject, $displayCriteria);
}

protected function doQueryAndCount(QueryObjectInterface $queryObject, DisplayCriteriaInterface $displayCriteria = null)
protected function doQueryAndCount(QueryObjectInterface $queryObject, ?DisplayCriteriaInterface $displayCriteria = null)
{
return $this->queryExecutor->executeAndCount($queryObject, $displayCriteria);
}
Expand Down
2 changes: 1 addition & 1 deletion Controller/Feature/Data/DataFeatureTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
trait DataFeatureTrait
{
public function addValue($name, QueryObjectInterface $queryObject, DisplayCriteriaInterface $displayCriteria = null)
public function addValue($name, QueryObjectInterface $queryObject, ?DisplayCriteriaInterface $displayCriteria = null)
{
$this->data->query($name, $queryObject, $displayCriteria);

Expand Down
4 changes: 2 additions & 2 deletions Controller/Feature/Request/RequestFeature.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ public function getCurrentRequest()
*/
public function getCurrentRoute()
{
return $this->getCurrentRequest()->get('_route');
return $this->getCurrentRequest()->attributes->get('_route');
}

/**
* @return array
*/
public function getCurrentRouteParams()
{
return $this->getCurrentRequest()->get('_route_params');
return $this->getCurrentRequest()->attributes->get('_route_params');
}

/**
Expand Down
2 changes: 1 addition & 1 deletion Controller/Feature/Security/SecurityFeature.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function enableDataAuthorization($enable = true)
$this->dataAuthorizationEnabled = $enable;
}

public function addDataCheck($attributes, $dataKey, \Closure $callback = null)
public function addDataCheck($attributes, $dataKey, ?\Closure $callback = null)
{
$this->dataAuthorizationEnabled = true;

Expand Down
2 changes: 1 addition & 1 deletion Controller/Feature/Security/SecurityFeatureTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ trait SecurityFeatureTrait
*
* @return $this
*/
public function addDataAuthorizationCheck($attributes, $dataKey = null, \Closure $callback = null)
public function addDataAuthorizationCheck($attributes, $dataKey = null, ?\Closure $callback = null)
{
if (null === $dataKey) {
$dataKey = 'item';
Expand Down
38 changes: 17 additions & 21 deletions Controller/Resource/ResourceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,44 @@
use Imatic\Bundle\ControllerBundle\Controller\Api\ApiTrait;
use Imatic\Bundle\ControllerBundle\Resource\Config\Resource;
use Imatic\Bundle\ControllerBundle\Resource\Config\ResourceAction;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Imatic\Bundle\ControllerBundle\Resource\ConfigurationRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class ResourceController implements ContainerAwareInterface
class ResourceController extends AbstractController
{
use ContainerAwareTrait;
use ApiTrait;
use SecurityTrait;

/**
* @return ResourceAction
*/
protected function getActionConfig()
public static function getSubscribedServices(): array
{
$container = $this->container;
$request = $container->get('request_stack')->getCurrentRequest();
return array_merge(parent::getSubscribedServices(), [
ConfigurationRepository::class => ConfigurationRepository::class,
]);
}

protected function getActionConfig(): ResourceAction
{
$request = $this->container->get('request_stack')->getCurrentRequest();

$resourceName = $request->attributes->get('resource');
$actionName = $request->attributes->get('action');

$resource = $container->get('imatic_controller.resource.' . $resourceName);
$resource = $this->container->get(ConfigurationRepository::class)->getResource($resourceName);
$action = $resource->getAction($actionName);

$this->checkAuthorization($resource, $action);

return $action;
}

/**
* @return \Imatic\Bundle\ControllerBundle\Resource\Config\Resource
*/
protected function getResourceConfig()
protected function getResourceConfig(): Resource
{
$container = $this->container;
$request = $container->get('request_stack')->getCurrentRequest();

$request = $this->container->get('request_stack')->getCurrentRequest();
$resourceName = $request->attributes->get('resource');

return $container->get('imatic_controller.resource.' . $resourceName);
return $this->container->get(ConfigurationRepository::class)->getResource($resourceName);
}

protected function checkAuthorization(Resource $resource, ResourceAction $action)
protected function checkAuthorization(Resource $resource, ResourceAction $action): void
{
if (isset($resource->getConfig()['role'])) {
$this->denyAccessUnlessGranted($resource->getConfig()['role']);
Expand Down
2 changes: 1 addition & 1 deletion DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('imatic_controller');
$rootNode = $treeBuilder->getRootNode();
Expand Down
18 changes: 10 additions & 8 deletions DependencyInjection/ImaticControllerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class ImaticControllerExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
public function load(array $configs, ContainerBuilder $container): void
{
// Merge configuration files
$config = [];
Expand All @@ -28,33 +28,35 @@ public function load(array $configs, ContainerBuilder $container)
$this->processResourcesConfiguration($config['resources_config'] ?? [], $config['resources'], $container);

// Load services
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.xml');
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yaml');
$this->loadImportConfiguration($loader);
}

private function processResourcesConfiguration(array $resourcesConfig, array $resources, ContainerBuilder $container)
private function processResourcesConfiguration(array $resourcesConfig, array $resources, ContainerBuilder $container): void
{
$resourceConfigurationProcessor = new ConfigurationProcessor();
$config = $resourceConfigurationProcessor->process($resourcesConfig, $resources);

$definition = new Definition(ConfigurationRepository::class);
foreach ($config as $resourceName => $resource) {
$resourceDefinition = new Definition(Resource::class);
$resourceDefinition->addMethodCall('unserialize', [\serialize($resource)]);
$resourceDefinition->setFactory([Resource::class, 'fromSerialized']);
$resourceDefinition->setArguments([\serialize($resource)]);
$resourceDefinition->setPublic(true);
$container->setDefinition('imatic_controller.resource.' . $resourceName, $resourceDefinition);

$definition->addMethodCall('addResource', [$resourceName, $resourceDefinition]);
}

$container->setDefinition('imatic_controller.resources.resource_repository', $definition);
$container->setAlias(ConfigurationRepository::class, 'imatic_controller.resources.resource_repository')->setPublic(true);
}

private function loadImportConfiguration(Loader\XmlFileLoader $loader)
private function loadImportConfiguration(Loader\YamlFileLoader $loader): void
{
if (\class_exists('Imatic\Bundle\ImportExportBundle\ImaticImportExportBundle')) {
$loader->load('import_export.xml');
$loader->load('import_export.yaml');
}
}
}
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ phpcs:

.PHONY: phpmd
phpmd:
./vendor/bin/phpmd $$((\
find * -maxdepth 0 -not -name 'vendor' -not -name 'Tests' -type d && \
find Tests/ -mindepth 1 -maxdepth 1 -not -name 'Fixtures' && \
find Tests/Fixtures/ -mindepth 2 -maxdepth 2 -not -name 'var' \
) | paste --delimiter , --serial) text phpmd.xml
# phpmd is temporarily disabled — phpmd/phpmd 2.15.0 does not support Symfony 8.1.
# Re-enable once phpmd releases a version compatible with Symfony 8.x.
#./vendor/bin/phpmd $$((\
# find * -maxdepth 0 -not -name 'vendor' -not -name 'Tests' -type d && \
# find Tests/ -mindepth 1 -maxdepth 1 -not -name 'Fixtures' && \
# find Tests/Fixtures/ -mindepth 2 -maxdepth 2 -not -name 'var' \
# ) | paste --delimiter , --serial) text phpmd.xml

.PHONY: phpunit
phpunit:
Expand Down
8 changes: 4 additions & 4 deletions Resource/Config/AccessTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@

trait AccessTrait
{
public function offsetExists($offset)
public function offsetExists(mixed $offset): bool
{
return isset($this->config[$offset]);
}

public function offsetGet($offset)
public function offsetGet(mixed $offset): mixed
{
return $this->config[$offset];
}

public function offsetSet($offset, $value)
public function offsetSet(mixed $offset, mixed $value): void
{
$this->config[$offset] = $value;
}

public function offsetUnset($offset)
public function offsetUnset(mixed $offset): void
{
unset($this->config[$offset]);
}
Expand Down
17 changes: 10 additions & 7 deletions Resource/Config/Config.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
<?php declare(strict_types=1);
namespace Imatic\Bundle\ControllerBundle\Resource\Config;

class Config implements \Serializable
class Config
{
public function serialize()
public function __serialize(): array
{
return \serialize(\get_object_vars($this));
return \get_object_vars($this);
}

public function unserialize($serialized)
public function __unserialize(array $data): void
{
$unserialized = \unserialize($serialized, ['allowed_classes' => true]);

foreach ($unserialized as $name => $value) {
foreach ($data as $name => $value) {
$this->{$name} = $value;
}
}

public static function fromSerialized(string $data): static
{
return \unserialize($data, ['allowed_classes' => true]);
}

public function copy()
{
return \unserialize(\serialize($this));
Expand Down
2 changes: 1 addition & 1 deletion Resource/Config/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Resource extends Config
*/
protected $name;

public function __construct(array $actions = [], ResourceConfig $config = null, $name = null)
public function __construct(array $actions = [], ?ResourceConfig $config = null, $name = null)
{
$this->actions = $actions;
$this->config = $config;
Expand Down
4 changes: 2 additions & 2 deletions Resource/RouteLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function __construct(ConfigurationRepository $configurationRepository)
$this->repository = $configurationRepository;
}

public function load($resource, $type = null)
public function load(mixed $resource, ?string $type = null): mixed
{
if (true === $this->loaded) {
throw new \RuntimeException('Do not add the "' . $this->name . '" loader twice');
Expand Down Expand Up @@ -73,7 +73,7 @@ public function load($resource, $type = null)
return $routes;
}

public function supports($resource, $type = null)
public function supports(mixed $resource, ?string $type = null): bool
{
return $this->name === $type;
}
Expand Down
Loading