TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
MarkerBasedTemplateService.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Service;
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  */
17 
23 {
33  public function getSubpart($content, $marker)
34  {
35  $start = strpos($content, $marker);
36  if ($start === false) {
37  return '';
38  }
39  $start += strlen($marker);
40  $stop = strpos($content, $marker, $start);
41  // Q: What shall get returned if no stop marker is given
42  // Everything till the end or nothing?
43  if ($stop === false) {
44  return '';
45  }
46  $content = substr($content, $start, $stop - $start);
47  $matches = [];
48  if (preg_match('/^([^\\<]*\\-\\-\\>)(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $content, $matches) === 1) {
49  return $matches[2];
50  }
51  // Resetting $matches
52  $matches = [];
53  if (preg_match('/(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $content, $matches) === 1) {
54  return $matches[1];
55  }
56  // Resetting $matches
57  $matches = [];
58  if (preg_match('/^([^\\<]*\\-\\-\\>)(.*)$/s', $content, $matches) === 1) {
59  return $matches[2];
60  }
61 
62  return $content;
63  }
64 
76  public function substituteSubpart($content, $marker, $subpartContent, $recursive = true, $keepMarker = false)
77  {
78  $start = strpos($content, $marker);
79  if ($start === false) {
80  return $content;
81  }
82  $startAM = $start + strlen($marker);
83  $stop = strpos($content, $marker, $startAM);
84  if ($stop === false) {
85  return $content;
86  }
87  $stopAM = $stop + strlen($marker);
88  $before = substr($content, 0, $start);
89  $after = substr($content, $stopAM);
90  $between = substr($content, $startAM, $stop - $startAM);
91  if ($recursive) {
92  $after = $this->substituteSubpart($after, $marker, $subpartContent, $recursive, $keepMarker);
93  }
94  if ($keepMarker) {
95  $matches = [];
96  if (preg_match('/^([^\\<]*\\-\\-\\>)(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $between, $matches) === 1) {
97  $before .= $marker . $matches[1];
98  $between = $matches[2];
99  $after = $matches[3] . $marker . $after;
100  } elseif (preg_match('/^(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $between, $matches) === 1) {
101  $before .= $marker;
102  $between = $matches[1];
103  $after = $matches[2] . $marker . $after;
104  } elseif (preg_match('/^([^\\<]*\\-\\-\\>)(.*)$/s', $between, $matches) === 1) {
105  $before .= $marker . $matches[1];
106  $between = $matches[2];
107  $after = $marker . $after;
108  } else {
109  $before .= $marker;
110  $after = $marker . $after;
111  }
112  } else {
113  $matches = [];
114  if (preg_match('/^(.*)\\<\\!\\-\\-[^\\>]*$/s', $before, $matches) === 1) {
115  $before = $matches[1];
116  }
117  if (is_array($subpartContent)) {
118  $matches = [];
119  if (preg_match('/^([^\\<]*\\-\\-\\>)(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $between, $matches) === 1) {
120  $between = $matches[2];
121  } elseif (preg_match('/^(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $between, $matches) === 1) {
122  $between = $matches[1];
123  } elseif (preg_match('/^([^\\<]*\\-\\-\\>)(.*)$/s', $between, $matches) === 1) {
124  $between = $matches[2];
125  }
126  }
127  $matches = [];
128  // resetting $matches
129  if (preg_match('/^[^\\<]*\\-\\-\\>(.*)$/s', $after, $matches) === 1) {
130  $after = $matches[1];
131  }
132  }
133  if (is_array($subpartContent)) {
134  $between = $subpartContent[0] . $between . $subpartContent[1];
135  } else {
136  $between = $subpartContent;
137  }
138 
139  return $before . $between . $after;
140  }
141 
150  public function substituteSubpartArray($content, array $subpartsContent)
151  {
152  foreach ($subpartsContent as $subpartMarker => $subpartContent) {
153  $content = $this->substituteSubpart($content, $subpartMarker, $subpartContent);
154  }
155 
156  return $content;
157  }
158 
170  public function substituteMarker($content, $marker, $markContent)
171  {
172  return str_replace($marker, $markContent, $content);
173  }
174 
194  public function substituteMarkerArray($content, $markContentArray, $wrap = '', $uppercase = false, $deleteUnused = false)
195  {
196  if (is_array($markContentArray)) {
197  $wrapArr = GeneralUtility::trimExplode('|', $wrap);
198  $search = [];
199  $replace = [];
200  foreach ($markContentArray as $marker => $markContent) {
201  if ($uppercase) {
202  // use strtr instead of strtoupper to avoid locale problems with Turkish
203  $marker = strtr($marker, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
204  }
205  if (!empty($wrapArr)) {
206  $marker = $wrapArr[0] . $marker . $wrapArr[1];
207  }
208  $search[] = $marker;
209  $replace[] = $markContent;
210  }
211  $content = str_replace($search, $replace, $content);
212  unset($search, $replace);
213  if ($deleteUnused) {
214  if (empty($wrap)) {
215  $wrapArr = ['###', '###'];
216  }
217  $content = preg_replace('/' . preg_quote($wrapArr[0], '/') . '([A-Z0-9_|\\-]*)' . preg_quote($wrapArr[1], '/') . '/is', '', $content);
218  }
219  }
220 
221  return $content;
222  }
223 
261  public function substituteMarkerAndSubpartArrayRecursive($content, array $markersAndSubparts, $wrap = '', $uppercase = false, $deleteUnused = false)
262  {
263  $wraps = GeneralUtility::trimExplode('|', $wrap);
264  $singleItems = [];
265  $compoundItems = [];
266  // Split markers and subparts into separate arrays
267  foreach ($markersAndSubparts as $markerName => $markerContent) {
268  if (is_array($markerContent)) {
269  $compoundItems[] = $markerName;
270  } else {
271  $singleItems[$markerName] = $markerContent;
272  }
273  }
274  $subTemplates = [];
275  $subpartSubstitutes = [];
276  // Build a cache for the sub template
277  foreach ($compoundItems as $subpartMarker) {
278  if ($uppercase) {
279  // Use strtr instead of strtoupper to avoid locale problems with Turkish
280  $subpartMarker = strtr($subpartMarker, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
281  }
282  if (!empty($wraps)) {
283  $subpartMarker = $wraps[0] . $subpartMarker . $wraps[1];
284  }
285  $subTemplates[$subpartMarker] = $this->getSubpart($content, $subpartMarker);
286  }
287  // Replace the subpart contents recursively
288  foreach ($compoundItems as $subpartMarker) {
289  $completeMarker = $subpartMarker;
290  if ($uppercase) {
291  // use strtr instead of strtoupper to avoid locale problems with Turkish
292  $completeMarker = strtr($completeMarker, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
293  }
294  if (!empty($wraps)) {
295  $completeMarker = $wraps[0] . $completeMarker . $wraps[1];
296  }
297  if (!empty($markersAndSubparts[$subpartMarker])) {
298  foreach ($markersAndSubparts[$subpartMarker] as $partialMarkersAndSubparts) {
299  $subpartSubstitutes[$completeMarker] .= $this->substituteMarkerAndSubpartArrayRecursive($subTemplates[$completeMarker],
300  $partialMarkersAndSubparts, $wrap, $uppercase, $deleteUnused);
301  }
302  } else {
303  $subpartSubstitutes[$completeMarker] = '';
304  }
305  }
306  // Substitute the single markers and subparts
307  $result = $this->substituteSubpartArray($content, $subpartSubstitutes);
308  $result = $this->substituteMarkerArray($result, $singleItems, $wrap, $uppercase, $deleteUnused);
309 
310  return $result;
311  }
312 }
substituteMarkerAndSubpartArrayRecursive($content, array $markersAndSubparts, $wrap= '', $uppercase=false, $deleteUnused=false)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
substituteMarkerArray($content, $markContentArray, $wrap= '', $uppercase=false, $deleteUnused=false)
substituteSubpart($content, $marker, $subpartContent, $recursive=true, $keepMarker=false)