uawdijnntqw1x1x1
IP : 216.73.216.146
Hostname : webm008.cluster111.gra.hosting.ovh.net
Kernel : Linux webm008.cluster111.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
OS : Linux
PATH:
/
home
/
bourgleram
/
www
/
c4d43
/
..
/
plugins-dist
/
..
/
.tmp
/
..
/
398a1
/
inc.tar
/
/
notes.php000066600000015263152522474730006433 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; // // Notes de bas de page // if (!defined('_NOTES_OUVRE_REF')) define('_NOTES_OUVRE_REF','<span class="spip_note_ref"> ['); if (!defined('_NOTES_FERME_REF')) define('_NOTES_FERME_REF',']</span>'); if (!defined('_NOTES_OUVRE_NOTE')) define('_NOTES_OUVRE_NOTE','<span class="spip_note_ref">['); if (!defined('_NOTES_FERME_NOTE')) define('_NOTES_FERME_NOTE','] </span>'); if (!defined('_NOTES_RACCOURCI')) define('_NOTES_RACCOURCI', ',\[\[(\s*(<([^>\'"]*)>)?(.*?))\]\],msS'); // argument = true: empiler l'etat courant, initialiser un nouvel etat // argument = false: restaurer l'etat precedent, denonce un etat courant perdu // argument chaine, on y recherche les notes et on les renvoie en tableau // argument tableau, texte de notes a rajouter dans ce qu'on a deja // le dernier cas retourne la composition totale // en particulier, envoyer un tableau vide permet de tout recuperer // C'est stocke dans la globale $les_notes, mais pas besoin de le savoir function inc_notes_dist($arg,$operation='traiter', $ignorer_autobr=false) { static $pile = array(); static $next_marqueur = 1; static $marqueur = 1; global $les_notes, $compt_note, $notes_vues; switch ($operation){ case 'traiter': if (is_array($arg)) return traiter_les_notes($arg,$ignorer_autobr); else return traiter_raccourci_notes($arg, $marqueur>1?$marqueur:''); break; case 'empiler': if ($compt_note==0) // si le marqueur n'a pas encore ete utilise, on le recycle dans la pile courante array_push($pile, array(@$les_notes, @$compt_note, $notes_vues,0)); else { // sinon on le stocke au chaud, et on en cree un nouveau array_push($pile, array(@$les_notes, @$compt_note, $notes_vues,$marqueur)); $next_marqueur++; // chaque fois qu'on rempile on incremente le marqueur general $marqueur = $next_marqueur; // et on le prend comme marqueur courant } $les_notes = ''; $compt_note = 0; break; case 'depiler': #$prev_notes = $les_notes; if (strlen($les_notes)) spip_log("notes perdues"); // si le marqueur n'a pas servi, le liberer if (!strlen($les_notes) AND $marqueur==$next_marqueur) $next_marqueur--; // on redepile tout suite a une fin d'inclusion ou d'un affichage des notes list($les_notes, $compt_note, $notes_vues, $marqueur) = array_pop($pile); #$les_notes .= $prev_notes; // si pas de marqueur attribue, on le fait if (!$marqueur){ $next_marqueur++; // chaque fois qu'on rempile on incremente le marqueur general $marqueur = $next_marqueur; // et on le prend comme marqueur courant } break; case 'sauver_etat': if ($compt_note OR $marqueur>1 OR $next_marqueur>1) return array($les_notes, $compt_note, $notes_vues, $marqueur,$next_marqueur); else return ''; // rien a sauver break; case 'restaurer_etat': if ($arg AND is_array($arg)) // si qqchose a restaurer list($les_notes, $compt_note, $notes_vues, $marqueur,$next_marqueur) = $arg; break; case 'contexter_cache': if ($compt_note OR $marqueur>1 OR $next_marqueur>1) return array("$compt_note:$marqueur:$next_marqueur"); else return ''; break; case 'reset_all': // a n'utiliser qu'a fins de test if (strlen($les_notes)) spip_log("notes perdues [reset_all]"); $pile = array(); $next_marqueur = 1; $marqueur = 1; $les_notes = ''; $compt_note = 0; $notes_vues = array(); break; } } function traiter_raccourci_notes($letexte, $marqueur_notes) { global $compt_note, $notes_vues; if (strpos($letexte, '[[') === false OR !preg_match_all(_NOTES_RACCOURCI, $letexte, $m, PREG_SET_ORDER)) return array($letexte, array()); // quand il y a plusieurs series de notes sur une meme page $mn = !$marqueur_notes ? '' : ($marqueur_notes.'-'); $mes_notes = array(); foreach ($m as $r) { list($note_source, $note_all, $ref, $nom, $note_texte) = $r; // reperer une note nommee, i.e. entre chevrons // On leve la Confusion avec une balise en regardant // si la balise fermante correspondante existe // Cas pathologique: [[ <a> <a href="x">x</a>]] if (!(isset($nom) AND $ref AND ((strpos($note_texte, '</' . $nom .'>') === false) OR preg_match(",<$nom\W.*</$nom>,", $note_texte)))) { $nom = ++$compt_note; $note_texte = $note_all; } // eliminer '%' pour l'attribut id $ancre = $mn . str_replace('%','_', rawurlencode($nom)); // ne mettre qu'une ancre par appel de note (XHTML) $att = ($notes_vues[$ancre]++) ? '' : " id='nh$ancre'"; // creer le popup 'title' sur l'appel de note // propre est couteux => nettoyer_raccourcis_typo if ($title = supprimer_tags(nettoyer_raccourcis_typo($note_texte))) { $title = " title='" . couper($title,80) . "'"; } // ajouter la note aux notes precedentes if ($note_texte) { $mes_notes[]= array($ancre, $nom, $note_texte); } // dans le texte, mettre l'appel de note a la place de la note if ($nom) $nom = _NOTES_OUVRE_REF."<a href='#nb$ancre' class='spip_note' rel='footnote'$title$att>$nom</a>"._NOTES_FERME_REF; $pos = strpos($letexte, $note_source); // supprimer les ' ' ou 'nbsp;' avant un appel de note $avant = preg_replace(',( | |'.chr(194).chr(160).')+$,S', '', substr($letexte, 0, $pos)); $letexte = $avant . code_echappement($nom) . substr($letexte, $pos + strlen($note_source)); } return array($letexte, $mes_notes); } // http://code.spip.net/@traiter_les_notes function traiter_les_notes($notes,$ignorer_autobr) { $mes_notes = ''; if ($notes) { $title = _T('info_notes'); foreach ($notes as $r) { list($ancre, $nom, $texte) = $r; $atts = " href='#nh$ancre' class='spip_note' title='$title $ancre' rev='footnote'"; $mes_notes .= "\n\n" . "<div id='nb$ancre'><p". ($GLOBALS['class_spip'] ? " class='spip_note'" : "") .">" . code_echappement($nom ? _NOTES_OUVRE_NOTE."<a".$atts.">$nom</a>"._NOTES_FERME_NOTE : '') . trim($texte) .'</div>'; } if ($ignorer_autobr) $mes_notes = _AUTOBR_IGNORER.$mes_notes; $mes_notes = propre($mes_notes); } return ($GLOBALS['les_notes'] .= $mes_notes); } ?> autoliens.php000066600000003422152522474730007300 0ustar00<?php // Les URLs brutes sont converties en <a href='url'>url</a> // http://code.spip.net/@traiter_raccourci_liens function tw_autoliens($t) { defined('_EXTRAIRE_LIENS') || define('_EXTRAIRE_LIENS', ',' . '\[[^\[\]]*(?:<-|->).*?\]' . '|<a\b.*?</a\b' . '|<\w.*?>' . '|((?:https?:/|www\.)[^"\'\s\[\]\}\)<>]*)' .',imsS'); $t = preg_replace_callback(_EXTRAIRE_LIENS, 'tw_traiter_autoliens', $t); include_spip('inc/ressource'); if (defined('_EXTRAIRE_RESSOURCES')) $t = preg_replace_callback(_EXTRAIRE_RESSOURCES, 'traiter_ressources', $t); // echapper les autoliens eventuellement inseres (en une seule fois) if (strpos($t,"<html>")!==false) $t = echappe_html($t); return $t; } // callback pour la fonction autoliens() // http://code.spip.net/@autoliens_callback function tw_traiter_autoliens($r) { if (count($r)<2) return reset($r); list($tout, $l) = $r; if (!$l) return $tout; // reperer le protocole if (preg_match(',^(https?):/*,S', $l, $m)) { $l = substr($l, strlen($m[0])); $protocol = $m[1]; } else $protocol = 'http'; // valider le nom de domaine if (!preg_match(_EXTRAIRE_DOMAINE, $l)) return $tout; // les ponctuations a la fin d'une URL n'en font certainement pas partie // en particulier le "|" quand elles sont dans un tableau a la SPIP preg_match('/^(.*?)([,.;?|]?)$/', $l, $k); $url = $protocol.'://'.$k[1]; $lien = charger_fonction('lien', 'inc'); // deux fois <html> car inc_lien echappe un coup et restaure ensuite // => un perd 1 <html> $r = $lien($url,"<html><html>$url</html></html>",'','','','nofollow') . $k[2]; // ajouter la class auto $r = inserer_attribut($r, 'class', trim(extraire_attribut($r,'class').' auto')); // si l'original ne contenait pas le 'http:' on le supprime du clic return ($m ? $r : str_replace('>http://', '>', $r)); } ?>memoization-mini.php000066600000000552152522474730010563 0ustar00<?php if (!defined('_ECRIRE_INC_VERSION')) return; # memoization minimale (preferer le plugin memoization) function cache_get($key) { return @unserialize(file_get_contents(_DIR_CACHE."wheels/".$key.".txt")); } function cache_set($key, $value) { $dir = sous_repertoire(_DIR_CACHE,"wheels/"); return ecrire_fichier($dir.$key.".txt", serialize($value)); } ?> yaml-mini.php000066600000000534152522474730007172 0ustar00<?php if (!defined('_ECRIRE_INC_VERSION')) return; # yaml_decode function yaml_decode($input) { require_once dirname(__FILE__).'/../lib/yaml/sfYaml.php'; require_once dirname(__FILE__).'/../lib/yaml/sfYamlParser.php'; $yaml = new sfYamlParser(); try { return $yaml->parse($input); } catch (Exception $e) { return null; } } ?>textwheel.php000066600000007522152522474730007313 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; include_spip('engine/textwheel'); // si une regle change et rend son cache non valide // incrementer ce define au numero de commit concerne // (inconsistence entre la wheel et l'inclusion php) if (!defined('_WHEELS_VERSION')) define('_WHEELS_VERSION',68672); // // Definition des principales wheels de SPIP // if (!isset($GLOBALS['spip_wheels'])) { $GLOBALS['spip_wheels'] = array(); } // Si le tableau des raccourcis existe déjà if (!isset($GLOBALS['spip_wheels']['raccourcis']) OR !is_array($GLOBALS['spip_wheels']['raccourcis'])) $GLOBALS['spip_wheels']['raccourcis'] = array( 'spip/spip.yaml', 'spip/spip-paragrapher.yaml' ); else $GLOBALS['spip_wheels']['raccourcis'] = array_merge( array( 'spip/spip.yaml', 'spip/spip-paragrapher.yaml' ), $GLOBALS['spip_wheels']['raccourcis'] ); if (test_espace_prive ()) $GLOBALS['spip_wheels']['raccourcis'][] = 'spip/ecrire.yaml'; $GLOBALS['spip_wheels']['interdire_scripts'] = array( 'spip/interdire-scripts.yaml' ); $GLOBALS['spip_wheels']['echappe_js'] = array( 'spip/echappe-js.yaml' ); $GLOBALS['spip_wheels']['paragrapher'] = array( 'spip/spip-paragrapher.yaml' ); $GLOBALS['spip_wheels']['listes'] = array( 'spip/spip-listes.yaml' ); // // Methode de chargement d'une wheel SPIP // class SPIPTextWheelRuleset extends TextWheelRuleSet { protected function findFile(&$file, $path=''){ static $default_path; // absolute file path? if (file_exists($file)) return $file; // file include with texwheels, relative to calling ruleset if ($path AND file_exists($f = $path.$file)) return $f; return find_in_path($file,'wheels/'); } public static function &loader($ruleset, $callback = '', $class = 'SPIPTextWheelRuleset') { # memoization # attention : le ruleset peut contenir apres loading des chemins relatifs # il faut donc que le cache depende du chemin courant vers la racine de SPIP $key = 'tw-'.md5(_WHEELS_VERSION."-".serialize($ruleset).$callback.$class._DIR_RACINE); # lecture du cache if ((!defined('_VAR_MODE') OR _VAR_MODE!='recalcul') AND $cacheruleset = tw_cache_get($key)) return $cacheruleset; # calcul de la wheel $ruleset = parent::loader($ruleset, $callback, $class); # ecriture du cache tw_cache_set($key, $ruleset); return $ruleset; } } function tw_trig_purger($quoi){ if ($quoi=='cache') purger_repertoire(_DIR_CACHE."wheels"); return $quoi; } /** * Lire une valeur en cache * memoization minimale * (utilise le plugin memoization si disponible) * * @param string $key * @return mixed */ function tw_cache_get($key) { if (function_exists('cache_get')){ return cache_get($key); } return @unserialize(file_get_contents(_DIR_CACHE."wheels/".$key.".txt")); } /** * Ecrire une valeur en cache * memoization minimale * (utilise le plugin memoization si disponible) * * @param string $key * @param mixed $value * @param int|null $ttl * @return bool */ function tw_cache_set($key, $value, $ttl=null) { if (function_exists('cache_set')){ return cache_set($key, $value, $ttl); } $dir = sous_repertoire(_DIR_CACHE,"wheels/"); return ecrire_fichier($dir.$key.".txt", serialize($value)); } ressource.php000066600000002122152522474730007303 0ustar00<?php /* * transforme un raccourci de ressource en un lien minimaliste * * */ define('_EXTRAIRE_RESSOURCES', ',' . '<"?(https?://|[^\s][\w -]+\.[\w -]+)[^<]*>'.',UimsS'); function traiter_ressources($r) { $html = null; if ($ressource = charger_fonction('ressource', 'inc', true)) { $html = $ressource($r[0]); } if (is_null($html)) { include_spip('inc/lien'); $url = explode(' ', trim($r[0], '<>')); $url = $url[0]; # <http://url/absolue> if (preg_match(',^https?://,i', $url)) $html = PtoBR(propre("<span class='ressource spip_out'><[->".$url."]></span>")); # <url/relative> else if (false !== strpos($url, '/')) $html = PtoBR(propre("<span class='ressource spip_in'><[->".$url."]></span>")); # <fichier.rtf> else { preg_match(',\.([^.]+)$,', $url, $regs); if (file_exists($f = _DIR_IMG.$regs[1].'/'.$url)) { $html = PtoBR(propre("<span class='ressource spip_in'><[".$url."->".$f."]></span>")); } else { $html = PtoBR(propre("<span class='ressource'><".$url."></span>")); } } } return '<html>'.$html.'</html>'; } ?> lien.php000066600000054521152522474730006232 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * * * * JYG : surcharge du plugin textwheel pour validation w3c * * * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('base/abstract_sql'); // // Production de la balise A+href a partir des raccourcis [xxx->url] etc. // Note : complique car c'est ici qu'on applique typo(), // et en plus on veut pouvoir les passer en pipeline // function inc_lien_dist($lien, $texte='', $class='', $title='', $hlang='', $rel='', $connect='', $env=array()) { static $u=null; if (!$u) $u=url_de_base(); $typo = false; // Si une langue est demandee sur un raccourci d'article, chercher // la traduction ; // - [{en}->art2] => traduction anglaise de l'article 2, sinon art 2 // - [{}->art2] => traduction en langue courante de l'art 2, sinon art 2 // s'applique a tout objet traduit if ($hlang AND $match = typer_raccourci($lien)) { @list($type,,$id,,$args,,$ancre) = $match; $trouver_table = charger_fonction('trouver_table', 'base'); $desc = $trouver_table(table_objet($type, $connect),$connect); if ($desc AND $id_table_objet = $desc['key']['PRIMARY KEY']) { $table_objet_sql = $desc['table']; if ($row=sql_fetsel('*', $table_objet_sql, "$id_table_objet=".intval($id)) AND isset($row['id_trad']) AND isset($row['lang']) AND $id_dest = sql_getfetsel($id_table_objet, $table_objet_sql,"id_trad=".intval($row['id_trad'])." AND lang=" . sql_quote($hlang)) AND objet_test_si_publie($type,$id_dest) ) $lien = "$type$id_dest"; else $hlang = ''; } else $hlang = ''; } $mode = ($texte AND $class) ? 'url' : 'tout'; $lien = calculer_url($lien, $texte, $mode, $connect); if ($mode === 'tout') { $texte = $lien['titre']; if (!$class AND isset($lien['class'])) $class = $lien['class']; $lang = isset($lien['lang']) ?$lien['lang'] : ''; $mime = isset($lien['mime']) ? " type='".$lien['mime']."'" : ""; $lien = $lien['url']; } $lien = trim($lien); if (strncmp($lien,"#",1) == 0) # ancres pures (internes a la page) $class = 'spip_ancre'; elseif (strncasecmp($lien,'mailto:',7)==0) # pseudo URL de mail $class = "spip_mail"; elseif (strncmp($texte,'<html>',6)==0) # cf traiter_lien_explicite $class = "spip_url spip_out"; elseif (!$class) $class = "spip_out"; # si pas spip_in|spip_glossaire // Si l'objet n'est pas de la langue courante, on ajoute hreflang if (!$hlang AND $lang!==$GLOBALS['spip_lang']) $hlang = $lang; $lang = ($hlang ? " hreflang='$hlang'" : ''); if ($title) $title = ' title="'.attribut_html($title).'"'; else $title = ''; // $title peut etre 'false' // rel=external pour les liens externes if ((strncmp($lien,'http://',7)==0 OR strncmp($lien,'https://',8)==0) AND strncmp("$lien/", $u ,strlen($u))!=0) $rel = trim("$rel external"); if ($rel) $rel = " rel='$rel'"; // si pas de modele dans le texte du lien, on peut juste passer typo sur le texte, c'est plus rapide // les rares cas de lien qui encapsule un modele passe en dessous, c'est plus lent if (traiter_modeles($texte, false, '', $connect, null, $env)==$texte){ $texte = typo($texte, true, $connect, $env); $lien = "<a href=\"".str_replace('"', '"', $lien)."\" class='$class'$lang$title$rel".(isset($mime)?$mime:'').">$texte</a>"; return $lien; } # ceci s'execute heureusement avant les tableaux et leur "|". # Attention, le texte initial est deja echappe mais pas forcement # celui retourne par calculer_url. # Penser au cas [<imgXX|right>->URL], qui exige typo('<a>...</a>') $lien = "<a href=\"".str_replace('"', '"', $lien)."\" class='$class'$lang$title$rel$mime>$texte</a>"; $res = typo($lien, true, $connect, $env); // dans ce cas, echapons le resultat du modele pour que propre etc ne viennent pas pouicher le html $res = echappe_html("<html>$res</html>"); return $res; } // Regexp des raccourcis, aussi utilisee pour la fusion de sauvegarde Spip // Laisser passer des paires de crochets pour la balise multi // mais refuser plus d'imbrications ou de mauvaises imbrications // sinon les crochets ne peuvent plus servir qu'a ce type de raccourci define('_RACCOURCI_LIEN', "/\[([^][]*?([[][^]>-]*[]][^][]*)*)->(>?)([^]]*)\]/msS"); // http://code.spip.net/@expanser_liens function expanser_liens($t, $connect='', $env=array()) { $t = pipeline('pre_liens', $t); expanser_un_lien($connect,'init', $env); if (strpos($t, '->') !== false) $t = preg_replace_callback (_RACCOURCI_LIEN, 'expanser_un_lien',$t); // on passe a traiter_modeles la liste des liens reperes pour lui permettre // de remettre le texte d'origine dans les parametres du modele $t = traiter_modeles($t, false, false, $connect, expanser_un_lien('','sources'), $env); $t = corriger_typo($t); $t = expanser_un_lien($t,'reinsert'); return $t; } function expanser_un_lien($reg, $quoi='echappe', $env=null){ static $pile = array(); static $inserts; static $sources; static $regs; static $k = 0; static $lien; static $connect=''; static $contexte = array(); switch ($quoi){ case 'init': if (!$lien) $lien = charger_fonction('lien', 'inc'); if (!is_null($env)) $contexte = $env; array_push($pile,array($inserts,$sources,$regs,$connect,$k)); $inserts = $sources = $regs = array(); $connect = $reg; // stocker le $connect pour les appels a inc_lien_dist $k=0; return; break; case 'echappe': $inserts[$k] = '@@SPIP_ECHAPPE_LIEN_' . $k . '@@'; $sources[$k] = $reg[0]; #$titre=$reg[1]; list($titre, $bulle, $hlang) = traiter_raccourci_lien_atts($reg[1]); $r = end($reg); // la mise en lien automatique est passee par la a tort ! // corrigeons pour eviter d'avoir un <a...> dans un href... if (strncmp($r,'<a',2)==0){ $href = extraire_attribut($r, 'href'); // remplacons dans la source qui peut etre reinjectee dans les arguments // d'un modele $sources[$k] = str_replace($r,$href,$sources[$k]); // et prenons le href comme la vraie url a linker $r = $href; } $regs[$k] = $lien($r, $titre, '', $bulle, $hlang, '', $connect, $contexte); return $inserts[$k++]; break; case 'reinsert': if (count($inserts)) $reg = str_replace($inserts, $regs, $reg); list($inserts,$sources,$regs,$connect,$k) = array_pop($pile); return $reg; break; case 'sources': return array($inserts, $sources); break; } } // Meme analyse mais pour eliminer les liens // et ne laisser que leur titre, a expliciter si ce n'est fait // http://code.spip.net/@nettoyer_raccourcis_typo function nettoyer_raccourcis_typo($texte, $connect='') { $texte = pipeline('nettoyer_raccourcis_typo',$texte); if (preg_match_all(_RACCOURCI_LIEN, $texte, $regs, PREG_SET_ORDER)) include_spip('inc/texte'); foreach ($regs as $reg) { list ($titre,,)= traiter_raccourci_lien_atts($reg[1]); if (!$titre) { $match = typer_raccourci($reg[count($reg)-1]); @list($type,,$id,,,,) = $match; if ($type) { $url = generer_url_entite($id,$type,'','',true); if (is_array($url)) list($type, $id) = $url; $titre = traiter_raccourci_titre($id, $type, $connect); } $titre = $titre ? $titre['titre'] : $match[0]; } $titre = corriger_typo(supprimer_tags($titre)); $texte = str_replace($reg[0], $titre, $texte); } // supprimer les ancres $texte = preg_replace(_RACCOURCI_ANCRE,"",$texte); // supprimer les notes $texte = preg_replace(",[[][[]([^]]|[]][^]])*[]][]],UimsS","",$texte); // supprimer les codes typos $texte = str_replace(array('}','{'), '', $texte); // supprimer les tableaux $texte = preg_replace(",(^|\r)\|.*\|\r,s", "\r", $texte); return $texte; } // Repere dans la partie texte d'un raccourci [texte->...] // la langue et la bulle eventuelles : [texte|title{lang}->...] // accepte un niveau de paire de crochets dans le texte : // [texte[]|title{lang}->...] // mais refuse // [texte[|title{lang}->...] // pour ne pas confondre avec un autre raccourci define('_RACCOURCI_ATTRIBUTS', '/^((?:[^[]*?(?:\[[^]]*\])?)*?)([|]([^<>]*?))?([{]([a-z_]*)[}])?$/'); // http://code.spip.net/@traiter_raccourci_lien_atts function traiter_raccourci_lien_atts($texte) { $bulle = $hlang = false; // title et hreflang donnes par le raccourci ? if (strpbrk($texte, "|{") !== false AND preg_match(_RACCOURCI_ATTRIBUTS, $texte, $m)) { $n =count($m); // |infobulle ? if ($n > 2) { $bulle = $m[3]; // {hreflang} ? if ($n > 4) { // si c'est un code de langue connu, on met un hreflang if (traduire_nom_langue($m[5]) <> $m[5]) { $hlang = $m[5]; } elseif (!$m[5]) { $hlang = test_espace_prive() ? $GLOBALS['lang_objet'] : $GLOBALS['spip_lang']; // sinon c'est un italique } else { $m[1] .= $m[4]; } // S'il n'y a pas de hreflang sous la forme {}, ce qui suit le | // est peut-etre une langue } else if (preg_match('/^[a-z_]+$/', $m[3])) { // si c'est un code de langue connu, on met un hreflang // mais on laisse le title (c'est arbitraire tout ca...) if (traduire_nom_langue($m[3]) <> $m[3]) { $hlang = $m[3]; } } } $texte = $m[1]; } return array(trim($texte), $bulle, $hlang); } define('_EXTRAIRE_DOMAINE', '/^(?:(?:[^\W_]((?:[^\W_]|-){0,61}[^\W_,])?\.)+[a-z0-9]{2,6}|localhost)\b/Si'); define('_RACCOURCI_CHAPO', '/^(\W*)(\W*)(\w*\d+([?#].*)?)$/'); /** * Fonction pour les champs virtuels de redirection qui peut etre: * 1. un raccourci Spip habituel (premier If) [texte->TYPEnnn] * 2. un ultra raccourci TYPEnnn voire nnn (article) (deuxieme If) * 3. une URL std * * renvoie l'url reelle de redirection si le $url=true, * l'url brute contenue dans le chapo sinon * * http://code.spip.net/@chapo_redirige * * @param string $virtuel * @param bool $url * @return string */ function virtuel_redirige($virtuel, $url=false){ if (!strlen($virtuel)) return ''; if (!preg_match(_RACCOURCI_LIEN, $virtuel, $m)) if (!preg_match(_RACCOURCI_CHAPO, $virtuel, $m)) return $virtuel; return !$url ? $m[3] : traiter_lien_implicite($m[3]); } // Cherche un lien du type [->raccourci 123] // associe a une fonction generer_url_raccourci() definie explicitement // ou implicitement par le jeu de type_urls courant. // // Valeur retournee selon le parametre $pour: // 'tout' : tableau d'index url,class,titre,lang (vise <a href="U" class='C' hreflang='L'>T</a>) // 'titre': seulement T ci-dessus (i.e. le TITRE ci-dessus ou dans table SQL) // 'url': seulement U (i.e. generer_url_RACCOURCI) // http://code.spip.net/@calculer_url function calculer_url ($ref, $texte='', $pour='url', $connect='', $echappe_typo = true) { $r = traiter_lien_implicite($ref, $texte, $pour, $connect, $echappe_typo); $r = ($r ? $r : traiter_lien_explicite($ref, $texte, $pour, $connect, $echappe_typo)); return $r; } define('_EXTRAIRE_LIEN', ",^\s*(http:?/?/?|mailto:?)\s*$,iS"); // http://code.spip.net/@traiter_lien_explicite function traiter_lien_explicite ($ref, $texte='', $pour='url', $connect='', $echappe_typo = true) { if (preg_match(_EXTRAIRE_LIEN, $ref)) return ($pour != 'tout') ? '' : array('','','',''); $lien = entites_html(trim($ref)); // Liens explicites if (!$texte) { $texte = str_replace('"', '', $lien); static $lien_court; // evite l'affichage de trop longues urls. if (!$lien_court) $lien_court = charger_fonction('lien_court', 'inc'); $texte = $lien_court($texte); if ($echappe_typo){ $texte = "<html>".quote_amp($texte)."</html>"; } } // petites corrections d'URL if (preg_match('/^www\.[^@]+$/S',$lien)) $lien = "http://".$lien; else if (strpos($lien, "@") && email_valide($lien)) { if (!$texte) $texte = $lien; $lien = "mailto:".$lien; } if ($pour == 'url') return $lien; if ($pour == 'titre') return $texte; return array('url' => $lien, 'titre' => $texte); } function liens_implicite_glose_dist($texte,$id,$type,$args,$ancre,$connect=''){ if ( ($ancre AND function_exists($f = 'glossaire_' . $ancre)) OR function_exists($f = 'glossaire_')) $url = $f($texte, $id, $ancre); else $url = glossaire_std($texte); return $url; } /** * Transformer un lien raccourci art23 en son URL * Par defaut la fonction produit une url prive si on est dans le prive * ou publique si on est dans le public. * La globale lien_implicite_cible_public permet de forcer un cas ou l'autre : * $GLOBALS['lien_implicite_cible_public'] = true; * => tous les liens raccourcis pointent vers le public * $GLOBALS['lien_implicite_cible_public'] = false; * => tous les liens raccourcis pointent vers le prive * unset($GLOBALS['lien_implicite_cible_public']); * => retablit le comportement automatique * * http://code.spip.net/@traiter_lien_implicite * * @param string $ref * @param string $texte * @param string $pour * @param string $connect * @return array|bool|string */ function traiter_lien_implicite ($ref, $texte='', $pour='url', $connect='') { $cible = ($connect ? $connect : (isset($GLOBALS['lien_implicite_cible_public'])?$GLOBALS['lien_implicite_cible_public']:null)); if (!($match = typer_raccourci($ref))) return false; @list($type,,$id,,$args,,$ancre) = $match; # attention dans le cas des sites le lien doit pointer non pas sur # la page locale du site, mais directement sur le site lui-meme $url = ''; if ($f = charger_fonction("implicite_$type","liens",true)) $url = $f($texte,$id,$type,$args,$ancre,$connect); if (!$url) $url = generer_url_entite($id,$type,$args,$ancre,$cible); if (!$url) return false; if (is_array($url)) { @list($type,$id) = $url; $url = generer_url_entite($id,$type,$args,$ancre,$cible); } if ($pour === 'url') return $url; $r = traiter_raccourci_titre($id, $type, $connect); if ($r) $r['class'] = ($type == 'site')?'spip_out':'spip_in'; if ($texte = trim($texte)) $r['titre'] = $texte; if (!@$r['titre']) $r['titre'] = _T($type) . " $id"; if ($pour=='titre') return $r['titre']; $r['url'] = $url; // dans le cas d'un lien vers un doc, ajouter le type='mime/type' if ($type == 'document' AND $mime = sql_getfetsel('mime_type', 'spip_types_documents', "extension IN (".sql_get_select("extension","spip_documents","id_document=".sql_quote($id)).")", '','','','',$connect) ) $r['mime'] = $mime; return $r; } // analyse des raccourcis issus de [TITRE->RACCOURCInnn] et connexes define('_RACCOURCI_URL', '/^\s*(\w*?)\s*(\d+)(\?(.*?))?(#([^\s]*))?\s*$/S'); // http://code.spip.net/@typer_raccourci function typer_raccourci ($lien) { if (!preg_match(_RACCOURCI_URL, $lien, $match)) return array(); $f = $match[1]; // valeur par defaut et alias historiques if (!$f) $f = 'article'; else if ($f == 'art') $f = 'article'; else if ($f == 'br') $f = 'breve'; else if ($f == 'rub') $f = 'rubrique'; else if ($f == 'aut') $f = 'auteur'; else if ($f == 'doc' OR $f == 'im' OR $f == 'img' OR $f == 'image' OR $f == 'emb') $f = 'document'; else if (preg_match('/^br..?ve$/S', $f)) $f = 'breve'; # accents :( $match[0] = $f; return $match; } // Retourne le champ textuel associe a une cle primaire, et sa langue function traiter_raccourci_titre($id, $type, $connect=NULL) { $trouver_table = charger_fonction('trouver_table', 'base'); $desc = $trouver_table(table_objet($type)); if (!($desc AND $s = $desc['titre'])) return array(); $_id = $desc['key']['PRIMARY KEY']; $r = sql_fetsel($s, $desc['table'], "$_id=$id", '','','','',$connect); if (!$r) return array(); $r['titre'] = supprimer_numero($r['titre']); if (!$r['titre']) $r['titre'] = $r['surnom']; if (!isset($r['lang'])) $r['lang'] = ''; return $r; } // traite les modeles (dans la fonction typo), en remplacant // le raccourci <modeleN|parametres> par la page calculee a // partir du squelette modeles/modele.html // Le nom du modele doit faire au moins trois caracteres (evite <h2>) // Si $doublons==true, on repere les documents sans calculer les modeles // mais on renvoie les params (pour l'indexation par le moteur de recherche) // http://code.spip.net/@traiter_modeles define('_PREG_MODELE', '(<([a-z_-]{3,})' # <modele .'\s*([0-9]*)\s*' # id .'([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>) .'\s*/?'.'>)' # fin du modele > ); define('_RACCOURCI_MODELE', _PREG_MODELE .'\s*(<\/a>)?' # eventuel </a> ); define('_RACCOURCI_MODELE_DEBUT', '@^' . _RACCOURCI_MODELE .'@isS'); // http://code.spip.net/@traiter_modeles function traiter_modeles($texte, $doublons=false, $echap='', $connect='', $liens = null, $env = array()) { // preserver la compatibilite : true = recherche des documents if ($doublons===true) $doublons = array('documents'=>array('doc','emb','img')); // 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); foreach ($matches as $match) { // Recuperer l'appel complet (y compris un eventuel lien) $a = strpos($texte,$match[0]); preg_match(_RACCOURCI_MODELE_DEBUT, substr($texte, $a), $regs); while(count($regs) < 6) $regs[] = ""; // s'assurer qu'il y a toujours un 5e arg, eventuellement vide list(,$mod, $type, $id, $params, $fin) = $regs; if ($fin AND preg_match('/<a\s[^<>]*>\s*$/i', substr($texte, 0, $a), $r)) { $lien = array( '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; $cherche = $n + strlen($regs[0]); } else { $lien = false; $cherche = strlen($mod); } // calculer le modele # hack indexation if ($doublons) $texte .= preg_replace(',[|][^|=]*,s',' ',$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 if (!is_null($liens)) $params = str_replace($liens[0], $liens[1], $params); $modele = inclure_modele($type, $id, $params, $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); if (!is_null($liens)) $modele = str_replace($liens[0], $liens[1], $modele); $contexte = array_merge($env,array('id'=>$id,'type'=>$type,'modele'=>$modele)); if ($lien) { # un eventuel guillemet (") sera reechappe par #ENV $contexte['lien'] = str_replace(""",'"', $lien['href']); $contexte['lien_class'] = $lien['class']; $contexte['lien_mime'] = $lien['mime']; $contexte['lien_title'] = $lien['title']; $contexte['lien_hreflang'] = $lien['hreflang']; } $modele = recuperer_fond("modeles/dist", $contexte, array(), $connect); } // le remplacer dans le texte if ($modele !== false) { $modele = protege_js_modeles($modele); if ($wrap_embed_html){ $modele = $wrap_embed_html($mod,$modele); } $rempl = code_echappement($modele, $echap); $texte = substr($texte, 0, $a) . $rempl . substr($texte, $a+$cherche); } } // hack pour tout l'espace prive if (((!_DIR_RESTREINT) OR ($doublons)) AND ($id)){ foreach($doublons?$doublons:array('documents'=>array('doc','emb','img')) as $quoi=>$modeles) if (in_array($type,$modeles)) $GLOBALS["doublons_{$quoi}_inclus"][] = $id; } } } return $texte; } // // Raccourcis ancre [#ancre<-] // define('_RACCOURCI_ANCRE', "/\[#?([^][]*)<-\]/S"); // http://code.spip.net/@traiter_raccourci_ancre function traiter_raccourci_ancre($letexte) { if (preg_match_all(_RACCOURCI_ANCRE, $letexte, $m, PREG_SET_ORDER)) foreach ($m as $regs) $letexte = str_replace($regs[0], // Pour validation w3c HTML5 (warning sur l'attribut "name" obsolete pour la balise <a>) // '<a name="'.entites_html($regs[1]).'"></a>', $letexte); /* JYG suppression */ '<a id="'.entites_html($regs[1]).'"></a>', $letexte); /* JYG ajout */ return $letexte; } // // Raccourcis automatiques [?SPIP] vers un glossaire // Wikipedia par defaut, avec ses contraintes techniques // cf. http://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Conventions_sur_les_titres define('_RACCOURCI_GLOSSAIRE', "/\[\?+\s*([^][<>]+)\]/S"); define('_RACCOURCI_GLOSES', '/^([^|#{]*\w[^|#{]*)([^#]*)(#([^|{}]*))?(.*)$/S'); // http://code.spip.net/@traiter_raccourci_glossaire function traiter_raccourci_glossaire($texte) { if (!preg_match_all(_RACCOURCI_GLOSSAIRE, $texte, $matches, PREG_SET_ORDER)) return $texte; include_spip('inc/charsets'); $lien = charger_fonction('lien', 'inc'); foreach ($matches as $regs) { // Eviter les cas particulier genre "[?!?]" // et isoler le lexeme a gloser de ses accessoires // (#:url du glossaire, | bulle d'aide, {} hreflang) // Transformation en pseudo-raccourci pour passer dans inc_lien if (preg_match(_RACCOURCI_GLOSES, $regs[1], $r)) { preg_match('/^(.*?)(\d*)$/', $r[4], $m); $_n = intval($m[2]); $gloss = $m[1] ? ('#' . $m[1]) : ''; $t = $r[1] . $r[2] . $r[5]; list($t, $bulle, $hlang) = traiter_raccourci_lien_atts($t); if ($bulle===false) $bulle = $m[1]; $t = unicode2charset(charset2unicode($t), 'utf-8'); $ref = $lien("glose$_n$gloss", $t, 'spip_glossaire', $bulle, $hlang); $texte = str_replace($regs[0], $ref, $texte); } } return $texte; } // http://code.spip.net/@glossaire_std function glossaire_std($terme) { global $url_glossaire_externe; static $pcre = NULL; if ($pcre === NULL) { $pcre = isset($GLOBALS['meta']['pcre_u']) ? $GLOBALS['meta']['pcre_u'] : ''; if (strpos($url_glossaire_externe, "%s") === false) $url_glossaire_externe .= '%s'; } $glosateur = str_replace("@lang@", $GLOBALS['spip_lang'], $GLOBALS['url_glossaire_externe']); $terme = rawurlencode(preg_replace(',\s+,'.$pcre, '_', $terme)); return str_replace("%s", $terme, $glosateur); } ?> texte.php000066600000043371152522474730006435 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('inc/texte_mini'); include_spip('inc/lien'); include_spip('inc/textwheel'); defined('_AUTOBR')||define('_AUTOBR', "<br class='autobr' />"); define('_AUTOBR_IGNORER', _AUTOBR?"<!-- ig br -->":""); // Avec cette surcharge, cette globale n'est plus définie, et du coup ça plante dans les plugins qui font un foreach dessus comme ZPIP $GLOBALS['spip_raccourcis_typo'] = array(); if (!isset($GLOBALS['toujours_paragrapher'])) $GLOBALS['toujours_paragrapher'] = true; // class_spip : savoir si on veut class="spip" sur p i strong & li // class_spip_plus : class="spip" sur les ul ol h3 hr quote table... // la difference c'est que des css specifiques existent pour les seconds // if (!isset($GLOBALS['class_spip'])) $GLOBALS['class_spip'] = ''; if (!isset($GLOBALS['class_spip_plus'])) $GLOBALS['class_spip_plus'] = ' class="spip"'; /** * echapper les < script ... * * @param string $t * @return string */ function echappe_js($t) { static $wheel = null; if (!isset($wheel)) $wheel = new TextWheel( SPIPTextWheelRuleset::loader($GLOBALS['spip_wheels']['echappe_js']) ); return $wheel->text($t); } /** * paragrapher seulement * * @param string $t * @param null $toujours_paragrapher * @return string */ function paragrapher($t, $toujours_paragrapher = null) { static $wheel = array(); if (is_null($toujours_paragrapher)) $toujours_paragrapher = $GLOBALS['toujours_paragrapher']; if (!isset($wheel[$toujours_paragrapher])) { $ruleset = SPIPTextWheelRuleset::loader($GLOBALS['spip_wheels']['paragrapher']); if (!$toujours_paragrapher AND $rule=$ruleset->getRule('toujours-paragrapher')) { $rule->disabled = true; $ruleset->addRules(array('toujours-paragrapher'=>$rule)); } $wheel[$toujours_paragrapher] = new TextWheel($ruleset); } return $wheel[$toujours_paragrapher]->text($t); } /** * Securite : empecher l'execution de code PHP, en le transformant en joli code * dans l'espace prive, cette fonction est aussi appelee par propre et typo * si elles sont appelees en direct * il ne faut pas desactiver globalement la fonction dans l'espace prive car elle protege * aussi les balises des squelettes qui ne passent pas forcement par propre ou typo apres * * http://code.spip.net/@interdire_scripts * * @param string $arg * @return string */ function interdire_scripts($arg) { // on memorise le resultat sur les arguments non triviaux static $dejavu = array(); static $wheel = array(); // Attention, si ce n'est pas une chaine, laisser intact if (!$arg OR !is_string($arg) OR !strstr($arg, '<')) return $arg; if (isset($dejavu[$GLOBALS['filtrer_javascript']][$arg])) return $dejavu[$GLOBALS['filtrer_javascript']][$arg]; if (!isset($wheel[$GLOBALS['filtrer_javascript']])){ $ruleset = SPIPTextWheelRuleset::loader( $GLOBALS['spip_wheels']['interdire_scripts'] ); // Pour le js, trois modes : parano (-1), prive (0), ok (1) // desactiver la regle echappe-js si besoin if ($GLOBALS['filtrer_javascript']==1 OR ($GLOBALS['filtrer_javascript']==0 AND !test_espace_prive())) $ruleset->addRules (array('securite-js'=>array('disabled'=>true))); $wheel[$GLOBALS['filtrer_javascript']] = new TextWheel($ruleset); } $t = $wheel[$GLOBALS['filtrer_javascript']]->text($arg); // Reinserer les echappements des modeles if (defined('_PROTEGE_JS_MODELES')) $t = echappe_retour($t,"javascript"._PROTEGE_JS_MODELES); if (defined('_PROTEGE_PHP_MODELES')) $t = echappe_retour($t,"php"._PROTEGE_PHP_MODELES); return $dejavu[$GLOBALS['filtrer_javascript']][$arg] = $t; } /** * Typographie generale * avec protection prealable des balises HTML et SPIP * * http://code.spip.net/@typo * * @param string $letexte * @param bool $echapper * @param null $connect * @param array $env * @return string */ function typo($letexte, $echapper=true, $connect=null, $env=array()) { // Plus vite ! if (!$letexte) return $letexte; // les appels directs a cette fonction depuis le php de l'espace // prive etant historiquement ecrit sans argment $connect // on utilise la presence de celui-ci pour distinguer les cas // ou il faut passer interdire_script explicitement // les appels dans les squelettes (de l'espace prive) fournissant un $connect // ne seront pas perturbes $interdire_script = false; if (is_null($connect)){ $connect = ''; $interdire_script = true; } $echapper = ($echapper?'TYPO':false); // Echapper les codes <html> etc if ($echapper) $letexte = echappe_html($letexte, $echapper); // // Installer les modeles, notamment images et documents ; // // NOTE : propre() ne passe pas par ici mais directement par corriger_typo // cf. inc/lien $letexte = traiter_modeles($mem = $letexte, false, $echapper ? $echapper : '', $connect, null, $env); if (!$echapper AND $letexte != $mem) $echapper = ''; unset($mem); $letexte = corriger_typo($letexte); $letexte = echapper_faux_tags($letexte); // reintegrer les echappements if ($echapper!==false) $letexte = echappe_retour($letexte, $echapper); // Dans les appels directs hors squelette, securiser ici aussi if ($interdire_script) $letexte = interdire_scripts($letexte); return $letexte; } // Correcteur typographique define('_TYPO_PROTEGER', "!':;?~%-"); define('_TYPO_PROTECTEUR', "\x1\x2\x3\x4\x5\x6\x7\x8"); define('_TYPO_BALISE', ",</?[a-z!][^<>]*[".preg_quote(_TYPO_PROTEGER)."][^<>]*>,imsS"); /** * http://code.spip.net/@corriger_typo * * @param string $t * @param string $lang * @return string */ function corriger_typo($t, $lang='') { static $typographie = array(); // Plus vite ! if (!$t) return $t; $t = pipeline('pre_typo', $t); // Caracteres de controle "illegaux" $t = corriger_caracteres($t); // Proteger les caracteres typographiques a l'interieur des tags html if (preg_match_all(_TYPO_BALISE, $t, $regs, PREG_SET_ORDER)) { foreach ($regs as $reg) { $insert = $reg[0]; // hack: on transforme les caracteres a proteger en les remplacant // par des caracteres "illegaux". (cf corriger_caracteres()) $insert = strtr($insert, _TYPO_PROTEGER, _TYPO_PROTECTEUR); $t = str_replace($reg[0], $insert, $t); } } // trouver les blocs multi et les traiter a part $t = extraire_multi($e = $t, $lang, true); $e = ($e === $t); // Charger & appliquer les fonctions de typographie $idxl = "$lang:" . (isset($GLOBALS['lang_objet'])? $GLOBALS['lang_objet']: $GLOBALS['spip_lang']); if (!isset($typographie[$idxl])) $typographie[$idxl] = charger_fonction(lang_typo($lang), 'typographie'); $t = $typographie[$idxl]($t); // Les citations en une autre langue, s'il y a lieu if (!$e) $t = echappe_retour($t, 'multi'); // Retablir les caracteres proteges $t = strtr($t, _TYPO_PROTECTEUR, _TYPO_PROTEGER); // pipeline $t = pipeline('post_typo', $t); # un message pour abs_url - on est passe en mode texte $GLOBALS['mode_abs_url'] = 'texte'; return $t; } // // Tableaux // define('_RACCOURCI_TH_SPAN', '\s*(:?{{[^{}]+}}\s*)?|<'); /** * http://code.spip.net/@traiter_tableau * * @param sring $bloc * @return string */ function traiter_tableau($bloc) { // id "unique" pour les id du tableau $tabid = substr(md5($bloc),0,4); // Decouper le tableau en lignes preg_match_all(',([|].*)[|]\n,UmsS', $bloc, $regs, PREG_PATTERN_ORDER); $lignes = array(); $debut_table = $summary = ''; $l = 0; $numeric = true; // Traiter chaque ligne $reg_line1 = ',^(\|(' . _RACCOURCI_TH_SPAN . '))+$,sS'; $reg_line_all = ',^(' . _RACCOURCI_TH_SPAN . ')$,sS'; $hc = $hl = array(); foreach ($regs[1] as $ligne) { $l ++; // Gestion de la premiere ligne : if ($l == 1) { // - <caption> et summary dans la premiere ligne : // || caption | summary || (|summary est optionnel) if (preg_match(',^\|\|([^|]*)(\|(.*))?$,sS', rtrim($ligne,'|'), $cap)) { $l = 0; if ($caption = trim($cap[1])) $debut_table .= "<caption>".$caption."</caption>\n"; $summary = ' summary="'.entites_html(trim($cap[3])).'"'; } // - <thead> sous la forme |{{titre}}|{{titre}}| // Attention thead oblige a avoir tbody else if (preg_match($reg_line1, $ligne, $thead)) { preg_match_all('/\|([^|]*)/S', $ligne, $cols); $ligne='';$cols= $cols[1]; $colspan=1; for($c=count($cols)-1; $c>=0; $c--) { $attr=''; if($cols[$c]=='<') { $colspan++; } else { if($colspan>1) { $attr= " colspan='$colspan'"; $colspan=1; } // inutile de garder le strong qui n'a servi que de marqueur $cols[$c] = str_replace(array('{','}'), '', $cols[$c]); $ligne= "<th id='id{$tabid}_c$c'$attr>$cols[$c]</th>$ligne"; $hc[$c] = "id{$tabid}_c$c"; // pour mettre dans les headers des td } } $debut_table .= "<thead><tr class='row_first'>". $ligne."</tr></thead>\n"; $l = 0; } } // Sinon ligne normale if ($l) { // Gerer les listes a puce dans les cellules // on declenche simplement sur \n- car il y a les // -* -# -? -! (qui produisent des - !) if (strpos($ligne,"\n-")!==false) $ligne = traiter_listes($ligne); // tout mettre dans un tableau 2d preg_match_all('/\|([^|]*)/S', $ligne, $cols); // Pas de paragraphes dans les cellules foreach ($cols[1] as &$col) { if (strlen($col = trim($col))) { $col = preg_replace("/\n{2,}/S", "<br /> <br />", $col); if (_AUTOBR) $col = str_replace("\n", _AUTOBR."\n", $col); } } // assembler le tableau $lignes[]= $cols[1]; } } // maintenant qu'on a toutes les cellules // on prepare une liste de rowspan par defaut, a partir // du nombre de colonnes dans la premiere ligne. // Reperer egalement les colonnes numeriques pour les cadrer a droite $rowspans = $numeric = array(); $n = count($lignes[0]); $k = count($lignes); // distinguer les colonnes numeriques a point ou a virgule, // pour les alignements eventuels sur "," ou "." $numeric_class = array('.'=>'point',','=>'virgule'); for($i=0;$i<$n;$i++) { $align = true; for ($j=0;$j<$k;$j++) { $rowspans[$j][$i] = 1; if ($align AND preg_match('/^[+-]?(?:\s|\d)*([.,]?)\d*$/', trim($lignes[$j][$i]), $r)){ if ($r[1]) $align = $r[1]; } else $align = ''; } $numeric[$i] = $align ? (" class='numeric ".$numeric_class[$align]."'") : ''; } for ($j=0;$j<$k;$j++) { if (preg_match($reg_line_all, $lignes[$j][0])) { $hl[$j] = "id{$tabid}_l$j"; // pour mettre dans les headers des td } else unset($hl[0]); } if (!isset($hl[0])) $hl = array(); // toute la colonne ou rien // et on parcourt le tableau a l'envers pour ramasser les // colspan et rowspan en passant $html = ''; for($l=count($lignes)-1; $l>=0; $l--) { $cols= $lignes[$l]; $colspan=1; $ligne=''; for($c=count($cols)-1; $c>=0; $c--) { $attr= $numeric[$c]; $cell = trim($cols[$c]); if($cell=='<') { $colspan++; } elseif($cell=='^') { $rowspans[$l-1][$c]+=$rowspans[$l][$c]; } else { if($colspan>1) { $attr .= " colspan='$colspan'"; $colspan=1; } if(($x=$rowspans[$l][$c])>1) { $attr.= " rowspan='$x'"; } $b = ($c==0 AND isset($hl[$l]))?'th':'td'; $h = (isset($hc[$c])?$hc[$c]:'').' '.(($b=='td' AND isset($hl[$l]))?$hl[$l]:''); if ($h=trim($h)) $attr.=" headers='$h'"; // inutile de garder le strong qui n'a servi que de marqueur if ($b=='th') { $attr.=" id='".$hl[$l]."'"; $cols[$c] = str_replace(array('{','}'), '', $cols[$c]); } $ligne= "\n<$b".$attr.'>'.$cols[$c]."</$b>".$ligne; } } // ligne complete $class = alterner($l+1, 'odd', 'even'); $html = "<tr class='row_$class $class'>$ligne</tr>\n$html"; } return "\n\n<table".$GLOBALS['class_spip_plus'].$summary.">\n" . $debut_table . "<tbody>\n" . $html . "</tbody>\n" . "</table>\n\n"; } /** * Traitement des listes * on utilise la wheel correspondante * * http://code.spip.net/@traiter_listes * * @param string $t * @return string */ function traiter_listes ($t) { static $wheel = null; if (!isset($wheel)) $wheel = new TextWheel( SPIPTextWheelRuleset::loader($GLOBALS['spip_wheels']['listes']) ); return $wheel->text($t); } // Ces deux constantes permettent de proteger certains caracteres // en les remplacanat par des caracteres "illegaux". (cf corriger_caracteres) define('_RACCOURCI_PROTEGER', "{}_-"); define('_RACCOURCI_PROTECTEUR', "\x1\x2\x3\x4"); define('_RACCOURCI_BALISE', ",</?[a-z!][^<>]*[".preg_quote(_RACCOURCI_PROTEGER)."][^<>]*>,imsS"); /** * mais d'abord, une callback de reconfiguration des raccourcis * a partir de globales (est-ce old-style ? on conserve quand meme * par souci de compat ascendante) * * @param $ruleset */ function personnaliser_raccourcis(&$ruleset){ if (isset($GLOBALS['debut_intertitre']) AND $rule=$ruleset->getRule('intertitres')){ $rule->replace[0] = preg_replace(',<[^>]*>,Uims',$GLOBALS['debut_intertitre'],$rule->replace[0]); $rule->replace[1] = preg_replace(',<[^>]*>,Uims',$GLOBALS['fin_intertitre'],$rule->replace[1]); $ruleset->addRules(array('intertitres'=>$rule)); } if (isset($GLOBALS['debut_gras']) AND $rule=$ruleset->getRule('gras')){ $rule->replace[0] = preg_replace(',<[^>]*>,Uims',$GLOBALS['debut_gras'],$rule->replace[0]); $rule->replace[1] = preg_replace(',<[^>]*>,Uims',$GLOBALS['fin_gras'],$rule->replace[1]); $ruleset->addRules(array('gras'=>$rule)); } if (isset($GLOBALS['debut_italique']) AND $rule=$ruleset->getRule('italiques')){ $rule->replace[0] = preg_replace(',<[^>]*>,Uims',$GLOBALS['debut_italique'],$rule->replace[0]); $rule->replace[1] = preg_replace(',<[^>]*>,Uims',$GLOBALS['fin_italique'],$rule->replace[1]); $ruleset->addRules(array('italiques'=>$rule)); } if (isset($GLOBALS['ligne_horizontale']) AND $rule=$ruleset->getRule('ligne-horizontale')){ $rule->replace = preg_replace(',<[^>]*>,Uims',$GLOBALS['ligne_horizontale'],$rule->replace); $ruleset->addRules(array('ligne-horizontale'=>$rule)); } if (isset($GLOBALS['toujours_paragrapher']) AND !$GLOBALS['toujours_paragrapher'] AND $rule=$ruleset->getRule('toujours-paragrapher')) { $rule->disabled = true; $ruleset->addRules(array('toujours-paragrapher'=>$rule)); } } /** * Nettoie un texte, traite les raccourcis autre qu'URL, la typo, etc. * * http://code.spip.net/@traiter_raccourcis * * @param string $t * @param bool $show_autobr * @return string */ function traiter_raccourcis($t, $show_autobr = false) { static $wheel, $notes; static $img_br_auto,$img_br_manuel,$img_br_no; // hack1: respecter le tag ignore br if (_AUTOBR_IGNORER AND strncmp($t, _AUTOBR_IGNORER, strlen(_AUTOBR_IGNORER))==0) { $ignorer_autobr = true; $t = substr($t, strlen(_AUTOBR_IGNORER)); } else $ignorer_autobr = false; // Appeler les fonctions de pre_traitement $t = pipeline('pre_propre', $t); if (!isset($wheel)) { $ruleset = SPIPTextWheelRuleset::loader( $GLOBALS['spip_wheels']['raccourcis'],'personnaliser_raccourcis' ); $wheel = new TextWheel($ruleset); if (_request('var_mode') == 'wheel' AND autoriser('debug')) { $f = $wheel->compile(); echo "<pre>\n".spip_htmlspecialchars($f)."</pre>\n"; exit; } $notes = charger_fonction('notes', 'inc'); } // Gerer les notes (ne passe pas dans le pipeline) list($t, $mes_notes) = $notes($t); $t = $wheel->text($t); // Appeler les fonctions de post-traitement $t = pipeline('post_propre', $t); if ($mes_notes) $notes($mes_notes,'traiter',$ignorer_autobr); // hack2: wrap des autobr dans l'espace prive, pour affichage css // car en css on ne sait pas styler l'element BR if ($ignorer_autobr AND _AUTOBR) { if (is_null($img_br_no)) $img_br_no = ($show_autobr?http_img_pack("br-no-10.png",_T("tw:retour_ligne_ignore"),"class='br-no'",_T("tw:retour_ligne_ignore")):""); $t = str_replace(_AUTOBR, $img_br_no, $t); } if ($show_autobr AND _AUTOBR) { if (is_null($img_br_manuel)) $img_br_manuel = http_img_pack("br-manuel-10.png",_T("tw:retour_ligne_manuel"),"class='br-manuel'",_T("tw:retour_ligne_manuel")); if (is_null($img_br_auto)) $img_br_auto = http_img_pack("br-auto-10.png",_T("tw:retour_ligne_auto"),"class='br-auto'",_T("tw:retour_ligne_auto")); if (false !== strpos(strtolower($t), '<br')) { $t = preg_replace("/<br\b.*>/UiS", "$img_br_manuel\\0", $t); $t = str_replace($img_br_manuel._AUTOBR, $img_br_auto._AUTOBR, $t); } } return $t; } /** * Filtre a appliquer aux champs du type #TEXTE* * http://code.spip.net/@propre * * @param string $t * @param string $connect * @param array $env * @return string */ function propre($t, $connect=null, $env=array()) { // les appels directs a cette fonction depuis le php de l'espace // prive etant historiquement ecrits sans argment $connect // on utilise la presence de celui-ci pour distinguer les cas // ou il faut passer interdire_script explicitement // les appels dans les squelettes (de l'espace prive) fournissant un $connect // ne seront pas perturbes $interdire_script = false; if (is_null($connect) AND test_espace_prive()){ $connect = ''; $interdire_script = true; } if (!$t) return strval($t); $t = pipeline('pre_echappe_html_propre', $t); $t = echappe_html($t); $t = expanser_liens($t,$connect, $env); $t = traiter_raccourcis($t, (isset($env['wysiwyg']) AND $env['wysiwyg'])?true:false); $t = echappe_retour_modeles($t, $interdire_script); return $t; } ?> forum_insert.php000066600000013157152522475200010010 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; include_spip('inc/forum'); include_spip('inc/filtres'); include_spip('inc/actions'); // Ce fichier est inclus par dist/formulaires/forum.php // http://code.spip.net/@mots_du_forum function mots_du_forum($ajouter_mot, $id_message) { include_spip('action/editer_mot'); mot_associer($ajouter_mot, array('forum'=>$id_message)); } // http://code.spip.net/@tracer_erreur_forum function tracer_erreur_forum($type='') { spip_log("erreur forum ($type): ".print_r($_POST, true)); define('_TRACER_ERREUR_FORUM', false); if (_TRACER_ERREUR_FORUM) { $envoyer_mail = charger_fonction('envoyer_mail','inc'); $envoyer_mail($GLOBALS['meta']['email_webmaster'], "erreur forum ($type)", "erreur sur le forum ($type) :\n\n". '$_POST = '.print_r($_POST, true)."\n\n". '$_SERVER = '.print_r($_SERVER, true)); } } /** * Un parametre permet de forcer le statut (exemple: plugin antispam) * * http://code.spip.net/@inc_forum_insert_dist * * @param $objet * @param $id_objet * @param $id_forum * en reponse a * @param null $force_statut * @return bool */ function inc_forum_insert_dist($objet, $id_objet, $id_forum, $force_statut = NULL) { if (!in_array($force_statut,array('privrac','privadm'))){ if (!strlen($objet) OR !intval($id_objet)){ spip_log("Erreur insertion forum sur objet='$objet', id_objet=$id_objet",'forum.'. _LOG_ERREUR); return 0; } } spip_log("insertion de forum $force_statut sur $objet $id_objet (+$id_forum)", 'forum'); include_spip('inc/filtres'); include_spip('inc/modifier'); $champs = objet_info('forum','champs_editables'); $c = collecter_requests($champs, array()); $c['statut'] = 'off'; $c['objet'] = $objet; $c['id_objet'] = $id_objet; $c['auteur'] = sinon($GLOBALS['visiteur_session']['nom'], $GLOBALS['visiteur_session']['session_nom']); $c['email_auteur'] = sinon($GLOBALS['visiteur_session']['email'], $GLOBALS['visiteur_session']['session_email']); $c = pipeline('pre_edition',array( 'args'=>array( 'table' => 'spip_forum', 'id_objet' => $id_forum, 'action'=>'instituer' ), 'data'=>forum_insert_statut($c, $force_statut) )); $id_reponse = forum_insert_base($c, $id_forum, $objet, $id_objet, $c['statut'], _request('ajouter_mot')); if (!$id_reponse) spip_log("Echec insertion forum sur $objet $id_objet (+$id_forum)", 'forum.'._LOG_ERREUR); else spip_log("forum insere' $id_reponse sur $objet $id_objet (+$id_forum)", 'forum'); return $id_reponse; } // http://code.spip.net/@forum_insert_base function forum_insert_base($c, $id_forum, $objet, $id_objet, $statut, $ajouter_mot = false) { if (!in_array($statut,array('privrac','privadm'))){ // si le statut est vide, c'est qu'on ne veut pas de ce presume spam ! if (!$statut OR !$objet OR !$id_objet){ $args = func_get_args(); spip_log("Erreur sur forum_insert_base ".var_export($args,1),'forum.'. _LOG_ERREUR); return false; } } // Entrer le message dans la base $id_reponse = sql_insertq('spip_forum', array( 'date_heure'=> date('Y-m-d H:i:s'), 'ip' => $GLOBALS['ip'], 'id_auteur' => $GLOBALS['visiteur_session']['id_auteur'] )); if ($id_reponse){ if ($id_forum>0) { $id_thread = sql_getfetsel("id_thread", "spip_forum", "id_forum =".intval($id_forum)); } else $id_thread = $id_reponse; # id_thread oblige INSERT puis UPDATE. // Entrer les cles sql_updateq('spip_forum', array('id_parent' => $id_forum, 'objet' => $objet, 'id_objet' => $id_objet, 'id_thread' => $id_thread, 'statut' => $statut), "id_forum=".intval($id_reponse)); // Entrer les mots-cles associes if ($ajouter_mot) mots_du_forum($ajouter_mot, $id_reponse); // // Entree du contenu et invalidation des caches // include_spip('action/editer_forum'); revision_forum($id_reponse, $c); // Ajouter un document if (isset($_FILES['ajouter_document']) AND $_FILES['ajouter_document']['tmp_name']) { $files[] = array('tmp_name'=>$_FILES['ajouter_document']['tmp_name'],'name'=>$_FILES['ajouter_document']['name']); $ajouter_documents = charger_fonction('ajouter_documents','action'); $ajouter_documents( 'new', $files, 'forum', $id_reponse, 'document'); // supprimer le temporaire et ses meta donnees spip_unlink($_FILES['ajouter_document']['tmp_name']); spip_unlink(preg_replace(',\.bin$,', '.txt', $_FILES['ajouter_document']['tmp_name'])); } // Notification $quoi = (strncmp($statut,'priv',4)==0?'forumprive':'forumposte'); if ($notifications = charger_fonction('notifications', 'inc')) $notifications($quoi, $id_reponse); } return $id_reponse; } // http://code.spip.net/@forum_insert_statut function forum_insert_statut($champs, $forcer_statut=NULL) { include_spip('inc/forum'); $statut = controler_forum($champs['objet'], $champs['id_objet']); if ($forcer_statut !== NULL) $champs['statut'] = $forcer_statut; else $champs['statut'] = ($statut == 'non') ? 'off' : (($statut == 'pri') ? 'prop' : 'publie'); return $champs; } ?> article_accepter_forums_publics.php000066600000001113152522475200013666 0ustar00<?php if (!defined("_ECRIRE_INC_VERSION")) return; /** * Moderation des forums specifique a un article * @param int $id_objet identifiant de l'article * @return string : "non", "pos"(teriori), "pri"(ori), "abo"(nnement) */ function inc_article_accepter_forums_publics_dist($id_objet) { $accepter_forum = $GLOBALS['meta']["forums_publics"]; $art_accepter_forum = sql_getfetsel('accepter_forum', 'spip_articles', array( "id_article = ". intval($id_objet) )); if ($art_accepter_forum) { $accepter_forum = $art_accepter_forum; } return substr($accepter_forum, 0, 3); } ?> email_notification_forum.php000066600000010134152522475200012331 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; /** * 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') # forum prive { if ($t['id_objet']) $url = generer_url_entite($t['id_objet'], $t['objet'], '', 'forum'.$id_forum, false); } else if ($t['statut'] == 'privrac') # forum general { $url = generer_url_ecrire('forum').'#forum'.$id_forum; } else if ($t['statut'] == 'privadm') # forum des admins { $url = generer_url_ecrire('forum','quoi=admin').'#forum'.$id_forum; } else if ($t['statut'] == 'publie') # forum publie { $url = generer_url_entite($id_forum, 'forum', '', 'forum'.$id_forum, true); } else # forum modere, spam, poubelle direct .... { $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; } forum.php000066600000022727152522475200006427 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; include_spip('inc/actions'); /** * recuperer le critere SQL qui selectionne nos forums * http://code.spip.net/@critere_statut_controle_forum * * @param string $type * @param int|array $id_secteur * @param string $recherche * @return array */ function critere_statut_controle_forum($type, $id_secteur=0, $recherche='') { if (!$id_secteur) { $from = 'spip_forum AS F'; $where = ""; $and = ""; } else { if (!is_array($id_secteur)){ $id_secteur = explode(',',$id_secteur); } $from = 'spip_forum AS F, spip_articles AS A'; $where = sql_in("A.id_secteur",$id_secteur)." AND F.objet='article' AND F.id_objet=A.id_article"; $and = ' AND '; } switch ($type) { case 'public': $and .= "F.statut IN ('publie', 'off', 'prop', 'spam') AND F.texte!=''"; break; case 'prop': $and .= "F.statut='prop'"; break; case 'spam': $and .= "F.statut='spam'"; break; case 'interne': $and .= "F.statut IN ('prive', 'privrac', 'privoff', 'privadm') AND F.texte!=''"; break; case 'vide': $and .= "F.statut IN ('publie', 'off', 'prive', 'privrac', 'privoff', 'privadm') AND F.texte=''"; break; default: $where = '0=1'; $and =''; break; } if ($recherche) { # recherche par IP if (preg_match(',^\d+\.\d+\.(\*|\d+\.(\*|\d+))$,', $recherche)) { $and .= " AND ip LIKE ".sql_quote(str_replace('*', '%', $recherche)); } else { include_spip('inc/rechercher'); if ($a = recherche_en_base($recherche, 'forum')) $and .= " AND ".sql_in('id_forum', array_keys(array_pop($a))); else $and .= " AND 0=1"; } } return array($from, "$where$and"); } // Index d'invalidation des forums // obsolete, remplace par l'appel systematique a 2 invalideurs : // - forum/id_forum // - objet/id_objet // http://code.spip.net/@calcul_index_forum function calcul_index_forum($objet,$id_objet) { return substr($objet,0,1).$id_objet; } // // Recalculer tous les threads // // http://code.spip.net/@calculer_threads function calculer_threads() { // fixer les id_thread des debuts de discussion sql_update('spip_forum', array('id_thread'=>'id_forum'), "id_parent=0"); // reparer les messages qui n'ont pas l'id_secteur de leur parent do { $discussion = "0"; $precedent = 0; $r = sql_select("fille.id_forum AS id, maman.id_thread AS thread", 'spip_forum AS fille, spip_forum AS maman', "fille.id_parent = maman.id_forum AND fille.id_thread <> maman.id_thread",'', "thread"); while ($row = sql_fetch($r)) { if ($row['thread'] == $precedent) $discussion .= "," . $row['id']; else { if ($precedent) sql_updateq("spip_forum", array("id_thread" => $precedent), "id_forum IN ($discussion)"); $precedent = $row['thread']; $discussion = $row['id']; } } sql_updateq("spip_forum", array("id_thread" => $precedent), "id_forum IN ($discussion)"); } while ($discussion != "0"); } // Calculs des URLs des forums (pour l'espace public) // http://code.spip.net/@racine_forum function racine_forum($id_forum){ if (!$id_forum = intval($id_forum)) return false; $row = sql_fetsel("id_parent, objet, id_objet, id_thread", "spip_forum", "id_forum=".$id_forum); if (!$row) return false; if ($row['id_parent'] AND $row['id_thread'] != $id_forum) // eviter boucle infinie return racine_forum($row['id_thread']); return array($row['objet'], $row['id_objet'], $id_forum); } // http://code.spip.net/@parent_forum function parent_forum($id_forum) { if (!$id_forum = intval($id_forum)) return; $row = sql_fetsel("id_parent, objet, id_objet", "spip_forum", "id_forum=".$id_forum); if(!$row) return array(); if ($row['id_parent']) return array('forum', $row['id_parent']); else return array($row['objet'], $row['id_objet']); } /** * Pour compatibilite : remplacer les appels par son contenu * * @param unknown_type $id_forum * @param unknown_type $args * @param unknown_type $ancre * @return unknown */ function generer_url_forum_dist($id_forum, $args='', $ancre='') { $generer_url_forum = charger_fonction('generer_url_forum','urls'); return $generer_url_forum($id_forum, $args, $ancre); } // http://code.spip.net/@generer_url_forum_parent function generer_url_forum_parent($id_forum) { if ($id_forum = intval($id_forum)) { list($type, $id) = parent_forum($id_forum); if ($type) return generer_url_entite($id, $type); } return ''; } // Quand on edite un forum, on tient a conserver l'original // sous forme d'un forum en reponse, de statut 'original' // http://code.spip.net/@conserver_original function conserver_original($id_forum) { $s = sql_fetsel("id_forum", "spip_forum", "id_parent=".intval($id_forum)." AND statut='original'"); if ($s) return ''; // pas d'erreur // recopier le forum $t = sql_fetsel("*", "spip_forum", "id_forum=".intval($id_forum)); if ($t) { unset($t['id_forum']); $id_copie = sql_insertq('spip_forum', $t); if ($id_copie) { sql_updateq('spip_forum', array('id_parent'=> $id_forum, 'statut'=>'original'), "id_forum=$id_copie"); return ''; // pas d'erreur } } return '&erreur'; } // appelle conserver_original(), puis modifie le contenu via l'API inc/modifier // http://code.spip.net/@enregistre_et_modifie_forum function enregistre_et_modifie_forum($id_forum, $c=false) { if ($err = conserver_original($id_forum)) { spip_log("erreur de sauvegarde de l'original, $err"); return; } include_spip('action/editer_forum'); return revision_forum($id_forum, $c); } /** * Trouver le titre d'un objet publie * @param string $objet * @param int $id_objet * @param int $id_forum * @param bool $publie * @return bool|string */ function forum_recuperer_titre_dist($objet, $id_objet, $id_forum=0, $publie = true) { include_spip('inc/filtres'); $titre = ""; if ($f = charger_fonction($objet.'_forum_extraire_titre', 'inc', true)){ $titre = $f($id_objet); } else { include_spip('base/objets'); if ($publie AND !objet_test_si_publie($objet, $id_objet)) return false; $titre = generer_info_entite($id_objet, $objet,'titre','*'); } if ($titre AND $id_forum){ $titre_m = sql_getfetsel('titre', 'spip_forum', "id_forum = " . intval($id_forum)); if (!$titre_m) { return false; // URL fabriquee } $titre = $titre_m; } $titre = supprimer_numero($titre); $titre = str_replace('~', ' ', extraire_multi($titre)); return $titre; } /** * Retourne pour un couple objet/id_objet donne * de quelle maniere les forums sont acceptes dessus * non: pas de forum * pos: a posteriori, acceptes et eventuellements moderes ensuite * pri: a priori, doivent etre valides par un admin * abo: les personnes doivent au prealable etre identifiees * * http://code.spip.net/@controler_forum * * @param string $objet * objet a tester * @param int $id_objet * identifiant de l'objet * @return string * chaine de 3 caractere parmi 'non','pos','pri','abo' */ function controler_forum($objet, $id_objet) { // Valeur par defaut $accepter_forum = $GLOBALS['meta']["forums_publics"]; // il y a un cas particulier pour l'acceptation de forum d'article... if ($f = charger_fonction($objet . '_accepter_forums_publics', 'inc', true)){ $accepter_forum = $f($id_objet); } return substr($accepter_forum, 0, 3); } /** * Verifier la presence du jeton de secu post previsu * http://code.spip.net/@forum_insert_noprevisu * @return bool */ function forum_insert_noprevisu(){ // simuler une action venant de l'espace public // pour se conformer au cas general. set_request('action', 'ajout_forum'); // Creer une session s'il n'y en a pas (cas du postage sans cookie) $securiser_action = charger_fonction('securiser_action', 'inc'); $arg = $securiser_action(); $file = _DIR_TMP ."forum_" . preg_replace('/[^0-9]/', '', $arg) .".lck"; if (!file_exists($file)) { # ne pas tracer cette erreur, peut etre due a un double POST # tracer_erreur_forum('session absente'); return true; } unlink($file); // antispam : si le champ au nom aleatoire verif_$hash n'est pas 'ok' // on meurt if (_request('verif_'._request('hash')) != 'ok') { tracer_erreur_forum('champ verif manquant'); return true; } return false; } /** * recuperer tous les objets dont on veut pouvoir obtenir l'identifiant * directement dans l'environnement * * @return array */ function forum_get_objets_depuis_env() { static $objets = null; if ($objets === null) { // on met une cle (le type d'objet) pour qu'un appel du pipeline // puisse facilement soustraire un objet qu'il ne veut pas avec // unset($objets['rubrique']) par exemple. $objets = pipeline('forum_objets_depuis_env', array( 'article' => id_table_objet('article'), 'rubrique' => id_table_objet('rubrique'), 'site' => id_table_objet('site'), 'breve' => id_table_objet('breve') )); asort($objets); } return $objets; } // http://code.spip.net/@reduce_strlen function reduce_strlen($n, $c) { return $n - (is_string($c) ? strlen($c) : 0); } ?>syndic.php000066600000040473152522550620006566 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; // ATTENTION // Cette inclusion charge executer_une_syndication pour compatibilite, // mais cette fonction ne doit plus etre invoquee directement: // il faut passer par cron() pour avoir un verrou portable // Voir un exemple dans action/editer/site include_spip('genie/syndic'); // prend un fichier backend et retourne un tableau des items lus, // et une chaine en cas d'erreur // http://code.spip.net/@analyser_backend 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; // atom 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'); if (!defined('_SYNDICATION_MAX_ITEMS')) define('_SYNDICATION_MAX_ITEMS',1000); $nb_items = 0; foreach ($items as $item) { $data = array(); if ($nb_items++>_SYNDICATION_MAX_ITEMS){ break; } // 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]; // contourner les redirections feedburner else if (_SYNDICATION_DEREFERENCER_URL AND preg_match(',<feedburner:origLink>(.*)<,Uims', $item, $regs)) $data['url'] = $regs[1]; // <link>, plus classique 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'); // Aucun link ni guid, mais une enclosure else if (preg_match(',<enclosure[^>]*>,ims', $item, $regs) AND $url = extraire_attribut($regs[0], 'url')) $data['url'] = $url; // pas d'url, c'est genre un compteur... 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) // pas dans le futur 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); # array() 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); // si on demande un dereferencement de l'URL, il faut verifier que ce n'est pas une redirection if (_SYNDICATION_DEREFERENCER_URL){ $target = $data['url']; include_spip("inc/distant"); for ($i = 0; $i<10; $i++){ // on fait un GET et pas un HEAD car les vieux SPIP ne repondent pas la redirection avec un HEAD (honte) sur un article virtuel $res = recuperer_lapage($target, false, "GET", 4096); if (!$res) break; // c'est pas bon signe car on a pas trouve l'URL... if (is_array($res)) break; // on a trouve la page, donc on a l'URL finale $target = $res; // c'est une redirection, on la suit pour voir ou elle mene } // ici $target est l'URL finale de la page $data['url'] = $target; } // 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; } // helas strtotime ne reconnait pas le format W3C // http://www.w3.org/TR/NOTE-datetime // http://code.spip.net/@my_strtotime function my_strtotime($la_date, $lang=null) { // format complet if (preg_match( ',^(\d+-\d+-\d+[T ]\d+:\d+(:\d+)?)(\.\d+)?' .'(Z|([-+]\d{2}):\d+)?$,', $la_date, $match)) { $la_date = str_replace("T", " ", $match[1])." GMT"; return strtotime($la_date) - intval($match[5]) * 3600; } // YYYY if (preg_match(',^\d{4}$,', $la_date, $match)) return strtotime($match[0]."-01-01"); // YYYY-MM if (preg_match(',^\d{4}-\d{2}$,', $la_date, $match)) return strtotime($match[0]."-01"); // YYYY-MM-DD hh:mm:ss if (preg_match(',^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\b,', $la_date, $match)) return strtotime($match[0]); // utiliser strtotime en dernier ressort // en nettoyant le jour qui prefixe parfois la date, suivi d'une virgule // et les UT qui sont en fait des UTC $la_date_c = preg_replace("/^\w+,\s*/ms","",$la_date); $la_date_c = preg_replace("/UT\s*$/ms","UTC",$la_date_c); if ($s=strtotime($la_date) OR $s=strtotime($la_date_c)) return $s; // essayons de voir si le nom du mois est dans la langue du flux et remplacons le // par la version anglaise avant de faire strtotime if ($lang){ // "fr-fr" list($lang) = explode("-", $lang); static $months = null; if (!isset($months[$lang])){ $prev_lang = $GLOBALS['spip_lang']; changer_langue($lang); foreach(range(1,12) as $m){ $s = _T("date_mois_$m"); $months[$lang][$s] = date("M",strtotime("2013-$m-01")); $s = _T("date_mois_".$m."_abbr"); $months[$lang][$s] = date("M",strtotime("2013-$m-01")); $months[$lang][trim($s,".")] = date("M",strtotime("2013-$m-01")); } changer_langue($prev_lang); } spip_log($la_date_c,"dbgs"); foreach($months[$lang] as $loc=>$en){ if (stripos($la_date_c,$loc)!==false){ $s=str_ireplace($loc,$en,$la_date_c); if ($s=strtotime($s)) return $s; } } } // erreur spip_log("Impossible de lire le format de date '$la_date'"); return false; } // A partir d'un <dc:subject> ou autre essayer de recuperer // le mot et son url ; on cree <a href="url" rel="tag">mot</a> // http://code.spip.net/@creer_tag function creer_tag($mot,$type,$url) { if (!strlen($mot = trim($mot))) return ''; $mot = "<a rel=\"tag\">$mot</a>"; if ($url) $mot = inserer_attribut($mot, 'href', $url); if ($type) $mot = inserer_attribut($mot, 'rel', $type); return $mot; } // http://code.spip.net/@ajouter_tags function ajouter_tags($matches, $item) { include_spip('inc/filtres'); $tags = array(); foreach ($matches as $match) { $type = ($match[3] == 'category' OR $match[3] == 'directory') ? 'directory':'tag'; $mot = supprimer_tags($match[0]); if (!strlen($mot) AND !strlen($mot = extraire_attribut($match[0], 'label'))) break; // rechercher un url if ($url = extraire_attribut($match[0], 'domain')) { // category@domain est la racine d'une url qui se prolonge // avec le contenu text du tag <category> ; mais dans SPIP < 2.0 // on donnait category@domain = #URL_RUBRIQUE, et // text = #TITRE_RUBRIQUE ; d'ou l'heuristique suivante sur le slash if (substr($url, -1) == '/') $url .= rawurlencode($mot); } else if ($url = extraire_attribut($match[0], 'resource') OR $url = extraire_attribut($match[0], 'url') ) {} ## cas particuliers else if (extraire_attribut($match[0], 'scheme') == 'urn:flickr:tags') { foreach(explode(' ', $mot) as $petit) if ($t = creer_tag($petit, $type, 'http://www.flickr.com/photos/tags/'.rawurlencode($petit).'/')) $tags[] = $t; $mot = ''; } else if ( // cas atom1, a faire apres flickr $term = extraire_attribut($match[0], 'term') ) { if ($scheme = extraire_attribut($match[0], 'scheme')) $url = suivre_lien($scheme,$term); else $url = $term; } else { # type delicious.com foreach(explode(' ', $mot) as $petit) if (preg_match(',<rdf\b[^>]*\bresource=["\']([^>]*/' .preg_quote(rawurlencode($petit),',').')["\'],i', $item, $m)) { $mot = ''; if ($t = creer_tag($petit, $type, $m[1])) $tags[] = $t; } } if ($t = creer_tag($mot, $type, $url)) $tags[] = $t; } return $tags; } // Lit contenu des blocs [[CDATA]] dans un flux // http://code.spip.net/@cdata_echappe_retour function cdata_echappe(&$rss, &$echappe_cdata) { $echappe_cdata = array(); if (preg_match_all(',<!\[CDATA\[(.*)]]>,Uims', $rss, $regs, PREG_SET_ORDER)) { foreach ($regs as $n => $reg) { if (strpos($reg[1],'<')!==false or strpos($reg[1],'>')!==false) { // verifier que la chaine est encore dans le flux, car on peut avoir X fois la meme // inutile de (sur)peupler le tableau avec des substitutions identiques if (strpos($rss,$reg[0])!==false){ $echappe_cdata["@@@SPIP_CDATA$n@@@"] = $reg[1]; $rss = str_replace($reg[0], "@@@SPIP_CDATA$n@@@", $rss); } } else $rss = str_replace($reg[0], $reg[1], $rss); } } } // Retablit le contenu des blocs [[CDATA]] dans une chaine ou un tableau // http://code.spip.net/@cdata_echappe_retour function cdata_echappe_retour(&$x, &$echappe_cdata) { if (is_string($x)) { if (strpos($x, '<') !== false){ $x = filtrer_entites($x); } if (strpos($x, '@@@SPIP_CDATA') !== false){ $x = str_replace( array_keys($echappe_cdata), array_values($echappe_cdata), $x); } } else if (is_array($x)) { foreach($x as $k => &$v) cdata_echappe_retour($v, $echappe_cdata); } } ?> feedfinder.php000066600000015410152522550620007361 0ustar00<?php /** * adaptation en php de feedfinder.py : * * """Ultra-liberal feed finder, de Mark Pilgrim * <http://diveintomark.org/projects/feed_finder/> * Par: courcy.michael@wanadoo.fr * * adaptation en php, je ne reprends qu'une partie de cette algorithme * * 0) A chaque etape on verifie si les feed indiques sont reellement des feeds * 1) Si l'uri passe est un feed on retourne le resultat tout simplement * 2) Si le header de la page contient des balises LINK qui renvoient vers des feed on les retourne * 3) on cherche les liens <a> qui se termine par ".rss", ".rdf", ".xml", ou ".atom" * 4) on cherche les liens <a> contenant "rss", "rdf", "xml", ou "atom" * * j'integre pas l'interrogation avec xml_rpc de syndic8, mais on peut le faire assez facilement * dans la phase de test sur differentes url je n'ai constate aucune diffrerence entre les reponses * donnees par feedfinder.py et les miennes donc je ne suis pas sur de voir l'interet * * Je ne me preoccupe pas comme l'auteur de savoir si mes liens de feed sont sur le meme serveur ou pas * * exemple d'utilisation * * print_r (get_feed_from_url("http://willy.boerland.com/myblog/")); * * on obtient * * Array * ( * [0] => http://willy.boerland.com/myblog/atom/feed * [1] => http://willy.boerland.com/myblog/blogapi/rsd * [2] => http://willy.boerland.com/myblog/rss.xml * [3] => http://willy.boerland.com/myblog/node/feed * ) */ if (!defined('_ECRIRE_INC_VERSION')) return; $verif_complete = 0; //mettez le a 1 si vous voulez controler la validite des feed trouves mais le temps d'execution //est alors plus long /** * une fonction qui permet de si un lien est un feed ou nom, * si c'est un feed elle retourne son type, si c'est pas un feed elle retourne 0, * cette verification est évidemment très très légère * * @param string $url * URL à analyser * @return string|0 * Retourne son type (rss|atom|rdf) ou 0 si pas feed */ function is_feed($url){ /** * méthode SPIP */ if (function_exists('recuperer_page')) { $buffer = recuperer_page($url); if (preg_match("/<(\w*) .*/", $buffer, $matches)){ //ici on detecte la premiere balise $type_feed = $matches[1]; switch ($type_feed) { case "rss": return "rss"; case "feed": return "atom"; case "rdf": return "rdf"; } } return ''; } $fp = @fopen($url, "r"); if (!$fp ) return 0; //verifion la nature de ce fichier while (!feof($fp)) { $buffer = fgets($fp, 4096); if (preg_match("/<(\w*) .*/", $buffer, $matches)){ //ici on detecte la premiere balise $type_feed = $matches[1]; switch ($type_feed) { case "rss": fclose($fp); return "rss"; case "feed": fclose($fp); return "atom"; case "rdf": fclose($fp); return "rdf"; default : fclose($fp); return 0; } } } } /*****************test is_feed****************************** echo is_feed("http://contrib.spip.net/spip.php?page=backend" _EXTENSIO_PHP") . "<br />"; //retourne rss echo is_feed("http://liberation.fr/rss.php") . "<br />"; //retourne rss echo is_feed("http://liberation.fr/rss.php") . "<br />"; //retourne rss echo is_feed("http://willy.boerland.com/myblog/atom/feed") //retourne atom echo is_feed("http://spip.net/") . "<br />"; //retoune 0 ************************************************************/ /** * 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; } /************************************ getFeed **************************** print_r (get_feed_from_url("contrib.spip.net")); print_r (get_feed_from_url("http://liberation.fr/")); print_r (get_feed_from_url("cnn.com")); print_r (get_feed_from_url("http://willy.boerland.com/myblog/")); ***************************** Resultat ***************************************** Array ( [0] => http://contrib.spip.net/backend.php ) Array ( [0] => http://www.liberation.fr/rss.php ) Array ( [0] => http://rss.cnn.com/rss/cnn_topstories.rss [1] => http://rss.cnn.com/rss/cnn_latest.rss [2] => http://www.cnn.com/services/rss/ [3] => http://www.cnn.com/services/rss/ [4] => http://www.cnn.com/services/rss/ ) Array ( [0] => http://willy.boerland.com/myblog/atom/feed [1] => http://willy.boerland.com/myblog/blogapi/rsd [2] => http://willy.boerland.com/myblog/rss.xml [3] => http://willy.boerland.com/myblog/node/feed ) ************************************************************************/ ?>site.php000066600000010500152522550620006225 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; // http://code.spip.net/@analyser_site 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; } ?> quete_calendrier.php000066600000021733152522552200010602 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('inc/filtres'); // http://code.spip.net/@calendrier_categories function calendrier_categories($table, $num, $objet) { if (function_exists('generer_calendrier_class')) return generer_calendrier_class($table, $num, $objet); else { // cf agenda.css $num= sql_getfetsel((($objet != 'id_breve') ? 'id_secteur' : 'id_rubrique') . " AS id", $table, "$objet=$num"); return 'calendrier-couleur' . (($num%14)+1); } } // ici on prend en fait le jour, la veille et le lendemain // http://code.spip.net/@quete_calendrier_jour function quete_calendrier_jour($annee,$mois,$jour) { $avant = "'" . date("Y-m-d", mktime(0,0,0,$mois,$jour-1,$annee)) . "'"; $apres = "'" . date("Y-m-d", mktime(1,1,1,$mois,$jour+1,$annee)) . " 23:59:59'"; return array($avant, $apres); } // retourne un tableau de 2 tableaux indexes par des dates // - le premier indique les evenements du jour, sans indication de duree // - le deuxime indique les evenements commencant ce jour, avec indication de duree // http://code.spip.net/@quete_calendrier_interval function quete_calendrier_interval($limites) { include_spip('inc/urls'); list($avant, $apres) = $limites; $evt = array(); quete_calendrier_interval_articles($avant, $apres, $evt); quete_calendrier_interval_breves($avant, $apres, $evt); quete_calendrier_interval_rubriques($avant, $apres, $evt); return array($evt, quete_calendrier_interval_rv($avant, $apres)); } // http://code.spip.net/@quete_calendrier_interval_forums function quete_calendrier_interval_forums($limites, &$evenements) { list($avant, $apres) = $limites; $result=sql_select("DISTINCT titre, date_heure, id_forum", "spip_forum", "date_heure >= $avant AND date_heure < $apres", '', "date_heure"); while($row=sql_fetch($result)){ $amj = date_anneemoisjour($row['date_heure']); $id = $row['id_forum']; if (autoriser('voir','forum',$id)) $evenements[$amj][]= array( 'URL' => generer_url_entite($id, 'forum'), 'CATEGORIES' => 'calendrier-couleur7', 'SUMMARY' => $row['titre'], 'DTSTART' => date_ical($row['date_heure'])); } } # 3 fonctions retournant les evenements d'une periode # le tableau retourne est indexe par les balises du format ics # afin qu'il soit facile de produire de tels documents. # L'URL de chacun de ces evenements est celle de l'espace prive # pour faciliter la navigation, ce qu'on obtient utilisant # le 4e argument des fonctions generer_url_ecrire_$table // http://code.spip.net/@quete_calendrier_interval_articles function quete_calendrier_interval_articles($avant, $apres, &$evenements) { $result=sql_select('id_article, titre, date, descriptif, chapo, lang', 'spip_articles', "statut='publie' AND date >= $avant AND date < $apres", '', "date"); // tables traduites $objets = explode(',', $GLOBALS['meta']['multi_objets']); if (in_array('spip_articles', $objets)) { include_spip('inc/lang_liste'); $langues = $GLOBALS['codes_langues']; } else $langues = array(); while($row=sql_fetch($result)){ $amj = date_anneemoisjour($row['date']); $id = $row['id_article']; if (autoriser('voir','article',$id)) $evenements[$amj][]= array( 'CATEGORIES' => calendrier_categories('spip_articles', $id, 'id_article'), 'DESCRIPTION' => $row['descriptif'] ? $row['descriptif'] : $langues[$row['lang']], 'SUMMARY' => $row['titre'], 'URL' => generer_url_ecrire_objet('article',$id, '','','prop')); } } // http://code.spip.net/@quete_calendrier_interval_rubriques function quete_calendrier_interval_rubriques($avant, $apres, &$evenements) { $result=sql_select('DISTINCT R.id_rubrique, titre, descriptif, date', 'spip_rubriques AS R, spip_documents_liens AS L', "statut='publie' AND date >= $avant AND date < $apres AND R.id_rubrique = L.id_objet AND L.objet='rubrique'",'', "date"); while($row=sql_fetch($result)){ $amj = date_anneemoisjour($row['date']); $id = $row['id_rubrique']; if (autoriser('voir','rubrique',$id)) $evenements[$amj][]= array( 'CATEGORIES' => calendrier_categories('spip_rubriques', $id, 'id_rubrique'), 'DESCRIPTION' => $row['descriptif'], 'SUMMARY' => $row['titre'], 'URL' => generer_url_ecrire_objet('rubrique',$id, '','', 'prop')); } } // http://code.spip.net/@quete_calendrier_interval_breves function quete_calendrier_interval_breves($avant, $apres, &$evenements) { $result=sql_select("id_breve, titre, date_heure, id_rubrique", 'spip_breves', "statut='publie' AND date_heure >= $avant AND date_heure < $apres", '', "date_heure"); while($row=sql_fetch($result)){ $amj = date_anneemoisjour($row['date_heure']); $id = $row['id_breve']; $ir = $row['id_rubrique']; if (autoriser('voir','breve',$id)) $evenements[$amj][]= array( 'URL' => generer_url_ecrire_objet('breve',$id, '','', 'prop'), 'CATEGORIES' => calendrier_categories('spip_breves', $ir, 'id_breve'), 'SUMMARY' => $row['titre']); } } // http://code.spip.net/@quete_calendrier_interval_rv function quete_calendrier_interval_rv($avant, $apres) { include_spip('inc/session'); $connect_id_auteur = session_get('id_auteur'); $evenements= array(); if (!$connect_id_auteur) return $evenements; $result=sql_select("M.id_message, M.titre, M.texte, M.date_heure, M.date_fin, M.type", "spip_messages AS M LEFT JOIN spip_auteurs_liens AS L ON (L.id_objet=M.id_message)", "((L.objet='message' AND (L.id_auteur=$connect_id_auteur OR M.type='affich')) OR (L.objet IS NULL AND M.id_auteur=$connect_id_auteur AND ".sql_in('M.type',array('pb','affich'))."))" ." AND M.rv='oui' AND ((M.date_fin >= $avant OR M.date_heure >= $avant) AND M.date_heure <= $apres) AND M.statut='publie'", "M.id_message", "M.date_heure"); while($row=sql_fetch($result)){ $date_heure=$row["date_heure"]; $date_fin=$row["date_fin"]; $type=$row["type"]; $id_message=$row['id_message']; if ($type=="pb") $cat = 'calendrier-couleur2'; else { if ($type=="affich") $cat = 'calendrier-couleur4'; else { if ($type!="normal") $cat = 'calendrier-couleur12'; else { $cat = 'calendrier-couleur9'; $auteurs = array_map('array_shift', sql_allfetsel("nom", "spip_auteurs AS A LEFT JOIN spip_auteurs_liens AS L ON L.id_auteur=A.id_auteur", "(L.objet='message' AND L.id_objet=$id_message AND (A.id_auteur!=$connect_id_auteur))")); } } } $jour_avant = substr($avant, 9,2); $mois_avant = substr($avant, 6,2); $annee_avant = substr($avant, 1,4); $jour_apres = substr($apres, 9,2); $mois_apres = substr($apres, 6,2); $annee_apres = substr($apres, 1,4); $ical_apres = date_anneemoisjour("$annee_apres-$mois_apres-".sprintf("%02d",$jour_apres)); // Calcul pour les semaines a cheval sur deux mois $j = 0; $amj = date_anneemoisjour("$annee_avant-$mois_avant-".sprintf("%02d", $j+($jour_avant))); while ($amj <= $ical_apres) { if (!($amj == date_anneemoisjour($date_fin) AND preg_match(",00:00:00,", $date_fin))) // Ne pas prendre la fin a minuit sur jour precedent $evenements[$amj][$id_message]= array( 'URL' => generer_url_ecrire("message","id_message=$id_message"), 'DTSTART' => date_ical($date_heure), 'DTEND' => date_ical($date_fin), 'DESCRIPTION' => $row['texte'], 'SUMMARY' => $row['titre'], 'CATEGORIES' => $cat, 'ATTENDEE' => (count($auteurs) == 0) ? '' : join($auteurs,", ")); $j ++; $ladate = date("Y-m-d",mktime (1,1,1,$mois_avant, ($j + $jour_avant), $annee_avant)); $amj = date_anneemoisjour($ladate); } } return $evenements; } // http://code.spip.net/@quete_calendrier_agenda function quete_calendrier_agenda ($annee, $mois) { include_spip('inc/session'); $connect_id_auteur = session_get('id_auteur'); $rv = array(); if (!$connect_id_auteur) return $rv; $date = date("Y-m-d", mktime(0,0,0,$mois, 1, $annee)); $mois = mois($date); $annee = annee($date); // rendez-vous personnels dans le mois $result_messages = sql_select("M.titre AS summary, M.texte AS description, M.id_message AS uid, M.date_heure", "spip_messages AS M, spip_auteurs_liens AS L", "((L.id_auteur=$connect_id_auteur AND L.id_objet=M.id_message AND L.objet='message') OR M.type='affich') AND M.rv='oui' AND M.date_heure >='$annee-$mois-1' AND date_heure < DATE_ADD('$annee-$mois-1', INTERVAL 1 MONTH) AND M.statut='publie'"); while($row=sql_fetch($result_messages)) { $rv[journum($row['date_heure'])] = $row; } return $rv; } ?> messages.php000066600000014062152522552200007073 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('inc/filtres'); include_spip('base/abstract_sql'); if (!defined('_EMAIL_GENERAL')) define('_EMAIL_GENERAL','general'); // permet aux admin d'envoyer un email a tout le monde /** * Lister les statuts des auteurs pouvant recevoir un message * c'est tous les auteurs au moins redacteur * * @return array */ function messagerie_statuts_destinataires_possibles(){ include_spip('inc/filtres_ecrire'); return pipeline('messagerie_statuts_destinataires_possibles', auteurs_lister_statuts('redacteurs',false)); } /** * Nettoyer une liste de destinataires * @param $destinataires * @return array */ function messagerie_nettoyer_destinataires($destinataires){ foreach ($destinataires as $k=>$id){ // il se peut que l'id recupere l'ancre qui suit avec certains ie ... :( if (preg_match(',^[0-9]+#[a-z_0-9]+,',$id)) $destinataires[$k] = intval($id); } return $destinataires; } /** * Fonction generique de verification des destinataires * lors de l'envoi d'un message ou de recommander * un destinataire peut etre un id_auteur numerique * ou une adresse mail valide, si l'options accepter_email est true * * @param array $destinataires * @param array $options * @return array */ function messagerie_verifier_destinataires($destinataires,$options=array('accepter_email'=>true)){ $erreurs = array(); $destinataires = messagerie_nettoyer_destinataires($destinataires); foreach ($destinataires as $id){ if (is_numeric($id)){ if (!$id) $erreurs[] = _T('organiseur:erreur_destinataire_invalide',array('dest'=>$id)); } else { if (!$options['accepter_email'] OR !email_valide($id)) $erreurs[] = _T('organiseur:erreur_destinataire_invalide',array('dest'=>$id)); } } return $erreurs; } /** * Selectionner les destinataires en distinguant emails et id_auteur * * @param array $dests * @return array */ function messagerie_destiner($dests){ // separer les destinataires auteur des destinataires email $auteurs_dest = array(); $email_dests = array(); $dests = messagerie_nettoyer_destinataires($dests); foreach ($dests as $id){ if (is_numeric($id)) $auteurs_dest[] = $id; elseif (defined('_MESSAGERIE_EMAIL_GENERAL') AND $id!=_MESSAGERIE_EMAIL_GENERAL) $email_dests[] = $id; } if (count($email_dests)) { // retrouver les id des emails pour ceux qui sont en base $res = sql_select('id_auteur,email','spip_auteurs',sql_in('email', $email_dests)); $auteurs_dest_found = array(); while ($row = sql_fetch($res)){ $auteurs_dest_found[] = $row['id_auteur']; } $auteurs_dest = array_merge($auteurs_dest,$auteurs_dest_found); } return array($auteurs_dest,$email_dests); } /** * Diffuser un message par la messagerie interne * * @param int $id_message * @param array $auteurs_dest * @return bool|int */ function messagerie_diffuser_message($id_message, $auteurs_dest=array()){ $out = false; if ($id_message=intval($id_message) AND count($auteurs_dest)){ include_spip('action/editer_liens'); $out = objet_associer(array('auteur'=>$auteurs_dest),array('message'=>$id_message),array('vu'=>'non')); } return $out; } /** * Envoyer un message par mail pour les destinataires externes * * @param int $id_message * @param array $emails_dest * @return bool */ function messagerie_mailer_message($id_message, $emails_dest=array()){ if ($id_message=intval($id_message) AND count($emails_dest)) { if ($row = sql_fetsel('titre,texte,id_auteur','spip_messages','id_message='.intval($id_message))){ $from = sql_getfetsel('email','spip_auteurs','id_auteur='.$row['id_auteur']); foreach($emails_dest as $email) job_queue_add( 'envoyer_mail', 'messagerie mail', array($email,$row['titre'],array('texte'=>$row['texte'],'from'=>$from)), 'inc/' ); return true; } } return false; } /** * Marquer un message dans l'etat indique par $vu * * @param int $id_auteur * @param array $liste * @param string $vu * @return void */ function messagerie_marquer_message($id_auteur,$liste,$vu){ include_spip('action/editer_liens'); if (!is_array($liste)) $liste = array($liste); // completer les liens qui n'existent pas encore // ex : pour marquer lue une annonce, on ajoute le lien d'abord (n'existe pas) // puis on le marque 'oui' $liens = objet_trouver_liens(array('auteur'=>$id_auteur),array('message'=>$liste)); $l = array(); foreach($liens as $lien) $l[] = $lien['message']; objet_associer(array('auteur'=>$id_auteur),array('message'=>array_diff($liste,$l)),array('vu'=>$vu)); // puis les marquer tous lus objet_qualifier_liens(array('auteur'=>$id_auteur),array('message'=>$liste),array('vu'=>$vu)); include_spip('inc/invalideur'); suivre_invalideur("message/".implode(',',$liste)); } /** * Marquer un message comme lu * * @param int $id_auteur * @param array $liste_id_message */ function messagerie_marquer_lus($id_auteur,$liste_id_message){messagerie_marquer_message($id_auteur,$liste_id_message,'oui');} /** * Marquer un message comme non lu * * @param int $id_auteur * @param array $liste_id_message */ function messagerie_marquer_non_lus($id_auteur,$liste_id_message){messagerie_marquer_message($id_auteur,$liste_id_message,'non');} /** * Effacer un message recu * * @param int $id_auteur * @param array $liste_id_message */ function messagerie_effacer_message_recu($id_auteur,$liste_id_message){messagerie_marquer_message($id_auteur,$liste_id_message,'poub');} ?> date_gestion.php000066600000003472152522552210007735 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; /** * Recuperer les champs date_xx et heure_xx, verifier leur coherence et les reformater * * @param string $suffixe * @param bool $horaire * @param array $erreurs * @return int */ function verifier_corriger_date_saisie($suffixe,$horaire,&$erreurs){ include_spip('inc/filtres'); $date = _request("date_$suffixe").($horaire?' '.trim(_request("heure_$suffixe")).':00':''); $date = recup_date($date); if (!$date) return ''; $ret = null; if (!$ret=mktime(0,0,0,$date[1],$date[2],$date[0])) $erreurs["date_$suffixe"] = _T('organiseur:erreur_date'); elseif (!$ret=mktime($date[3],$date[4],$date[5],$date[1],$date[2],$date[0])) $erreurs["date_$suffixe"] = _T('organiseur:erreur_heure'); if ($ret){ if (trim(_request("date_$suffixe")!==($d=date('d/m/Y',$ret)))){ $erreurs["date_$suffixe"] = _T('organiseur:erreur_date_corrigee'); set_request("date_$suffixe",$d); } if ($horaire AND trim(_request("heure_$suffixe")!==($h=date('H:i',$ret)))){ $erreurs["heure_$suffixe"] = _T('organiseur:erreur_heure_corrigee'); set_request("heure_$suffixe",$h); } } return $ret; } ?>
/home/bourgleram/www/c4d43/../plugins-dist/../.tmp/../398a1/inc.tar