/** * Vérifier une taille minimale/maximale, pour un mot de passe par exemple * * @param string $valeur * La valeur à vérifier. * @param array $options * Les éléments à vérifier (min, max, egal). * @return string * Retourne une chaine vide si c'est valide, sinon une chaine expliquant l'erreur. */ function verifier_taille_dist($valeur, $options=array()){ $ok = true; if (!is_string($valeur)) return _T('erreur_inconnue_generique'); include_spip('inc/charsets'); $erreur = ''; $taille = spip_strlen($valeur); if (isset($options['min'])) $ok = ($ok and ($taille >= $options['min'])); if (isset($options['max'])){ $ok = ($ok and ($taille <= $options['max'])); } if (isset($options['egal'])){ $ok = ($ok and ($taille == $options['egal'])); } if (!$ok){ // On ajoute la taille actuelle aux valeurs de remplacement $options['nb'] = $taille; if (isset($options['min']) and isset($options['max'])) $erreur = _T('verifier:erreur_taille_entre', $options); elseif (isset($options['max'])) $erreur = _T('verifier:erreur_taille_max', $options); elseif (isset($options['egal'])) $erreur = _T('verifier:erreur_taille_egal', $options); else $erreur = _T('verifier:erreur_taille_min', $options); } return $erreur; }
function expression_recherche($recherche, $options) { // ne calculer qu'une seule fois l'expression par hit // (meme si utilisee dans plusieurs boucles) static $expression = array(); $key = serialize(array($recherche, $options['preg_flags'])); if (isset($expression[$key])) { return $expression[$key]; } $u = $GLOBALS['meta']['pcre_u']; if ($u and strpos($options['preg_flags'], $u) === false) { $options['preg_flags'] .= $u; } include_spip('inc/charsets'); $recherche = trim($recherche); $is_preg = false; if (substr($recherche, 0, 1) == '/' and substr($recherche, -1, 1) == '/') { // c'est une preg $recherche_trans = translitteration($recherche); $preg = $recherche_trans . $options['preg_flags']; $is_preg = true; } else { // s'il y a plusieurs mots il faut les chercher tous : oblige REGEXP, // sauf ceux de moins de 4 lettres (on supprime ainsi 'le', 'les', 'un', // 'une', 'des' ...) // attention : plusieurs mots entre guillemets sont a rechercher tels quels $recherche_trans = $recherche_mod = $recherche; // les expressions entre " " sont un mot a chercher tel quel // -> on remplace les espaces par un \x1 et on enleve les guillemets if (preg_match(',["][^"]+["],Uims', $recherche_mod, $matches)) { foreach ($matches as $match) { $word = preg_replace(",\\s+,Uims", "", $match); $word = trim($word, '"'); $recherche_mod = str_replace($match, $word, $recherche_mod); } } if (preg_match(",\\s+," . $u, $recherche_mod)) { $is_preg = true; $recherche_inter = '|'; $recherche_mots = explode(' ', $recherche_mod); $min_long = defined('_RECHERCHE_MIN_CAR') ? _RECHERCHE_MIN_CAR : 4; foreach ($recherche_mots as $mot) { if (strlen($mot) >= $min_long) { // echapper les caracteres de regexp qui sont eventuellement dans la recherche $recherche_inter .= preg_quote($mot) . ' '; } } $recherche_inter = str_replace("", '\\s', $recherche_inter); // mais on cherche quand même l'expression complète, même si elle // comporte des mots de moins de quatre lettres $recherche = rtrim(preg_quote($recherche) . preg_replace(',\\s+,' . $u, '|', $recherche_inter), '|'); $recherche_trans = translitteration($recherche); } $preg = '/' . str_replace('/', '\\/', $recherche_trans) . '/' . $options['preg_flags']; } // Si la chaine est inactive, on va utiliser LIKE pour aller plus vite // ou si l'expression reguliere est invalide if (!$is_preg or @preg_match($preg, '') === FALSE) { $methode = 'LIKE'; $u = $GLOBALS['meta']['pcre_u']; // echapper les % et _ $q = str_replace(array('%', '_'), array('\\%', '\\_'), trim($recherche)); // eviter les parentheses et autres caractères qui interferent avec pcre par la suite (dans le preg_match_all) s'il y a des reponses $recherche = preg_quote($recherche); $recherche_trans = translitteration($recherche); $recherche_mod = $recherche_trans; // les expressions entre " " sont un mot a chercher tel quel // -> on remplace les espaces par un _ et on enleve les guillemets // corriger le like dans le $q if (preg_match(',["][^"]+["],Uims', $q, $matches)) { foreach ($matches as $match) { $word = preg_replace(",\\s+,Uims", "_", $match); $word = trim($word, '"'); $q = str_replace($match, $word, $q); } } // corriger la regexp if (preg_match(',["][^"]+["],Uims', $recherche_mod, $matches)) { foreach ($matches as $match) { $word = preg_replace(",\\s+,Uims", "[\\s]", $match); $word = trim($word, '"'); $recherche_mod = str_replace($match, $word, $recherche_mod); } } $q = sql_quote("%" . preg_replace(",\\s+," . $u, "%", $q) . "%"); $preg = '/' . preg_replace(",\\s+," . $u, ".+", trim($recherche_mod)) . '/' . $options['preg_flags']; } else { $methode = 'REGEXP'; $q = sql_quote(trim($recherche, '/')); } // tous les caracteres transliterables de $q sont remplaces par un joker // permet de matcher en SQL meme si on est sensible aux accents (SQLite) $q_t = $q; for ($i = 0; $i < spip_strlen($q); $i++) { $char = spip_substr($q, $i, 1); if (!is_ascii($char) and $char_t = translitteration($char) and $char_t !== $char) { $q_t = str_replace($char, $is_preg ? "." : "_", $q_t); } } $q = $q_t; // fix : SQLite 3 est sensible aux accents, on jokerise les caracteres // les plus frequents qui peuvent etre accentues // (oui c'est tres dicustable...) if (isset($GLOBALS['connexions'][$options['serveur'] ? $options['serveur'] : 0]['type']) and strncmp($GLOBALS['connexions'][$options['serveur'] ? $options['serveur'] : 0]['type'], 'sqlite', 6) == 0) { $q_t = strtr($q, "aeuioc", $is_preg ? "......" : "______"); // si il reste au moins un char significatif... if (preg_match(",[^'%_.],", $q_t)) { $q = $q_t; } } return $expression[$key] = array($methode, $q, $preg); }
function printWordWrapped($image, $top, $left, $maxWidth, $font, $couleur, $text, $textSize, $align = "left", $hauteur_ligne = 0) { static $memps = array(); $fontps = false; // imageftbbox exige un float, et settype aime le double pour php < 4.2.0 settype($textSize, 'double'); // calculer les couleurs ici, car fonctionnement different selon TTF ou PS $black = imagecolorallocatealpha($image, hexdec("0x{" . substr($couleur, 0, 2) . "}"), hexdec("0x{" . substr($couleur, 2, 2) . "}"), hexdec("0x{" . substr($couleur, 4, 2) . "}"), 0); $grey2 = imagecolorallocatealpha($image, hexdec("0x{" . substr($couleur, 0, 2) . "}"), hexdec("0x{" . substr($couleur, 2, 2) . "}"), hexdec("0x{" . substr($couleur, 4, 2) . "}"), 127); // Gaffe, T1Lib ne fonctionne carrement pas bien des qu'on sort de ASCII // C'est dommage, parce que la rasterisation des caracteres est autrement plus jolie qu'avec TTF. // A garder sous le coude en attendant que ca ne soit plus une grosse bouse. // Si police Postscript et que fonction existe... if (false and strtolower(substr($font, -4)) == ".pfb" and function_exists("imagepstext")) { // Traitement specifique pour polices PostScript (experimental) $textSizePs = round(1.32 * $textSize); if (!($fontps = $memps["{$font}"])) { $fontps = imagepsloadfont($font); // Est-ce qu'il faut reencoder? Pas testable proprement, alors... // imagepsencodefont($fontps,find_in_path('polices/standard.enc')); $memps["{$font}"] = $fontps; } } $rtl_global = false; for ($i = 0; $i < spip_strlen($text); $i++) { $lettre = spip_substr($text, $i, 1); $code = rtl_mb_ord($lettre); if ($code >= 54928 && $code <= 56767 || $code >= 15707294 && $code <= 15711164) { $rtl_global = true; } } // split the text into an array of single words $words = explode(' ', $text); // les espaces foreach ($words as $k => $v) { $words[$k] = str_replace(array('~'), array(' '), $v); } if ($hauteur_ligne == 0) { $lineHeight = floor($textSize * 1.3); } else { $lineHeight = $hauteur_ligne; } $dimensions_espace = imageftbbox($textSize, 0, $font, ' ', array()); if ($dimensions_espace[2] < 0) { $dimensions_espace = imageftbbox($textSize, 0, $font, $line, array()); } $largeur_espace = $dimensions_espace[2] - $dimensions_espace[0]; $retour["espace"] = $largeur_espace; $line = ''; $lines = array(); while (count($words) > 0) { $mot = $words[0]; if ($rtl_global) { $mot = rtl_visuel($mot, $rtl_global); } $dimensions = imageftbbox($textSize, 0, $font, $line . ' ' . $mot, array()); $lineWidth = $dimensions[2] - $dimensions[0]; // get the length of this line, if the word is to be included if ($lineWidth > $maxWidth) { // if this makes the text wider that anticipated $lines[] = $line; // add the line to the others $line = ''; // empty it (the word will be added outside the loop) } $line .= ' ' . $words[0]; // add the word to the current sentence $words = array_slice($words, 1); // remove the word from the array } if ($line != '') { $lines[] = $line; } // add the last line to the others, if it isn't empty $height = count($lines) * $lineHeight; // the height of all the lines total // do the actual printing $i = 0; // Deux passes pour recuperer, d'abord, largeur_ligne // necessaire pour alignement right et center $largeur_max = 0; foreach ($lines as $line) { if ($rtl_global) { $line = rtl_visuel($line, $rtl_global); } $dimensions = imageftbbox($textSize, 0, $font, $line, array()); $largeur_ligne = $dimensions[2] - $dimensions[0]; if ($largeur_ligne > $largeur_max) { $largeur_max = $largeur_ligne; } } foreach ($lines as $i => $line) { if ($rtl_global) { $line = rtl_visuel($line, $rtl_global); } $dimensions = imageftbbox($textSize, 0, $font, $line, array()); $largeur_ligne = $dimensions[2] - $dimensions[0]; if ($align == "right") { $left_pos = $largeur_max - $largeur_ligne; } else { if ($align == "center") { $left_pos = floor(($largeur_max - $largeur_ligne) / 2); } else { $left_pos = 0; } } if ($fontps) { $line = trim($line); imagepstext($image, "{$line}", $fontps, $textSizePs, $black, $grey2, $left + $left_pos, $top + $lineHeight * $i, 0, 0, 0, 16); } else { imagefttext($image, $textSize, 0, $left + $left_pos, $top + $lineHeight * $i, $black, $font, trim($line), array()); } } $retour["height"] = $height; # + round(0.3 * $hauteur_ligne); $retour["width"] = $largeur_max; return $retour; }
function couper($texte, $taille = 50, $suite = ' (...)') { if (!($length = strlen($texte)) or $taille <= 0) { return ''; } $offset = 400 + 2 * $taille; while ($offset < $length and strlen(preg_replace(",<[^>]+>,Uims", "", substr($texte, 0, $offset))) < $taille) { $offset = 2 * $offset; } if ($offset < $length && ($p_tag_ouvrant = strpos($texte, '<', $offset)) !== NULL) { $p_tag_fermant = strpos($texte, '>', $offset); if ($p_tag_fermant && $p_tag_fermant < $p_tag_ouvrant) { $offset = $p_tag_fermant + 1; } // prolonger la coupe jusqu'au tag fermant suivant eventuel } $texte = substr($texte, 0, $offset); /* eviter de travailler sur 10ko pour extraire 150 caracteres */ // on utilise les \r pour passer entre les gouttes $texte = str_replace("\r\n", "\n", $texte); $texte = str_replace("\r", "\n", $texte); // sauts de ligne et paragraphes $texte = preg_replace("/\n\n+/", "\r", $texte); $texte = preg_replace("/<(p|br)( [^>]*)?" . ">/", "\r", $texte); // supprimer les traits, lignes etc $texte = preg_replace("/(^|\r|\n)(-[-#\\*]*|_ )/", "\r", $texte); // supprimer les tags $texte = supprimer_tags($texte); $texte = trim(str_replace("\n", " ", $texte)); $texte .= "\n"; // marquer la fin // travailler en accents charset $texte = unicode2charset(html2unicode($texte, true)); if (!function_exists('nettoyer_raccourcis_typo')) { include_spip('inc/lien'); } $texte = nettoyer_raccourcis_typo($texte); // corriger la longueur de coupe // en fonction de la presence de caracteres utf if ($GLOBALS['meta']['charset'] == 'utf-8') { $long = charset2unicode($texte); $long = spip_substr($long, 0, max($taille, 1)); $nbcharutf = preg_match_all('/(&#[0-9]{3,5};)/S', $long, $matches); $taille += $nbcharutf; } // couper au mot precedent $long = spip_substr($texte, 0, max($taille - 4, 1)); $u = $GLOBALS['meta']['pcre_u']; $court = preg_replace("/([^\\s][\\s]+)[^\\s]*\n?\$/" . $u, "\\1", $long); $points = $suite; // trop court ? ne pas faire de (...) if (spip_strlen($court) < max(0.75 * $taille, 2)) { $points = ''; $long = spip_substr($texte, 0, $taille); $texte = preg_replace("/([^\\s][\\s]+)[^\\s]*\n?\$/" . $u, "\\1", $long); // encore trop court ? couper au caractere if (spip_strlen($texte) < 0.75 * $taille) { $texte = $long; } } else { $texte = $court; } if (strpos($texte, "\n")) { // la fin est encore la : c'est qu'on n'a pas de texte de suite $points = ''; } // remettre les paragraphes $texte = preg_replace("/\r+/", "\n\n", $texte); // supprimer l'eventuelle entite finale mal coupee $texte = preg_replace('/&#?[a-z0-9]*$/S', '', $texte); return quote_amp(trim($texte)) . $points; }
function spip_substr_manuelle($c, $start, $length = NULL) { // Cas pathologique if ($length === 0) return ''; // S'il y a un demarrage, on se positionne if ($start > 0) $c = substr($c, strlen(spip_substr_manuelle($c, 0, $start))); elseif ($start < 0) return spip_substr_manuelle($c, spip_strlen($c)+$start, $length); if (!$length) return $c; if ($length > 0) { // on prend n fois la longueur desiree, pour etre surs d'avoir tout // (un caractere utf-8 prenant au maximum n bytes) $n = 0; while (preg_match(',[\x80-\xBF]{'.(++$n).'},', $c)); $c = substr($c, 0, $n*$length); // puis, tant qu'on est trop long, on coupe... while (($l = spip_strlen($c)) > $length) $c = substr($c, 0, $length - $l); return $c; } // $length < 0 return spip_substr_manuelle($c, 0, spip_strlen($c)+$length); }
/** * Compte le nombre de caracteres d'une chaine, * mais en supprimant tous les liens * (qu'ils soient ou non ecrits en raccourcis SPIP) * ainsi que tous les espaces en trop * * @param string $texte * texte d'entree * @param bool $propre * passer le texte dans propre ou non * @return int * compte du texte nettoye */ function compter_caracteres_utiles($texte, $propre = true) { include_spip('inc/charsets'); if ($propre) { $texte = propre($texte); } $u = $GLOBALS['meta']['pcre_u']; // regarder si il y a du contenu en dehors des liens ! $texte = PtoBR($texte); $texte = preg_replace(",<a.*</a>,{$u}Uims", '', $texte); // \W matche tous les caracteres non ascii apres 0x80 // et vide donc les chaines constitues de caracteres unicodes uniquement // on remplace par un match qui elimine uniquement // les non \w et les non unicodes $texte = trim(preg_replace(",[^\\w€-ÿ]+,ims", ' ', $texte)); // on utilise spip_strlen pour compter la longueur correcte // pour les chaines unicodes return spip_strlen($texte); }