/** * @test */ public function trimFromHTMLString() { $helper = new DOMHelper(); $directory = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'htmlData' . DIRECTORY_SEPARATOR; $dom = new DOMDocument(); $input = file_get_contents($directory . 'trimAfterString_input_1.html'); // Si le marqueur n'existe pas, le texte est renvoyé intact $expected = str_replace("\n", "", $input); $actual = str_replace("\n", "", $helper->trimFromHTMLString($input, "{{XXXXXX}}")); $this->assertEquals(preg_replace('/\\s+/', '', $expected), preg_replace('/\\s+/', '', $actual)); // Suppression simple $htmlHead = '<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><title>***</title></head><body>'; $htmlFoot = '</body></html>'; $actual = str_replace("\n", "", $helper->trimFromHTMLString($input, "{{LIRE_LA_SUITE}}")); $dom->loadHTML($htmlHead . file_get_contents($directory . 'trimAfterString_output_1.html') . $htmlFoot); $expected = $this->cleanTmpHTML(str_replace("\n", "", $dom->saveHTML()), $htmlHead, $htmlFoot); $this->assertEquals(preg_replace('/\\s+/', '', $expected), preg_replace('/\\s+/', '', $actual)); // Suppression avec insertion d'un bouton "Lire la suite" $actual = str_replace("\n", "", $helper->trimFromHTMLString($input, "{{LIRE_LA_SUITE}}", "<button>Lire la suite</button>")); $dom->loadHTML($htmlHead . file_get_contents($directory . 'trimAfterString_output_2.html') . $htmlFoot); $expected = $this->cleanTmpHTML(str_replace("\n", "", $dom->saveHTML()), $htmlHead, $htmlFoot); $this->assertEquals(preg_replace('/\\s+/', '', $expected), preg_replace('/\\s+/', '', $actual)); // Suppression avec insertion d'un texte et d'un bouton "Lire la suite" $actual = str_replace("\n", "", $helper->trimFromHTMLString($input, "{{LIRE_LA_SUITE}}", "Pour en savoir plus : <button>Lire la suite</button>")); $dom->loadHTML($htmlHead . file_get_contents($directory . 'trimAfterString_output_3.html') . $htmlFoot); $expected = $this->cleanTmpHTML(str_replace("\n", "", $dom->saveHTML()), $htmlHead, $htmlFoot); $this->assertEquals(preg_replace('/\\s+/', '', $expected), preg_replace('/\\s+/', '', $actual)); }
/** * Tronque un texte formatté en HTML à partir du marqueur {{LIRE_LA_SUITE}}. * Toutes les balises ouvertes sont refermées pour que le texte renvoyé soit toujours du HTML correct. * Le marqueur {{LIRE_LA_SUITE}} est remplacé par le bouton $buttonMore * @param string $fullText * @param string $buttonMore * @return string */ public static function getShortHTMLText($fullText, $buttonMore = null) { $tag = '{{LIRE_LA_SUITE}}'; if (strpos($fullText, $tag) === false) { // Si le marqueur n'est pas là, inutile de faire tous ces traitements... return $fullText; } if (is_null($buttonMore)) { $buttonMore = self::getButtonMore(); } $helper = new DOMHelper(); try { if (!($out = $helper->trimFromHTMLString($fullText, $tag, $buttonMore))) { Yii::log(h::_("Erreur sur l'appel à trimFromHTMLString()", __FILE__, __LINE__, __METHOD__), CLogger::LEVEL_ERROR); return $fullText; } } catch (Exception $x) { Yii::log(h::_($x, __FILE__, __LINE__, __METHOD__), CLogger::LEVEL_ERROR); return "<error>" . $x->getMessage() . "</error>"; } return $out; }
private function rewrite($dom, $saveto, $top = TRUE) { if (!$dom instanceof DOMElement) { throw new BotMsgException('Nieznany element DOM: ' . get_class($dom)); } foreach ($dom->childNodes as $node) { if ($node instanceof DOMElement) { switch (strtolower($node->tagName)) { case 'b': case 'i': case 'u': case 'sup': case 'sub': case 'span': $tag = DOMHelper::cloneNode($node, $saveto); $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); break; case 'strong': $tag = DOMHelper::cloneNode($node, $saveto, 'b'); $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); break; case 'script': case 'style': break; case 'p': DOMHelper::rtrim($saveto); DOMHelper::insertElement('br', $saveto); DOMHelper::insertElement('br', $saveto); $tag = DOMHelper::cloneNode($node, $saveto, 'span'); $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); DOMHelper::insertElement('br', $saveto); DOMHelper::insertElement('br', $saveto); break; case 'a': $tag = DOMHelper::cloneNode($node, $saveto, 'span'); $this->rewrite($node, $tag, FALSE); if ($node->getAttribute('href') != $node->textContent) { $tag->appendChild($tag->ownerDocument->createTextNode(' (' . $node->getAttribute('href') . ')')); } $saveto->appendChild($tag); break; case 'h1': DOMHelper::rtrim($saveto); DOMHelper::insertElement('br', $saveto); DOMHelper::insertElement('br', $saveto); $tag = DOMHelper::cloneNode($node, $saveto, 'b'); $tag2 = $tag->ownerDocument->createElement('u'); $tag->appendChild($tag2); $this->rewrite($node, $tag2, FALSE); $saveto->appendChild($tag); DOMHelper::insertElement('br', $saveto); break; case 'h2': DOMHelper::rtrim($saveto); DOMHelper::insertElement('br', $saveto); DOMHelper::insertElement('br', $saveto); $tag = DOMHelper::cloneNode($node, $saveto, 'b'); $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); DOMHelper::insertElement('br', $saveto); break; case 'h3': DOMHelper::rtrim($saveto); DOMHelper::insertElement('br', $saveto); DOMHelper::insertElement('br', $saveto); $tag = DOMHelper::cloneNode($node, $saveto, 'b'); $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); DOMHelper::insertElement('br', $saveto); break; case 'ul': DOMHelper::rtrim($saveto); DOMHelper::insertElement('br', $saveto); $tag = DOMHelper::cloneNode($node, $saveto, 'span'); $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); break; case 'ol': DOMHelper::rtrim($saveto); DOMHelper::insertElement('br', $saveto); if (!$node->hasAttribute('start') || !ctype_digit($node->getAttribute('start'))) { $node->setAttribute('start', 1); } $tag = DOMHelper::cloneNode($node, $saveto, 'span'); $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); break; case 'li': $tag = DOMHelper::cloneNode($node, $saveto, 'span'); if (strtolower($dom->tagName) == 'ul') { $tag->appendChild($tag->ownerDocument->createTextNode('- ')); } elseif (strtolower($dom->tagName) == 'ol') { $tag->appendChild($tag->ownerDocument->createTextNode($dom->getAttribute('start') . '. ')); $dom->setAttribute('start', $dom->getAttribute('start') + 1); } $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); $saveto->appendChild($saveto->ownerDocument->createElement('br')); break; case 'br': case 'img': $tag = DOMHelper::cloneNode($node, $saveto); $saveto->appendChild($tag); break; default: $tag = DOMHelper::cloneNode($node, $saveto, 'span'); $this->rewrite($node, $tag, FALSE); $saveto->appendChild($tag); break; } } elseif ($node instanceof DOMText) { $val = strtr($node->nodeValue, array("\n" => '', "\r" => '')); if ($val) { $saveto->appendChild($saveto->ownerDocument->createTextNode($val)); } } else { $saveto->appendChild($saveto->ownerDocument->importNode($node, TRUE)); } } if ($top) { DOMHelper::trim($saveto); } foreach ($saveto->childNodes as $node) { if ($node instanceof DOMElement && $node->tagName == 'span' && $node->attributes->length == 0) { while ($node->hasChildNodes()) { $node->parentNode->insertBefore($node->firstChild, $node); } $node->parentNode->removeChild($node); } } foreach ($saveto->childNodes as $node) { if ($node instanceof DOMElement && $node->hasAttribute('auto')) { $node->removeAttribute('auto'); } } }