/** * Dans le code $fullHtml, remplace la chaîne $needle par l'élément $replace. Cette fonctionnalité sert par exemple à insérer un * bouton 'lire la suite' à la place du marqueur {{LIRE_LA_SUITE}} dans un bloc de texte qu'on ne veut pas afficher entièrement. * @param string $fullHtml Le code HTML à traiter * @param string $needle Le marqueur * @param string $replace Le code de remplacement * @return string|bool Le code HTML modifié, false en cas d'erreur * @throws \Exception */ public function trimFromHTMLString($fullHtml, $needle, $replace = "") { $text = trim(html_entity_decode($fullHtml)); if (!Inflector::seemsUtf8($text)) { // @internal Conserver ce bloc car le serveur de production pose des problèmes d'encodage... require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'ForceUTF8' . DIRECTORY_SEPARATOR . 'Encoding.php'; $text = ForceUTF8\Encoding::toUTF8($text); } // On charge le texte dans un DOMDocument pour le manipuler proprement $this->dom = new DOMDocument(); $htmlHead = '<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><title>***</title></head><body>'; $htmlFoot = '</body></html>'; if (!$this->dom->loadHTML($htmlHead . $text . $htmlFoot)) { Yii::log(h::_("Erreur sur loadXML()\n{$text}", __FILE__, __LINE__, __METHOD__), CLogger::LEVEL_ERROR); return false; } // On récupère le noeud texte contenant $needle. // Si aucun noeud n'a été trouvé, on renvoie le texte complet tel qu'on l'a reçu. $zeunode = $this->findStringNode($needle, $this->dom); if (!$zeunode) { Yii::log(h::_("!!!! Pas de noeud contenant -> {$needle} <-", __FILE__, __LINE__, __METHOD__), 'debug'); Yii::log(h::_(h::xmlTreeDump($this->dom), __FILE__, __LINE__, __METHOD__), 'debug'); return $fullHtml; } // On supprime tout le texte après $needle et tous les noeuds suivant $zeunode $zeunode->data = preg_replace("/({$needle}).*/ms", "\$1", $zeunode->data); $this->removeNextNodes($zeunode); $out = $this->dom->saveHTML(); // On retire le code HTML ajouté de part et d'autre de $text // On remplace le marqueur $needle par le code HTML $replace if (($pos = strpos($out, $htmlHead)) === false) { Yii::log(h::_("Erreur sur : strpos({$htmlHead}, {$out})", __FILE__, __LINE__, __METHOD__), CLogger::LEVEL_ERROR); } else { $out = substr($out, $pos + strlen($htmlHead)); } $out = str_replace($htmlFoot, '', $out); $out = trim(preg_replace("/{$needle}/", $replace, $out)); return $out; }