8889841cemogrifier/src/Emogrifier/error_log000064400000003154150513746240013502 0ustar00[28-Jun-2025 01:46:02 UTC] PHP Fatal error: Uncaught Error: Class "Pelago\Emogrifier\HtmlProcessor\AbstractHtmlProcessor" not found in /home/clixcotz/public_html/wp-content/plugins/woocommerce/vendor/pelago/emogrifier/src/Emogrifier/CssInliner.php:24 Stack trace: #0 {main} thrown in /home/clixcotz/public_html/wp-content/plugins/woocommerce/vendor/pelago/emogrifier/src/Emogrifier/CssInliner.php on line 24 [07-Aug-2025 04:08:31 UTC] PHP Fatal error: Uncaught Error: Class "Pelago\Emogrifier\HtmlProcessor\AbstractHtmlProcessor" not found in /home/clixcotz/public_html/wp-content/plugins/woocommerce/vendor/pelago/emogrifier/src/Emogrifier/CssInliner.php:24 Stack trace: #0 {main} thrown in /home/clixcotz/public_html/wp-content/plugins/woocommerce/vendor/pelago/emogrifier/src/Emogrifier/CssInliner.php on line 24 [10-Aug-2025 18:01:58 UTC] PHP Fatal error: Uncaught Error: Class "Pelago\Emogrifier\HtmlProcessor\AbstractHtmlProcessor" not found in /home/clixcotz/public_html/wp-content/plugins/woocommerce/vendor/pelago/emogrifier/src/Emogrifier/CssInliner.php:24 Stack trace: #0 {main} thrown in /home/clixcotz/public_html/wp-content/plugins/woocommerce/vendor/pelago/emogrifier/src/Emogrifier/CssInliner.php on line 24 [10-Aug-2025 18:23:06 UTC] PHP Fatal error: Uncaught Error: Class "Pelago\Emogrifier\HtmlProcessor\AbstractHtmlProcessor" not found in /home/clixcotz/public_html/wp-content/plugins/woocommerce/vendor/pelago/emogrifier/src/Emogrifier/CssInliner.php:24 Stack trace: #0 {main} thrown in /home/clixcotz/public_html/wp-content/plugins/woocommerce/vendor/pelago/emogrifier/src/Emogrifier/CssInliner.php on line 24 emogrifier/src/Emogrifier/Utilities/ArrayIntersector.php000064400000003503150513746240017547 0ustar00 */ class ArrayIntersector { /** * the array with which the object was constructed, with all its keys exchanged with their associated values * * @var (int|string)[] */ private $invertedArray; /** * Constructs the object with the array that will be reused for many intersection computations. * * @param (int|string)[] $array */ public function __construct(array $array) { $this->invertedArray = \array_flip($array); } /** * Computes the intersection of `$array` and the array with which this object was constructed. * * @param (int|string)[] $array * * @return (int|string)[] Returns an array containing all of the values in `$array` whose values exist in the array * with which this object was constructed. Note that keys are preserved, order is maintained, but * duplicates are removed. */ public function intersectWith(array $array) { $invertedArray = \array_flip($array); $invertedIntersection = \array_intersect_key($invertedArray, $this->invertedArray); return \array_flip($invertedIntersection); } } emogrifier/src/Emogrifier/Utilities/CssConcatenator.php000064400000013552150513746240017345 0ustar00append(['body'], 'color: blue;'); * $concatenator->append(['body'], 'font-size: 16px;'); * $concatenator->append(['p'], 'margin: 1em 0;'); * $concatenator->append(['ul', 'ol'], 'margin: 1em 0;'); * $concatenator->append(['body'], 'font-size: 14px;', '@media screen and (max-width: 400px)'); * $concatenator->append(['ul', 'ol'], 'margin: 0.75em 0;', '@media screen and (max-width: 400px)'); * $css = $concatenator->getCss(); * * `$css` (if unminified) would contain the following CSS: * ` body { * ` color: blue; * ` font-size: 16px; * ` } * ` p, ul, ol { * ` margin: 1em 0; * ` } * ` @media screen and (max-width: 400px) { * ` body { * ` font-size: 14px; * ` } * ` ul, ol { * ` margin: 0.75em 0; * ` } * ` } * * @internal * * @author Jake Hotson */ class CssConcatenator { /** * Array of media rules in order. Each element is an object with the following properties: * - string `media` - The media query string, e.g. "@media screen and (max-width:639px)", or an empty string for * rules not within a media query block; * - \stdClass[] `ruleBlocks` - Array of rule blocks in order, where each element is an object with the following * properties: * - mixed[] `selectorsAsKeys` - Array whose keys are selectors for the rule block (values are of no * significance); * - string `declarationsBlock` - The property declarations, e.g. "margin-top: 0.5em; padding: 0". * * @var \stdClass[] */ private $mediaRules = []; /** * Appends a declaration block to the CSS. * * @param string[] $selectors Array of selectors for the rule, e.g. ["ul", "ol", "p:first-child"]. * @param string $declarationsBlock The property declarations, e.g. "margin-top: 0.5em; padding: 0". * @param string $media The media query for the rule, e.g. "@media screen and (max-width:639px)", * or an empty string if none. */ public function append(array $selectors, $declarationsBlock, $media = '') { $selectorsAsKeys = \array_flip($selectors); $mediaRule = $this->getOrCreateMediaRuleToAppendTo($media); $lastRuleBlock = \end($mediaRule->ruleBlocks); $hasSameDeclarationsAsLastRule = $lastRuleBlock !== false && $declarationsBlock === $lastRuleBlock->declarationsBlock; if ($hasSameDeclarationsAsLastRule) { $lastRuleBlock->selectorsAsKeys += $selectorsAsKeys; } else { $hasSameSelectorsAsLastRule = $lastRuleBlock !== false && self::hasEquivalentSelectors($selectorsAsKeys, $lastRuleBlock->selectorsAsKeys); if ($hasSameSelectorsAsLastRule) { $lastDeclarationsBlockWithoutSemicolon = \rtrim(\rtrim($lastRuleBlock->declarationsBlock), ';'); $lastRuleBlock->declarationsBlock = $lastDeclarationsBlockWithoutSemicolon . ';' . $declarationsBlock; } else { $mediaRule->ruleBlocks[] = (object)\compact('selectorsAsKeys', 'declarationsBlock'); } } } /** * @return string */ public function getCss() { return \implode('', \array_map([self::class, 'getMediaRuleCss'], $this->mediaRules)); } /** * @param string $media The media query for rules to be appended, e.g. "@media screen and (max-width:639px)", * or an empty string if none. * * @return \stdClass Object with properties as described for elements of `$mediaRules`. */ private function getOrCreateMediaRuleToAppendTo($media) { $lastMediaRule = \end($this->mediaRules); if ($lastMediaRule !== false && $media === $lastMediaRule->media) { return $lastMediaRule; } $newMediaRule = (object)[ 'media' => $media, 'ruleBlocks' => [], ]; $this->mediaRules[] = $newMediaRule; return $newMediaRule; } /** * Tests if two sets of selectors are equivalent (i.e. the same selectors, possibly in a different order). * * @param mixed[] $selectorsAsKeys1 Array in which the selectors are the keys, and the values are of no * significance. * @param mixed[] $selectorsAsKeys2 Another such array. * * @return bool */ private static function hasEquivalentSelectors(array $selectorsAsKeys1, array $selectorsAsKeys2) { return \count($selectorsAsKeys1) === \count($selectorsAsKeys2) && \count($selectorsAsKeys1) === \count($selectorsAsKeys1 + $selectorsAsKeys2); } /** * @param \stdClass $mediaRule Object with properties as described for elements of `$mediaRules`. * * @return string CSS for the media rule. */ private static function getMediaRuleCss(\stdClass $mediaRule) { $css = \implode('', \array_map([self::class, 'getRuleBlockCss'], $mediaRule->ruleBlocks)); if ($mediaRule->media !== '') { $css = $mediaRule->media . '{' . $css . '}'; } return $css; } /** * @param \stdClass $ruleBlock Object with properties as described for elements of the `ruleBlocks` property of * elements of `$mediaRules`. * * @return string CSS for the rule block. */ private static function getRuleBlockCss(\stdClass $ruleBlock) { $selectors = \array_keys($ruleBlock->selectorsAsKeys); return \implode(',', $selectors) . '{' . $ruleBlock->declarationsBlock . '}'; } } emogrifier/src/Emogrifier/CssInliner.php000064400000113521150513746240014347 0ustar00 * @author Roman Ožana * @author Sander Kruger * @author Zoli Szabó */ class CssInliner extends AbstractHtmlProcessor { /** * @var int */ const CACHE_KEY_CSS = 0; /** * @var int */ const CACHE_KEY_SELECTOR = 1; /** * @var int */ const CACHE_KEY_CSS_DECLARATIONS_BLOCK = 2; /** * @var int */ const CACHE_KEY_COMBINED_STYLES = 3; /** * Regular expression component matching a static pseudo class in a selector, without the preceding ":", * for which the applicable elements can be determined (by converting the selector to an XPath expression). * (Contains alternation without a group and is intended to be placed within a capturing, non-capturing or lookahead * group, as appropriate for the usage context.) * * @var string */ const PSEUDO_CLASS_MATCHER = 'empty|(?:first|last|nth(?:-last)?+|only)-child|(?:first|last|nth(?:-last)?+)-of-type|not\\([[:ascii:]]*\\)'; /** * @var bool[] */ private $excludedSelectors = []; /** * @var bool[] */ private $allowedMediaTypes = ['all' => true, 'screen' => true, 'print' => true]; /** * @var mixed[] */ private $caches = [ self::CACHE_KEY_CSS => [], self::CACHE_KEY_SELECTOR => [], self::CACHE_KEY_CSS_DECLARATIONS_BLOCK => [], self::CACHE_KEY_COMBINED_STYLES => [], ]; /** * @var CssSelectorConverter */ private $cssSelectorConverter = null; /** * the visited nodes with the XPath paths as array keys * * @var \DOMElement[] */ private $visitedNodes = []; /** * the styles to apply to the nodes with the XPath paths as array keys for the outer array * and the attribute names/values as key/value pairs for the inner array * * @var string[][] */ private $styleAttributesForNodes = []; /** * Determines whether the "style" attributes of tags in the the HTML passed to this class should be preserved. * If set to false, the value of the style attributes will be discarded. * * @var bool */ private $isInlineStyleAttributesParsingEnabled = true; /** * Determines whether the