33namespace Statamic \Fields ;
44
55use Closure ;
6+ use Exception ;
67use Statamic \Exceptions \BlueprintNotFoundException ;
78use Statamic \Facades \Blink ;
89use Statamic \Facades \File ;
@@ -17,20 +18,43 @@ class BlueprintRepository
1718 protected const BLINK_FROM_FILE = 'blueprints.from-file ' ;
1819 protected const BLINK_NAMESPACE_PATHS = 'blueprints.paths-in-namespace ' ;
1920
20- protected $ directory ;
21+ protected $ directories = [ ' default ' => null ] ;
2122 protected $ fallbacks = [];
2223 protected $ additionalNamespaces = [];
2324
24- public function setDirectory (string $ directory )
25+ public function setDirectories (string | array $ directories )
2526 {
26- $ this ->directory = Path::tidy ($ directory );
27+ if (is_string ($ directories )) {
28+ $ directories = ['default ' => $ directories ];
29+ }
30+
31+ $ this ->directories = collect ($ directories )
32+ ->map (fn ($ directory ) => Path::tidy ($ directory ))
33+ ->all ();
34+
35+ if (! isset ($ this ->directories ['default ' ])) {
36+ throw new Exception ('Default blueprint directory not provided ' );
37+ }
2738
2839 return $ this ;
2940 }
3041
42+ /** @deprecated */
43+ public function setDirectory (string $ directory )
44+ {
45+ return $ this ->setDirectories ($ directory );
46+ }
47+
3148 public function directory ()
3249 {
33- return $ this ->directory ;
50+ return $ this ->directories ['default ' ];
51+ }
52+
53+ public function namespaceDirectory ($ namespace )
54+ {
55+ return isset ($ this ->directories [$ namespace ])
56+ ? $ this ->directories [$ namespace ]
57+ : $ this ->directories ['default ' ].'/ ' .$ namespace ;
3458 }
3559
3660 public function find ($ blueprint ): ?Blueprint
@@ -69,7 +93,14 @@ public function findStandardBlueprintPath($handle)
6993 return null ;
7094 }
7195
72- return $ this ->directory .'/ ' .str_replace ('. ' , '/ ' , $ handle ).'.yaml ' ;
96+ if (! Str::contains ($ handle , '. ' )) {
97+ return $ this ->directory ().'/ ' .str_replace ('. ' , '/ ' , $ handle ).'.yaml ' ;
98+ }
99+
100+ $ namespace = Str::before ($ handle , '. ' );
101+ $ handle = Str::after ($ handle , '. ' );
102+
103+ return $ this ->namespaceDirectory ($ namespace ).'/ ' .str_replace ('. ' , '/ ' , $ handle ).'.yaml ' ;
73104 }
74105
75106 public function findNamespacedBlueprintPath ($ handle )
@@ -79,7 +110,7 @@ public function findNamespacedBlueprintPath($handle)
79110 $ handle = str_replace ('/ ' , '. ' , $ handle );
80111 $ path = str_replace ('. ' , '/ ' , $ handle );
81112
82- $ overridePath = "{$ this ->directory }/vendor/ {$ namespaceDir }/ {$ path }.yaml " ;
113+ $ overridePath = "{$ this ->directory () }/vendor/ {$ namespaceDir }/ {$ path }.yaml " ;
83114
84115 if (File::exists ($ overridePath )) {
85116 return $ overridePath ;
@@ -233,7 +264,7 @@ protected function filesIn($namespace)
233264 return Blink::store (self ::BLINK_NAMESPACE_PATHS )->once ($ namespace , function () use ($ namespace ) {
234265 $ namespace = str_replace ('/ ' , '. ' , $ namespace );
235266 $ namespaceDir = str_replace ('. ' , '/ ' , $ namespace );
236- $ directory = $ this ->directory .'/ ' .$ namespaceDir ;
267+ $ directory = $ this ->directory () .'/ ' .$ namespaceDir ;
237268
238269 if (isset ($ this ->additionalNamespaces [$ namespace ])) {
239270 $ directory = "{$ this ->additionalNamespaces [$ namespace ]}" ;
@@ -243,7 +274,7 @@ protected function filesIn($namespace)
243274 ->getFilesByType ($ directory , 'yaml ' )
244275 ->mapWithKeys (fn ($ path ) => [Str::after ($ path , $ directory .'/ ' ) => $ path ]);
245276
246- if (File::exists ($ directory = $ this ->directory .'/vendor/ ' .$ namespaceDir )) {
277+ if (File::exists ($ directory = $ this ->directory () .'/vendor/ ' .$ namespaceDir )) {
247278 $ overrides = File::withAbsolutePaths ()
248279 ->getFilesByType ($ directory , 'yaml ' )
249280 ->mapWithKeys (fn ($ path ) => [Str::after ($ path , $ directory .'/ ' ) => $ path ]);
@@ -259,9 +290,7 @@ protected function makeBlueprintFromFile($path, $namespace = null)
259290 {
260291 return Blink::store (self ::BLINK_FROM_FILE )->once ($ path , function () use ($ path , $ namespace ) {
261292 if (! $ namespace || ! isset ($ this ->additionalNamespaces [$ namespace ])) {
262- [$ namespace , $ handle ] = $ this ->getNamespaceAndHandle (
263- Str::after (Str::before ($ path , '.yaml ' ), $ this ->directory .'/ ' )
264- );
293+ [$ namespace , $ handle ] = $ this ->getNamespaceAndHandleFromPath ($ path );
265294 } else {
266295 $ handle = Str::of ($ path )->afterLast ('/ ' )->before ('. ' );
267296 }
@@ -287,4 +316,21 @@ protected function getNamespaceAndHandle($blueprint)
287316
288317 return [$ namespace , $ handle ];
289318 }
319+
320+ public function getNamespaceAndHandleFromPath ($ path )
321+ {
322+ $ namespace = collect ($ this ->directories )
323+ ->search (function ($ directory ) use ($ path ) {
324+ return Str::startsWith ($ path , $ directory );
325+ });
326+
327+ if ($ namespace === 'default ' ) {
328+ return $ this ->getNamespaceAndHandle (Str::after (Str::before ($ path , '.yaml ' ), $ this ->directory ().'/ ' ));
329+ }
330+
331+ $ directory = $ this ->directories [$ namespace ];
332+ $ handle = Str::after (Str::before ($ path , '.yaml ' ), $ directory .'/ ' );
333+
334+ return [$ namespace , $ handle ];
335+ }
290336}
0 commit comments