stylesheet = $stylesheet; // Capture the parameters' values from the stylesheet preg_match_all('#/>|>([^<]+))#', $stylesheet, $matches); foreach ($matches[1] as $k => $paramName) { $this->params[$paramName] = htmlspecialchars_decode($matches[2][$k]); } } /** * Serializer * * @return string[] List of properties to serialize */ public function __sleep() { $props = get_object_vars($this); unset($props['proc']); if (empty($props['reloadParams'])) { unset($props['reloadParams']); } return array_keys($props); } /** * Unserialize helper * * Will reload parameters if they were changed between generation and serialization * * @return void */ public function __wakeup() { if (!empty($this->reloadParams)) { $this->setParameters($this->params); $this->reloadParams = false; } } /** * {@inheritdoc} */ public function setParameter($paramName, $paramValue) { /** * @link https://bugs.php.net/64137 */ if (strpos($paramValue, '"') !== false && strpos($paramValue, "'") !== false) { $paramValue = str_replace('"', "\xEF\xBC\x82", $paramValue); } else { $paramValue = (string) $paramValue; } if (!isset($this->params[$paramName]) || $this->params[$paramName] !== $paramValue) { $this->load(); $this->proc->setParameter('', $paramName, $paramValue); $this->params[$paramName] = $paramValue; $this->reloadParams = true; } } /** * {@inheritdoc} */ protected function renderRichText($xml) { // Load the intermediate representation $dom = $this->loadXML($xml); // Load the stylesheet $this->load(); // Perform the transformation and cast it as a string because it may return NULL if the // transformation didn't output anything $this->setLocale(); $output = (string) $this->proc->transformToXml($dom); $this->restoreLocale(); // XSLTProcessor does not correctly identify as a void element. We fix it by // removing end tags $output = str_replace('', '', $output); // Remove the \n that XSL adds at the end of the output, if applicable if (substr($output, -1) === "\n") { $output = substr($output, 0, -1); } // Force HTML attributes to use double quotes to be consistent with the PHP renderer if (strpos($output, "='") !== false) { $output = $this->normalizeAttributes($output); } return $output; } /** * Create an XSLTProcessor and load the stylesheet * * @return void */ protected function load() { if (!isset($this->proc)) { $xsl = $this->loadXML($this->stylesheet); $this->proc = new XSLTProcessor; $this->proc->importStylesheet($xsl); } } /** * Normalize given attribute's value to use double quotes * * @param string[] $m * @return string */ protected function normalizeAttribute(array $m) { if ($m[0][0] === '"') { return $m[0]; } return '"' . str_replace('"', '"', substr($m[0], 1, -1)) . '"'; } /** * Normalize all attributes in given HTML to use double quotes * * @param string $html * @return string */ protected function normalizeAttributes($html) { return preg_replace_callback('(<\\S++ [^>]++>)', [$this, 'normalizeElement'], $html); } /** * Normalize attributes in given element to use double quotes * * @param string[] $m * @return string */ protected function normalizeElement(array $m) { if (strpos($m[0], "='") === false) { return $m[0]; } return preg_replace_callback('((?:"[^"]*"|\'[^\']*\'))S', [$this, 'normalizeAttribute'], $m[0]); } }