Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
TemplateGenerator.php
001 <?php
002
003 /**
004 * @package s9e\TextFormatter
005 * @copyright Copyright (c) 2010-2022 The s9e authors
006 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
007 */
008 namespace s9e\TextFormatter\Plugins\MediaEmbed\Configurator;
009
010 use s9e\TextFormatter\Configurator\Helpers\AVTHelper;
011
012 abstract class TemplateGenerator
013 {
014 /**
015 * @var array Attributes used to generate current template
016 */
017 protected $attributes;
018
019 /**
020 * @var array Default attributes
021 */
022 protected $defaultAttributes = [
023 'height' => 360,
024 'padding-height' => 0,
025 'style' => [],
026 'width' => 640
027 ];
028
029 /**
030 * Build the template representing the embedded content
031 *
032 * @return string
033 */
034 abstract protected function getContentTemplate();
035
036 /**
037 * Build a template based on a list of attributes
038 *
039 * @param array $attributes
040 * @return string
041 */
042 public function getTemplate(array $attributes)
043 {
044 $this->attributes = $attributes + $this->defaultAttributes;
045
046 return ($this->needsWrapper()) ? $this->getWrappedTemplate() : $this->getUnwrappedTemplate();
047 }
048
049 /**
050 * Format an attribute value to be used in an XPath expression
051 *
052 * @param string $expr Original value
053 * @return string Formatted value
054 */
055 protected function expr($expr)
056 {
057 $expr = trim($expr, '{}');
058
059 return (preg_match('(^[@$]?[-\\w]+$)D', $expr)) ? $expr : "($expr)";
060 }
061
062 /**
063 * Generate xsl:attributes elements from an array
064 *
065 * @param array $attributes Array of [name => value] where value can be XSL code
066 * @return string XSL source
067 */
068 protected function generateAttributes(array $attributes)
069 {
070 if (isset($attributes['style']) && is_array($attributes['style']))
071 {
072 $attributes['style'] = $this->generateStyle($attributes['style']);
073 }
074
075 ksort($attributes);
076 $xsl = '';
077 foreach ($attributes as $attrName => $attrValue)
078 {
079 $innerXML = (strpos($attrValue, '<xsl:') !== false) ? $attrValue : AVTHelper::toXSL($attrValue);
080
081 $xsl .= '<xsl:attribute name="' . htmlspecialchars($attrName, ENT_QUOTES, 'UTF-8') . '">' . $innerXML . '</xsl:attribute>';
082 }
083
084 return $xsl;
085 }
086
087 /**
088 * Generate a CSS declaration based on an array of CSS properties
089 *
090 * @param array $properties Property name => property value
091 * @return string
092 */
093 protected function generateStyle(array $properties)
094 {
095 ksort($properties);
096
097 $style = '';
098 foreach ($properties as $name => $value)
099 {
100 $style .= $name . ':' . $value . ';';
101 }
102
103 return trim($style, ';');
104 }
105
106 /**
107 * Generate and return the padding declaration used in the responsive wrapper
108 *
109 * @return string
110 */
111 protected function getResponsivePadding()
112 {
113 $height = $this->expr($this->attributes['height']);
114 $paddingHeight = $this->expr($this->attributes['padding-height']);
115 $width = $this->expr($this->attributes['width']);
116
117 // Create the padding declaration for the fixed ratio
118 $css = 'padding-bottom:<xsl:value-of select="100*(' . $height . '+' . $paddingHeight . ')div' . $width . '"/>%';
119
120 // Add the padding declaration for the computed ratio if applicable
121 if (!empty($this->attributes['padding-height']))
122 {
123 // NOTE: there needs to be whitespace around tokens in calc()
124 $css .= ';padding-bottom:calc(<xsl:value-of select="100*' . $height . ' div' . $width . '"/>% + ' . $paddingHeight . 'px)';
125 }
126
127 // If the width is dynamic, use a conditional to protect against divisions by zero
128 if (strpos($width, '@') !== false)
129 {
130 $css = '<xsl:if test="@width>0">' . $css . '</xsl:if>';
131 }
132
133 return $css;
134 }
135
136 /**
137 * Generate and return a responsive template for the embedded content
138 *
139 * @return string
140 */
141 protected function getUnwrappedTemplate()
142 {
143 $this->attributes['style']['width'] = '100%';
144 $this->attributes['style']['height'] = $this->attributes['height'] . 'px';
145 $this->attributes['style']['max-width'] = '100%';
146
147 if (isset($this->attributes['max-width']))
148 {
149 $this->attributes['style']['max-width'] = $this->attributes['max-width'] . 'px';
150 }
151 elseif ($this->attributes['width'] !== '100%')
152 {
153 $property = ($this->hasDynamicWidth()) ? 'width' : 'max-width';
154 $this->attributes['style'][$property] = $this->attributes['width'] . 'px';
155 }
156
157 if ($this->attributes['style']['width'] === $this->attributes['style']['max-width'])
158 {
159 unset($this->attributes['style']['max-width']);
160 }
161
162 return $this->getContentTemplate();
163 }
164
165 /**
166 * Generate and return a template for the embedded content, complete with a responsive wrapper
167 *
168 * @return string
169 */
170 protected function getWrappedTemplate()
171 {
172 $this->attributes['style']['width'] = '100%';
173 $this->attributes['style']['height'] = '100%';
174 $this->attributes['style']['position'] = 'absolute';
175 $this->attributes['style']['left'] = '0';
176
177 $outerStyle = 'display:inline-block;width:100%;max-width:' . $this->attributes['width'] . 'px';
178 $innerStyle = 'display:block;overflow:hidden;position:relative;' . $this->getResponsivePadding();
179
180 $template = '<span>' . $this->generateAttributes(['style' => $outerStyle]);
181 $template .= '<span>' . $this->generateAttributes(['style' => $innerStyle]);
182 $template .= $this->getContentTemplate();
183 $template .= '</span></span>';
184
185 return $template;
186 }
187
188 /**
189 * Test whether current template has a dynamic height
190 *
191 * @return bool
192 */
193 protected function hasDynamicHeight()
194 {
195 return (isset($this->attributes['onload']) && strpos($this->attributes['onload'], '.height') !== false);
196 }
197
198 /**
199 * Test whether current template has a dynamic width
200 *
201 * @return bool
202 */
203 protected function hasDynamicWidth()
204 {
205 return (isset($this->attributes['onload']) && strpos($this->attributes['onload'], '.width') !== false);
206 }
207
208 /**
209 * Merge two array of attributes
210 *
211 * @param array $defaultAttributes
212 * @param array $newAttributes
213 * @return array
214 */
215 protected function mergeAttributes(array $defaultAttributes, array $newAttributes)
216 {
217 $attributes = array_merge($defaultAttributes, $newAttributes);
218 if (isset($defaultAttributes['style'], $newAttributes['style']))
219 {
220 // Re-add the default attributes that were lost (but not replaced) in the merge
221 $attributes['style'] += $defaultAttributes['style'];
222 }
223
224 return $attributes;
225 }
226
227 /**
228 * Test whether current template needs a wrapper to be responsive
229 *
230 * @return bool
231 */
232 protected function needsWrapper()
233 {
234 return ($this->attributes['width'] !== '100%' && !$this->hasDynamicHeight());
235 }
236 }