Browse Source

chores: refactorer la fonction traiter_modele en separant la detection/collecte d'une part dans une fonction modeles_collecter() du traitement d'autre part

remotes/checkIfPRContentChanged-1659714283585166050/refactor_texte_safety
Cerdic 2 months ago
parent
commit
4a5ccaddc8
  1. 156
      ecrire/inc/modeles.php

156
ecrire/inc/modeles.php

@ -37,110 +37,162 @@ define(
define('_RACCOURCI_MODELE_DEBUT', '@^' . _RACCOURCI_MODELE . '@isS');
function traiter_modeles($texte, $doublons = false, $echap = '', string $connect = '', $liens = null, $env = []) {
// preserver la compatibilite : true = recherche des documents
if ($doublons === true) {
$doublons = ['documents' => ['doc', 'emb', 'img']];
}
/**
* Detecter et collecter les modeles d'un texte dans un tableau descriptif
* qui pourra servir a leurs traitements ou echappement selon le besoin
* @param string $texte
* @param bool $collecter_liens
* @return array
*/
function modeles_collecter($texte, bool $collecter_liens = true) {
$modeles = [];
// detecter les modeles (rapide)
if (
strpos($texte, '<') !== false
and preg_match_all('/<[a-z_-]{3,}\s*[0-9|]+/iS', $texte, $matches, PREG_SET_ORDER)
) {
include_spip('public/assembler');
$wrap_embed_html = charger_fonction('wrap_embed_html', 'inc', true);
$pos = 0;
// Recuperer l'appel complet (y compris un eventuel lien)
foreach ($matches as $match) {
$a = strpos($texte, (string) $match[0]);
preg_match(_RACCOURCI_MODELE_DEBUT, substr($texte, $a), $regs);
$a = strpos($texte, (string)$match[0], $pos);
// s'assurer qu'il y a toujours un 5e arg, eventuellement vide
while (count($regs) < 6) {
$regs[] = '';
}
if (preg_match(_RACCOURCI_MODELE_DEBUT, substr($texte, $a), $regs)) {
// s'assurer qu'il y a toujours un 5e arg, eventuellement vide
while (count($regs) < 6) {
$regs[] = '';
}
[, $mod, $type, $id, $params, $fin] = $regs;
if (
$fin
and preg_match('/<a\s[^<>]*>\s*$/i', substr($texte, 0, $a), $r)
) {
$lien = [
'href' => extraire_attribut($r[0], 'href'),
'class' => extraire_attribut($r[0], 'class'),
'mime' => extraire_attribut($r[0], 'type'),
'title' => extraire_attribut($r[0], 'title'),
'hreflang' => extraire_attribut($r[0], 'hreflang')
];
$n = strlen($r[0]);
$a -= $n;
$longueur = $n+strlen($regs[0]);
} else {
$lien = false;
$longueur = strlen($mod);
}
[, $mod, $type, $id, $params, $fin] = $regs;
if (
$fin
and preg_match('/<a\s[^<>]*>\s*$/i', substr($texte, 0, $a), $r)
) {
$lien = [
'href' => extraire_attribut($r[0], 'href'),
'class' => extraire_attribut($r[0], 'class'),
'mime' => extraire_attribut($r[0], 'type'),
'title' => extraire_attribut($r[0], 'title'),
'hreflang' => extraire_attribut($r[0], 'hreflang')
$modele = [
'modele' => $mod,
'pos' => $a,
'length' => $longueur,
'type' => $type,
'id' => $id,
'params' => $params,
'lien' => $lien,
];
$n = strlen($r[0]);
$a -= $n;
$cherche = $n + strlen($regs[0]);
} else {
$lien = false;
$cherche = strlen($mod);
$modeles[] = $modele;
}
$pos = $a + strlen((string)$match[0]);
}
}
return $modeles;
}
/**
* Traiter les modeles d'un texte
* @param string $texte
* @param bool|array $doublons
* @param string $echap
* @param string $connect
* @param ?array $liens
* @param array $env
* @return string
*/
function traiter_modeles($texte, $doublons = false, $echap = '', string $connect = '', $liens = null, $env = []) {
// preserver la compatibilite : true = recherche des documents
if ($doublons === true) {
$doublons = ['documents' => ['doc', 'emb', 'img']];
}
$modeles = modeles_collecter($texte, true);
if (!empty($modeles)) {
include_spip('public/assembler');
$wrap_embed_html = charger_fonction('wrap_embed_html', 'inc', true);
$offset_pos = 0;
foreach ($modeles as $m) {
// calculer le modele
# hack indexation
if ($doublons) {
$texte .= preg_replace(',[|][^|=]*,s', ' ', $params);
$texte .= preg_replace(',[|][^|=]*,s', ' ', $m['params']);
} # version normale
else {
// si un tableau de liens a ete passe, reinjecter le contenu d'origine
// dans les parametres, plutot que les liens echappes
$params = $m['params'];
if (!is_null($liens)) {
$params = str_replace($liens[0], $liens[1], $params);
}
$modele = inclure_modele($type, $id, $params, $lien, $connect ?? '', $env);
$modele = inclure_modele($m['type'], $m['id'], $params, $m['lien'], $connect ?? '', $env);
// en cas d'echec,
// si l'objet demande a une url,
// creer un petit encadre vers elle
if ($modele === false) {
$modele = substr($texte, $a, $cherche);
$modele = $m['modele'];
if (!is_null($liens)) {
$modele = str_replace($liens[0], $liens[1], $modele);
}
$contexte = array_merge($env, ['id' => $id, 'type' => $type, 'modele' => $modele]);
$contexte = array_merge($env, ['id' => $m['id'], 'type' => $m['type'], 'modele' => $modele]);
if ($lien) {
if (!empty($m['lien'])) {
# un eventuel guillemet (") sera reechappe par #ENV
$contexte['lien'] = str_replace('&quot;', '"', $lien['href']);
$contexte['lien_class'] = $lien['class'];
$contexte['lien_mime'] = $lien['mime'];
$contexte['lien_title'] = $lien['title'];
$contexte['lien_hreflang'] = $lien['hreflang'];
}
$contexte['lien'] = str_replace('&quot;', '"', $m['lien']['href']);
$contexte['lien_class'] = $m['lien']['class'];
$contexte['lien_mime'] = $m['lien']['mime'];
$contexte['lien_title'] = $m['lien']['title'];
$contexte['lien_hreflang'] = $m['lien']['hreflang'];
}
$modele = recuperer_fond('modeles/dist', $contexte, [], $connect ?? '');
}
// le remplacer dans le texte
if ($modele !== false) {
$modele = protege_js_modeles($modele);
if ($wrap_embed_html) {
$modele = $wrap_embed_html($mod, $modele);
$modele = $wrap_embed_html($m['modele'], $modele);
}
$rempl = code_echappement($modele, $echap);
$texte = substr($texte, 0, $a)
. $rempl
. substr($texte, $a + $cherche);
$texte = substr_replace($texte, $rempl, $m['pos'] + $offset_pos, $m['length']);
$offset_pos += strlen($rempl) - $m['length'];
}
}
// hack pour tout l'espace prive
if (((!_DIR_RESTREINT) or ($doublons)) and ($id)) {
foreach ($doublons ?: ['documents' => ['doc', 'emb', 'img']] as $quoi => $modeles) {
if (in_array(strtolower($type), $modeles)) {
$GLOBALS["doublons_{$quoi}_inclus"][] = $id;
if ((test_espace_prive() or ($doublons)) and !empty($m['id'])) {
$type = strtolower($m['type']);
foreach ($doublons ?: ['documents' => ['doc', 'emb', 'img']] as $quoi => $type_modeles) {
if (in_array($type, $modeles)) {
$GLOBALS["doublons_{$quoi}_inclus"][] = $m['id'];
}
}
}
}
}
return $texte;

Loading…
Cancel
Save