Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <fabien@symfony.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 Symfony\Component\Routing\Loader;
13
 
14
use Symfony\Component\Config\Loader\Loader;
15
use Symfony\Component\Config\Resource\FileResource;
16
use Symfony\Component\Routing\RouteCollection;
17
 
18
/**
19
 * A route loader that calls a method on an object to load the routes.
20
 *
21
 * @author Ryan Weaver <ryan@knpuniversity.com>
22
 */
23
abstract class ObjectLoader extends Loader
24
{
25
    /**
26
     * Returns the object that the method will be called on to load routes.
27
     *
28
     * For example, if your application uses a service container,
29
     * the $id may be a service id.
30
     *
31
     * @return object
32
     */
33
    abstract protected function getObject(string $id);
34
 
35
    /**
36
     * Calls the object method that will load the routes.
37
     *
38
     * @param string      $resource object_id::method
39
     * @param string|null $type     The resource type
40
     *
41
     * @return RouteCollection
42
     */
43
    public function load($resource, string $type = null)
44
    {
45
        if (!preg_match('/^[^\:]+(?:::(?:[^\:]+))?$/', $resource)) {
46
            throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the %s route loader: use the format "object_id::method" or "object_id" if your object class has an "__invoke" method.', $resource, \is_string($type) ? '"'.$type.'"' : 'object'));
47
        }
48
 
49
        $parts = explode('::', $resource);
50
        $method = $parts[1] ?? '__invoke';
51
 
52
        $loaderObject = $this->getObject($parts[0]);
53
 
54
        if (!\is_object($loaderObject)) {
55
            throw new \TypeError(sprintf('"%s:getObject()" must return an object: "%s" returned.', static::class, get_debug_type($loaderObject)));
56
        }
57
 
58
        if (!\is_callable([$loaderObject, $method])) {
59
            throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s".', $method, get_debug_type($loaderObject), $resource));
60
        }
61
 
62
        $routeCollection = $loaderObject->$method($this);
63
 
64
        if (!$routeCollection instanceof RouteCollection) {
65
            $type = get_debug_type($routeCollection);
66
 
67
            throw new \LogicException(sprintf('The "%s::%s()" method must return a RouteCollection: "%s" returned.', get_debug_type($loaderObject), $method, $type));
68
        }
69
 
70
        // make the object file tracked so that if it changes, the cache rebuilds
71
        $this->addClassResource(new \ReflectionClass($loaderObject), $routeCollection);
72
 
73
        return $routeCollection;
74
    }
75
 
76
    private function addClassResource(\ReflectionClass $class, RouteCollection $collection)
77
    {
78
        do {
79
            if (is_file($class->getFileName())) {
80
                $collection->addResource(new FileResource($class->getFileName()));
81
            }
82
        } while ($class = $class->getParentClass());
83
    }
84
}