|
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
|
|
|
use Symfony\Component\HttpKernel\Kernel; |
|
21
|
|
|
|
|
22
|
|
|
/** |
|
23
|
|
|
* RestRouteLoader REST-enabled controller router loader. |
|
24
|
|
|
* |
|
25
|
|
|
* @author Konstantin Kudryashov <[email protected]> |
|
26
|
|
|
* @author Bulat Shakirzyanov <[email protected]> |
|
27
|
|
|
*/ |
|
28
|
|
|
class RestRouteLoader extends Loader |
|
29
|
|
|
{ |
|
30
|
|
|
protected $container; |
|
31
|
|
|
protected $controllerParser; |
|
32
|
|
|
protected $controllerReader; |
|
33
|
|
|
protected $defaultFormat; |
|
34
|
|
|
protected $locator; |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* Initializes loader. |
|
38
|
|
|
* |
|
39
|
|
|
* @param ContainerInterface $container |
|
40
|
|
|
* @param FileLocatorInterface $locator |
|
41
|
|
|
* @param RestControllerReader $controllerReader |
|
42
|
|
|
* @param string $defaultFormat |
|
43
|
|
|
*/ |
|
44
|
56 |
|
public function __construct( |
|
45
|
|
|
ContainerInterface $container, |
|
46
|
|
|
FileLocatorInterface $locator, |
|
47
|
|
|
$controllerReader, |
|
48
|
|
|
$defaultFormat = 'html' |
|
49
|
|
|
) { |
|
50
|
56 |
|
$this->container = $container; |
|
51
|
56 |
|
$this->locator = $locator; |
|
52
|
56 |
|
|
|
53
|
56 |
|
if ($controllerReader instanceof ControllerNameParser || null === $controllerReader) { |
|
|
|
|
|
|
54
|
56 |
|
@trigger_error(sprintf('Not passing an instance of %s as the 3rd argument of %s() is deprecated since FOSRestBundle 2.8.', RestControllerReader::class, __METHOD__), E_USER_DEPRECATED); |
|
|
|
|
|
|
55
|
56 |
|
|
|
56
|
|
|
$this->controllerParser = $controllerReader; |
|
57
|
|
|
|
|
58
|
|
View Code Duplication |
if (!$defaultFormat instanceof RestControllerReader) { |
|
59
|
|
|
throw new \TypeError(sprintf('Argument 4 passed to %s() must be an instance of %s, %s given.', __METHOD__, RestControllerReader::class, is_object($defaultFormat) ? get_class($defaultFormat) : gettype($defaultFormat))); |
|
|
|
|
|
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
26 |
|
$this->controllerReader = $defaultFormat; |
|
63
|
1 |
|
$this->defaultFormat = func_num_args() > 4 ? func_get_arg(4) : 'html'; |
|
64
|
26 |
View Code Duplication |
} elseif (!$controllerReader instanceof RestControllerReader) { |
|
65
|
|
|
throw new \TypeError(sprintf('Argument 3 passed to %s() must be an instance of %s, %s given.', __METHOD__, RestControllerReader::class, is_object($controllerReader) ? get_class($controllerReader) : gettype($controllerReader))); |
|
|
|
|
|
|
66
|
|
|
} else { |
|
67
|
|
|
$this->controllerReader = $controllerReader; |
|
68
|
|
|
$this->defaultFormat = $defaultFormat; |
|
69
|
|
|
} |
|
70
|
37 |
|
} |
|
71
|
|
|
|
|
72
|
37 |
|
/** |
|
73
|
|
|
* Returns controller reader. |
|
74
|
37 |
|
* |
|
75
|
37 |
|
* @return RestControllerReader |
|
76
|
37 |
|
*/ |
|
77
|
|
|
public function getControllerReader() |
|
78
|
37 |
|
{ |
|
79
|
|
|
return $this->controllerReader; |
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
|
|
/** |
|
83
|
|
|
* {@inheritdoc} |
|
84
|
21 |
|
*/ |
|
85
|
|
|
public function load($controller, $type = null) |
|
86
|
21 |
|
{ |
|
87
|
21 |
|
list($prefix, $class) = $this->getControllerLocator($controller); |
|
88
|
21 |
|
|
|
89
|
21 |
|
$collection = $this->controllerReader->read(new \ReflectionClass($class)); |
|
90
|
|
|
$collection->prependRouteControllersWithPrefix($prefix); |
|
91
|
|
|
$collection->setDefaultFormat($this->defaultFormat); |
|
92
|
|
|
|
|
93
|
|
|
return $collection; |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* {@inheritdoc} |
|
98
|
|
|
*/ |
|
99
|
|
|
public function supports($resource, $type = null) |
|
100
|
|
|
{ |
|
101
|
37 |
|
return is_string($resource) |
|
102
|
|
|
&& 'rest' === $type |
|
103
|
37 |
|
&& !in_array(pathinfo($resource, PATHINFO_EXTENSION), ['xml', 'yml', 'yaml'] |
|
104
|
37 |
|
); |
|
105
|
|
|
} |
|
106
|
37 |
|
|
|
107
|
|
|
/** |
|
108
|
|
|
* Returns controller locator by it's id. |
|
109
|
|
|
* |
|
110
|
|
|
* @param string $controller |
|
111
|
|
|
* |
|
112
|
|
|
* @throws \InvalidArgumentException |
|
113
|
|
|
* |
|
114
|
|
|
* @return array |
|
115
|
|
|
*/ |
|
116
|
|
|
private function getControllerLocator($controller) |
|
117
|
37 |
|
{ |
|
118
|
|
|
$class = null; |
|
119
|
1 |
|
$prefix = null; |
|
120
|
1 |
|
|
|
121
|
1 |
|
if (0 === strpos($controller, '@')) { |
|
122
|
|
|
$file = $this->locator->locate($controller); |
|
123
|
|
|
$controllerClass = ClassUtils::findClassInFile($file); |
|
|
|
|
|
|
124
|
|
|
|
|
125
|
1 |
|
if (false === $controllerClass) { |
|
126
|
1 |
|
throw new \InvalidArgumentException(sprintf('Can\'t find class for controller "%s"', $controller)); |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
37 |
|
$controller = $controllerClass; |
|
130
|
|
|
} |
|
131
|
37 |
|
|
|
132
|
37 |
|
if ($this->container->has($controller)) { |
|
133
|
37 |
|
// service_id |
|
134
|
|
|
$prefix = $controller.':'; |
|
135
|
|
|
|
|
136
|
|
|
if (Kernel::VERSION_ID >= 40100) { |
|
137
|
|
|
$prefix .= ':'; |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
$useScope = method_exists($this->container, 'enterScope') && $this->container->hasScope('request'); |
|
|
|
|
|
|
141
|
|
|
if ($useScope) { |
|
142
|
|
|
$this->container->enterScope('request'); |
|
|
|
|
|
|
143
|
|
|
$this->container->set('request', new Request()); |
|
144
|
|
|
} |
|
145
|
|
|
$class = get_class($this->container->get($controller)); |
|
146
|
37 |
|
if ($useScope) { |
|
147
|
|
|
$this->container->leaveScope('request'); |
|
|
|
|
|
|
148
|
|
|
} |
|
149
|
|
|
} elseif (class_exists($controller)) { |
|
150
|
|
|
// full class name |
|
151
|
|
|
$class = $controller; |
|
152
|
37 |
|
$prefix = $class.'::'; |
|
153
|
|
|
} elseif ($this->controllerParser && false !== strpos($controller, ':')) { |
|
154
|
|
|
// bundle:controller notation |
|
155
|
|
|
try { |
|
156
|
|
|
$notation = $this->controllerParser->parse($controller.':method'); |
|
157
|
|
|
list($class) = explode('::', $notation); |
|
158
|
|
|
$prefix = $class.'::'; |
|
159
|
|
|
} catch (\Exception $e) { |
|
160
|
|
|
throw new \InvalidArgumentException(sprintf('Can\'t locate "%s" controller.', $controller)); |
|
161
|
|
|
} |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
if (empty($class)) { |
|
165
|
|
|
throw new \InvalidArgumentException(sprintf('Class could not be determined for Controller identified by "%s".', $controller)); |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
return [$prefix, $class]; |
|
169
|
|
|
} |
|
170
|
|
|
} |
|
171
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.jsonfile (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.jsonto be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
requireorrequire-devsection?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceofchecks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.