raw = $raw_html; $this->loadImageDom(); } public function loadImageDom() { if (function_exists("mb_convert_encoding")) { $this->raw = mb_encode_numericentity($this->raw, [0x80, 0x10FFFF, 0, ~0], 'UTF-8'); } $dom = new \DOMDocument(); libxml_use_internal_errors(true); // disable error emit from libxml $result = $dom->loadHTML($this->raw, LIBXML_NOWARNING); // HTML failed loading if (false === $result) { return false; } $image = $dom->getElementsByTagName('img')->item(0); $attributes = array(); /* This can happen with mismatches, or extremely malformed HTML. In customer case, a javascript that did for (i */ if (! is_object($image)) { $this->is_parsable = false; return false; } foreach ($image->attributes as $attr) { // Skip is no value if (strlen($attr->nodeValue) == 0) continue; if (property_exists($this, $attr->nodeName)) { $this->{$attr->nodeName} = $attr->nodeValue; } $this->attributes[$attr->nodeName] = $attr->nodeValue; } // Parse the directory path and other sources $result = $this->setupSources(); if (true === $result) $this->image_loaded = true; } public function hasBackground() { if (! is_null($this->style) && strpos($this->style, 'background') !== false) { return true; } return false; } public function hasPreventClasses() { // no class, no prevent. if (is_null($this->class)) { return false; } $preventArray = apply_filters('shortpixel/front/preventclasses', array('sp-no-webp', 'rev-sildebg') ); foreach($preventArray as $classname) { if (false !== strpos($this->class, $classname) ) { return true; } } return false; } public function hasSource() { if (is_null($this->src) && is_null($this->srcset)) { return false; } return true; } public function isParseable() { if ( false === $this->hasPreventClasses() && false === $this->hasBackground() && true === $this->hasSource() && true === $this->image_loaded ) { return true; } return false; } public function getImageData() { if (! is_null($this->srcset)) { $data = $this->getLazyData('srcset'); $data = explode(',', $data); // srcset is multiple images, split. } else { $data = $this->getLazyData('src'); $data = array($data); // single item, wrap in array } $this->getLazyData('sizes'); // sets the sizes. return $data; } public function getImageBase() { if (! is_null($this->imageBase)) return $this->imageBase->getPath(); return null; } public function parseReplacement($args) { if (is_null($this->class)) { $this->class = ''; } $this->class .= ' sp-no-webp'; $output = ""; if (isset($args['avif']) && count($args['avif']) > 0) { $output .= $this->buildSource($args['avif'], 'avif'); } if (isset($args['webp']) && count($args['webp']) > 0) { $output .= $this->buildSource($args['webp'], 'webp'); } $output .= $this->buildImage(); $output .= ""; return $output; } protected function setupSources() { $src = null; if (! is_null($this->src)) { $src = $this->src; } elseif (! is_null($this->srcset)) { $parts = preg_split('/\s+/', trim($this->srcset)); $image_url = $parts[0]; $src = $image_url; } if (is_null($src)) { return false; } // Filter out extension that are not for us. if (false === $this->checkExtensionConvertable($src)) { return false; } $fs = \wpSPIO()->filesystem(); $fileObj = $fs->getFile($src); $fileDir = $fileObj->getFileDir(); $this->imageBase = $fileObj->getFileDir(); return true; // If (! is_hnull $srcset) // Get first item from srcset ( remove the size ? , then feed it to FS, get directory from it. } /*** Check if the extension is something we want to check * @param String The URL source of the image. **/ private function checkExtensionConvertable($source) { $extension = substr($source, strrpos($source, '.') + 1); if (in_array($extension, ImageModel::PROCESSABLE_EXTENSIONS)) { return true; } return false; } protected function buildSource($sources, $fileFormat) { $prefix = (isset($this->dataTags['srcset'])) ? $this->dataTags['srcset'] : $this->dataTags['src']; $srcset = implode(',', $sources); $sizeOutput = ''; if (! is_null($this->sizes)) { $sizeOutput = $this->dataTags['sizes'] . 'sizes="' . $this->sizes . '"'; } $output = ''; return $output; } protected function buildImage() { $src = $this->src; $output = '{$attr})) { $output .= $attr . '="' . $this->{$attr} . '" '; } } // Always output alt tag, because it's important to screen readers and otherwise. $output .= 'alt="' . $this->alt . '" '; // Left over attributes that should be harmless, ie extra image data or other custom tags. $leftAttrs = $this->getImageAttributes(); foreach($leftAttrs as $name => $value) { $output .= $name . '="' . $value . '" '; } $output .= ' > '; // ending image. return $output; } protected function getImageAttributes() { $dontuse = array( 'src', 'data-src', 'data-lazy-src', 'srcset', 'sizes' ); $dontuse = array_merge($dontuse, array('id', 'alt', 'height', 'width', 'srcset', 'sizes', 'class')); $attributes = $this->attributes; $leftAttrs = array(); foreach($attributes as $name => $value) { if (! in_array($name, $dontuse )) { $leftAttrs[$name] = $value; } } return $leftAttrs; } protected function getLazyData($type) { $attributes = $this->attributes; $value = $prefix = false; if (isset($attributes['data-lazy-' . $type]) && strlen($attributes['data-lazy-' . $type]) > 0) { $value = $attributes['data-lazy-' . $type]; $prefix = 'data-lazy-'; } elseif( isset($attributes['data-' . $type]) && strlen($attributes['data-' . $type]) > 0) { $value = $attributes['data-' . $type]; $prefix = 'data-'; } elseif(isset($attributes[$type]) && strlen($attributes[$type]) > 0) { $value = $attributes[$type]; $prefix = ''; } $this->dataTags[$type] = $prefix; return $value; } } // class FrontImage