src/Twig/TextExtension.php line 21

Open in your IDE?
  1. <?php
  2. namespace App\Twig;
  3. use Twig\Extension\AbstractExtension;
  4. use Twig\TwigFilter;
  5. class TextExtension extends AbstractExtension
  6. {
  7. public function getFilters()
  8. {
  9. return array(
  10. new TwigFilter('excerpt', array($this, 'excerptFilter')),
  11. new TwigFilter('striptags', array($this, 'stripTagsFilter')),
  12. new TwigFilter('metadescription', array($this, 'metaDescriptionFilter')),
  13. new TwigFilter('base64_encode', array($this, 'base64Encode')),
  14. new TwigFilter('unpad', array($this, 'unpad')),
  15. );
  16. }
  17. public function unpad($str, $pad = '0') {
  18. while(substr($str, 0, 1) == $pad){
  19. $str = substr($str, 1);
  20. }
  21. return $str;
  22. }
  23. public function stripTagsFilter($str) {
  24. $str = strip_tags($str);
  25. $str = str_replace("\n", "", $str);
  26. return str_replace("\r", "", $str);
  27. }
  28. public function metaDescriptionFilter($str) {
  29. $str = strip_tags($str);
  30. $str = str_replace(["\n","\r"], "", $str);
  31. return $this->excerptFilter($str, 170);
  32. }
  33. public function base64Encode($str) {
  34. return base64_encode($str);
  35. }
  36. public function excerptFilter($str, $length = 250, $suffixe = "...") {
  37. if (strlen($str) <= $length) {
  38. return $str;
  39. }
  40. //$texte = strip_tags($str,'<span><a><strong><em>');
  41. $texte = strip_tags($str);
  42. // Suppression des commentaires HTML
  43. $texte = preg_replace('#<!--.*?-->#s', '', $texte);
  44. // ----------------------------------
  45. // longueur du texte brut sans html
  46. $LongueurTexteBrutSansHtml = strlen(strip_tags($texte));
  47. $MasqueHtmlSplit = '#</?([a-zA-Z1-6]+)(?: +[a-zA-Z]+="[^"]*")*( ?/)?>#';
  48. $MasqueHtmlMatch = '#<(?:/([a-zA-Z1-6]+)|([a-zA-Z1-6]+)(?: +[a-zA-Z]+="[^"]*")*( ?/)?)>#';
  49. $texte .= ' ';
  50. // ----------------------------------
  51. // Capture de tous les bouts de texte (en dehors des balises html)
  52. $BoutsTexte = preg_split($MasqueHtmlSplit, $texte, -1, PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_NO_EMPTY);
  53. // ----------------------------------
  54. $NombreBouts = count($BoutsTexte);
  55. if ($NombreBouts == 1) {
  56. $longueur = strlen($texte);
  57. // pour ne pas couper un mot, on va à l espace suivant
  58. return substr($texte, 0, strpos($texte, ' ', $longueur > $length ? $length : $longueur)) . $suffixe;
  59. }
  60. // ----------------------------------
  61. // Variable contenant la longueur des bouts de texte
  62. $longueur = 0;
  63. // ----------------------------------
  64. // (position du dernier élément du tableau $chaines)
  65. $indexDernierBout = $NombreBouts - 1;
  66. // ----------------------------------
  67. // Position par défaut de la césure au cas où la longueur du texte serait inférieure au nombre de caractères à sélectionner
  68. // La position de la césure est égale à sa position [1] + la longueur du bout de texte [0] - 1 (dernier caractère)
  69. $position = $BoutsTexte[$indexDernierBout][1] + strlen($BoutsTexte[$indexDernierBout][0]) - 1;
  70. // ----------------------------------
  71. $indexBout = $indexDernierBout;
  72. $rechercheEspace = true;
  73. // ----------------------------------
  74. // Boucle parcourant l'array et ayant pour fonction d'incrémenter au fur et à mesure la longueur des morceaux de texte,
  75. // et de calculer la position de césure de l'extrait dans le texte
  76. foreach ($BoutsTexte as $index => $bout) {
  77. $longueur += strlen($bout[0]);
  78. // Si la longueur désirée de l'extrait à obtenir est atteinte
  79. if ($longueur >= $length) {
  80. // On calcule la position de césure du texte (position de chaîne + sa longueur -1 )
  81. $position_fin_bout = $bout[1] + strlen($bout[0]) - 1;
  82. // calcul de la position de césure
  83. $position = $position_fin_bout - ($longueur - $length);
  84. // On regarde si un espace est présent après la position dans le bout de texte
  85. if (($positionEspace = strpos($bout[0], ' ', $position - $bout[1])) !== false) {
  86. // Un espace est détecté dans le bout de texte APRÈS la position
  87. $position = $bout[1] + $positionEspace;
  88. $rechercheEspace = false;
  89. }
  90. // Si on ne se trouve pas sur le dernier élément
  91. if ($index != $indexDernierBout)
  92. $indexBout = $index + 1;
  93. break;
  94. }
  95. }
  96. // ----------------------------------
  97. // Donc il n'y avait pas d'espace dans le bout de texte où la position de césure sert de référence
  98. if ($rechercheEspace === true) {
  99. // Recherche d'un espace dans les bouts de texte suivants
  100. for ($i = $indexBout; $i <= $indexDernierBout; $i++) {
  101. $position = $BoutsTexte[$i][1];
  102. if (($positionEspace = strpos($BoutsTexte[$i][0], ' ')) !== false) {
  103. $position += $positionEspace;
  104. break;
  105. }
  106. }
  107. }
  108. // **********************************
  109. // COUPE DU TEXTE pour le RÉSUMÉ
  110. // **********************************
  111. // On effectue la césure sur le texte suivant la position calculée
  112. $texte = substr($texte, 0, $position);
  113. // **********************************
  114. // RECHERCHE DES BALISES HTML
  115. // **********************************
  116. // Récupération de toutes les balises du texte et de leur position (PREG_OFFSET_CAPTURE)
  117. preg_match_all($MasqueHtmlMatch, $texte, $retour, PREG_OFFSET_CAPTURE);
  118. // ----------------------------------
  119. $BoutsTag = array();
  120. // ----------------------------------
  121. foreach ($retour[0] as $index => $tag) {
  122. // Si on se trouve sur une balise unique, on passe au tour suivant
  123. if (isset($retour[3][$index][0])) {
  124. continue;
  125. }
  126. // Si le caractère slash n'est pas détecté en seconde position dans la balise entière, on est sur une balise ouvrante
  127. if ($retour[0][$index][0][1] != '/') {
  128. // On empile l'élément en début de l'array
  129. array_unshift($BoutsTag, $retour[2][$index][0]);
  130. }
  131. // Donc balise fermante
  132. else {
  133. // suppression du premier élément de l'array
  134. array_shift($BoutsTag);
  135. }
  136. }
  137. if (!empty($BoutsTag)) {
  138. foreach ($BoutsTag as $tag) {
  139. $texte .= '</' . $tag . '>';
  140. }
  141. }
  142. // ----------------------------------
  143. // si le texte brut est plus long que $length : on ajoute [...] a la fin
  144. if ($LongueurTexteBrutSansHtml > $length) {
  145. $texte .= '...';
  146. // si on a une balise fermante (/p ou /ul ou /div) a la fin :
  147. $texte = str_replace('</p> [......]', ' ... </p>', $texte);
  148. $texte = str_replace('</ul> [......]', ' ... </ul>', $texte);
  149. $texte = str_replace('</div> [......]', ' ... </div>', $texte);
  150. }
  151. // ----------------------------------
  152. // On renvoie le résumé du texte correctement formaté.
  153. $bp = 0;
  154. for ($i = 0; $i < strlen($texte); $i++) {
  155. if (strcmp(substr($texte, $i, 3), "<p>") == 0) {
  156. $bp++;
  157. //echo "1";
  158. }
  159. if (strcmp(substr($texte, $i, 4), "</p>") == 0) {
  160. $bp--;
  161. //echo"2";
  162. }
  163. }
  164. $res = '';
  165. $balisep = '';
  166. for ($j = 0; $j < $bp; $j++) {
  167. $balisep = $balisep . "</p>";
  168. }
  169. $btable = 0;
  170. for ($i = 0; $i < strlen($texte); $i++) {
  171. if (strcmp(substr($texte, $i, 6), "<table") == 0) {
  172. $btable++;
  173. }
  174. if (strcmp(substr($texte, $i, 8), "</table>") == 0) {
  175. $btable--;
  176. }
  177. }
  178. $res = '';
  179. $balisetable = '';
  180. for ($j = 0; $j < $btable; $j++) {
  181. $balisetable = $balisetable . "</table>";
  182. }
  183. $return = $texte . $balisetable . $balisep;
  184. //printr($texte); echo '<br>--------------------';
  185. return $return;
  186. }
  187. private function checkTags($str) {
  188. if ((strpos($str, '<b') !== false) && (strpos($str, '</b>') === false))
  189. $str .= '</b>';
  190. if ((strpos($str, '<a') !== false) && (strpos($str, '</a>') === false))
  191. $str .= '</a>';
  192. if ((strpos($str, '<strong') !== false) && (strpos($str, '</strong>') === false))
  193. $str .= '</strong>';
  194. if ((strpos($str, '<em') !== false) && (strpos($str, '</em>') === false))
  195. $str .= '</em>';
  196. $str .= 'test : ' . strpos('<strong', $str);
  197. return $str;
  198. }
  199. public function getName()
  200. {
  201. return 'text_extension';
  202. }
  203. }