bankiru /
rpc-server-bundle
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Bankiru\Api\Rpc\Routing\Loader; |
||
| 4 | |||
| 5 | use Bankiru\Api\Rpc\Routing\MethodCollection; |
||
| 6 | use Bankiru\Api\Rpc\Routing\Route; |
||
| 7 | use Symfony\Component\Config\Resource\FileResource; |
||
| 8 | use Symfony\Component\Yaml\Exception\ParseException; |
||
| 9 | use Symfony\Component\Yaml\Parser; |
||
| 10 | |||
| 11 | class YamlLoader extends FileLoader |
||
| 12 | { |
||
| 13 | private static $availableKeys = [ |
||
| 14 | 'resource', |
||
| 15 | 'type', |
||
| 16 | 'prefix', |
||
| 17 | 'method', |
||
| 18 | 'controller', |
||
| 19 | 'context', |
||
| 20 | 'default_context', |
||
| 21 | 'inherit', |
||
| 22 | ]; |
||
| 23 | |||
| 24 | /** @var Parser */ |
||
| 25 | private $parser; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * Loads a resource. |
||
| 29 | * |
||
| 30 | * @param mixed $resource The resource |
||
| 31 | * @param string|null $type The resource type or null if unknown |
||
| 32 | * |
||
| 33 | * @return MethodCollection |
||
| 34 | * @throws \Exception If something went wrong |
||
| 35 | */ |
||
| 36 | 2 | public function load($resource, $type = null) |
|
| 37 | { |
||
| 38 | 2 | $path = $this->getLocator()->locate($resource); |
|
| 39 | |||
| 40 | 2 | if (!stream_is_local($path)) { |
|
| 41 | throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $path)); |
||
| 42 | } |
||
| 43 | |||
| 44 | 2 | if (!file_exists($path)) { |
|
| 45 | throw new \InvalidArgumentException(sprintf('File "%s" not found.', $path)); |
||
| 46 | } |
||
| 47 | |||
| 48 | 2 | if (null === $this->parser) { |
|
| 49 | 2 | $this->parser = new Parser(); |
|
| 50 | 2 | } |
|
| 51 | |||
| 52 | try { |
||
| 53 | 2 | $parsedConfig = $this->parser->parse(file_get_contents($path)); |
|
| 54 | 2 | } catch (ParseException $e) { |
|
| 55 | throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e); |
||
| 56 | } |
||
| 57 | |||
| 58 | 2 | $collection = new MethodCollection(); |
|
| 59 | 2 | $collection->addResource(new FileResource($path)); |
|
| 60 | |||
| 61 | // empty file |
||
| 62 | 2 | if (null === $parsedConfig) { |
|
| 63 | return $collection; |
||
| 64 | } |
||
| 65 | |||
| 66 | // not an array |
||
| 67 | 2 | if (!is_array($parsedConfig)) { |
|
| 68 | throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $path)); |
||
| 69 | } |
||
| 70 | |||
| 71 | 2 | foreach ($parsedConfig as $name => $config) { |
|
| 72 | 2 | $this->validate($config, $name, $path); |
|
| 73 | |||
| 74 | 2 | if (isset($config['resource'])) { |
|
| 75 | 2 | $this->parseImport($collection, $config, $path, $resource); |
|
| 76 | 2 | } else { |
|
| 77 | 2 | $this->parseRoute($collection, $name, $config, $path); |
|
| 78 | } |
||
| 79 | 2 | } |
|
| 80 | |||
| 81 | 2 | return $collection; |
|
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * Returns whether this class supports the given resource. |
||
| 86 | * |
||
| 87 | * @param mixed $resource A resource |
||
| 88 | * @param string|null $type The resource type or null if unknown |
||
| 89 | * |
||
| 90 | * @return bool True if this class supports the given resource, false otherwise |
||
| 91 | */ |
||
| 92 | 2 | public function supports($resource, $type = null) |
|
| 93 | { |
||
| 94 | 2 | return is_string($resource) && |
|
| 95 | 2 | in_array(pathinfo($resource, PATHINFO_EXTENSION), ['yml', 'yaml'], true) && |
|
| 96 | 2 | (!$type || 'yaml' === $type); |
|
| 97 | } |
||
| 98 | |||
| 99 | /** |
||
| 100 | * Validates the route configuration. |
||
| 101 | * |
||
| 102 | * @param array $config A resource config |
||
| 103 | * @param string $name The config key |
||
| 104 | * @param string $path The loaded file path |
||
| 105 | * |
||
| 106 | * @return array |
||
| 107 | * @throws \InvalidArgumentException If one of the provided config keys is not supported, |
||
| 108 | * something is missing or the combination is nonsense |
||
| 109 | */ |
||
| 110 | 2 | protected function validate($config, $name, $path) |
|
| 111 | { |
||
| 112 | 2 | if (!is_array($config)) { |
|
| 113 | throw new \InvalidArgumentException( |
||
| 114 | sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path) |
||
| 115 | ); |
||
| 116 | } |
||
| 117 | 2 | if ($extraKeys = array_diff(array_keys($config), self::$availableKeys)) { |
|
| 118 | throw new \InvalidArgumentException( |
||
| 119 | sprintf( |
||
| 120 | 'The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".', |
||
| 121 | $path, |
||
| 122 | $name, |
||
| 123 | implode('", "', $extraKeys), |
||
| 124 | implode('", "', self::$availableKeys) |
||
| 125 | ) |
||
| 126 | ); |
||
| 127 | } |
||
| 128 | 2 | View Code Duplication | if (isset($config['resource']) && isset($config['method'])) { |
| 129 | throw new \InvalidArgumentException( |
||
| 130 | sprintf( |
||
| 131 | 'The routing file "%s" must not specify both the "resource" key and the "path" key for "%s". ' . |
||
| 132 | 'Choose between an import and a route definition.', |
||
| 133 | $path, |
||
| 134 | $name |
||
| 135 | ) |
||
| 136 | ); |
||
| 137 | } |
||
| 138 | 2 | View Code Duplication | if (!isset($config['resource']) && isset($config['type'])) { |
| 139 | throw new \InvalidArgumentException( |
||
| 140 | sprintf( |
||
| 141 | 'The "type" key for the route definition "%s" in "%s" is unsupported. ' . |
||
| 142 | 'It is only available for imports in combination with the "resource" key.', |
||
| 143 | $name, |
||
| 144 | $path |
||
| 145 | ) |
||
| 146 | ); |
||
| 147 | } |
||
| 148 | 2 | } |
|
| 149 | |||
| 150 | /** |
||
| 151 | * Parses an import and adds the routes in the resource to the RouteCollection. |
||
| 152 | * |
||
| 153 | * @param MethodCollection $collection A RouteCollection instance |
||
| 154 | * @param array $config Route definition |
||
| 155 | * @param string $path Full path of the YAML file being processed |
||
| 156 | * @param string $file Loaded file name |
||
| 157 | */ |
||
| 158 | 2 | protected function parseImport(MethodCollection $collection, array $config, $path, $file) |
|
| 159 | { |
||
| 160 | 2 | $type = isset($config['type']) ? $config['type'] : null; |
|
| 161 | 2 | $prefix = isset($config['prefix']) ? $config['prefix'] : ''; |
|
| 162 | 2 | $this->setCurrentDir(dirname($path)); |
|
| 163 | |||
| 164 | 2 | $subCollection = $this->import($config['resource'], $type, false, $file); |
|
| 165 | /* @var $subCollection MethodCollection */ |
||
| 166 | 2 | $subCollection->addPrefix($prefix); |
|
| 167 | |||
| 168 | 2 | if (array_key_exists('context', $config)) { |
|
| 169 | 2 | foreach ((array)$config['context'] as $context) { |
|
| 170 | 2 | $subCollection->addContext($context); |
|
| 171 | 2 | } |
|
| 172 | 2 | } |
|
| 173 | |||
| 174 | 2 | $collection->addCollection($subCollection); |
|
| 175 | 2 | } |
|
| 176 | |||
| 177 | /** |
||
| 178 | * Parses a route and adds it to the RouteCollection. |
||
| 179 | * |
||
| 180 | * @param MethodCollection $collection A RouteCollection instance |
||
| 181 | * @param string $name Route name |
||
| 182 | * @param array $config Route definition |
||
| 183 | * @param string $path Full path of the YAML file being processed |
||
| 184 | */ |
||
| 185 | 2 | protected function parseRoute(MethodCollection $collection, $name, array $config, $path) |
|
|
0 ignored issues
–
show
|
|||
| 186 | { |
||
| 187 | 2 | $context = array_key_exists('context', $config) ? (array)$config['context'] : []; |
|
| 188 | 2 | $method = array_key_exists('method', $config) ? $config['method'] : $name; |
|
| 189 | 2 | $inherit = array_key_exists('inherit', $config) ? $config['inherit'] : true; |
|
| 190 | 2 | $route = new Route( |
|
| 191 | 2 | $method, |
|
| 192 | 2 | $config['controller'], |
|
| 193 | 2 | $context, |
|
| 194 | 2 | array_key_exists('default_context', $config) ? $config['default_context'] : true, |
|
| 195 | $inherit |
||
| 196 | 2 | ); |
|
| 197 | |||
| 198 | 2 | $collection->add($name, $route); |
|
| 199 | 2 | } |
|
| 200 | } |
||
| 201 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.