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.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.