ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
EntriesYamlParser.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use Symfony\Component\Yaml;
25
26/***
27 * @author Timon Amstutz <timon.amstutz@ilub.unibe.ch>
28 * @version $Id$
29 */
31{
32 public const PARSER_STATE_OUTSIDE = 1;
33 public const PARSER_STATE_ENTRY = 2;
36
37 protected array $items = array();
38 protected ?Exception\Factory $ef = null;
39
43 protected string $file_path = "none";
44
48 public function __construct()
49 {
50 $this->ef = new Exception\Factory();
51 }
52
56 public function parseYamlStringArrayFromFile(string $filePath): array
57 {
58 $this->file_path = $filePath;
59 $content = $this->getFileContentAsString($filePath);
60 return $this->parseYamlStringArrayFromString($content);
61 }
62
66 public function parseArrayFromFile(string $filePath): array
67 {
68 $this->file_path = $filePath;
69 $content = $this->getFileContentAsString($filePath);
70 return $this->parseArrayFromString($content);
71 }
72
76 public function parseEntriesFromFile(string $filePath): Entry\ComponentEntries
77 {
78 $this->file_path = $filePath;
79 $content = $this->getFileContentAsString($filePath);
80 return $this->parseEntriesFromString($content);
81 }
82
86 public function parseYamlStringArrayFromString(string $content): array
87 {
88 return $this->getYamlEntriesFromString($content);
89 }
90
94 public function parseArrayFromString(string $content): array
95 {
96 return $this->getPHPArrayFromYamlArray(
97 $this->getYamlEntriesFromString($content)
98 );
99 }
100
101 public function parseEntriesFromString(string $content): Entry\ComponentEntries
102 {
103 $entries_array = $this->parseArrayFromString($content);
104 return $this->getEntriesFromArray($entries_array);
105 }
106
110 protected function getFileContentAsString(string $filePath): string
111 {
112 if (!file_exists($filePath)) {
113 throw $this->ef->exception(Exception\CrawlerException::INVALID_FILE_PATH, $filePath);
114 }
115 $content = file_get_contents($filePath);
116 if (!$content) {
117 throw $this->ef->exception(Exception\CrawlerException::FILE_OPENING_FAILED, $filePath);
118 }
119 return $content;
120 }
121
125 protected function getYamlEntriesFromString(string $content): array
126 {
127 $parser_state = self::PARSER_STATE_OUTSIDE;
128 $current_entry = "";
129 $yaml_entries = array();
130
131 foreach (preg_split("/((\r?\n)|(\r\n?))/", $content) as $line) {
132 if ($parser_state === self::PARSER_STATE_OUTSIDE) {
133 if (preg_match('/---/', $line)) {
134 $current_entry = "";
135 $parser_state = self::PARSER_STATE_ENTRY;
136 }
137 if (preg_match('/\@return/', $line)) {
138 throw $this->ef->exception(
139 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
140 " in file: " . $this->file_path . ", " . $line
141 );
142 }
143 if (preg_match('/public function (.*)\‍(/', $line)) {
144 throw $this->ef->exception(
145 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
146 " in file: " . $this->file_path . ", " . $line
147 );
148 }
149 } elseif ($parser_state === self::PARSER_STATE_ENTRY) {
150 if (!preg_match('/(\*$)|(---)/', $line)) {
151 $current_entry .= $this->purifyYamlLine($line);
152 }
153 if (preg_match('/---/', $line)) {
154 $parser_state = self::PARSER_STATE_SEEKING_RETURN;
155 }
156 if (preg_match('/\@return/', $line)) {
157 throw $this->ef->exception(
158 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
159 " in file: " . $this->file_path . ", " . $line
160 );
161 }
162 if (preg_match('/public function (.*)\‍(/', $line)) {
163 throw $this->ef->exception(
164 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
165 " in file: " . $this->file_path . ", " . $line
166 );
167 }
168 } elseif ($parser_state === self::PARSER_STATE_SEEKING_RETURN) {
169 if (preg_match('/\@return/', $line)) {
170 $current_entry .= "namespace: " . ltrim($this->purifyYamlLine($line), '@return');
172 }
173 if (preg_match('/---/', $line)) {
174 throw $this->ef->exception(
175 Exception\CrawlerException::ENTRY_WITH_NO_VALID_RETURN_STATEMENT,
176 " in file: " . $this->file_path . " line " . $current_entry
177 );
178 }
179 if (preg_match('/public function (.*)\‍(/', $line)) {
180 throw $this->ef->exception(
181 Exception\CrawlerException::ENTRY_WITH_NO_VALID_RETURN_STATEMENT,
182 " in file: " . $this->file_path . " line " . $current_entry
183 );
184 }
185 } else {
186 if (preg_match('/public function (.*)\‍(/', $line, $matches)) {
187 preg_match('/public function (.*)\‍(/', $line, $matches);
188 $current_entry .= "function_name: " . $matches[1];
189 $yaml_entries[] = $current_entry;
190 $parser_state = self::PARSER_STATE_OUTSIDE;
191 }
192 if (preg_match('/---/', $line)) {
193 throw $this->ef->exception(
194 Exception\CrawlerException::ENTRY_WITHOUT_FUNCTION,
195 " in file: " . $this->file_path . " line " . $current_entry
196 );
197 }
198 }
199 }
200 if ($parser_state === self::PARSER_STATE_SEEKING_RETURN) {
201 throw $this->ef->exception(
202 Exception\CrawlerException::ENTRY_WITH_NO_VALID_RETURN_STATEMENT,
203 " in file: " . $this->file_path . " line " . $current_entry
204 );
205 } elseif ($parser_state === self::PARSER_STATE_ENTRY) {
206 throw $this->ef->exception(
207 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
208 " in file: " . $this->file_path
209 );
210 } elseif ($parser_state === self::PARSER_STATE_SEEKING_FUNCTION_NAME) {
211 throw $this->ef->exception(
212 Exception\CrawlerException::ENTRY_WITHOUT_FUNCTION,
213 " in file: " . $this->file_path
214 );
215 }
216 return $yaml_entries;
217 }
218
219 protected function purifyYamlLine(string $line): string
220 {
221 return str_replace("* ", "", ltrim($line)) . PHP_EOL;
222 }
223
227 protected function getPHPArrayFromYamlArray(array $yaml_entries): array
228 {
229 $entries = array();
230 $parser = new Yaml\Parser();
231
232 foreach ($yaml_entries as $yaml_entry) {
233 try {
234 $entries[] = $parser->parse($yaml_entry);
235 } catch (\Exception $e) {
236 throw $this->ef->exception(Exception\CrawlerException::PARSING_YAML_ENTRY_FAILED, " file: " . $this->file_path . "; " . $e);
237 }
238 }
239
240
241 array_walk_recursive($entries, function (&$item) {
242 if (!is_null($item)) {
243 $item = rtrim($item, PHP_EOL);
244 } else {
245 $item = '';
246 }
247 });
248
249 return $entries;
250 }
251
252 protected function getEntriesFromArray(array $entries_array): Entry\ComponentEntries
253 {
254 $entries = new Entry\ComponentEntries();
255
256 foreach ($entries_array as $entry_data) {
257 $entries->addEntry($this->getEntryFromData($entry_data));
258 }
259
260 return $entries;
261 }
262
266 protected function getEntryFromData(array $entry_data): Entry\ComponentEntry
267 {
268 $entry_data['title'] = self::fromCamelCaseToWords($entry_data['function_name']);
269
270 if (!array_key_exists("title", $entry_data) || !$entry_data['title'] || $entry_data['title'] == "") {
271 throw $this->ef->exception(Exception\CrawlerException::ENTRY_TITLE_MISSING, " File: " . $this->file_path);
272 }
273 if (!array_key_exists("namespace", $entry_data) || !$entry_data['namespace'] || $entry_data['namespace'] == "") {
274 throw $this->ef->exception(Exception\CrawlerException::ENTRY_WITH_NO_VALID_RETURN_STATEMENT, " File: " . $this->file_path);
275 }
276 $entry_data['namespace'] = str_replace('[]', '', $entry_data['namespace']);
277
278 $entry_data['id'] = str_replace(
279 "\\",
280 "",
281 str_replace("\\ILIAS\\UI\\", "", str_replace("\\ILIAS\\UI\\Component\\", "", $entry_data['namespace']))
282 )
283 . self::toUpperCamelCase($entry_data['title'], ' ');
284 $entry_data['abstract'] = preg_match("/Factory/", $entry_data['namespace']);
285 $entry_data['path'] = str_replace("/ILIAS/UI", "components/ILIAS/UI/src", str_replace("\\", "/", $entry_data['namespace']));
286
287 if (str_contains($entry_data['path'], 'tests/UI/')) {
288 $entry_data['path'] = str_replace("tests/UI/", "components/ILIAS/UI/tests/", $entry_data['path']);
289 }
290
291 try {
292 $entry = new Entry\ComponentEntry($entry_data);
293 } catch (\Exception $e) {
294 throw $this->ef->exception(
295 Exception\CrawlerException::PARSING_YAML_ENTRY_FAILED,
296 " could not convert data to entry, message: '" . $e->getMessage() . "' file: " . $this->file_path
297 );
298 }
299
300 return $entry;
301 }
302
306 public static function toUpperCamelCase(string $string, string $seperator)
307 {
308 return str_replace($seperator, '', ucwords($string));
309 }
310
314 public static function toLowerCamelCase(string $string, string $seperator)
315 {
316 return str_replace($seperator, '', lcfirst(ucwords($string)));
317 }
318
319 public static function fromCamelCaseToWords(string $camelCaseString): string
320 {
321 return implode(' ', preg_split('/(?<=[a-z])(?=[A-Z])/x', ucwords($camelCaseString)));
322 }
323}
static toLowerCamelCase(string $string, string $seperator)
static fromCamelCaseToWords(string $camelCaseString)
string $file_path
Used to add for Information in Exceptions.
static toUpperCamelCase(string $string, string $seperator)
parseEntriesFromString(string $content)
Returns a list UI Component Entries of the parsed YAML entries in a given string.
Container storing a list of UI Component Entries, can act as Iterator, countable and is serializable.
Stores Information of UI Components parsed from YAML, examples and less files.
Parses information from UI components.
Definition: YamlParser.php:29