14
14
use Symfony \Component \Config \FileLocatorInterface ;
15
15
use Symfony \Component \Config \Exception \FileLoaderLoadException ;
16
16
use Symfony \Component \Config \Exception \FileLoaderImportCircularReferenceException ;
17
+ use Symfony \Component \Config \Exception \FileLocatorFileNotFoundException ;
18
+ use Symfony \Component \Finder \Finder ;
19
+ use Symfony \Component \Finder \Glob ;
17
20
18
21
/**
19
22
* FileLoader is the abstract class used by all built-in loaders that are file based.
@@ -32,7 +35,7 @@ abstract class FileLoader extends Loader
32
35
*/
33
36
protected $ locator ;
34
37
35
- protected $ currentDir ;
38
+ private $ currentDir ;
36
39
37
40
/**
38
41
* Constructor.
@@ -78,6 +81,87 @@ public function getLocator()
78
81
* @throws FileLoaderImportCircularReferenceException
79
82
*/
80
83
public function import ($ resource , $ type = null , $ ignoreErrors = false , $ sourceResource = null )
84
+ {
85
+ $ ret = array ();
86
+ $ ct = 0 ;
87
+ foreach ($ this ->glob ($ resource , false , $ _ , $ ignoreErrors ) as $ resource => $ info ) {
88
+ ++$ ct ;
89
+ $ ret [] = $ this ->doImport ($ resource , $ type , $ ignoreErrors , $ sourceResource );
90
+ }
91
+
92
+ return $ ct > 1 ? $ ret : isset ($ ret [0 ]) ? $ ret [0 ] : null ;
93
+ }
94
+
95
+ /**
96
+ * @internal
97
+ */
98
+ protected function glob ($ resource , $ recursive , &$ prefix = null , $ ignoreErrors = false )
99
+ {
100
+ if (strlen ($ resource ) === $ i = strcspn ($ resource , '*?{[ ' )) {
101
+ if (!$ recursive ) {
102
+ $ prefix = null ;
103
+
104
+ yield $ resource => new \SplFileInfo ($ resource );
105
+
106
+ return ;
107
+ }
108
+ $ prefix = $ resource ;
109
+ $ resource = '' ;
110
+ } elseif (0 === $ i ) {
111
+ $ prefix = '. ' ;
112
+ $ resource = '/ ' .$ resource ;
113
+ } else {
114
+ $ prefix = dirname (substr ($ resource , 0 , 1 + $ i ));
115
+ $ resource = substr ($ resource , strlen ($ prefix ));
116
+ }
117
+
118
+ try {
119
+ $ prefix = $ this ->locator ->locate ($ prefix , $ this ->currentDir , true );
120
+ } catch (FileLocatorFileNotFoundException $ e ) {
121
+ if (!$ ignoreErrors ) {
122
+ throw $ e ;
123
+ }
124
+
125
+ return ;
126
+ }
127
+ $ prefix = realpath ($ prefix ) ?: $ prefix ;
128
+
129
+ if (false === strpos ($ resource , '/**/ ' ) && (defined ('GLOB_BRACE ' ) || false === strpos ($ resource , '{ ' ))) {
130
+ foreach (glob ($ prefix .$ resource , defined ('GLOB_BRACE ' ) ? GLOB_BRACE : 0 ) as $ path ) {
131
+ if ($ recursive && is_dir ($ path )) {
132
+ $ flags = \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS ;
133
+ foreach (new \RecursiveIteratorIterator (new \RecursiveDirectoryIterator ($ path , $ flags )) as $ path => $ info ) {
134
+ if ($ info ->isFile ()) {
135
+ yield $ path => $ info ;
136
+ }
137
+ }
138
+ } elseif (is_file ($ path )) {
139
+ yield $ path => new \SplFileInfo ($ path );
140
+ }
141
+ }
142
+
143
+ return ;
144
+ }
145
+
146
+ if (!class_exists (Finder::class)) {
147
+ throw new LogicException (sprintf ('Extended glob pattern "%s" cannot be used as the Finder component is not installed. ' , $ resource ));
148
+ }
149
+
150
+ $ finder = new Finder ();
151
+ $ regex = Glob::toRegex ($ resource );
152
+ if ($ recursive ) {
153
+ $ regex = substr_replace ($ regex , '(/|$) ' , -2 , 1 );
154
+ }
155
+
156
+ $ prefixLen = strlen ($ prefix );
157
+ foreach ($ finder ->followLinks ()->in ($ prefix ) as $ path => $ info ) {
158
+ if (preg_match ($ regex , substr ($ path , $ prefixLen )) && $ info ->isFile ()) {
159
+ yield $ path => $ info ;
160
+ }
161
+ }
162
+ }
163
+
164
+ private function doImport ($ resource , $ type = null , $ ignoreErrors = false , $ sourceResource = null )
81
165
{
82
166
try {
83
167
$ loader = $ this ->resolve ($ resource , $ type );
0 commit comments