[BUGFIX] Respect width/height settings in renderMode inline
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / ContentObject / ScalableVectorGraphicsContentObject.php
1 <?php
2 namespace TYPO3\CMS\Frontend\ContentObject;
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
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Core\Utility\PathUtility;
19
20 /**
21 * Contains RESTORE_REGISTER class object.
22 */
23 class ScalableVectorGraphicsContentObject extends AbstractContentObject
24 {
25 /**
26 * Rendering the cObject, SVG
27 *
28 * @param array $conf Array of TypoScript properties
29 * @return string
30 */
31 public function render($conf = []) : string
32 {
33 $renderMode = isset($conf['renderMode.'])
34 ? $this->cObj->stdWrap($conf['renderMode'], $conf['renderMode.'])
35 : $conf['renderMode'];
36
37 if ($renderMode === 'inline') {
38 return $this->renderInline($conf);
39 }
40
41 return $this->renderObject($conf);
42 }
43
44 /**
45 * @param array $conf
46 *
47 * @return string
48 */
49 protected function renderInline(array $conf) : string
50 {
51 $src = $this->resolveAbsoluteSourcePath($conf);
52 list($width, $height, $isDefaultWidth, $isDefaultHeight) = $this->getDimensions($conf);
53
54 $content = '';
55 if (file_exists($src)) {
56 $svgContent = file_get_contents($src);
57 $svgContent = preg_replace('/<script[\s\S]*?>[\s\S]*?<\/script>/i', '', $svgContent);
58 // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
59 $previousValueOfEntityLoader = libxml_disable_entity_loader();
60 $svgElement = simplexml_load_string($svgContent);
61 libxml_disable_entity_loader($previousValueOfEntityLoader);
62
63 $domXml = dom_import_simplexml($svgElement);
64 if (!$isDefaultWidth) {
65 $domXml->setAttribute('width', $width);
66 }
67 if (!$isDefaultHeight) {
68 $domXml->setAttribute('height', $height);
69 }
70 // remove xml version tag
71 $content = $domXml->ownerDocument->saveXML($domXml->ownerDocument->documentElement);
72 } else {
73 $value = isset($conf['value.']) ? $this->cObj->stdWrap($conf['value'], $conf['value.']) : $conf['value'];
74 if (!empty($value)) {
75 $content = [];
76 $content[] = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="' . (int)$width . '" height="' . (int)$height . '">';
77 $content[] = $value;
78 $content[] = '</svg>';
79 $content = implode(LF, $content);
80 }
81 }
82 return $content;
83 }
84
85 /**
86 * Render the SVG as <object> tag
87 * @param array $conf
88 *
89 * @return string
90 */
91 protected function renderObject(array $conf) : string
92 {
93 $src = $this->resolveAbsoluteSourcePath($conf);
94 list($width, $height) = $this->getDimensions($conf);
95
96 $src = $src === '' ? null : PathUtility::getAbsoluteWebPath($src);
97
98 $value = isset($conf['value.']) ? $this->cObj->stdWrap($conf['value'], $conf['value.']) : $conf['value'];
99 $noscript = isset($conf['noscript.']) ? $this->cObj->stdWrap($conf['noscript'], $conf['noscript.']) : $conf['noscript'];
100
101 $content = [];
102 if ($src) {
103 $content[] = '<!--[if IE]>';
104 $content[] = ' <object src="' . htmlspecialchars($src) . '" classid="image/svg+xml" width="' . (int)$width . '" height="' . (int)$height . '">';
105 $content[] = '<![endif]-->';
106 $content[] = '<!--[if !IE]>-->';
107 $content[] = ' <object data="' . htmlspecialchars($src) . '" type="image/svg+xml" width="' . (int)$width . '" height="' . (int)$height . '">';
108 $content[] = '<!--<![endif]-->';
109 $content[] = $noscript;
110 $content[] = '</object>';
111 } else {
112 $content[] = '<script type="image/svg+xml">';
113 $content[] = ' <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="' . (int)$width . '" height="' . (int)$height . '">';
114 $content[] = $value;
115 $content[] = ' </svg>';
116 $content[] = '</script>';
117 $content[] = '<noscript>';
118 $content[] = $noscript;
119 $content[] = '</noscript>';
120 }
121 $content = implode(LF, $content);
122 if (isset($conf['stdWrap.'])) {
123 $content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
124 }
125 return $content;
126 }
127
128 /**
129 * @param array $conf
130 *
131 * @return string
132 */
133 protected function resolveAbsoluteSourcePath(array $conf) : string
134 {
135 $src = isset($conf['src.']) ? $this->cObj->stdWrap($conf['src'], $conf['src.']) : $conf['src'];
136 return GeneralUtility::getFileAbsFileName($src);
137 }
138
139 /**
140 * @param array $conf
141 *
142 * @return array
143 */
144 protected function getDimensions(array $conf) : array
145 {
146 $isDefaultWidth = false;
147 $isDefaultHeight = false;
148 $width = isset($conf['width.']) ? $this->cObj->stdWrap($conf['width'], $conf['width.']) : $conf['width'];
149 $height = isset($conf['height.']) ? $this->cObj->stdWrap($conf['height'], $conf['height.']) : $conf['height'];
150
151 if (empty($width)) {
152 $isDefaultWidth = true;
153 $width = 600;
154 }
155 if (empty($height)) {
156 $isDefaultHeight = true;
157 $height = 400;
158 }
159
160 return [$width, $height, $isDefaultWidth, $isDefaultHeight];
161 }
162 }