TYPO3 CMS  TYPO3_8-7
YamlFileLoader.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
19 
35 {
36 
44  public function load(string $fileName): array
45  {
46  $content = $this->getFileContents($fileName);
47  $content = Yaml::parse($content);
48 
49  if (!is_array($content)) {
50  throw new \RuntimeException('YAML file "' . $fileName . '" could not be parsed into valid syntax, probably empty?', 1497332874);
51  }
52 
53  $content = $this->processImports($content);
54 
55  // Check for "%" placeholders
56  $content = $this->processPlaceholders($content, $content);
57 
58  return $content;
59  }
60 
69  protected function getFileContents(string $fileName): string
70  {
71  $streamlinedFileName = GeneralUtility::getFileAbsFileName($fileName);
72  if (!$streamlinedFileName) {
73  throw new \RuntimeException('YAML File "' . $fileName . '" could not be loaded', 1485784246);
74  }
75  return file_get_contents($streamlinedFileName);
76  }
77 
85  protected function processImports(array $content): array
86  {
87  if (isset($content['imports']) && is_array($content['imports'])) {
88  foreach ($content['imports'] as $import) {
89  $importedContent = $this->load($import['resource']);
90  // override the imported content with the one from the current file
91  $content = $this->merge($importedContent, $content);
92  }
93  unset($content['imports']);
94  }
95  return $content;
96  }
97 
107  protected function processPlaceholders(array $content, array $referenceArray): array
108  {
109  foreach ($content as $k => $v) {
110  if ($this->isPlaceholder($v)) {
111  $content[$k] = $this->getValueFromReferenceArray($v, $referenceArray);
112  } elseif (is_array($v)) {
113  $content[$k] = $this->processPlaceholders($v, $referenceArray);
114  }
115  }
116  return $content;
117  }
118 
127  protected function getValueFromReferenceArray(string $placeholder, array $referenceArray)
128  {
129  $pointer = trim($placeholder, '%');
130  $parts = explode('.', $pointer);
131  $referenceData = $referenceArray;
132  foreach ($parts as $part) {
133  if (isset($referenceData[$part])) {
134  $referenceData = $referenceData[$part];
135  } else {
136  // return unsubstituted placeholder
137  return $placeholder;
138  }
139  }
140  if ($this->isPlaceholder($referenceData)) {
141  $referenceData = $this->getValueFromReferenceArray($referenceData, $referenceArray);
142  }
143  return $referenceData;
144  }
145 
152  protected function isPlaceholder($value): bool
153  {
154  return is_string($value) && substr($value, 0, 1) === '%' && substr($value, -1) === '%';
155  }
156 
166  protected function merge(array $val1, array $val2): array
167  {
168  // Simple lists get merged / added up
169  if (count(array_filter(array_keys($val1), 'is_int')) === count($val1)) {
170  return array_merge($val1, $val2);
171  }
172  foreach ($val1 as $k => $v) {
173  // The key also exists in second array, if it is a simple value
174  // then $val2 will override the value, where an array is calling merge() recursively.
175  if (isset($val2[$k])) {
176  if (is_array($v) && isset($val2[$k])) {
177  if (is_array($val2[$k])) {
178  $val1[$k] = $this->merge($v, $val2[$k]);
179  } else {
180  $val1[$k] = $val2[$k];
181  }
182  } else {
183  $val1[$k] = $val2[$k];
184  }
185  unset($val2[$k]);
186  }
187  }
188  // If there are properties in the second array left, they are added up
189  if (!empty($val2)) {
190  foreach ($val2 as $k => $v) {
191  $val1[$k] = $v;
192  }
193  }
194 
195  return $val1;
196  }
197 }
static getFileAbsFileName($filename, $_=null, $_2=null)
processPlaceholders(array $content, array $referenceArray)
getValueFromReferenceArray(string $placeholder, array $referenceArray)