/** * signer le contexte du formulaire * s'applique sur le html pour permettre sa personalisation * * @param string $texte * @param array $config * @return string */ function ogone_form_sha_in($texte, $config = null) { // ne rien faire si pas de config if (!$config) { return $texte; } $forms = extraire_balises($texte, "form"); foreach ($forms as $form) { $form_s = $form; $input = extraire_balises($form, "input"); $args = array(); foreach ($input as $i) { if (extraire_attribut($i, 'type') == 'hidden') { $name = extraire_attribut($i, 'name'); $value = extraire_attribut($i, 'value'); // si jamais on applique 2 fois, supprimer la signature precedement calculee if ($name == "SHASign") { $form_s = str_replace($i, "", $form_s); } else { $args[$name] = $value; } } } $s = ogone_sha_in($args, $config); $form_s = str_replace(end($input), end($input) . "<input type='hidden' name='SHASign' value='{$s}' />", $form_s); $texte = str_replace($form, $form_s, $texte); } return $texte; }
/** * Ajouter le markup html pour une navbar responsive * [<div class="navbar navbar-inverse navbar-responsive" id="nav"> * (#INCLURE{fond=inclure/nav,env}|navbar_responsive) * </div>] * * @param string $nav * @param string $class_collapse nom de la class à plier/déplier * @return string */ function navbar_responsive($nav, $class_collapse = 'nav-collapse-main') { if (strpos($nav, 'nav-collapse') !== false) { return $nav; } $respnav = ''; $uls = extraire_balises($nav, "ul"); $n = 1; while ($ul = array_shift($uls) and strpos(extraire_attribut($ul, "class"), "nav") === false) { $n++; } if ($ul) { $respnav = $nav; $p = strpos($respnav, $ul); $respnav = substr_replace($respnav, '<a class="btn btn-navbar" data-toggle="collapse" data-target=".' . $class_collapse . '">' . '<span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></a>' . "\n" . '<div class="nav-collapse ' . $class_collapse . ' collapse">', $p, 0); $l = strlen($respnav); $p = $l - 1; while ($n--) { $p = strrpos($respnav, "</ul>", $p - $l); } if ($p) { $respnav = substr_replace($respnav, '</div>', $p + 5, 0); } else { $respnav = $nav; } } return $respnav; }
function inc_safehtml_dist($t) { static $process, $test; if (!$test) { $process = false; if ($f = find_in_path('lib/safehtml/classes')) { define('XML_HTMLSAX3', $f.'/'); require_once XML_HTMLSAX3.'safehtml.php'; $process = new safehtml(); $process->deleteTags[] = 'param'; // sinon bug Firefox } if ($process) $test = 1; # ok else $test = -1; # se rabattre sur une fonction de securite basique } if ($test > 0) { # autoriser des trucs # ex: l'embed de youtube if ( false !== strpos($t, 'iframe')) { foreach (extraire_balises($t, 'iframe') as $iframe) { if (preg_match(',^http://(www\.)?(youtube\.com|(player\.)?vimeo\.com)/.*,', extraire_attribut($iframe, 'src'))) { $re = '___IFRAME___'.md5($iframe); $ok[$re] = $iframe; $t = str_replace($iframe, $re, $t); } } } # reset ($process->clear() ne vide que _xhtml...), # on doit pouvoir programmer ca plus propremement $process->_counter = array(); $process->_stack = array(); $process->_dcCounter = array(); $process->_dcStack = array(); $process->_listScope = 0; $process->_liStack = array(); # $process->parse(''); # cas particulier ? $process->clear(); $t = $process->parse($t); # reinserer les trucs autorises if ($ok) foreach ($ok as $re => $v) $t = str_replace($re, $v, $t); } else $t = entites_html($t); // tres laid, en cas d'erreur return $t; }
function skeleditor_extraire_css($texte){ $url_base = url_de_base(); $url_page = substr(generer_url_public('A'), 0, -1); $dir = preg_quote($url_page,',').'|'.preg_quote(preg_replace(",^$url_base,",_DIR_RACINE,$url_page),','); $css = array(); // trouver toutes les css pour les afficher dans le bouton // repris du compresseur foreach (extraire_balises($texte, 'link') as $s) { if (extraire_attribut($s, 'rel') === 'stylesheet' AND (!($type = extraire_attribut($s, 'type')) OR $type == 'text/css') AND !strlen(strip_tags($s)) AND $src = preg_replace(",^$url_base,",_DIR_RACINE,extraire_attribut($s, 'href')) AND ( // regarder si c'est du format spip.php?page=xxx preg_match(',^('.$dir.')(.*)$,', $src, $r) OR ( // ou si c'est un fichier // enlever un timestamp eventuel derriere un nom de fichier statique $src2 = preg_replace(",[.]css[?].+$,",'.css',$src) // verifier qu'il n'y a pas de ../ ni / au debut (securite) AND !preg_match(',(^/|\.\.),', substr($src2,strlen(_DIR_RACINE))) // et si il est lisible AND @is_readable($src2) ) )) { if ($r) $css[$s] = explode('&', str_replace('&', '&', $r[2]), 2); else{ $file = preg_replace(",[?]\d+$,","",$src); if (strncmp($file,_DIR_VAR,strlen(_DIR_VAR))==0){ lire_fichier($file,$c); if (preg_match(",^\/\*\s*(#@.*)\s*\*\/,Uims",$c,$m)){ $inc = explode("#@",$m[1]); $inc = array_map('trim',$inc); $inc = array_filter($inc); foreach($inc as $i){ if (!in_array($i,$css)) $css["$s:$i"] = $i; } } } else $css[$s] = $file; } } } return $css; }
/** * signer le contexte du formulaire * s'applique sur le html pour permettre sa personalisation * * @param string $texte */ function ogone_form_sha_in($texte) { $form = extraire_balise($texte, "form"); $input = extraire_balises($form, "input"); $args = array(); foreach ($input as $i) { if (extraire_attribut($i, 'type') == 'hidden') { $name = extraire_attribut($i, 'name'); $value = extraire_attribut($i, 'value'); $args[$name] = $value; } } $s = ogone_sha_in($args); $texte = str_replace(end($input), end($input) . "<input type='hidden' name='SHASign' value='{$s}' />", $texte); return $texte; }
function filtre_photoswipe_preparer($texte) { foreach (extraire_balises($texte, 'img') as $img) { if ($src = extraire_attribut($img, 'src') and !extraire_attribut($img, 'data-photo')) { $l = largeur($img); $h = hauteur($img); if ($l > 500 or $h > 300) { // pour echapper à la ligne de filtres_images_lib_mini qui remplace tout: // `$tag = str_replace($src,$surcharge['src'],$tag);` $photo_src = str_replace('.', '__.__', $src); $img2 = inserer_attribut($img, 'data-photo', $photo_src); $img2 = inserer_attribut($img2, 'data-photo-w', $l); $img2 = inserer_attribut($img2, 'data-photo-h', $h); $texte = str_replace($img, $img2, $texte); } } } return $texte; }
function podcast_post_syndication($flux) { include_spip("inc/filtres"); $enclosures = extraire_balises($flux["data"]["enclosures"], "a"); $date = date("Y-m-d h:i:s", $flux["data"]["date"]); if (!$date) { $date = date("Y-m-d h:i:s"); } if (is_array($enclosures) and sizeof($enclosures) > 0) { foreach ($enclosures as $link) { if (extraire_attribut($link, 'type') == "audio/mpeg" or extraire_attribut($link, 'type') == "audio/mp3") { $liens[] = extraire_attribut($link, 'href'); } } } if (is_array($liens) and sizeof($liens) > 0) { inserer_document_syndic_article($liens, $flux['args']['id_objet'], $date, $flux["data"]["titre"]); } else { include_spip("inc/utils"); // lancer une tache cron de scan $id_job = job_queue_add('radiobot_scan', "Scan de " . $flux['args']['id_objet'] . " : " . $flux["data"]["titre"], $arguments = array($flux['args']['id_objet'], $flux["data"]["titre"], $flux['data']['url'], $date), 'podcast_pipelines', $no_duplicate = FALSE, strtotime("+10 seconds"), $priority = 0); } return $flux; }
/** * fonction sans finesse mais efficace * on parcourt ligne par ligne a la recherche de balise <a> ou <link> * si dans le corps de celle-ci on trouve les mots rss, xml, atom ou rdf * alors on recupere la valeur href='<url>', on adapte celle-ci si elle * est relative et on verifie que c'est bien un feed si oui on l'ajoute * au tableau des feed si on ne trouve rien ou si aucun feed est trouve on retourne * un tableau vide * * @param string $url * L'URL à analyser * @param $buffer * @return array $feed_list * Le tableau des feed trouvés dans la page */ function get_feed_from_url($url, $buffer = false) { global $verif_complete; //j'ai prevenu ce sera pas fin if (!preg_match("/^http:\\/\\/.*/", $url)) { $url = "http://www." . $url; } if (!$buffer) { $buffer = @file_get_contents($url); } include_spip("inc/filtres"); $feed_list = array(); //extraction des <link> if ($links = extraire_balises($buffer, "link")) { //y a t-y rss atom rdf ou xml dans ces balises foreach ($links as $link) { if ((strpos($link, "rss") || strpos($link, "rdf") || strpos($link, "atom") || strpos($link, "xml")) && (!strpos($link, 'opensearch') && !strpos($link, 'oembed'))) { //voila un candidat on va extraire sa partie href et la placer dans notre tableau if ($href = extraire_attribut($link, "href")) { //on aura pris soin de verifier si ce lien est relatif d'en faire un absolu $href = suivre_lien($url, $href); if (!$verif_complete or is_feed($href)) { $feed_list[] = $href; } } } } } //extraction des <a> if ($links = extraire_balises($buffer, "a")) { //y a t-y rss atom rdf ou xml dans ces balises foreach ($links as $link) { if ((strpos($link, "rss") || strpos($link, "rdf") || strpos($link, "atom") || strpos($link, "xml")) && (!strpos($link, 'opensearch') && !strpos($link, 'oembed'))) { //voila un candidat on va extraire sa partie href et la placer dans notre tableau if ($href = extraire_attribut($link, "href")) { //on aura pris soin de verifier si ce lien est relatif d'en faire un absolu $href = suivre_lien($url, $href); if (!$verif_complete or is_feed($href)) { $feed_list[] = $href; } } } } } // si c'est un site SPIP, tentons l'url connue if (!count($feed_list) and (strpos($url, "spip") or stripos($buffer, "spip"))) { $href = suivre_lien($url, "spip.php?page=backend"); if (is_feed($href)) { $feed_list[] = $href; } } return $feed_list; }
/** * Retrouver les champs d'un formulaire en parcourant son squelette * et en extrayant les balises input, textarea, select * * @param string $form * @return array */ function cvtconf_formulaires_configurer_recense($form) { $valeurs = array('editable' => ' '); // sinon cas analyse du squelette if ($f = find_in_path($form . '.' . _EXTENSION_SQUELETTES, 'formulaires/') and lire_fichier($f, $contenu)) { for ($i = 0; $i < 2; $i++) { // a la seconde iteration, evaluer le fond avec les valeurs deja trouvees // permet de trouver aussi les name="#GET{truc}" if ($i == 1) { $contenu = recuperer_fond("formulaires/{$form}", $valeurs); } $balises = array_merge(extraire_balises($contenu, 'input'), extraire_balises($contenu, 'textarea'), extraire_balises($contenu, 'select')); foreach ($balises as $b) { if ($n = extraire_attribut($b, 'name') and preg_match(",^([\\w\\-]+)(\\[\\w*\\])?\$,", $n, $r) and !in_array($n, array('formulaire_action', 'formulaire_action_args')) and extraire_attribut($b, 'type') !== 'submit') { $valeurs[$r[1]] = ''; // recuperer les valeurs _meta_xx qui peuvent etre fournies // en input hidden dans le squelette if (strncmp($r[1], '_meta_', 6) == 0) { $valeurs[$r[1]] = extraire_attribut($b, 'value'); } } } } } cvtconf_configurer_lire_meta($form, $valeurs); return $valeurs; }
/** * Construitre l'email personalise de notification d'un forum * * @param array $t * @param string $email * @return string */ function email_notification_forum ($t, $email) { static $contexte = array(); if(!isset($contexte[$t['id_forum']])){ $url = ''; $id_forum = $t['id_forum']; if ($t['statut'] == 'prive') # forum prive { if ($t['id_article']) $url = generer_url_ecrire('articles', 'id_article='.$t['id_article']).'#id'.$id_forum; else if ($t['id_breve']) $url = generer_url_ecrire('breves_voir', 'id_breve='.$t['id_breve']).'#id'.$id_forum; else if ($t['id_syndic']) $url = generer_url_ecrire('sites', 'id_syndic='.$t['id_syndic']).'#id'.$id_forum; } else if ($t['statut'] == 'privrac') # forum general { $url = generer_url_ecrire('forum').'#id'.$id_forum; } else if ($t['statut'] == 'privadm') # forum des admins { $url = generer_url_ecrire('forum_admin').'#id'.$id_forum; } else if ($t['statut'] == 'publie') # forum publie { $url = generer_url_entite($id_forum, 'forum'); } else # forum modere, spam, poubelle direct .... { $url = generer_url_ecrire('controle_forum', "debut_id_forum=".$id_forum); } if (!$url) { spip_log("forum $id_forum sans referent",'notifications'); $url = './'; } if ($t['id_article']) { $titre = sql_getfetsel("titre", "spip_articles", "id_article=".sql_quote($t['id_article'])); } if ($t['id_message']) { $titre = sql_getfetsel("titre", "spip_messages", "id_message=".sql_quote($t['id_message'])); } $t['titre_source'] = $titre; $t['url'] = $url; // detecter les url des liens du forum // pour la moderation (permet de reperer les SPAMS avec des liens caches) $links = array(); foreach ($t as $champ) $links = $links + extraire_balises($champ,'a'); $links = extraire_attribut($links,'href'); $links = implode("\n",$links); $t['liens'] = $links; $contexte[$t['id_forum']] = $t; } $t = $contexte[$t['id_forum']]; // Rechercher eventuellement la langue du destinataire if (NULL !== ($l = sql_getfetsel('lang', 'spip_auteurs', "email=" . sql_quote($email)))) $l = lang_select($l); $parauteur = (strlen($t['auteur']) <= 2) ? '' : (" " ._T('forum_par_auteur', array( 'auteur' => $t['auteur']) ) . ($t['email_auteur'] ? ' <' . $t['email_auteur'] . '>' : '')); $titre = textebrut(typo($t['titre_source'])); $forum_poste_par = ($t['id_article'] ? _T('forum_poste_par', array( 'parauteur' => $parauteur, 'titre' => $titre)) : $parauteur . ' (' . $titre . ')'); $t['par_auteur'] = $forum_poste_par; $envoyer_mail = charger_fonction('envoyer_mail','inc'); // pour nettoyer_titre_email $corps = recuperer_fond("notifications/forum_poste",$t); if ($l) lang_select(); return $corps; }
function chercher_enclosures_zip($rss, $desc = '') { $liste = array(); include_spip('inc/syndic'); foreach(analyser_backend($rss) as $item){ if ($item['enclosures'] AND $zips = extraire_balises($item['enclosures'], 'a')){ if ($img = extraire_balise($item['descriptif'], 'img') AND $src = extraire_attribut($img, 'src')) { $item['icon'] = $src; } foreach ($zips as $zip) if (extraire_attribut($zip, 'type') == 'application/zip') { if ($url = extraire_attribut($zip, 'href')) { $liste[$url] = array($item['titre'], $item['url']); if ($desc===true OR $desc == $url) $liste[$url][] = $item; } } } } spip_log(count($liste).' enclosures au format zip'); return $liste; }
function page_base_href(&$texte) { static $set_html_base = null; if (is_null($set_html_base)) { if (!defined('_SET_HTML_BASE')) { $set_html_base = ($GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) and _request(_SPIP_PAGE) !== 'login' and !_request('action')) ? true : false; } else { $set_html_base = _SET_HTML_BASE; } } if ($set_html_base and isset($GLOBALS['html']) and $GLOBALS['html'] and $GLOBALS['profondeur_url'] > 0 and ($poshead = strpos($texte, '</head>')) !== false) { $head = substr($texte, 0, $poshead); $insert = false; if (strpos($head, '<base') === false) { $insert = true; } else { // si aucun <base ...> n'a de href c'est bon quand meme ! $insert = true; include_spip('inc/filtres'); $bases = extraire_balises($head, 'base'); foreach ($bases as $base) { if (extraire_attribut($base, 'href')) { $insert = false; } } } if ($insert) { include_spip('inc/filtres_mini'); // ajouter un base qui reglera tous les liens relatifs $base = url_absolue('./'); $bbase = "\n<base href=\"{$base}\" />"; if (($pos = strpos($head, '<head>')) !== false) { $head = substr_replace($head, $bbase, $pos + 6, 0); } elseif (preg_match(",<head[^>]*>,i", $head, $r)) { $head = str_replace($r[0], $r[0] . $bbase, $head); } $texte = $head . substr($texte, $poshead); // gerer les ancres $base = $_SERVER['REQUEST_URI']; if (strpos($texte, "href='#") !== false) { $texte = str_replace("href='#", "href='{$base}#", $texte); } if (strpos($texte, "href=\"#") !== false) { $texte = str_replace("href=\"#", "href=\"{$base}#", $texte); } } } }
function analyser_backend($rss, $url_syndic = '') { include_spip('inc/texte'); # pour couper() $rss = pipeline('pre_syndication', $rss); // si true, les URLs de type feedburner sont dereferencees define('_SYNDICATION_DEREFERENCER_URL', false); // Echapper les CDATA cdata_echappe($rss, $echappe_cdata); // supprimer les commentaires $rss = preg_replace(',<!--.*-->,Ums', '', $rss); // simplifier le backend, en supprimant les espaces de nommage type "dc:" $rss = preg_replace(',<(/?)(dc):,i', '<\\1', $rss); // chercher auteur/lang dans le fil au cas ou les items n'en auraient pas list($header) = preg_split(',<(item|entry)\\b,', $rss, 2); if (preg_match_all(',<(author|creator)\\b(.*)</\\1>,Uims', $header, $regs, PREG_SET_ORDER)) { $les_auteurs_du_site = array(); foreach ($regs as $reg) { $nom = $reg[2]; if (preg_match(',<name>(.*)</name>,Uims', $nom, $reg)) { $nom = $reg[1]; } $les_auteurs_du_site[] = trim(textebrut(filtrer_entites($nom))); } $les_auteurs_du_site = join(', ', array_unique($les_auteurs_du_site)); } else { $les_auteurs_du_site = ''; } if (preg_match(',<([^>]*xml:)?lang(uage)?' . '>([^<>]+)<,i', $header, $match) and $l = $match[3] or $l = extraire_attribut(extraire_balise($header, 'feed'), 'xml:lang')) { $langue_du_site = $l; } elseif (preg_match(',<feed\\s[^>]*xml:lang=[\'"]([^<>\'"]+)[\'"],i', $header, $match)) { $langue_du_site = $match[1]; } // Recuperer les blocs item et entry $items = array_merge(extraire_balises($rss, 'item'), extraire_balises($rss, 'entry')); // // Analyser chaque <item>...</item> du backend et le transformer en tableau // if (!count($items)) { return _T('sites:avis_echec_syndication_01'); } foreach ($items as $item) { $data = array(); // URL (semi-obligatoire, sert de cle) // guid n'est un URL que si marque de <guid ispermalink="true"> ; // attention la valeur par defaut est 'true' ce qui oblige a quelque // gymnastique if (preg_match(',<guid.*>[[:space:]]*(https?:[^<]*)</guid>,Uims', $item, $regs) and preg_match(',^(true|1)?$,i', extraire_attribut($regs[0], 'ispermalink'))) { $data['url'] = $regs[1]; } else { if (_SYNDICATION_DEREFERENCER_URL and preg_match(',<feedburner:origLink>(.*)<,Uims', $item, $regs)) { $data['url'] = $regs[1]; } else { if (preg_match(',<link[^>]*[[:space:]]rel=["\']?alternate[^>]*>(.*)</link>,Uims', $item, $regs)) { $data['url'] = $regs[1]; } else { if (preg_match(',<link[^>]*[[:space:]]rel=.alternate[^>]*>,Uims', $item, $regs)) { $data['url'] = extraire_attribut($regs[0], 'href'); } else { if (preg_match(',<link[^>]*>\\s*([^\\s]+)\\s*</link>,Uims', $item, $regs)) { $data['url'] = $regs[1]; } else { if (preg_match(',<link[^>]*>,Uims', $item, $regs)) { $data['url'] = extraire_attribut($regs[0], 'href'); } else { if (preg_match(',<enclosure[^>]*>,ims', $item, $regs) and $url = extraire_attribut($regs[0], 'url')) { $data['url'] = $url; } else { $data['url'] = ''; } } } } } } } // Titre (semi-obligatoire) if (preg_match(",<title[^>]*>(.*?)</title>,ims", $item, $match)) { $data['titre'] = $match[1]; } else { if (preg_match(',<link[[:space:]][^>]*>,Uims', $item, $mat) and $title = extraire_attribut($mat[0], 'title')) { $data['titre'] = $title; } } if (!strlen($data['titre'] = trim($data['titre']))) { $data['titre'] = _T('ecrire:info_sans_titre'); } // Date $la_date = ''; if (preg_match(',<(published|modified|issued)>([^<]*)<,Uims', $item, $match)) { cdata_echappe_retour($match[2], $echappe_cdata); $la_date = my_strtotime($match[2], $langue_du_site); } if (!$la_date and preg_match(',<(pubdate)>([^<]*)<,Uims', $item, $match)) { cdata_echappe_retour($match[2], $echappe_cdata); $la_date = my_strtotime($match[2], $langue_du_site); } if (!$la_date and preg_match(',<([a-z]+:date)>([^<]*)<,Uims', $item, $match)) { cdata_echappe_retour($match[2], $echappe_cdata); $la_date = my_strtotime($match[2], $langue_du_site); } if (!$la_date and preg_match(',<date>([^<]*)<,Uims', $item, $match)) { cdata_echappe_retour($match[1], $echappe_cdata); $la_date = my_strtotime($match[1], $langue_du_site); } // controle de validite de la date // pour eviter qu'un backend errone passe toujours devant // (note: ca pourrait etre defini site par site, mais ca risque d'etre // plus lourd que vraiment utile) if ($GLOBALS['controler_dates_rss']) { if (!$la_date or $la_date > time() + 48 * 3600) { $la_date = time(); } } if ($la_date) { $data['date'] = $la_date; } // Honorer le <lastbuilddate> en forcant la date if (preg_match(',<(lastbuilddate|updated|modified)>([^<>]+)</\\1>,i', $item, $regs) and $lastbuilddate = my_strtotime(trim($regs[2]), $langue_du_site) and $lastbuilddate < time()) { $data['lastbuilddate'] = $lastbuilddate; } // Auteur(s) if (preg_match_all(',<(author|creator)\\b[^>]*>(.*)</\\1>,Uims', $item, $regs, PREG_SET_ORDER)) { $auteurs = array(); foreach ($regs as $reg) { $nom = $reg[2]; if (preg_match(',<name\\b[^>]*>(.*)</name>,Uims', $nom, $reg)) { $nom = $reg[1]; } // Cas particulier d'un auteur Flickr if (preg_match(',nobody@flickr.com \\((.*)\\),Uims', $nom, $reg)) { $nom = $reg[1]; } $auteurs[] = trim(textebrut(filtrer_entites($nom))); } $data['lesauteurs'] = join(', ', array_unique($auteurs)); } else { $data['lesauteurs'] = $les_auteurs_du_site; } // Description if (preg_match(',<(description|summary)\\b.*' . '>(.*)</\\1\\b,Uims', $item, $match)) { $data['descriptif'] = trim($match[2]); } if (preg_match(',<(content)\\b.*' . '>(.*)</\\1\\b,Uims', $item, $match)) { $data['content'] = trim($match[2]); } // lang if (preg_match(',<([^>]*xml:)?lang(uage)?' . '>([^<>]+)<,i', $item, $match)) { $data['lang'] = trim($match[3]); } else { if ($lang = trim(extraire_attribut($item, 'xml:lang'))) { $data['lang'] = $lang; } else { $data['lang'] = trim($langue_du_site); } } // source et url_source (pas trouve d'exemple en ligne !!) # <source url="http://www.truc.net/music/uatsap.mp3" length="19917" /> # <source url="http://www.truc.net/rss">Site source</source> if (preg_match(',(<source[^>]*>)(([^<>]+)</source>)?,i', $item, $match)) { $data['source'] = trim($match[3]); $data['url_source'] = str_replace('&', '&', trim(extraire_attribut($match[1], 'url'))); } // tags # a partir de "<dc:subject>", (del.icio.us) # ou <media:category> (flickr) # ou <itunes:category> (apple) # on cree nos tags microformat <a rel="directory" href="url">titre</a> # http://microformats.org/wiki/rel-directory-fr $tags = array(); if (preg_match_all(',<(([a-z]+:)?(subject|category|directory|keywords?|tags?|type))[^>]*>' . '(.*?)</\\1>,ims', $item, $matches, PREG_SET_ORDER)) { $tags = ajouter_tags($matches, $item); } elseif (preg_match_all(',<(([a-z]+:)?(subject|category|directory|keywords?|tags?|type))[^>]*/>' . ',ims', $item, $matches, PREG_SET_ORDER)) { $tags = ajouter_tags($matches, $item); } # array() // Pieces jointes : // chercher <enclosure> au format RSS et les passer en microformat // ou des microformats relEnclosure, // ou encore les media:content if (!afficher_enclosures(join(', ', $tags))) { // on prend toutes les pièces jointes possibles, et on essaie de les rendre uniques. $enclosures = array(); # rss 2 if (preg_match_all(',<enclosure[[:space:]][^<>]+>,i', $item, $matches, PREG_PATTERN_ORDER)) { $enclosures += array_map('enclosure2microformat', $matches[0]); } # atom if (preg_match_all(',<link\\b[^<>]+rel=["\']?enclosure["\']?[^<>]+>,i', $item, $matches, PREG_PATTERN_ORDER)) { $enclosures += array_map('enclosure2microformat', $matches[0]); } # media rss if (preg_match_all(',<media:content\\b[^<>]+>,i', $item, $matches, PREG_PATTERN_ORDER)) { $enclosures += array_map('enclosure2microformat', $matches[0]); } $data['enclosures'] = join(', ', array_unique($enclosures)); unset($enclosures); } $data['item'] = $item; // Nettoyer les donnees et remettre les CDATA en place cdata_echappe_retour($data, $echappe_cdata); cdata_echappe_retour($tags, $echappe_cdata); // passer l'url en absolue $data['url'] = url_absolue(filtrer_entites($data['url']), $url_syndic); // Trouver les microformats (ecrase les <category> et <dc:subject>) if (preg_match_all(',<a[[:space:]]([^>]+[[:space:]])?rel=[^>]+>.*</a>,Uims', $data['item'], $regs, PREG_PATTERN_ORDER)) { $tags = $regs[0]; } // Cas particulier : tags Connotea sous la forme <a class="postedtag"> if (preg_match_all(',<a[[:space:]][^>]+ class="postedtag"[^>]*>.*</a>,Uims', $data['item'], $regs, PREG_PATTERN_ORDER)) { $tags = preg_replace(', class="postedtag",i', ' rel="tag"', $regs[0]); } $data['tags'] = $tags; // enlever le html des titre pour etre homogene avec les autres objets spip $data['titre'] = textebrut($data['titre']); $articles[] = $data; } return $articles; }
/** * Extraire les balises JS à compacter * * @param string $flux * Contenu HTML dont on extrait les balises CSS * @param string $url_base * @return array * Couples (balise => src) */ function compresseur_extraire_balises_js_dist($flux, $url_base) { $balises = extraire_balises($flux, 'script'); $files = array(); foreach ($balises as $s) { if (extraire_attribut($s, 'type') === 'text/javascript' and is_null(extraire_attribut($s, 'id')) and $src = extraire_attribut($s, 'src') and !strlen(strip_tags($s))) { $files[$s] = $src; } } return $files; }
function tags2dcsubject($tags) { $subjects = ''; foreach (extraire_balises($tags, 'a') as $e) { if (extraire_attribut($e, rel) == 'tag') { $subjects .= '<dc:subject>' . texte_backend(textebrut($e)) . '</dc:subject>'."\n"; } } return $subjects; }
function compacte_head_css($flux) { $url_base = url_de_base(); $url_page = substr(generer_url_public('A'), 0, -1); $dir = preg_quote($url_page,',').'|'.preg_quote(preg_replace(",^$url_base,",_DIR_RACINE,$url_page),','); $css = array(); $flux_nocomment = preg_replace(",<!--.*-->,Uims","",$flux); foreach (extraire_balises($flux_nocomment, 'link') as $s) { if (extraire_attribut($s, 'rel') === 'stylesheet' AND (!($type = extraire_attribut($s, 'type')) OR $type == 'text/css') AND is_null(extraire_attribut($s, 'name')) # css nommee : pas touche AND is_null(extraire_attribut($s, 'id')) # idem AND !strlen(strip_tags($s)) AND $src = preg_replace(",^$url_base,",_DIR_RACINE,extraire_attribut($s, 'href')) AND ( // regarder si c'est du format spip.php?page=xxx preg_match(',^('.$dir.')(.*)$,', $src, $r) OR ( // ou si c'est un fichier // enlever un timestamp eventuel derriere un nom de fichier statique $src2 = preg_replace(",[.]css[?].+$,",'.css',$src) // verifier qu'il n'y a pas de ../ ni / au debut (securite) AND !preg_match(',(^/|\.\.),', substr($src2,strlen(_DIR_RACINE))) // et si il est lisible AND @is_readable($src2) ) )) { $media = strval(extraire_attribut($s, 'media')); if ($media==='') $media='all'; if ($r) $css[$media][$s] = explode('&', str_replace('&', '&', $r[2]), 2); else $css[$media][$s] = $src; } } // et mettre le tout dans un cache statique foreach($css as $m=>$s){ // si plus d'une css pour ce media ou si c'est une css dynamique if (count($s)>1 OR is_array(reset($s))){ if (list($src,$comms) = filtre_cache_static($s,'css')){ $compacte_ecrire_balise_link = charger_fonction('compacte_ecrire_balise_link',''); $s = array_keys($s); $flux = str_replace(reset($s), $comms . $compacte_ecrire_balise_link($src,$m)."\n", $flux); $flux = str_replace($s,"",$flux); } } } return $flux; }
/** * Retourne un tableau d'analyse du texte transmis * Cette analyse concerne principalement des statistiques sur les liens * * @param string $texte texte d'entree * @return array rapport d'analyse */ function analyser_spams($texte) { $infos = array('caracteres_utiles' => 0, 'nombre_liens' => 0, 'caracteres_texte_lien_min' => 0); if (!$texte) { return $infos; } // on travaille d'abord sur le texte 'brut' tel que saisi par // l'utilisateur pour ne pas avoir les class= et style= que spip ajoute // sur les raccourcis. // on ne tient pas compte des blocs <code> et <cadre> ni de leurs contenus include_spip("inc/texte_mini"); if (!function_exists('echappe_html')) { // SPIP 2.x include_spip("inc/texte"); } $texte_humain = echappe_html($texte); // on repère dans ce qui reste la présence de style= ou class= qui peuvent // servir à masquer du contenu // les spammeurs utilisent le laxisme des navigateurs pour envoyer aussi style = // soyons donc mefiant // (mais en enlevant le base64 !) $texte_humain = str_replace('class="base64"', '', $texte_humain); $hidden = ",(<(img|object)|\\s(?:style|class)\\s*=[^>]+>),UimsS"; if (preg_match($hidden, $texte_humain)) { // suspicion de spam $infos['contenu_cache'] = true; } include_spip('inc/texte'); $texte = propre($texte); // caracteres_utiles $infos['caracteres_utiles'] = compter_caracteres_utiles($texte, false); // nombre de liens $liens = array_filter(extraire_balises($texte, 'a'), 'pas_lien_ancre'); $infos['nombre_liens'] = count($liens); $infos['liens'] = $liens; // taille du titre de lien minimum if (count($liens)) { // supprimer_tags() s'applique a tout le tableau, // mais attention a verifier dans le temps que ca continue a fonctionner # $titres_liens = array_map('supprimer_tags', $liens); $titres_liens = supprimer_tags($liens); $titres_liens = array_map('strlen', $titres_liens); $infos['caracteres_texte_lien_min'] = min($titres_liens); } return $infos; }
function page_base_href(&$texte){ if (!defined('_SET_HTML_BASE')) // si la profondeur est superieure a 1 // est que ce n'est pas une url page ni une url action // activer par defaut define('_SET_HTML_BASE', $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT?1:2) AND _request(_SPIP_PAGE) !== 'login' AND !_request('action')); if (_SET_HTML_BASE AND isset($GLOBALS['html']) AND $GLOBALS['html'] AND $GLOBALS['profondeur_url']>0 AND ($poshead = strpos($texte,'</head>'))!==FALSE){ $head = substr($texte,0,$poshead); $insert = false; if (strpos($head, '<base')===false) $insert = true; else { // si aucun <base ...> n'a de href c'est bon quand meme ! $insert = true; include_spip('inc/filtres'); $bases = extraire_balises($head,'base'); foreach ($bases as $base) if (extraire_attribut($base,'href')) $insert = false; } if ($insert) { include_spip('inc/filtres_mini'); // ajouter un base qui reglera tous les liens relatifs $base = url_absolue('./'); $bbase = "\n<base href=\"$base\" />"; if (($pos = strpos($head, '<head>')) !== false) $head = substr_replace($head, $bbase, $pos+6, 0); elseif(preg_match(",<head[^>]*>,i",$head,$r)){ $head = str_replace($r[0], $r[0].$bbase, $head); } $texte = $head . substr($texte,$poshead); // gerer les ancres $base = $_SERVER['REQUEST_URI']; if (strpos($texte,"href='#")!==false) $texte = str_replace("href='#","href='$base#",$texte); if (strpos($texte, "href=\"#")!==false) $texte = str_replace("href=\"#","href=\"$base#",$texte); } } }
/** * Inserer un champ nobot au hasard dans le form * et crypter tous les name * @param string $texte */ function nospam_inserer_nobot(&$texte) { if (false === strpos($texte, 'name="email_nobot"') and false !== ($pos = strpos($texte, '</form>'))) { // essayer de s'inserer au hasard entre 2 div/li du form if (preg_match_all(",<(div|li)\\b[^>]*class=['\"]editer[^>]*,ims", $texte, $m) and $i = rand(0, count($m[0]) - 1) and $p = strpos($texte, $m[0][$i])) { $nobot = recuperer_fond("inclure/nobot", array('email_nobot' => '', 'div' => $m[1][$i])); $texte = substr_replace($texte, $nobot, $p, 0); } else { $nobot = recuperer_fond("inclure/nobot", array('email_nobot' => '')); $texte = str_replace('</form>', $nobot . '</form>', $texte); } } if (_SPAM_ENCRYPT_NAME) { // recuperer toutes les balises input, textarea, select $balises = array_merge(extraire_balises($texte, 'input')); foreach ($balises as $k => $b) { if (in_array(extraire_attribut($b, "type"), array("hidden", "file"))) { unset($balises[$k]); } } $balises = array_merge($balises, extraire_balises($texte, 'textarea'), extraire_balises($texte, 'select')); $key = ""; if (preg_match(",<input type='hidden' name='_jeton' value='([^>]*)' />,Uims", $texte, $m)) { $key = $m[1]; } foreach ($balises as $k => $b) { if ($name = extraire_attribut($b, "name") and strncmp($name, "session_", 8) !== 0) { // cas des truc[chose] : on ne brouille que truc $crypted_name = explode("[", $name); $crypted_name[0] = nospam_name_encode($crypted_name[0], $key); $crypted_name = implode("[", $crypted_name); $b_e = inserer_attribut($b, "name", $crypted_name); $texte = str_replace($b, $b_e, $texte); } } } }
/** * Construitre l'email personalise de notification d'un forum * * @param array $t * @param string $email * @param array $contexte * @return string */ function inc_email_notification_forum_dist($t, $email, $contexte = array()) { static $contextes_store = array(); if (!isset($contextes_store[$t['id_forum']])) { $url = ''; $id_forum = $t['id_forum']; if ($t['statut'] == 'prive') { if ($t['id_objet']) { $url = generer_url_entite($t['id_objet'], $t['objet'], '', 'forum' . $id_forum, false); } } else { if ($t['statut'] == 'privrac') { $url = generer_url_ecrire('forum') . '#forum' . $id_forum; } else { if ($t['statut'] == 'privadm') { $url = generer_url_ecrire('forum', 'quoi=admin') . '#forum' . $id_forum; } else { if ($t['statut'] == 'publie') { $url = generer_url_entite($id_forum, 'forum'); } else { $url = generer_url_ecrire('controler_forum', "debut_id_forum=" . $id_forum); } } } } if (!$url) { spip_log("forum {$id_forum} sans referent", 'notifications'); $url = './'; } if ($t['id_objet']) { include_spip('inc/filtres'); $t['titre_source'] = generer_info_entite($t['id_objet'], $t['objet'], 'titre'); } $t['url'] = $url; // detecter les url des liens du forum // pour la moderation (permet de reperer les SPAMS avec des liens caches) // il faut appliquer le traitement de raccourci car sinon on rate des liens sous forme [->..] utilises par les spammeurs ! include_spip("public/interfaces"); $table_objet = "forum"; $links = array(); foreach ($t as $champ => $v) { $champ = strtoupper($champ); $traitement = isset($GLOBALS['table_des_traitements'][$champ]) ? $GLOBALS['table_des_traitements'][$champ] : null; if (is_array($traitement) and (isset($traitement[$table_objet]) or isset($traitement[0]))) { $traitement = $traitement[isset($traitement[$table_objet]) ? $table_objet : 0]; $traitement = str_replace('%s', "'" . texte_script($v) . "'", $traitement); eval("\$v = {$traitement};"); } $links = $links + extraire_balises($v, 'a'); } $links = extraire_attribut($links, 'href'); $links = implode("\n", $links); $t['liens'] = $links; $contextes_store[$t['id_forum']] = $t; } $fond = "notifications/forum_poste"; if (isset($contexte['fond'])) { $fond = $contexte['fond']; unset($contexte['fond']); } $t = array_merge($contextes_store[$t['id_forum']], $contexte); // Rechercher eventuellement la langue du destinataire if (null !== ($l = sql_getfetsel('lang', 'spip_auteurs', "email=" . sql_quote($email)))) { $l = lang_select($l); } $parauteur = strlen($t['auteur']) <= 2 ? '' : " " . _T('forum_par_auteur', array('auteur' => $t['auteur'])) . ($t['email_auteur'] ? ' <' . $t['email_auteur'] . '>' : ''); $titre = textebrut(typo($t['titre_source'])); if ($titre) { $forum_poste_par = _T($t['objet'] == 'article' ? 'forum:forum_poste_par' : 'forum:forum_poste_par_generique', array('parauteur' => $parauteur, 'titre' => $titre, 'objet' => $t['objet'])); } else { $forum_poste_par = _T('forum:forum_poste_par_court', array('parauteur' => $parauteur)); } $t['par_auteur'] = $forum_poste_par; $envoyer_mail = charger_fonction('envoyer_mail', 'inc'); // pour nettoyer_titre_email $corps = recuperer_fond($fond, $t); if ($l) { lang_select(); } return $corps; }
function importer_links($page) { $ps = explode('<li id="item-', $page); array_shift($ps); // le premier ne nous interesse pas $links = array(); foreach ($ps as $p) { $link = array(); if (preg_match(',<div class="date">([^<]*)<,Uims', $p, $m)) { $link['date'] = $m[1]; $link['date'] = date('Y-m-d', strtotime($link['date'])); } $h4 = extraire_balise($p, 'h4'); $a = extraire_balise($h4, 'a'); $link['url'] = extraire_attribut($a, 'href'); $link['title'] = trim(strip_tags($a)); $p = explode('<ul class="tag-chain">', $p); $notes = reset($p); $p = end($p); if (preg_match(',<div class="notes">(.*)</div>,Uims', $notes, $m)) { #var_dump($m[1]); $link['descriptif'] = nettoyer_notes($m[1]); #var_dump($link['descriptif']); } $p = explode("</ul>", $p); $p = reset($p); $tags = extraire_balises($p, 'a'); foreach ($tags as $tag) { $link['tags'][] = trim(strip_tags($tag)); } $links[] = $link; } return $links; }
/** * Analyser une URL de site distant, qui peut être une syndication. * * @param string $url * URL du site à analyser * @return array|bool * - array : informations du site * - false : site impossible à récupérer **/ function analyser_site($url) { include_spip('inc/filtres'); include_spip('inc/distant'); // Accepter les URLs au format feed:// ou qui ont oublie le http:// $url = preg_replace(',^feed://,i', 'http://', $url); if (!preg_match(',^[a-z]+://,i', $url)) { $url = 'http://' . $url; } $texte = recuperer_page($url, true); if (!$texte) { return false; } include_spip('inc/syndic'); cdata_echappe($texte, $echappe_cdata); if (preg_match(',<(channel|feed)([\\:[:space:]][^>]*)?' . '>(.*)</\\1>,ims', $texte, $regs)) { $result['syndication'] = 'oui'; $result['url_syndic'] = $url; $channel = $regs[3]; // Pour recuperer l'entete, on supprime tous les items $b = array_merge(extraire_balises($channel, 'item'), extraire_balises($channel, 'entry')); $header = str_replace($b, array(), $channel); if ($t = extraire_balise($header, 'title')) { cdata_echappe_retour($t, $echappe_cdata); $result['nom_site'] = filtrer_entites(supprimer_tags($t)); } if ($t = extraire_balises($header, 'link')) { cdata_echappe_retour($t, $echappe_cdata); foreach ($t as $link) { $u = supprimer_tags(filtrer_entites($link)); if (!strlen($u)) { $u = extraire_attribut($link, 'href'); } if (strlen($u)) { // on installe l'url comme url du site // si c'est non vide, en donnant la priorite a rel=alternate if (preg_match(',\\balternate\\b,', extraire_attribut($link, 'rel')) or !isset($result['url_site'])) { $result['url_site'] = filtrer_entites($u); } } } } $result['url_site'] = url_absolue($result['url_site'], $url); if ($a = extraire_balise($header, 'description') or $a = extraire_balise($header, 'tagline')) { cdata_echappe_retour($a, $echappe_cdata); $result['descriptif'] = filtrer_entites(supprimer_tags($a)); } if (preg_match(',<image.*<url.*>(.*)</url>.*</image>,Uims', $header, $r) and preg_match(',(https?://.*/.*(gif|png|jpg)),ims', $r[1], $r) and $image = recuperer_infos_distantes($r[1])) { if (in_array($image['extension'], array('gif', 'jpg', 'png'))) { $result['format_logo'] = $image['extension']; $result['logo'] = $r[1]; } else { if ($image['fichier']) { spip_unlink($image['fichier']); } } } } else { $result['syndication'] = 'non'; $result['url_site'] = $url; if (preg_match(',<head>(.*(description|title).*)</head>,Uims', $texte, $regs)) { $head = filtrer_entites($regs[1]); } else { $head = $texte; } if (preg_match(',<title[^>]*>(.*),ims', $head, $regs)) { $titre = trim($regs[1]); if (!strlen($titre)) { $titre = substr($head, strpos($head, $regs[0])); } $result['nom_site'] = filtrer_entites(supprimer_tags(preg_replace(',</title>.*$,ims', '', $titre))); } if ($a = array_merge(extraire_balises($head, 'meta'), extraire_balises($head, 'http-equiv'))) { foreach ($a as $meta) { if (extraire_attribut($meta, 'name') == 'description') { $desc = trim(extraire_attribut($meta, 'content')); if (!strlen($desc)) { $desc = trim(extraire_attribut($meta, 'value')); } $result['descriptif'] = $desc; } } } // Cherchons quand meme un backend include_spip('inc/distant'); include_spip('inc/feedfinder'); $feeds = get_feed_from_url($url, $texte); // si on a a trouve un (ou plusieurs) on le note avec select: // ce qui constitue un signal pour exec=sites qui proposera de choisir // si on syndique, et quelle url. if (count($feeds) >= 1) { spip_log("feedfinder.php :\n" . join("\n", $feeds)); $result['url_syndic'] = "select: " . join(' ', $feeds); } } cdata_echappe_retour($result, $echappe_cdata); return $result; }
/** * Retourne la liste des formulaires de configuration * presents dans le fichier dont l'adresse est donnee * * @param string $file adresse du fichier * @return array liste des formulaires trouves **/ function lister_formulaires_configurer($file) { $forms = array(); lire_fichier($file, $skel); if (preg_match_all(",#FORMULAIRE_(CONFIGURER_[A-Z0-9_]*),", $skel, $matches, PREG_SET_ORDER)) { $matches = array_map('end', $matches); $matches = array_map('strtolower', $matches); $forms = array_merge($forms, $matches); } // evaluer le fond en lui passant un exec coherent pour que les pipelines le reconnaissent // et reperer les formulaires CVT configurer_xx insereres par les plugins via pipeline $config = basename(substr($file, 0, -strlen("." . _EXTENSION_SQUELETTES))); spip_log('Calcul de ' . "prive/squelettes/contenu/{$config}"); $fond = recuperer_fond("prive/squelettes/contenu/{$config}", array("exec" => $config)); // passer dans le pipeline affiche_milieu pour que les plugins puissent ajouter leur formulaires... // et donc que l'on puisse les referencer aussi ! $fond = pipeline('affiche_milieu', array('args' => array("exec" => $config), 'data' => $fond)); // recuperer les noms des formulaires presents. if (is_array($inputs = extraire_balises($fond, "input"))) { foreach ($inputs as $i) { if (extraire_attribut($i, 'name') == 'formulaire_action') { $forms[] = $c = extraire_attribut($i, 'value'); } } } return $forms; }
/** * Wrap un texte avec des balises * wrap('mot','<b>') => '<b>mot</b>' * @param string $texte * @param string $wrap * @return string */ function wrap($texte, $wrap) { $balises = extraire_balises($wrap); if (preg_match_all(",<([a-z]\\w*)\\b[^>]*>,UimsS", $wrap, $regs, PREG_PATTERN_ORDER)) { $texte = $wrap . $texte; $regs = array_reverse($regs[1]); $wrap = "</" . implode("></", $regs) . ">"; $texte = $texte . $wrap; } return $texte; }
/** * Attraper automatiquement toutes les .less ou .less.css du head * les compiler, et les remplacer par leur css compilee * * @param string $head * @return string */ function lesscss_cssify_head($head) { $url_base = url_de_base(); $balises = extraire_balises($head, 'link'); $files = array(); foreach ($balises as $s) { if (extraire_attribut($s, 'rel') === 'stylesheet' and (!($type = extraire_attribut($s, 'type')) or $type == 'text/css') and $src = extraire_attribut($s, 'href') and preg_match(",\\.(less\\.css|less)(\\?\\d+)?\$,", $src) and $src = preg_replace(",\\?\\d+\$,", "", $src) and $src = preg_replace(",^{$url_base},", _DIR_RACINE, $src) and file_exists($src)) { $files[$s] = $src; } } if (!count($files)) { return $head; } foreach ($files as $s => $lessfile) { $cssfile = less_css($lessfile); $m = @filemtime($cssfile); $s2 = inserer_attribut($s, "href", "{$cssfile}?{$m}"); $head = str_replace($s, $s2, $head); } return $head; }