Completed
Pull Request — master (#36)
by Yann
02:23 queued 30s
created

ResourcesListener   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 22
c 1
b 0
f 0
lcom 1
cbo 9
dl 0
loc 132
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
C resolveResources() 0 46 11
A addParser() 0 6 1
A addParameterCaster() 0 6 1
A throwMissingException() 0 14 2
A parse() 0 8 3
A castParameter() 0 8 3
1
<?php
2
3
namespace Knp\Rad\ResourceResolver\EventListener;
4
5
use Knp\Rad\ResourceResolver\CasterContainer;
6
use Knp\Rad\ResourceResolver\ParameterCaster;
7
use Knp\Rad\ResourceResolver\Parser;
8
use Knp\Rad\ResourceResolver\ParserContainer;
9
use Knp\Rad\ResourceResolver\ResourceContainer;
10
use Knp\Rad\ResourceResolver\ResourceResolver;
11
use Knp\Rad\ResourceResolver\RoutingNormalizer;
12
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
13
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
14
15
class ResourcesListener implements CasterContainer, ParserContainer
16
{
17
    /** @var Parser[] */
18
    private $parsers;
19
20
    /** @var ResourceContainer */
21
    private $container;
22
23
    /** @var ResourceResolver */
24
    private $resolver;
25
26
    /** @var ParameterCaster[] */
27
    private $parameterCasters;
28
29
    /** @var RoutingNormalizer */
30
    private $normalizer;
31
32
    public function __construct(ResourceResolver $resolver, ResourceContainer $container, RoutingNormalizer $normalizer)
33
    {
34
        $this->resolver         = $resolver;
35
        $this->container        = $container;
36
        $this->parsers          = [];
37
        $this->parameterCasters = [];
38
        $this->normalizer       = $normalizer;
39
    }
40
41
    public function resolveResources(FilterControllerEvent $event)
42
    {
43
        $request   = $event->getRequest();
44
        $resources = [];
45
46
        foreach ($request->attributes->get('_resources', []) as $resourceKey => $resourceValue) {
47
            $resourceValue = $this->parse($resourceValue) ?: $resourceValue;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 11 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
48
            $resources[$resourceKey] = $resourceValue;
49
        }
50
51
        foreach ($resources as $resourceKey => $resourceDetails) {
52
            $resourceDetails = $this->normalizer->normalizeDeclaration($resourceDetails);
53
            $parameters = [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
54
55
            foreach ($resourceDetails['arguments'] as $parameter) {
56
                $parameter = $this->castParameter($parameter) ?: $parameter;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
57
                $parameters[] = $parameter;
58
            }
59
60
            $resource = $this
61
                ->resolver
62
                ->resolveResource(
63
                    $resourceDetails['service'],
64
                    $resourceDetails['method'],
65
                    $parameters
66
                )
67
            ;
68
69
            if (false !== $resourceDetails['required'] && null === $resource) {
70
                if (!array_key_exists('on-missing', $resourceDetails)) {
71
                    throw new NotFoundHttpException(sprintf('The resource %s could not be found', $resourceKey));
72
                }
73
74
                if (!is_array($resourceDetails['on-missing']) || !array_key_exists('throw', $resourceDetails['on-missing'])) {
75
                    throw new \InvalidArgumentException('"on-missing" must be an array and contain "throw" parameter.');
76
                }
77
                $this->throwMissingException($resourceDetails['on-missing'], $resourceKey);
78
            }
79
80
            $request->attributes->set($resourceKey, $resource);
81
82
            $this->container->addResource($resourceKey, $resource);
83
        }
84
85
        return $event;
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    public function addParser(Parser $parser)
92
    {
93
        $this->parsers[] = $parser;
94
95
        return $this;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    public function addParameterCaster(ParameterCaster $parameterCaster)
102
    {
103
        $this->parameterCasters[] = $parameterCaster;
104
105
        return $this;
106
    }
107
108
    private function throwMissingException(array $configuration, $resourceKey)
109
    {
110
        if (!in_array($configuration['throw'], array_keys($this->exceptions))) {
111
            throw new \InvalidArgumentException(sprintf(
112
                '%s is not an available HTTP return code. Available are %s.',
113
                $configuration['throw'],
114
                implode(', ', array_keys($this->exceptions))
0 ignored issues
show
Bug introduced by
The property exceptions does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
115
            ));
116
        }
117
118
        $message = sprintf('The resource %s was not found.', $resourceKey);
119
120
        throw new $this->exceptions[$configuration['throw']]($message);
121
    }
122
123
    /**
124
     * @return null|array
125
     */
126
    private function parse($resourceDetails)
127
    {
128
        foreach ($this->parsers as $parser) {
129
            if (true === $parser->supports($resourceDetails)) {
130
                return $parser->parse($resourceDetails);
131
            }
132
        }
133
    }
134
135
    /**
136
     * @return mixed
137
     */
138
    private function castParameter($parameter)
139
    {
140
        foreach ($this->parameterCasters as $parameterCaster) {
141
            if (true === $parameterCaster->supports($parameter)) {
142
                return $parameterCaster->cast($parameter);
143
            }
144
        }
145
    }
146
}
147