Classe de coupage de texte html avec conservation des balises

Description

Bonjour,

Cette classe permet de couper une chaîne de caractère à une longueur donnée. La chaîne sera coupée entre deux mots et en dehors d'une balise.
Toutes les balises qui sont restées ouverte sont refermées à la fin de la chaîne.

Les balises ne sont pas exclues du calcul du nombre de caractères.
La classe gère les balises de type <br /> (qui n'ont qu'une seul balise).

Avec la généralisation des éditeurs wysiwyg qui retournent du texte html, ce genre de script devrait être de plus en plus rependu.

Exemple :

<p>Lorem ipsum <i>dolor</i> sit amet, <b>consec tetuer adipiscing elit</b></p>.

<p>Lorem ipsum <i>dolor</i> sit amet, <b>consec</b></p>

Source / Exemple :


<?php
class HtmlString {
	
	/*
	Chaine d'origine

  • /
private $strChaineOrigine; /* Chaine coupée à la longueur donnée
  • /
private $strChaineCoupee; /* Caractère ou doit se faire la césure Par défaut, un espace
  • /
private $strCaractereCesure = ' '; /* Messages d'erreur
  • /
private $strErreur; /* Position de la césure
  • /
private $intCesurePos; /* Position du dernier espace de la chaine coupée
  • /
private $intDernierCaracCesure; /* Valeur de décrémentation de la taille de la chaine si on est dans une balise
  • /
private $intDecrementationCesurePos = 5; /* Indique si la césure est bien faite en dehors d'une balise Par défaut on considère qu'elle est effectuée au milieu d'une balise
  • /
private $blnCesureHorsBalise = 0; /* Indique si la chaine est plus courte que la longueur de césure Par défaut la chaine est plus longue
  • /
private $blnChaineTropCourte = 0; /* Pile des balises ouvertes
  • /
private $t_strBalisesOuvertes; function __construct($strChaineOrigine, $intCesurePos) { $this->strChaineOrigine = $strChaineOrigine; $this->intCesurePos = $intCesurePos; } function SetParams($strCaractereCesure, $intDecrementationCesurePos) { $this->strCaractereCesure = $strCaractereCesure; $this->intDecrementationCesurePos = $intDecrementationCesurePos; } /* Coupe la chaine d'origine au dernier espace avant la longueur voulue
  • /
private function CouperChaine(){ /* Coupe la chaine à la longuer maximale */ $this->strChaineCoupee = substr($this->strChaineOrigine, 0, $this->intCesurePos); /* Extrait la position du dernier caractère de césure de la chaine coupée */ $this->intDernierCaracCesure = strrpos($this->strChaineCoupee, $this->strCaractereCesure); /* Si le caractère de césure a été trouvé */ if($this->intDernierCaracCesure) /* Coupe la chaine au dernier espace de sa longueur maximale */ $this->strChaineCoupee = substr($this->strChaineOrigine, 0, $this->intDernierCaracCesure); } /* Vérifie que la césure n'aie pas été effectuée au milieu d'une balise
  • /
private function VerifierCesure() { /* Parcours toute la chaine depuis la fin */ for($i=strlen($this->strChaineCoupee)-1; $i>=0; $i--) { /* Si on tombe sur une fermeture de balise */ if($this->strChaineCoupee[$i] == '>' && $this->strChaineCoupee[$i-1] != '\\') { /* Alors on est pas dans une balise */ $this->blnCesureHorsBalise = 1; break; } /* Si on tombe sur une ouverture de balise, alors on est dans une balise */ elseif($this->strChaineCoupee[$i] == '<' && $this->strChaineCoupee[$i-1] != '\\') { /* On le respécifie même si la valeur est censée être à 0 */ $this->blnCesureHorsBalise = 0; break; } /* Si c'est le premier caractère de la chaine */ if($i==0) /* Alors c'est qu'il n'y avait pas de balises du tout */ $this->blnCesureHorsBalise = 1; } } /* Vérifie que la chaine soit plus longue que la position de césure
  • /
private function VerifierLongueurChaine(){ /* Si la chaine est vide */ if(strlen($this->strChaineOrigine) == 0) /* Indiquer que la chaine est trop courte */ $this->blnChaineTropCourte = 1; /* Si la chaine est plus petite que la position de césure */ elseif(strlen($this->strChaineOrigine) <= $this->intCesurePos) /* Indiquer que la chaine est trop courte */ $this->blnChaineTropCourte = 1; /* Si la chaine est plus grande */ else /* Indiquer que la chaine n'est pas trop courte */ $this->blnChaineTropCourte = 0; } /* Obtient la chaine coupée à un espace en dehors d'une balise
  • /
private function ObtenirChaineCoupeeJuste() { /* Tant que la césure n'est pas effectuée en dehors d'une balise */ while(!$this->blnCesureHorsBalise) { /* Couper la chaine */ $this->CouperChaine(); /* Réduire la longueur de la chaine coupée */ if($this->intCesurePos - $this->intDecrementationCesurePos >= 0) { $this->intCesurePos -= $this->intDecrementationCesurePos; } /* Si on a réduit la position de césure au point de couper toute la chaine, on affiche une erreur */ /* Peut arriver si la position de césure est courte et qu'il y a une très longue balise au début */ else { $this->strErreur = 'Erreur : la position de la césure est trop courte par rapport à la taille de la chaine.'; break; } $this->VerifierCesure(); } } private function TrouverBalises() { /* Place toutes les balises ouvrantes dans un tableau */ $strBalisesOuvrantes = preg_match_all('|<([a-z]+)[^>]*>|i', $this->strChaineCoupee, $t_strBalisesOuvrantes); /* Place le résultat dans le tableau de la classe */ $this->t_strBalisesOuvertes = $t_strBalisesOuvrantes[1]; /* Place toutes les balises fermantes dans un tableau */ $strBalisesFermantes = preg_match_all('|</([a-z]+)[^>]*>|i', $this->strChaineCoupee, $t_strBalisesFermantes); /* Inverse le tableau des balises ouvrantes (vu qu'elles doivent se fermer en ordre inverse) */ $this->t_strBalisesOuvertes = array_reverse($this->t_strBalisesOuvertes); /* Parcours le tableau des balises fermantes */ foreach($t_strBalisesFermantes[1] as $Index => $strBaliseFermante) { /* Parcours le tableau des balises ouvrantes */ foreach($this->t_strBalisesOuvertes as $Index => $strBaliseOuvrante) { /* Si le nom de la balise est identique */ if($strBaliseOuvrante == $strBaliseFermante) { /* Supprime la balise de la liste des balises ouvrantes */ unset($this->t_strBalisesOuvertes[$Index]); break; } } } } private function FermerBalises() { /* Pour chaque balise ouverte restante */ foreach($this->t_strBalisesOuvertes as $strBaliseOuverte) /* Ferme la balise */ $this->strChaineCoupee .= '</' . $strBaliseOuverte . '>'; } public function ExecuterCoupe() { $this->VerifierLongueurChaine(); if(!$this->blnChaineTropCourte) { $this->ObtenirChaineCoupeeJuste(); $this->TrouverBalises(); $this->FermerBalises(); $strRetour = $this->strChaineCoupee; } else { $strRetour = $this->strChaineOrigine; } if(strlen($this->strErreur) > 2) return $this->strErreur; else return $strRetour; } } ?>

Conclusion :


Il y a encore beaucoup d'améliorations à y apporter, dans la gestion des caractères échappés par exemple (\< ne doit pas être considéré comme balise si magic_quotes est activé)

C'est mon premier script en php orienté objet, donc il y a sûrement pas mal de choses a améliorer, n'hésitez surtout pas à faire des critiques.

Codes Sources

A voir également