Completed
Push — master ( 1f8ceb...056ad3 )
by Christian
23s queued 11s
created

RestRouteLoader::load()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 3
cts 3
cp 1
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
/*
4
 * This file is part of the FOSRestBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\RestBundle\Routing\Loader;
13
14
use FOS\RestBundle\Routing\Loader\Reader\RestControllerReader;
15
use Symfony\Component\Config\FileLocatorInterface;
16
use Symfony\Component\Config\Loader\Loader;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpKernel\Kernel;
20
21
/**
22
 * RestRouteLoader REST-enabled controller router loader.
23
 *
24
 * @author Konstantin Kudryashov <[email protected]>
25
 * @author Bulat Shakirzyanov <[email protected]>
26
 */
27
class RestRouteLoader extends Loader
28
{
29
    protected $container;
30
    protected $controllerReader;
31
    protected $defaultFormat;
32
    protected $locator;
33
34
    public function __construct(
35
        ContainerInterface $container,
36
        FileLocatorInterface $locator,
37
        RestControllerReader $controllerReader,
38
        ?string $defaultFormat = 'html'
39
    ) {
40
        $this->container = $container;
41
        $this->locator = $locator;
42
        $this->controllerReader = $controllerReader;
43
        $this->defaultFormat = $defaultFormat;
44 56
    }
45
46
    /**
47
     * Returns controller reader.
48
     *
49
     * @return RestControllerReader
50 56
     */
51 56
    public function getControllerReader()
52 56
    {
53 56
        return $this->controllerReader;
54 56
    }
55 56
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function load($controller, $type = null)
60
    {
61
        list($prefix, $class) = $this->getControllerLocator($controller);
62 26
63 1
        $collection = $this->controllerReader->read(new \ReflectionClass($class));
64 26
        $collection->prependRouteControllersWithPrefix($prefix);
65
        $collection->setDefaultFormat($this->defaultFormat);
66
67
        return $collection;
68
    }
69
70 37
    /**
71
     * {@inheritdoc}
72 37
     */
73
    public function supports($resource, $type = null)
74 37
    {
75 37
        return is_string($resource)
76 37
            && 'rest' === $type
77
            && !in_array(pathinfo($resource, PATHINFO_EXTENSION), ['xml', 'yml', 'yaml']
78 37
        );
79
    }
80
81
    /**
82
     * Returns controller locator by it's id.
83
     *
84 21
     * @param string $controller
85
     *
86 21
     * @throws \InvalidArgumentException
87 21
     *
88 21
     * @return array
89 21
     */
90
    private function getControllerLocator($controller)
91
    {
92
        $class = null;
93
        $prefix = null;
94
95
        if (0 === strpos($controller, '@')) {
96
            $file = $this->locator->locate($controller);
97
            $controllerClass = ClassUtils::findClassInFile($file);
0 ignored issues
show
Bug introduced by
It seems like $file defined by $this->locator->locate($controller) on line 96 can also be of type array; however, FOS\RestBundle\Routing\L...tils::findClassInFile() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
98
99
            if (false === $controllerClass) {
100
                throw new \InvalidArgumentException(sprintf('Can\'t find class for controller "%s"', $controller));
101 37
            }
102
103 37
            $controller = $controllerClass;
104 37
        }
105
106 37
        if ($this->container->has($controller)) {
107
            // service_id
108
            $prefix = $controller.':';
109
110
            if (Kernel::VERSION_ID >= 40100) {
111
                $prefix .= ':';
112
            }
113
114
            $useScope = method_exists($this->container, 'enterScope') && $this->container->hasScope('request');
0 ignored issues
show
Bug introduced by
The method hasScope() does not seem to exist on object<Symfony\Component...ion\ContainerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
115
            if ($useScope) {
116
                $this->container->enterScope('request');
0 ignored issues
show
Bug introduced by
The method enterScope() does not seem to exist on object<Symfony\Component...ion\ContainerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
117 37
                $this->container->set('request', new Request());
118
            }
119 1
            $class = get_class($this->container->get($controller));
120 1
            if ($useScope) {
121 1
                $this->container->leaveScope('request');
0 ignored issues
show
Bug introduced by
The method leaveScope() does not seem to exist on object<Symfony\Component...ion\ContainerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
122
            }
123
        } elseif (class_exists($controller)) {
124
            // full class name
125 1
            $class = $controller;
126 1
            $prefix = $class.'::';
127
        }
128
129 37
        if (empty($class)) {
130
            throw new \InvalidArgumentException(sprintf('Class could not be determined for Controller identified by "%s".', $controller));
131 37
        }
132 37
133 37
        return [$prefix, $class];
134
    }
135
}
136