[!!!][CLEANUP] Remove deprecated code in sysext fluid
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / View / TemplateView.php
1 <?php
2 namespace TYPO3\CMS\Fluid\View;
3
4 /* *
5 * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License, either version 3 *
9 * of the License, or (at your option) any later version. *
10 * *
11 * The TYPO3 project - inspiring people to share! *
12 * */
13
14 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
15 use TYPO3\CMS\Core\Utility\GeneralUtility;
16 use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
17 use TYPO3\CMS\Fluid\Compatibility\TemplateParserBuilder;
18 use TYPO3\CMS\Fluid\Fluid;
19
20 /**
21 * The main template view. Should be used as view if you want Fluid Templating
22 *
23 * @api
24 */
25 class TemplateView extends AbstractTemplateView {
26
27 /**
28 * Pattern to be resolved for "@templateRoot" in the other patterns.
29 * Following placeholders are supported:
30 * - "@packageResourcesPath"
31 *
32 * @var string
33 */
34 protected $templateRootPathPattern = '@packageResourcesPath/Private/Templates';
35
36 /**
37 * Pattern to be resolved for "@partialRoot" in the other patterns.
38 * Following placeholders are supported:
39 * - "@packageResourcesPath"
40 *
41 * @var string
42 */
43 protected $partialRootPathPattern = '@packageResourcesPath/Private/Partials';
44
45 /**
46 * Pattern to be resolved for "@layoutRoot" in the other patterns.
47 * Following placeholders are supported:
48 * - "@packageResourcesPath"
49 *
50 * @var string
51 */
52 protected $layoutRootPathPattern = '@packageResourcesPath/Private/Layouts';
53
54 /**
55 * Path(s) to the template root. If NULL, then $this->templateRootPathPattern will be used.
56 *
57 * @var array
58 */
59 protected $templateRootPaths = NULL;
60
61 /**
62 * Path(s) to the partial root. If NULL, then $this->partialRootPathPattern will be used.
63 *
64 * @var array
65 */
66 protected $partialRootPaths = NULL;
67
68 /**
69 * Path(s) to the layout root. If NULL, then $this->layoutRootPathPattern will be used.
70 *
71 * @var array
72 */
73 protected $layoutRootPaths = NULL;
74
75 /**
76 * File pattern for resolving the template file
77 * Following placeholders are supported:
78 * - "@templateRoot"
79 * - "@partialRoot"
80 * - "@layoutRoot"
81 * - "@subpackage"
82 * - "@action"
83 * - "@format"
84 *
85 * @var string
86 */
87 protected $templatePathAndFilenamePattern = '@templateRoot/@subpackage/@controller/@action.@format';
88
89 /**
90 * Directory pattern for global partials. Not part of the public API, should not be changed for now.
91 * Following placeholders are supported:
92 * - "@templateRoot"
93 * - "@partialRoot"
94 * - "@layoutRoot"
95 * - "@subpackage"
96 * - "@partial"
97 * - "@format"
98 *
99 * @var string
100 */
101 private $partialPathAndFilenamePattern = '@partialRoot/@subpackage/@partial.@format';
102
103 /**
104 * File pattern for resolving the layout
105 * Following placeholders are supported:
106 * - "@templateRoot"
107 * - "@partialRoot"
108 * - "@layoutRoot"
109 * - "@subpackage"
110 * - "@layout"
111 * - "@format"
112 *
113 * @var string
114 */
115 protected $layoutPathAndFilenamePattern = '@layoutRoot/@layout.@format';
116
117 /**
118 * Path and filename of the template file. If set, overrides the templatePathAndFilenamePattern
119 *
120 * @var string
121 */
122 protected $templatePathAndFilename = NULL;
123
124 /**
125 * Path and filename of the layout file. If set, overrides the layoutPathAndFilenamePattern
126 *
127 * @var string
128 */
129 protected $layoutPathAndFilename = NULL;
130
131 /**
132 * Constructor
133 */
134 public function __construct() {
135 $this->templateParser = TemplateParserBuilder::build();
136 $this->objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
137 $this->setRenderingContext($this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Rendering\\RenderingContextInterface'));
138 }
139
140 /**
141 * Init view
142 */
143 public function initializeView() {
144 }
145 // Here, the backporter can insert a constructor method, which is needed for the TYPO3 CMS extension
146
147 /**
148 * Sets the path and name of of the template file. Effectively overrides the
149 * dynamic resolving of a template file.
150 *
151 * @param string $templatePathAndFilename Template file path
152 * @return void
153 * @api
154 */
155 public function setTemplatePathAndFilename($templatePathAndFilename) {
156 $this->templatePathAndFilename = $templatePathAndFilename;
157 }
158
159 /**
160 * Sets the path and name of the layout file. Overrides the dynamic resolving of the layout file.
161 *
162 * @param string $layoutPathAndFilename Path and filename of the layout file
163 * @return void
164 * @api
165 */
166 public function setLayoutPathAndFilename($layoutPathAndFilename) {
167 $this->layoutPathAndFilename = $layoutPathAndFilename;
168 }
169
170 /**
171 * Set the root path to the templates.
172 * If set, overrides the one determined from $this->templateRootPathPattern
173 *
174 * @param string $templateRootPath Root path to the templates. If set, overrides the one determined from $this->templateRootPathPattern
175 * @return void
176 * @api
177 * @see setTemplateRootPaths()
178 */
179 public function setTemplateRootPath($templateRootPath) {
180 $this->setTemplateRootPaths(array($templateRootPath));
181 }
182
183 /**
184 * Resolves the template root to be used inside other paths.
185 *
186 * @return array Path(s) to template root directory
187 */
188 public function getTemplateRootPaths() {
189 if ($this->templateRootPaths !== NULL) {
190 return $this->templateRootPaths;
191 }
192 /** @var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
193 $actionRequest = $this->controllerContext->getRequest();
194 return array(str_replace('@packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->templateRootPathPattern));
195 }
196
197 /**
198 * Set the root path(s) to the templates.
199 * If set, overrides the one determined from $this->templateRootPathPattern
200 *
201 * @param array $templateRootPaths Root path(s) to the templates. If set, overrides the one determined from $this->templateRootPathPattern
202 * @return void
203 * @api
204 */
205 public function setTemplateRootPaths(array $templateRootPaths) {
206 $this->templateRootPaths = $templateRootPaths;
207 }
208
209 /**
210 * Set the root path to the partials.
211 * If set, overrides the one determined from $this->partialRootPathPattern
212 *
213 * @param string $partialRootPath Root path to the partials. If set, overrides the one determined from $this->partialRootPathPattern
214 * @return void
215 * @api
216 * @see setPartialRootPaths()
217 */
218 public function setPartialRootPath($partialRootPath) {
219 $this->setPartialRootPaths(array($partialRootPath));
220 }
221
222 /**
223 * Set the root path(s) to the partials.
224 * If set, overrides the one determined from $this->partialRootPathPattern
225 *
226 * @param array $partialRootPaths Root paths to the partials. If set, overrides the one determined from $this->partialRootPathPattern
227 * @return void
228 * @api
229 */
230 public function setPartialRootPaths(array $partialRootPaths) {
231 $this->partialRootPaths = $partialRootPaths;
232 }
233
234 /**
235 * Resolves the partial root to be used inside other paths.
236 *
237 * @return array Path(s) to partial root directory
238 */
239 protected function getPartialRootPaths() {
240 if ($this->partialRootPaths !== NULL) {
241 return $this->partialRootPaths;
242 }
243 /** @var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
244 $actionRequest = $this->controllerContext->getRequest();
245 return array(str_replace('@packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->partialRootPathPattern));
246 }
247
248 /**
249 * Set the root path to the layouts.
250 * If set, overrides the one determined from $this->layoutRootPathPattern
251 *
252 * @param string $layoutRootPath Root path to the layouts. If set, overrides the one determined from $this->layoutRootPathPattern
253 * @return void
254 * @api
255 * @see setLayoutRootPaths()
256 */
257 public function setLayoutRootPath($layoutRootPath) {
258 $this->setLayoutRootPaths(array($layoutRootPath));
259 }
260
261 /**
262 * Set the root path(s) to the layouts.
263 * If set, overrides the one determined from $this->layoutRootPathPattern
264 *
265 * @param array $layoutRootPaths Root path to the layouts. If set, overrides the one determined from $this->layoutRootPathPattern
266 * @return void
267 * @api
268 */
269 public function setLayoutRootPaths(array $layoutRootPaths) {
270 $this->layoutRootPaths = $layoutRootPaths;
271 }
272
273 /**
274 * Resolves the layout root to be used inside other paths.
275 *
276 * @return string Path(s) to layout root directory
277 */
278 protected function getLayoutRootPaths() {
279 if ($this->layoutRootPaths !== NULL) {
280 return $this->layoutRootPaths;
281 }
282 /** @var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
283 $actionRequest = $this->controllerContext->getRequest();
284 return array(str_replace('@packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->layoutRootPathPattern));
285 }
286
287 /**
288 * Returns a unique identifier for the resolved template file
289 * This identifier is based on the template path and last modification date
290 *
291 * @param string $actionName Name of the action. If NULL, will be taken from request.
292 * @return string template identifier
293 */
294 protected function getTemplateIdentifier($actionName = NULL) {
295 $templatePathAndFilename = $this->getTemplatePathAndFilename($actionName);
296 if ($actionName === NULL) {
297 /** @var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
298 $actionRequest = $this->controllerContext->getRequest();
299 $actionName = $actionRequest->getControllerActionName();
300 }
301 $prefix = 'action_' . $actionName;
302 return $this->createIdentifierForFile($templatePathAndFilename, $prefix);
303 }
304
305 /**
306 * Resolve the template path and filename for the given action. If $actionName
307 * is NULL, looks into the current request.
308 *
309 * @param string $actionName Name of the action. If NULL, will be taken from request.
310 * @return string Full path to template
311 * @throws Exception\InvalidTemplateResourceException
312 */
313 protected function getTemplateSource($actionName = NULL) {
314 $templatePathAndFilename = $this->getTemplatePathAndFilename($actionName);
315 $templateSource = file_get_contents($templatePathAndFilename);
316 if ($templateSource === FALSE) {
317 throw new Exception\InvalidTemplateResourceException('"' . $templatePathAndFilename . '" is not a valid template resource URI.', 1257246929);
318 }
319 return $templateSource;
320 }
321
322 /**
323 * Resolve the template path and filename for the given action. If $actionName
324 * is NULL, looks into the current request.
325 *
326 * @param string $actionName Name of the action. If NULL, will be taken from request.
327 * @return string Full path to template
328 * @throws Exception\InvalidTemplateResourceException
329 */
330 protected function getTemplatePathAndFilename($actionName = NULL) {
331 if ($this->templatePathAndFilename !== NULL) {
332 return $this->templatePathAndFilename;
333 }
334 if ($actionName === NULL) {
335 /** @var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
336 $actionRequest = $this->controllerContext->getRequest();
337 $actionName = $actionRequest->getControllerActionName();
338 }
339 $actionName = ucfirst($actionName);
340
341 $paths = $this->expandGenericPathPattern($this->templatePathAndFilenamePattern, FALSE, FALSE);
342 foreach ($paths as &$templatePathAndFilename) {
343 $templatePathAndFilename = $this->resolveFileNamePath(str_replace('@action', $actionName, $templatePathAndFilename));
344 if (is_file($templatePathAndFilename)) {
345 return $templatePathAndFilename;
346 }
347 }
348 throw new Exception\InvalidTemplateResourceException('Template could not be loaded. I tried "' . implode('", "', $paths) . '"', 1225709595);
349 }
350
351 /**
352 * Returns a unique identifier for the resolved layout file.
353 * This identifier is based on the template path and last modification date
354 *
355 * @param string $layoutName The name of the layout
356 * @return string layout identifier
357 */
358 protected function getLayoutIdentifier($layoutName = 'Default') {
359 $layoutPathAndFilename = $this->getLayoutPathAndFilename($layoutName);
360 $prefix = 'layout_' . $layoutName;
361 return $this->createIdentifierForFile($layoutPathAndFilename, $prefix);
362 }
363
364 /**
365 * Resolve the path and file name of the layout file, based on
366 * $this->layoutPathAndFilename and $this->layoutPathAndFilenamePattern.
367 *
368 * In case a layout has already been set with setLayoutPathAndFilename(),
369 * this method returns that path, otherwise a path and filename will be
370 * resolved using the layoutPathAndFilenamePattern.
371 *
372 * @param string $layoutName Name of the layout to use. If none given, use "Default"
373 * @return string contents of the layout template
374 * @throws Exception\InvalidTemplateResourceException
375 */
376 protected function getLayoutSource($layoutName = 'Default') {
377 $layoutPathAndFilename = $this->getLayoutPathAndFilename($layoutName);
378 $layoutSource = file_get_contents($layoutPathAndFilename);
379 if ($layoutSource === FALSE) {
380 throw new Exception\InvalidTemplateResourceException('"' . $layoutPathAndFilename . '" is not a valid template resource URI.', 1257246930);
381 }
382 return $layoutSource;
383 }
384
385 /**
386 * Resolve the path and file name of the layout file, based on
387 * $this->layoutPathAndFilename and $this->layoutPathAndFilenamePattern.
388 *
389 * In case a layout has already been set with setLayoutPathAndFilename(),
390 * this method returns that path, otherwise a path and filename will be
391 * resolved using the layoutPathAndFilenamePattern.
392 *
393 * @param string $layoutName Name of the layout to use. If none given, use "Default"
394 * @return string Path and filename of layout files
395 * @throws Exception\InvalidTemplateResourceException
396 */
397 protected function getLayoutPathAndFilename($layoutName = 'Default') {
398 if ($this->layoutPathAndFilename !== NULL) {
399 return $this->layoutPathAndFilename;
400 }
401 $paths = $this->expandGenericPathPattern($this->layoutPathAndFilenamePattern, TRUE, TRUE);
402 $layoutName = ucfirst($layoutName);
403 foreach ($paths as &$layoutPathAndFilename) {
404 $layoutPathAndFilename = $this->resolveFileNamePath(str_replace('@layout', $layoutName, $layoutPathAndFilename));
405 if (is_file($layoutPathAndFilename)) {
406 return $layoutPathAndFilename;
407 }
408 }
409 throw new Exception\InvalidTemplateResourceException('The template files "' . implode('", "', $paths) . '" could not be loaded.', 1225709596);
410 }
411
412 /**
413 * Returns a unique identifier for the resolved partial file.
414 * This identifier is based on the template path and last modification date
415 *
416 * @param string $partialName The name of the partial
417 * @return string partial identifier
418 */
419 protected function getPartialIdentifier($partialName) {
420 $partialPathAndFilename = $this->getPartialPathAndFilename($partialName);
421 $prefix = 'partial_' . $partialName;
422 return $this->createIdentifierForFile($partialPathAndFilename, $prefix);
423 }
424
425 /**
426 * Figures out which partial to use.
427 *
428 * @param string $partialName The name of the partial
429 * @return string contents of the partial template
430 * @throws Exception\InvalidTemplateResourceException
431 */
432 protected function getPartialSource($partialName) {
433 $partialPathAndFilename = $this->getPartialPathAndFilename($partialName);
434 $partialSource = file_get_contents($partialPathAndFilename);
435 if ($partialSource === FALSE) {
436 throw new Exception\InvalidTemplateResourceException('"' . $partialPathAndFilename . '" is not a valid template resource URI.', 1257246931);
437 }
438 return $partialSource;
439 }
440
441 /**
442 * Resolve the partial path and filename based on $this->partialPathAndFilenamePattern.
443 *
444 * @param string $partialName The name of the partial
445 * @return string the full path which should be used. The path definitely exists.
446 * @throws Exception\InvalidTemplateResourceException
447 */
448 protected function getPartialPathAndFilename($partialName) {
449 $paths = $this->expandGenericPathPattern($this->partialPathAndFilenamePattern, TRUE, TRUE);
450 foreach ($paths as &$partialPathAndFilename) {
451 $partialPathAndFilename = $this->resolveFileNamePath(str_replace('@partial', $partialName, $partialPathAndFilename));
452 if (is_file($partialPathAndFilename)) {
453 return $partialPathAndFilename;
454 }
455 }
456 throw new Exception\InvalidTemplateResourceException('The template files "' . implode('", "', $paths) . '" could not be loaded.', 1225709597);
457 }
458
459 /**
460 * Checks whether a template can be resolved for the current request context.
461 *
462 * @param ControllerContext $controllerContext Controller context which is available inside the view
463 * @return bool
464 * @api
465 */
466 public function canRender(ControllerContext $controllerContext) {
467 $this->setControllerContext($controllerContext);
468 try {
469 $this->getTemplateSource();
470 return TRUE;
471 } catch (Exception\InvalidTemplateResourceException $e) {
472 return FALSE;
473 }
474 }
475
476 /**
477 * Processes following placeholders inside $pattern:
478 * - "@templateRoot"
479 * - "@partialRoot"
480 * - "@layoutRoot"
481 * - "@subpackage"
482 * - "@controller"
483 * - "@format"
484 *
485 * This method is used to generate "fallback chains" for file system locations where a certain Partial can reside.
486 *
487 * If $bubbleControllerAndSubpackage is FALSE and $formatIsOptional is FALSE, then the resulting array will only have one element
488 * with all the above placeholders replaced.
489 *
490 * If you set $bubbleControllerAndSubpackage to TRUE, then you will get an array with potentially many elements:
491 * The first element of the array is like above. The second element has the @ controller part set to "" (the empty string)
492 * The third element now has the @ controller part again stripped off, and has the last subpackage part stripped off as well.
493 * This continues until both "@subpackage" and "@controller" are empty.
494 *
495 * Example for $bubbleControllerAndSubpackage is TRUE, we have the Tx_MyExtension_MySubPackage_Controller_MyController
496 * as Controller Object Name and the current format is "html"
497 *
498 * If pattern is "@templateRoot/@subpackage/@controller/@action.@format", then the resulting array is:
499 * - "Resources/Private/Templates/MySubPackage/My/@action.html"
500 * - "Resources/Private/Templates/MySubPackage/@action.html"
501 * - "Resources/Private/Templates/@action.html"
502 *
503 * If you set $formatIsOptional to TRUE, then for any of the above arrays, every element will be duplicated - once with "@format"
504 * replaced by the current request format, and once with ."@format" stripped off.
505 *
506 * @param string $pattern Pattern to be resolved
507 * @param bool $bubbleControllerAndSubpackage if TRUE, then we successively split off parts from "@controller" and "@subpackage" until both are empty.
508 * @param bool $formatIsOptional if TRUE, then half of the resulting strings will have ."@format" stripped off, and the other half will have it.
509 * @return array unix style paths
510 */
511 protected function expandGenericPathPattern($pattern, $bubbleControllerAndSubpackage, $formatIsOptional) {
512 $paths = array($pattern);
513 $this->expandPatterns($paths, '@templateRoot', $this->getTemplateRootPaths());
514 $this->expandPatterns($paths, '@partialRoot', $this->getPartialRootPaths());
515 $this->expandPatterns($paths, '@layoutRoot', $this->getLayoutRootPaths());
516
517 /** @var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
518 $actionRequest = $this->controllerContext->getRequest();
519 $subpackageKey = $actionRequest->getControllerSubpackageKey();
520 $controllerName = $actionRequest->getControllerName();
521 if ($subpackageKey !== NULL) {
522 if (strpos($subpackageKey, Fluid::NAMESPACE_SEPARATOR) !== FALSE) {
523 $namespaceSeparator = Fluid::NAMESPACE_SEPARATOR;
524 } else {
525 $namespaceSeparator = Fluid::LEGACY_NAMESPACE_SEPARATOR;
526 }
527 $subpackageKeyParts = explode($namespaceSeparator, $subpackageKey);
528 } else {
529 $subpackageKeyParts = array();
530 }
531 if ($bubbleControllerAndSubpackage) {
532 $numberOfPathsBeforeSubpackageExpansion = count($paths);
533 $numberOfSubpackageParts = count($subpackageKeyParts);
534 $subpackageReplacements = array();
535 for ($i = 0; $i <= $numberOfSubpackageParts; $i++) {
536 $subpackageReplacements[] = implode('/', ($i < 0 ? $subpackageKeyParts : array_slice($subpackageKeyParts, $i)));
537 }
538 $this->expandPatterns($paths, '@subpackage', $subpackageReplacements);
539
540 for ($i = ($numberOfPathsBeforeSubpackageExpansion - 1) * ($numberOfSubpackageParts + 1); $i >= 0; $i -= ($numberOfSubpackageParts + 1)) {
541 array_splice($paths, $i, 0, str_replace('@controller', $controllerName, $paths[$i]));
542 }
543 $this->expandPatterns($paths, '@controller', array(''));
544 } else {
545 $i = $controllerName === NULL ? 0 : -1;
546 $this->expandPatterns($paths, '@subpackage', array(implode('/', $i < 0 ? $subpackageKeyParts :
547 array_slice($subpackageKeyParts, $i))));
548 $this->expandPatterns($paths, '@controller', array($controllerName));
549 }
550
551 if ($formatIsOptional) {
552 $this->expandPatterns($paths, '.@format', array('.' . $actionRequest->getFormat(), ''));
553 $this->expandPatterns($paths, '@format', array($actionRequest->getFormat(), ''));
554 } else {
555 $this->expandPatterns($paths, '.@format', array('.' . $actionRequest->getFormat()));
556 $this->expandPatterns($paths, '@format', array($actionRequest->getFormat()));
557 }
558 return array_values(array_unique($paths));
559 }
560
561 /**
562 * Expands the given $patterns by adding an array element for each $replacement
563 * replacing occurrences of $search.
564 *
565 * @param array $patterns
566 * @param string $search
567 * @param array $replacements
568 * @return void
569 */
570 protected function expandPatterns(array &$patterns, $search, array $replacements) {
571 $patternsWithReplacements = array();
572 foreach ($patterns as $pattern) {
573 foreach ($replacements as $replacement) {
574 $patternsWithReplacements[] = GeneralUtility::fixWindowsFilePath(str_replace($search, $replacement, $pattern));
575 }
576 }
577 $patterns = $patternsWithReplacements;
578 }
579
580 /**
581 * Returns a unique identifier for the given file in the format
582 * <PackageKey>_<SubPackageKey>_<ControllerName>_<prefix>_<SHA1>
583 * The SH1 hash is a checksum that is based on the file path and last modification date
584 *
585 * @param string $pathAndFilename
586 * @param string $prefix
587 * @return string
588 */
589 protected function createIdentifierForFile($pathAndFilename, $prefix) {
590 /** @var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
591 $actionRequest = $this->controllerContext->getRequest();
592 $extensionName = $actionRequest->getControllerExtensionName();
593 $subPackageKey = $actionRequest->getControllerSubpackageKey();
594 if ($subPackageKey !== NULL) {
595 $extensionName .= '_' . $subPackageKey;
596 }
597 $controllerName = $actionRequest->getControllerName();
598 $templateModifiedTimestamp = filemtime($pathAndFilename);
599 $templateIdentifier = sprintf('%s_%s_%s_%s', $extensionName, $controllerName, $prefix, sha1($pathAndFilename . '|' . $templateModifiedTimestamp));
600 return $templateIdentifier;
601 }
602
603 /**
604 * Wrapper method to make the static call to GeneralUtility mockable in tests
605 *
606 * @param string $pathAndFilename
607 *
608 * @return string absolute pathAndFilename
609 */
610 protected function resolveFileNamePath($pathAndFilename) {
611 return GeneralUtility::getFileAbsFileName($pathAndFilename);
612 }
613 }