Completed
Push — master ( 98adac...89edb3 )
by Christian
05:26
created

RestRouteLoader::findClass()   C

Complexity

Conditions 12
Paths 11

Size

Total Lines 35
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156
Metric Value
dl 0
loc 35
ccs 0
cts 24
cp 0
rs 5.1612
cc 12
eloc 21
nc 11
nop 1
crap 156

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Bundle\FrameworkBundle\Controller\ControllerNameParser;
16
use Symfony\Component\Config\FileLocatorInterface;
17
use Symfony\Component\Config\Loader\Loader;
18
use Symfony\Component\DependencyInjection\ContainerInterface;
19
use Symfony\Component\HttpFoundation\Request;
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 $controllerParser;
31
    protected $controllerReader;
32
    protected $defaultFormat;
33
    protected $locator;
34
35
    /**
36
     * Initializes loader.
37
     *
38
     * @param ContainerInterface   $container
39
     * @param FileLocatorInterface $locator
40
     * @param ControllerNameParser $controllerParser
41
     * @param RestControllerReader $controllerReader
42
     * @param string               $defaultFormat
43
     */
44 41
    public function __construct(
45
        ContainerInterface $container,
46
        FileLocatorInterface $locator,
47
        ControllerNameParser $controllerParser,
48
        RestControllerReader $controllerReader, $defaultFormat = 'html'
49
    ) {
50 41
        $this->container = $container;
51 41
        $this->locator = $locator;
52 41
        $this->controllerParser = $controllerParser;
53 41
        $this->controllerReader = $controllerReader;
54 41
        $this->defaultFormat = $defaultFormat;
55 41
    }
56
57
    /**
58
     * Returns controller reader.
59
     *
60
     * @return RestControllerReader
61
     */
62 24
    public function getControllerReader()
63 1
    {
64 24
        return $this->controllerReader;
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70 31
    public function load($controller, $type = null)
71
    {
72 31
        list($prefix, $class) = $this->getControllerLocator($controller);
73
74 31
        $collection = $this->controllerReader->read(new \ReflectionClass($class));
75 31
        $collection->prependRouteControllersWithPrefix($prefix);
76 31
        $collection->setDefaultFormat($this->defaultFormat);
77
78 31
        return $collection;
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84 16
    public function supports($resource, $type = null)
85
    {
86 16
        return is_string($resource)
87 16
            && 'rest' === $type
88 16
            && !in_array(pathinfo($resource, PATHINFO_EXTENSION), ['xml', 'yml']
89 16
        );
90
    }
91
92
    /**
93
     * Returns controller locator by it's id.
94
     *
95
     * @param string $controller
96
     *
97
     * @throws \InvalidArgumentException
98
     *
99
     * @return array
100
     */
101 31
    private function getControllerLocator($controller)
102
    {
103 31
        $class = null;
104 31
        $prefix = null;
105
106 31
        if (0 === strpos($controller, '@')) {
107
            $file = $this->locator->locate($controller);
108
            $controllerClass = ClassUtils::findClassInFile($file);
0 ignored issues
show
Bug introduced by
It seems like $file defined by $this->locator->locate($controller) on line 107 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...
109
110
            if (false === $controllerClass) {
111
                throw new \InvalidArgumentException(sprintf('Can\'t find class for controller "%s"', $controller));
112
            }
113
114
            $controller = $controllerClass;
115
        }
116
117 31
        if ($this->container->has($controller)) {
118
            // service_id
119 1
            $prefix = $controller.':';
120 1
            if (method_exists($this->container, 'enterScope')) {
121 1
                $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...
122 1
                $this->container->set('request', new Request());
123 1
            }
124 1
            $class = get_class($this->container->get($controller));
125 1
            if (method_exists($this->container, 'enterScope')) {
126 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...
127 1
            }
128 31
        } elseif (class_exists($controller)) {
129
            // full class name
130 31
            $class = $controller;
131 31
            $prefix = $class.'::';
132 31
        } elseif (false !== strpos($controller, ':')) {
133
            // bundle:controller notation
134
            try {
135
                $notation = $this->controllerParser->parse($controller.':method');
136
                list($class) = explode('::', $notation);
137
                $prefix = $class.'::';
138
            } catch (\Exception $e) {
139
                throw new \InvalidArgumentException(
140
                    sprintf('Can\'t locate "%s" controller.', $controller)
141
                );
142
            }
143
        }
144
145 31
        if (empty($class)) {
146
            throw new \InvalidArgumentException(sprintf(
147
                'Class could not be determined for Controller identified by "%s".', $controller
148
            ));
149
        }
150
151 31
        return [$prefix, $class];
152
    }
153
}
154