public function getHTML($options = [], $removeAttributes = [])
{
$image = $this->getAsset();
$attributes = [];
$pictureAttribs = [];
// this is used for the html5 <picture> element
// re-add support for disableWidthHeightAttributes
if (isset($options['disableWidthHeightAttributes']) && $options['disableWidthHeightAttributes']) {
// make sure the attributes are removed
$removeAttributes = array_merge($removeAttributes, ['width', 'height']);
} else {
if ($this->getWidth()) {
$attributes['width'] = 'width="' . $this->getWidth() . '"';
}
if ($this->getHeight()) {
$attributes['height'] = 'height="' . $this->getHeight() . '"';
}
}
$w3cImgAttributes = ["alt", "align", "border", "height", "hspace", "ismap", "longdesc", "usemap", "vspace", "width", "class", "dir", "id", "lang", "style", "title", "xml:lang", "onmouseover", "onabort", "onclick", "ondblclick", "onmousedown", "onmousemove", "onmouseout", "onmouseup", "onkeydown", "onkeypress", "onkeyup", "itemprop", "itemscope", "itemtype"];
$customAttributes = [];
if (array_key_exists("attributes", $options) && is_array($options["attributes"])) {
$customAttributes = $options["attributes"];
}
$altText = "";
$titleText = "";
if (isset($options["alt"])) {
$altText = $options["alt"];
}
if (isset($options["title"])) {
$titleText = $options["title"];
}
if (empty($titleText) && (!isset($options["disableAutoTitle"]) || !$options["disableAutoTitle"])) {
if ($image->getMetadata("title")) {
$titleText = $image->getMetadata("title");
}
}
if (empty($altText) && (!isset($options["disableAutoAlt"]) || !$options["disableAutoAlt"])) {
if ($image->getMetadata("alt")) {
$altText = $image->getMetadata("alt");
} else {
$altText = $titleText;
}
}
// get copyright from asset
if ($image->getMetadata("copyright") && (!isset($options["disableAutoCopyright"]) || !$options["disableAutoCopyright"])) {
if (!empty($altText)) {
$altText .= " | ";
}
if (!empty($titleText)) {
$titleText .= " | ";
}
$altText .= "© " . $image->getMetadata("copyright");
$titleText .= "© " . $image->getMetadata("copyright");
}
$options["alt"] = $altText;
if (!empty($titleText)) {
$options["title"] = $titleText;
}
$attributesRaw = array_merge($options, $customAttributes);
foreach ($attributesRaw as $key => $value) {
if (!(is_string($value) || is_numeric($value) || is_bool($value))) {
continue;
}
if (!(in_array($key, $w3cImgAttributes) || array_key_exists($key, $customAttributes) || strpos($key, "data-") === 0)) {
continue;
}
//only include attributes with characters a-z and dashes in their name.
if (preg_match("/^[a-z-]+\$/i", $key)) {
$attributes[$key] = $key . '="' . htmlspecialchars($value) . '"';
// do not include all attributes
if (!in_array($key, ["width", "height", "alt"])) {
$pictureAttribs[$key] = $key . '="' . htmlspecialchars($value) . '"';
}
// some attributes need to be added also as data- attribute, this is specific to picturePolyfill
if (in_array($key, ["alt"])) {
$pictureAttribs["data-" . $key] = "data-" . $key . '="' . htmlspecialchars($value) . '"';
}
}
}
$path = $this->getPath(true);
$attributes['src'] = 'src="' . $path . '"';
$thumbConfig = $this->getConfig();
if ($this->getConfig() && !$this->getConfig()->hasMedias()) {
// generate the srcset
$srcSetValues = [];
foreach ([1, 2] as $highRes) {
$thumbConfigRes = clone $thumbConfig;
$thumbConfigRes->setHighResolution($highRes);
$srcsetEntry = $image->getThumbnail($thumbConfigRes, true) . " " . $highRes . "x";
$srcSetValues[] = $srcsetEntry;
}
$attributes['srcset'] = 'srcset="' . implode(", ", $srcSetValues) . '"';
}
foreach ($removeAttributes as $attribute) {
unset($attributes[$attribute]);
unset($pictureAttribs[$attribute]);
}
// build html tag
$htmlImgTag = '<img ' . implode(' ', $attributes) . ' />';
// $this->getConfig() can be empty, the original image is returned
if (!$this->getConfig() || !$this->getConfig()->hasMedias()) {
return $htmlImgTag;
} else {
// output the <picture> - element
// set this variable so that Pimcore_Controller_Plugin_Thumbnail::dispatchLoopShutdown() knows that
// the picture polyfill script needs to be included
self::$pictureElementInUse = true;
// mobile first => fallback image is the smallest possible image
$fallBackImageThumb = null;
$html = '<picture ' . implode(" ", $pictureAttribs) . ' data-default-src="' . $path . '">' . "\n";
$mediaConfigs = $thumbConfig->getMedias();
// currently only max-width is supported, the key of the media is WIDTHw (eg. 400w) according to the srcset specification
ksort($mediaConfigs, SORT_NUMERIC);
array_push($mediaConfigs, $thumbConfig->getItems());
//add the default config at the end - picturePolyfill v4
foreach ($mediaConfigs as $mediaQuery => $config) {
$srcSetValues = [];
foreach ([1, 2] as $highRes) {
$thumbConfigRes = clone $thumbConfig;
$thumbConfigRes->selectMedia($mediaQuery);
$thumbConfigRes->setHighResolution($highRes);
$thumb = $image->getThumbnail($thumbConfigRes, true);
$srcSetValues[] = $thumb . " " . $highRes . "x";
if (!$fallBackImageThumb) {
$fallBackImageThumb = $thumb;
}
}
$html .= "\t" . '<source srcset="' . implode(", ", $srcSetValues) . '"';
if ($mediaQuery) {
// currently only max-width is supported, so we replace the width indicator (400w) out of the name
$maxWidth = str_replace("w", "", $mediaQuery);
$html .= ' media="(max-width: ' . $maxWidth . 'px)"';
$thumb->reset();
}
$html .= ' />' . "\n";
}
//$html .= "\t" . '<noscript>' . "\n\t\t" . $htmlImgTag . "\n\t" . '</noscript>' . "\n";
$attrCleanedForPicture = $attributes;
unset($attrCleanedForPicture["width"]);
unset($attrCleanedForPicture["height"]);
$attrCleanedForPicture["src"] = 'src="' . (string) $fallBackImageThumb . '"';
$htmlImgTagForpicture = '<img ' . implode(' ', $attrCleanedForPicture) . ' />';
$html .= $htmlImgTagForpicture . "\n";
$html .= '</picture>' . "\n";
return $html;
}
}