8
8
use Drupal \Core \Theme \ThemeManagerInterface ;
9
9
use Drupal \patternkit \Pattern ;
10
10
use Drupal \patternkit \PatternEditorConfig ;
11
+ use Drupal \patternkit \PatternLibraryJSONParserTrait ;
11
12
use Drupal \patternkit \PatternLibraryParserBase ;
12
- use Symfony \Component \Finder \Iterator \RecursiveDirectoryIterator ;
13
13
14
14
/**
15
15
* Parses a Twig pattern library collection into usable metadata.
16
16
*/
17
17
class TwigPatternLibraryParser extends PatternLibraryParserBase {
18
-
19
- /** @var \Drupal\Component\Serialization\SerializationInterface */
20
- protected $ serializer ;
18
+ use PatternLibraryJSONParserTrait;
21
19
22
20
/**
23
21
* TwigPatternLibraryParser constructor.
24
22
*
25
23
* @param \Drupal\Component\Serialization\SerializationInterface $serializer
26
- * Serialization service.
27
- *
28
- * {@inheritdoc}
24
+ * Serializes and de-serializes data.
25
+ * @param string $root
26
+ * The application root path.
27
+ * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
28
+ * Allows modules to alter library parsing.
29
+ * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
30
+ * Allows themes to alter library parsing.
29
31
*/
30
- public function __construct (SerializationInterface $ serializer , $ root , ModuleHandlerInterface $ module_handler , ThemeManagerInterface $ theme_manager ) {
32
+ public function __construct (
33
+ SerializationInterface $ serializer ,
34
+ $ root ,
35
+ ModuleHandlerInterface $ module_handler ,
36
+ ThemeManagerInterface $ theme_manager ) {
37
+
31
38
$ this ->serializer = $ serializer ;
32
39
parent ::__construct ($ root , $ module_handler , $ theme_manager );
33
40
}
34
41
35
- /**
36
- * Returns a new Patternkit Pattern.
37
- *
38
- * @param $name
39
- * The name of the pattern.
40
- * @param $schema
41
- * The optional schema for the pattern.
42
- *
43
- * @return \Drupal\patternkit\Pattern
44
- */
45
- public function createPattern ($ name , $ schema ): Pattern {
46
- return new Pattern ($ name , $ schema );
47
- }
48
-
49
42
/**
50
43
* Fetches all assets for a pattern.
51
44
*
52
- * @param Pattern $pattern
45
+ * @param \Drupal\patternkit\ Pattern $pattern
53
46
* The pattern to use for asset retrieval.
54
- * @param PatternEditorConfig $config
47
+ * @param \Drupal\patternkit\ PatternEditorConfig $config
55
48
* The configuration object to use for provisioning the pattern.
56
49
*
57
- * @return Pattern
50
+ * @return \Drupal\patternkit\ Pattern
58
51
* The pattern parameter with updated asset references.
59
52
*/
60
53
public function fetchPatternAssets (Pattern $ pattern ,
@@ -74,16 +67,12 @@ public function fetchPatternAssets(Pattern $pattern,
74
67
* and defines the following elements:
75
68
* - patterns: A list of pattern libraries and subtypes to include. Each
76
69
* subtype is keyed by the subtype path.
77
- * @code
70
+ * @code
78
71
* patterns:
79
- * library:
80
- * atoms:
81
- * path/atoms: {}
82
- * molecules:
83
- * path/molecules: {}
84
- * organisms:
85
- * path/organisms: {}
86
- * @endcode
72
+ * path/atoms: {type: twig, category: atoms}
73
+ * path/molecules: {type: twig, category: molecules}
74
+ * path/organisms: {}
75
+ * @endcode
87
76
* - dependencies: A list of libraries this library depends on.
88
77
* - version: The library version. The string "VERSION" can be used to mean
89
78
* the current Drupal core version.
@@ -121,50 +110,26 @@ public function parseLibraryInfo($library, $path, array $library_data = []): arr
121
110
if (!file_exists ($ path )) {
122
111
throw new InvalidLibraryFileException ("Path $ path does not exist. " );
123
112
}
124
- $ rdit = new RecursiveDirectoryIterator ($ path , \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO );
125
- $ filter = ['json ' , 'twig ' ];
126
113
$ metadata = [];
127
- $ components = [];
128
-
129
- /** @var \SplFileInfo $file */
130
- foreach (new \RecursiveIteratorIterator ($ rdit ) as $ file ) {
131
- // Skip directories and non-files.
132
- if (!$ file ->isFile ()) {
114
+ foreach (self ::discoverComponents ($ path , ['json ' , 'twig ' ]) as $ name => $ data ) {
115
+ if (empty ($ data ['twig ' ]) || !file_exists ($ data ['twig ' ])) {
133
116
continue ;
134
117
}
135
- $ file_path = $ file ->getPath ();
136
-
137
- // Skip tests folders.
138
- if (strpos ($ file_path , '/tests ' ) !== FALSE ) {
139
- continue ;
140
- }
141
-
142
- // Get the file extension for the file.
143
- $ file_ext = $ file ->getExtension ();
144
- if (!in_array (strtolower ($ file_ext ), $ filter , TRUE )) {
145
- continue ;
146
- }
147
-
148
- // We use file_basename as a unique key, it is required that the
149
- // JSON and twig file share this basename.
150
- $ file_basename = $ file ->getBasename ('. ' . $ file_ext );
151
-
152
- // Build an array of all the filenames of interest, keyed by name.
153
- $ components [$ file_basename ][$ file_ext ] = "$ file_path/ $ file_basename. $ file_ext " ;
154
- }
155
-
156
- foreach ($ components as $ name => $ data ) {
157
118
// If the component has a json file, create the pattern from it.
119
+ $ category = $ library_data ['category ' ] ?? 'default ' ;
158
120
if (!empty ($ data ['json ' ]) && $ file_contents = file_get_contents ($ data ['json ' ])) {
159
121
$ pattern = $ this ->createPattern ($ name , (array ) $ this ->serializer ::decode ($ file_contents ) + $ library_data );
160
- $ pattern ->name = $ name ;
122
+ $ pattern_path = trim (substr ($ data ['json ' ], strlen ($ path ), -strlen ('.json ' )), '/ \\' );
123
+ $ category_guess = $ library_data ['category ' ] ?? strstr ($ pattern_path , DIRECTORY_SEPARATOR , TRUE );
124
+ $ pattern ->category = $ pattern ->category ?? $ category_guess ;
161
125
}
162
126
else {
163
127
// Create the pattern from defaults.
128
+ // @todo Have this cleverly infer defaults from the template.
164
129
$ pattern = $ this ->createPattern ($ name ,
165
130
[
166
131
'$schema ' => 'http =>//json-schema.org/draft-04/schema# ' ,
167
- 'category ' => ' atom ' ,
132
+ 'category ' => $ category ,
168
133
'title ' => $ name ,
169
134
'type ' => 'object ' ,
170
135
'format ' => 'grid ' ,
@@ -174,21 +139,15 @@ public function parseLibraryInfo($library, $path, array $library_data = []): arr
174
139
] + $ library_data
175
140
);
176
141
}
177
-
178
- if (!empty ($ data ['twig ' ])) {
179
- $ twig_file = $ data ['twig ' ];
180
- if (file_exists ($ twig_file )) {
181
- $ pattern ->filename = trim (substr ($ twig_file , strlen ($ path )), '/ \\' );
182
- $ pattern ->template = file_get_contents ($ twig_file );
183
- // URL is redundant for the twig based components, so we use it to
184
- // store namespace.
185
- $ pattern ->url = $ library ;
186
- // @todo add default of library version fallback to extension version.
187
- $ pattern ->version = $ pattern ->version ?? 'VERSION ' ;
188
- }
189
- }
190
-
191
- $ metadata [$ name ] = $ pattern ;
142
+ $ pattern ->filename = trim (substr ($ data ['twig ' ], strlen ($ path )), '/ \\' );
143
+ $ pattern_path = substr ($ pattern ->filename , 0 , -strlen ('.twig ' ));
144
+ $ pattern ->template = file_get_contents ($ data ['twig ' ]);
145
+ // URL is redundant for the twig based components, so we use it to
146
+ // store namespace.
147
+ $ pattern ->url = $ library ;
148
+ // @todo add default of library version fallback to extension version.
149
+ $ pattern ->version = $ pattern ->version ?? 'VERSION ' ;
150
+ $ metadata ["@ $ library/ $ pattern_path " ] = $ pattern ;
192
151
}
193
152
194
153
foreach ($ metadata as $ pattern_type => $ pattern ) {
0 commit comments