Pull merge.
[yaffs-website] / vendor / symfony / config / Loader / FileLoader.php
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\Config\Loader;
13
14 use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
15 use Symfony\Component\Config\Exception\FileLoaderLoadException;
16 use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
17 use Symfony\Component\Config\FileLocatorInterface;
18 use Symfony\Component\Config\Resource\FileExistenceResource;
19 use Symfony\Component\Config\Resource\GlobResource;
20
21 /**
22  * FileLoader is the abstract class used by all built-in loaders that are file based.
23  *
24  * @author Fabien Potencier <fabien@symfony.com>
25  */
26 abstract class FileLoader extends Loader
27 {
28     protected static $loading = array();
29
30     protected $locator;
31
32     private $currentDir;
33
34     public function __construct(FileLocatorInterface $locator)
35     {
36         $this->locator = $locator;
37     }
38
39     /**
40      * Sets the current directory.
41      *
42      * @param string $dir
43      */
44     public function setCurrentDir($dir)
45     {
46         $this->currentDir = $dir;
47     }
48
49     /**
50      * Returns the file locator used by this loader.
51      *
52      * @return FileLocatorInterface
53      */
54     public function getLocator()
55     {
56         return $this->locator;
57     }
58
59     /**
60      * Imports a resource.
61      *
62      * @param mixed       $resource       A Resource
63      * @param string|null $type           The resource type or null if unknown
64      * @param bool        $ignoreErrors   Whether to ignore import errors or not
65      * @param string|null $sourceResource The original resource importing the new resource
66      *
67      * @return mixed
68      *
69      * @throws FileLoaderLoadException
70      * @throws FileLoaderImportCircularReferenceException
71      * @throws FileLocatorFileNotFoundException
72      */
73     public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
74     {
75         if (\is_string($resource) && \strlen($resource) !== $i = strcspn($resource, '*?{[')) {
76             $ret = array();
77             $isSubpath = 0 !== $i && false !== strpos(substr($resource, 0, $i), '/');
78             foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath) as $path => $info) {
79                 if (null !== $res = $this->doImport($path, $type, $ignoreErrors, $sourceResource)) {
80                     $ret[] = $res;
81                 }
82                 $isSubpath = true;
83             }
84
85             if ($isSubpath) {
86                 return isset($ret[1]) ? $ret : (isset($ret[0]) ? $ret[0] : null);
87             }
88         }
89
90         return $this->doImport($resource, $type, $ignoreErrors, $sourceResource);
91     }
92
93     /**
94      * @internal
95      */
96     protected function glob($pattern, $recursive, &$resource = null, $ignoreErrors = false)
97     {
98         if (\strlen($pattern) === $i = strcspn($pattern, '*?{[')) {
99             $prefix = $pattern;
100             $pattern = '';
101         } elseif (0 === $i || false === strpos(substr($pattern, 0, $i), '/')) {
102             $prefix = '.';
103             $pattern = '/'.$pattern;
104         } else {
105             $prefix = \dirname(substr($pattern, 0, 1 + $i));
106             $pattern = substr($pattern, \strlen($prefix));
107         }
108
109         try {
110             $prefix = $this->locator->locate($prefix, $this->currentDir, true);
111         } catch (FileLocatorFileNotFoundException $e) {
112             if (!$ignoreErrors) {
113                 throw $e;
114             }
115
116             $resource = array();
117             foreach ($e->getPaths() as $path) {
118                 $resource[] = new FileExistenceResource($path);
119             }
120
121             return;
122         }
123         $resource = new GlobResource($prefix, $pattern, $recursive);
124
125         foreach ($resource as $path => $info) {
126             yield $path => $info;
127         }
128     }
129
130     private function doImport($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
131     {
132         try {
133             $loader = $this->resolve($resource, $type);
134
135             if ($loader instanceof self && null !== $this->currentDir) {
136                 $resource = $loader->getLocator()->locate($resource, $this->currentDir, false);
137             }
138
139             $resources = \is_array($resource) ? $resource : array($resource);
140             for ($i = 0; $i < $resourcesCount = \count($resources); ++$i) {
141                 if (isset(self::$loading[$resources[$i]])) {
142                     if ($i == $resourcesCount - 1) {
143                         throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading));
144                     }
145                 } else {
146                     $resource = $resources[$i];
147                     break;
148                 }
149             }
150             self::$loading[$resource] = true;
151
152             try {
153                 $ret = $loader->load($resource, $type);
154             } finally {
155                 unset(self::$loading[$resource]);
156             }
157
158             return $ret;
159         } catch (FileLoaderImportCircularReferenceException $e) {
160             throw $e;
161         } catch (\Exception $e) {
162             if (!$ignoreErrors) {
163                 // prevent embedded imports from nesting multiple exceptions
164                 if ($e instanceof FileLoaderLoadException) {
165                     throw $e;
166                 }
167
168                 throw new FileLoaderLoadException($resource, $sourceResource, null, $e, $type);
169             }
170         }
171     }
172 }