ILIAS  release_7 Revision v7.30-3-g800a261c036
EntriesYamlParser.php
Go to the documentation of this file.
1<?php
2/***
3 * @author Timon Amstutz <timon.amstutz@ilub.unibe.ch>
4 * @version $Id$
5 *
6 */
8
9use Symfony\Component\Yaml;
11
13{
14 public const PARSER_STATE_OUTSIDE = 1;
15 public const PARSER_STATE_ENTRY = 2;
18
22 protected $items = array();
23
27 protected $ef = null;
28
34 protected $file_path = "none";
35
39 public function __construct()
40 {
41 $this->ef = new Exception\Factory();
42 }
43
49 public function parseYamlStringArrayFromFile($filePath)
50 {
51 $this->file_path = $filePath;
52 $content = $this->getFileContentAsString($filePath);
53 return $this->parseYamlStringArrayFromString($content);
54 }
55
61 public function parseArrayFromFile($filePath)
62 {
63 $this->file_path = $filePath;
64 $content = $this->getFileContentAsString($filePath);
65 return $this->parseArrayFromString($content);
66 }
67
73 public function parseEntriesFromFile($filePath)
74 {
75 $this->file_path = $filePath;
76 $content = $this->getFileContentAsString($filePath);
77 return $this->parseEntriesFromString($content);
78 }
79
85 public function parseYamlStringArrayFromString($content)
86 {
87 return $this->getYamlEntriesFromString($content);
88 }
89
95 public function parseArrayFromString($content)
96 {
97 return $this->getPHPArrayFromYamlArray(
98 $this->getYamlEntriesFromString($content)
99 );
100 }
101
106 public function parseEntriesFromString($content)
107 {
108 $entries_array = $this->parseArrayFromString($content);
109 return $this->getEntriesFromArray($entries_array);
110 }
111
117 protected function getFileContentAsString($filePath)
118 {
119 if (!file_exists($filePath)) {
120 throw $this->ef->exception(Exception\CrawlerException::INVALID_FILE_PATH, $filePath);
121 }
122 $content = file_get_contents($filePath);
123 if (!$content) {
124 throw $this->ef->exception(Exception\CrawlerException::FILE_OPENING_FAILED, $filePath);
125 }
126 return $content;
127 }
128
134 protected function getYamlEntriesFromString($content)
135 {
136 $parser_state = self::PARSER_STATE_OUTSIDE;
137 $current_entry = "";
138 $yaml_entries = array();
139
140 foreach (preg_split("/((\r?\n)|(\r\n?))/", $content) as $line) {
141 if ($parser_state === self::PARSER_STATE_OUTSIDE) {
142 if (preg_match('/---/', $line)) {
143 $current_entry = "";
144 $parser_state = self::PARSER_STATE_ENTRY;
145 }
146 if (preg_match('/\@return/', $line)) {
147 throw $this->ef->exception(
148 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
149 " in file: " . $this->file_path . ", " . $line
150 );
151 }
152 if (preg_match('/public function (.*)\‍(/', $line)) {
153 throw $this->ef->exception(
154 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
155 " in file: " . $this->file_path . ", " . $line
156 );
157 }
158 } elseif ($parser_state === self::PARSER_STATE_ENTRY) {
159 if (!preg_match('/(\*$)|(---)/', $line)) {
160 $current_entry .= $this->purifyYamlLine($line);
161 }
162 if (preg_match('/---/', $line)) {
163 $parser_state = self::PARSER_STATE_SEEKING_RETURN;
164 }
165 if (preg_match('/\@return/', $line)) {
166 throw $this->ef->exception(
167 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
168 " in file: " . $this->file_path . ", " . $line
169 );
170 }
171 if (preg_match('/public function (.*)\‍(/', $line)) {
172 throw $this->ef->exception(
173 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
174 " in file: " . $this->file_path . ", " . $line
175 );
176 }
177 } elseif ($parser_state === self::PARSER_STATE_SEEKING_RETURN) {
178 if (preg_match('/\@return/', $line)) {
179 $current_entry .= "namespace: " . ltrim($this->purifyYamlLine($line), '@return');
181 }
182 if (preg_match('/---/', $line)) {
183 throw $this->ef->exception(
184 Exception\CrawlerException::ENTRY_WITH_NO_VALID_RETURN_STATEMENT,
185 " in file: " . $this->file_path . " line " . $current_entry
186 );
187 }
188 if (preg_match('/public function (.*)\‍(/', $line)) {
189 throw $this->ef->exception(
190 Exception\CrawlerException::ENTRY_WITH_NO_VALID_RETURN_STATEMENT,
191 " in file: " . $this->file_path . " line " . $current_entry
192 );
193 }
194 } else {
195 if (preg_match('/public function (.*)\‍(/', $line, $matches)) {
196 preg_match('/public function (.*)\‍(/', $line, $matches);
197 $current_entry .= "function_name: " . $matches[1];
198 $yaml_entries[] = $current_entry;
199 $parser_state = self::PARSER_STATE_OUTSIDE;
200 }
201 if (preg_match('/---/', $line)) {
202 throw $this->ef->exception(
203 Exception\CrawlerException::ENTRY_WITHOUT_FUNCTION,
204 " in file: " . $this->file_path . " line " . $current_entry
205 );
206 }
207 }
208 }
209 if ($parser_state === self::PARSER_STATE_SEEKING_RETURN) {
210 throw $this->ef->exception(
211 Exception\CrawlerException::ENTRY_WITH_NO_VALID_RETURN_STATEMENT,
212 " in file: " . $this->file_path . " line " . $current_entry
213 );
214 } elseif ($parser_state === self::PARSER_STATE_ENTRY) {
215 throw $this->ef->exception(
216 Exception\CrawlerException::ENTRY_WITH_NO_YAML_DESCRIPTION,
217 " in file: " . $this->file_path
218 );
219 } elseif ($parser_state === self::PARSER_STATE_SEEKING_FUNCTION_NAME) {
220 throw $this->ef->exception(
221 Exception\CrawlerException::ENTRY_WITHOUT_FUNCTION,
222 " in file: " . $this->file_path
223 );
224 }
225 return $yaml_entries;
226 }
227
232 protected function purifyYamlLine($line)
233 {
234 return str_replace("* ", "", ltrim($line)) . PHP_EOL;
235 }
236
242 protected function getPHPArrayFromYamlArray($yaml_entries)
243 {
244 $entries = array();
245 $parser = new Yaml\Parser();
246
247 foreach ($yaml_entries as $yaml_entry) {
248 try {
249 $entries[] = $parser->parse($yaml_entry);
250 } catch (\Exception $e) {
251 throw $this->ef->exception(Exception\CrawlerException::PARSING_YAML_ENTRY_FAILED, " file: " . $this->file_path . "; " . $e);
252 }
253 }
254
255
256 array_walk_recursive($entries, function (&$item) {
257 $item = rtrim($item, PHP_EOL);
258 });
259
260 return $entries;
261 }
262
267 protected function getEntriesFromArray(array $entries_array)
268 {
269 $entries = new Entry\ComponentEntries();
270
271 foreach ($entries_array as $entry_data) {
272 $entries->addEntry($this->getEntryFromData($entry_data));
273 }
274
275 return $entries;
276 }
277
283 protected function getEntryFromData(array $entry_data)
284 {
285 $entry_data['title'] = self::fromCamelCaseToWords($entry_data['function_name']);
286
287 if (!array_key_exists("title", $entry_data) || !$entry_data['title'] || $entry_data['title'] == "") {
288 throw $this->ef->exception(Exception\CrawlerException::ENTRY_TITLE_MISSING, " File: " . $this->file_path);
289 }
290 if (!array_key_exists("namespace", $entry_data) || !$entry_data['namespace'] || $entry_data['namespace'] == "") {
291 throw $this->ef->exception(Exception\CrawlerException::ENTRY_WITH_NO_VALID_RETURN_STATEMENT, " File: " . $this->file_path);
292 }
293
294 $entry_data['id'] = str_replace(
295 "\\",
296 "",
297 str_replace("\\ILIAS\\UI\\", "", str_replace("\\ILIAS\\UI\\Component\\", "", $entry_data['namespace']))
298 )
299 . self::toUpperCamelCase($entry_data['title'], ' ');
300 $entry_data['abstract'] = preg_match("/Factory/", $entry_data['namespace']);
301 $entry_data['path'] = str_replace("/ILIAS", "src", str_replace("\\", "/", $entry_data['namespace']));
302
303 try {
304 $entry = new Entry\ComponentEntry($entry_data);
305 } catch (\Exception $e) {
306 throw $this->ef->exception(
307 Exception\CrawlerException::PARSING_YAML_ENTRY_FAILED,
308 " could not convert data to entry, message: '" . $e->getMessage() . "' file: " . $this->file_path
309 );
310 }
311
312 return $entry;
313 }
314
320 public static function toUpperCamelCase($string, $seperator)
321 {
322 return str_replace($seperator, '', ucwords($string));
323 }
324
330 public static function toLowerCamelCase($string, $seperator)
331 {
332 return str_replace($seperator, '', lcfirst(ucwords($string)));
333 }
334
339 public static function fromCamelCaseToWords($camelCaseString)
340 {
341 return implode(' ', preg_split('/(?<=[a-z])(?=[A-Z])/x', ucwords($camelCaseString)));
342 }
343}
An exception for terminatinating execution or to throw for unit testing.
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:13