Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found

Cible

Sélectionner le projet cible
  • spip/spip
  • Roman/spip
  • g0uZ/spip_puce_changement_statut_rapide_sans_JS_inline
  • erational/issue_4450
  • cy.altern/spip_core
  • fa_b/spip
  • glopglop/spip
  • MathieuAlphamosa/spip
  • taffit/spip
  • claffont/spip
  • RealET/spip
  • alexis.pellicier/spip
  • syl20/spip
  • cpol/spip_cpol0
  • franck_r/spip
  • JLuc/spip
  • JLuc/jluc-spip
  • bricebou/spip
  • Jack31/spip-issue-5919
  • Plumf/spip
  • jo/spip
  • pierretux/spip
  • placido/spip
  • touti/spip
  • florent.tri/spip
25 résultats
Afficher les modifications
Affichage de
avec 0 ajout et 5873 suppressions
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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/charsets');
include_spip('inc/texte');
// http://doc.spip.org/@nettoyer_titre_email
function nettoyer_titre_email($titre) {
return str_replace("\n", ' ', textebrut(corriger_typo($titre)));
}
// http://doc.spip.org/@nettoyer_caracteres_mail
function nettoyer_caracteres_mail($t) {
$t = filtrer_entites($t);
if ($GLOBALS['meta']['charset'] <> 'utf-8') {
$t = str_replace(
array("&#8217;","&#8220;","&#8221;"),
array("'", '"', '"'),
$t);
}
$t = str_replace(
array("&mdash;", "&endash;"),
array("--","-" ),
$t);
return $t;
}
// http://doc.spip.org/@inc_envoyer_mail_dist
function inc_envoyer_mail_dist($email, $sujet, $texte, $from = "", $headers = "") {
if (!email_valide($email)) return false;
if ($email == _T('info_mail_fournisseur')) return false; // tres fort
// Traiter les headers existants
if (strlen($headers)) $headers = trim($headers)."\n";
// Fournir si possible un Message-Id: conforme au RFC1036,
// sinon SpamAssassin denoncera un MSGID_FROM_MTA_HEADER
$email_envoi = $GLOBALS['meta']["email_envoi"];
if (email_valide($email_envoi)) {
preg_match('/(@\S+)/', $email_envoi, $domain);
$mid = 'Message-Id: <' . time() . '_' . rand() . '_' . md5($email . $texte) . $domain[1] . ">\n";
} else {
spip_log("Meta email_envoi invalide. Le mail sera probablement vu comme spam.");
$email_envoi = $email;
$mid = '';
}
if (!$from) $from = $email_envoi;
// ceci est la RegExp NO_REAL_NAME faisant hurler SpamAssassin
if (preg_match('/^["\s]*\<?\S+\@\S+\>?\s*$/', $from))
$from .= ' (' . str_replace(')','', translitteration(str_replace('@', ' at ', $from))) . ')';
// Et maintenant le champ From:
$headers .= "From: $from\n";
// indispensable pour les sites qui colle d'office From: serveur-http
// sauf si deja mis par l'envoyeur
if (strpos($headers,"Reply-To:")===FALSE)
$headers .= "Reply-To: $from\n";
$charset = $GLOBALS['meta']['charset'];
// Ajouter le Content-Type et consort s'il n'y est pas deja
if (strpos($headers, "Content-Type: ") === false)
$headers .=
"Content-Type: text/plain; charset=$charset\n".
"Content-Transfer-Encoding: 8bit\n" .
"MIME-Version: 1.0\n";
$headers .= $mid;
// nettoyer les &eacute; &#8217, &emdash; etc...
// les 'cliquer ici' etc sont a eviter; voir:
// http://mta.org.ua/spamassassin-2.55/stuff/wiki.CustomRulesets/20050914/rules/french_rules.cf
$texte = nettoyer_caracteres_mail($texte);
$sujet = nettoyer_caracteres_mail($sujet);
// encoder le sujet si possible selon la RFC
if (init_mb_string()) {
# un bug de mb_string casse mb_encode_mimeheader si l'encoding interne
# est UTF-8 et le charset iso-8859-1 (constate php5-mac ; php4.3-debian)
mb_internal_encoding($charset);
$sujet = mb_encode_mimeheader($sujet, $charset, 'Q', "\n");
mb_internal_encoding('utf-8');
}
spip_log("mail $email\n$sujet\n$headers",'mails');
// mode TEST : forcer l'email
if (defined('_TEST_EMAIL_DEST')) {
if (!_TEST_EMAIL_DEST)
return false;
else
$email = _TEST_EMAIL_DEST;
}
// Ajouter le \n final
if ($headers = trim($headers)) $headers .= "\n";
if (function_exists('wordwrap'))
$texte = wordwrap($texte);
if (_OS_SERVEUR == 'windows') {
$texte = preg_replace ("@\r*\n@","\r\n", $texte);
$headers = preg_replace ("@\r*\n@","\r\n", $headers);
$sujet = preg_replace ("@\r*\n@","\r\n", $sujet);
}
return @mail($email, $sujet, $texte, $headers);
}
?>
<?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
)
*****************************************************************/
$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 v�rification est �videmment tres tres l�g�re
// http://doc.spip.org/@is_feed
function is_feed($url){
# methode 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://spip-contrib.net/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
//pas trouver d'exmples avec rdf j'ai encore du mal a saisir ce que rdf apporte de plus que rss
//mais bon j'ai pas aprofondi
************************************************************/
//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
// http://doc.spip.org/@get_feed_from_url
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);
$feed_list = array();
//extraction des <link>
if (preg_match_all("/<link [^>]*>/i", $buffer, $matches)){
//y a t-y rss atom rdf ou xml dans ces balises
foreach($matches[0] as $link){
if ( strpos($link, "rss")
|| strpos($link, "rdf")
|| strpos($link, "atom")
|| strpos($link, "xml") ){
//voila un candidat on va extraire sa partie href et la placer dans notre tableau
if (preg_match("/href=['|\"]?([^\s'\"]*)['|\"]?/",$link,$matches2)){
//on aura pris soin de verifier si ce lien est relatif d'en faire un absolu
if (!preg_match("/^http:\/\/.*/", $matches2[1])){
$matches2[1] = concat_url($url,$matches2[1]);
}
if($verif_complete){
if (is_feed($matches2[1])) $feed_list[] = $matches2[1];
}else $feed_list[] = $matches2[1];
}
}
}
//print_r($matches);
}
//extraction des <a>
if (preg_match_all("/<a [^>]*>/i", $buffer, $matches)){
//y a t-y rss atom rdf ou xml dans ces balises
foreach($matches[0] as $link){
if ( strpos($link, "rss")
|| strpos($link, "rdf")
|| strpos($link, "atom")
|| strpos($link, "xml") ){
//voila un candidat on va extraire sa partie href et la placer dans notre tableau
if (preg_match("/href=['|\"]?([^\s'\"]*)['|\"]?/",$link,$matches2)){
//on aura pris soin de verifier si ce lien est relatif d'en faire un absolu
if (!preg_match("/^http:\/\/.*/", $matches2[1])){
$matches2[1] = concat_url($url,$matches2[1]);
}
if($verif_complete){
if (is_feed($matches2[1])) $feed_list[] = $matches2[1];
}else $feed_list[] = $matches2[1];
}
}
}
}
return $feed_list;
}
/************************************ getFeed ****************************
print_r (get_feed_from_url("spip-contrib.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://www.spip-contrib.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
)
************************************************************************/
//petite fonction qui prend en charge les problemes de double slash
//qunad on concatene les lien
// http://doc.spip.org/@concat_url
function concat_url($url1, $path){
# methode spip
if(function_exists('suivre_lien')) {
return suivre_lien($url1,$path);
}
$url = $url1 . "/" . $path;
//cette operation peut tres facilement avoir genere // ou ///
$url = str_replace("///", "/", $url);
$url = str_replace("//", "/", $url);
//cas particulier de http://
$url = str_replace("http:/", "http://", $url);
return $url;
}
/****************************test concat**********************
echo concat_url("http://spip.net" , "ecrire")."<br />";
echo concat_url("http://spip.net/" , "ecrire")."<br />";
echo concat_url("http://spip.net" , "/ecrire")."<br />";
echo concat_url("http://spip.net/" , "/ecrire")."<br />";
*************************************************************/
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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/charsets');
include_spip('inc/filtres_mini');
/**
* Charger un filtre depuis le php :
* - on inclue tous les fichiers fonctions des plugins et du skel
* - on appelle chercher_filtre
*/
function charger_filtre($fonc, $default=NULL) {
include_spip('public/parametrer'); // inclure les fichiers fonctions
return chercher_filtre($fonc, $default);
}
// http://adoc.spip.org/@chercher_filtre
function chercher_filtre($fonc, $default=NULL) {
if (!$fonc) return $default;
// Cas des types mime, sans confondre avec les appels de fonction de classe
// Foo::Bar
// qui peuvent etre avec un namespace : space\Foo::Bar
if (preg_match(',^[\w]+/,',$fonc)){
$nom = preg_replace(',\W,','_', $fonc);
$f = chercher_filtre($nom);
// cas du sous-type MIME sans filtre associe, passer au type:
// si filtre_text_plain pas defini, passe a filtre_text
if (!$f AND $nom!==$fonc)
$f = chercher_filtre(preg_replace(',\W.*$,','', $fonc));
return $f;
}
foreach (
array('filtre_'.$fonc, 'filtre_'.$fonc.'_dist', $fonc) as $f){
if (is_string($g = $GLOBALS['spip_matrice'][$f]))
find_in_path($g,'', true);
if (function_exists($f)
OR (preg_match("/^(\w*)::(\w*)$/", $f, $regs)
AND is_callable(array($regs[1], $regs[2]))
)) {
return $f;
}
}
return $default;
}
// http://doc.spip.org/@appliquer_filtre
function appliquer_filtre($arg, $filtre) {
$f = chercher_filtre($filtre);
if (!$f)
return ''; // ou faut-il retourner $arg inchange == filtre_identite?
$args = func_get_args();
array_shift($args); // enlever $arg
array_shift($args); // enlever $filtre
array_unshift($args, $arg); // remettre $arg
return call_user_func_array($f,$args);
}
// http://doc.spip.org/@spip_version
function spip_version() {
$version = $GLOBALS['spip_version_affichee'];
if ($svn_revision = version_svn_courante(_DIR_RACINE))
$version .= ($svn_revision<0 ? ' SVN':'').' ['.abs($svn_revision).']';
return $version;
}
//
// Mention de la revision SVN courante de l'espace restreint standard
// (numero non garanti pour l'espace public et en cas de mutualisation)
// on est negatif si on est sur .svn, et positif si on utilise svn.revision
// http://doc.spip.org/@version_svn_courante
function version_svn_courante($dir) {
if (!$dir) $dir = '.';
// version installee par paquet ZIP
if (lire_fichier($dir.'/svn.revision', $c)
AND preg_match(',Revision: (\d+),', $c, $d))
return intval($d[1]);
// version installee par SVN
if (lire_fichier($dir . '/.svn/entries', $c)
AND (
(preg_match_all(
',committed-rev="([0-9]+)",', $c, $r1, PREG_PATTERN_ORDER)
AND $v = max($r1[1])
)
OR
(preg_match(',^\d.*dir[\r\n]+(\d+),ms', $c, $r1) # svn >= 1.4
AND $v = $r1[1]
)))
return -$v;
// Bug ou paquet fait main
return 0;
}
// La matrice est necessaire pour ne filtrer _que_ des fonctions definies dans filtres_images
// et laisser passer les fonctions personnelles baptisees image_...
$GLOBALS['spip_matrice']['image_graver'] = 'inc/filtres_images_mini.php';
$GLOBALS['spip_matrice']['image_select'] = 'inc/filtres_images_mini.php';
$GLOBALS['spip_matrice']['image_reduire'] = 'inc/filtres_images_mini.php';
$GLOBALS['spip_matrice']['image_reduire_par'] = 'inc/filtres_images_mini.php';
$GLOBALS['spip_matrice']['image_passe_partout'] = 'inc/filtres_images_mini.php';
$GLOBALS['spip_matrice']['couleur_html_to_hex'] = 'inc/filtres_images_mini.php';
$GLOBALS['spip_matrice']['couleur_foncer'] = 'inc/filtres_images_mini.php';
$GLOBALS['spip_matrice']['couleur_eclaircir'] = 'inc/filtres_images_mini.php';
// ou pour inclure un script au moment ou l'on cherche le filtre
$GLOBALS['spip_matrice']['filtre_image_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_audio_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_video_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_application_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_message_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_multipart_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_text_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_text_csv_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_text_html_dist'] = 'inc/filtres_mime.php';
$GLOBALS['spip_matrice']['filtre_audio_x_pn_realaudio'] = 'inc/filtres_mime.php';
// charge les fonctions graphiques et applique celle demandee
// http://doc.spip.org/@filtrer
function filtrer($filtre) {
include_spip('public/parametrer'); // charger les fichiers fonctions
if (is_string($f = $GLOBALS['spip_matrice'][$filtre]))
find_in_path($f,'', true);
$tous = func_get_args();
if (substr($filtre,0,6)=='image_' && $GLOBALS['spip_matrice'][$filtre])
return image_filtrer($tous);
elseif($f = chercher_filtre($filtre)) {
array_shift($tous);
return call_user_func_array($f, $tous);
}
else {
// le filtre n'existe pas, on provoque une erreur
$msg = array('zbug_erreur_filtre', array('filtre'=>texte_script($filtre)));
erreur_squelette($msg);
return '';
}
}
// fonction generique d'entree des filtres images
// accepte en entree un texte complet, un img-log (produit par #LOGO_XX),
// un tag <img ...> complet, ou encore un nom de fichier *local* (passer
// le filtre |copie_locale si on veut l'appliquer a un document)
// applique le filtre demande a chacune des occurrences
// http://doc.spip.org/@image_filtrer
function image_filtrer($args){
$filtre = array_shift($args); # enlever $filtre
$texte = array_shift($args);
if (!strlen($texte)) return;
find_in_path('filtres_images_mini.php','inc/', true);
statut_effacer_images_temporaires(true); // activer la suppression des images temporaires car le compilo finit la chaine par un image_graver
// Cas du nom de fichier local
if ( strpos(substr($texte,strlen(_DIR_RACINE)),'..')===FALSE
AND !preg_match(',^/|[<>]|\s,S', $texte)
AND (
file_exists(preg_replace(',[?].*$,','',$texte))
OR preg_match(';^(\w{3,7}://);', $texte)
)) {
array_unshift($args,"<img src='$texte' />");
$res = call_user_func_array($filtre, $args);
statut_effacer_images_temporaires(false); // desactiver pour les appels hors compilo
return $res;
}
// Cas general : trier toutes les images, avec eventuellement leur <span>
if (preg_match_all(
',(<([a-z]+) [^<>]*spip_documents[^<>]*>)?\s*(<img\s.*>),UimsS',
$texte, $tags, PREG_SET_ORDER)) {
foreach ($tags as $tag) {
$class = extraire_attribut($tag[3],'class');
if (!$class || (strpos($class,'no_image_filtrer')===FALSE)){
array_unshift($args,$tag[3]);
if ($reduit = call_user_func_array($filtre, $args)) {
// En cas de span spip_documents, modifier le style=...width:
if($tag[1]){
$w = extraire_attribut($reduit, 'width');
if (!$w AND preg_match(",width:\s*(\d+)px,S",extraire_attribut($reduit,'style'),$regs))
$w = $regs[1];
if ($w AND ($style = extraire_attribut($tag[1], 'style'))){
$style = preg_replace(",width:\s*\d+px,S", "width:${w}px", $style);
$replace = inserer_attribut($tag[1], 'style', $style);
$texte = str_replace($tag[1], $replace, $texte);
}
}
// traiter aussi un eventuel mouseover
if ($mouseover = extraire_attribut($reduit,'onmouseover')){
if (preg_match(",this[.]src=['\"]([^'\"]+)['\"],ims", $mouseover, $match)){
$srcover = $match[1];
array_shift($args);
array_unshift($args,"<img src='".$match[1]."' />");
$srcover_filter = call_user_func_array($filtre, $args);
$srcover_filter = extraire_attribut($srcover_filter,'src');
$reduit = str_replace($srcover,$srcover_filter,$reduit);
}
}
$texte = str_replace($tag[3], $reduit, $texte);
}
array_shift($args);
}
}
}
statut_effacer_images_temporaires(false); // desactiver pour les appels hors compilo
return $texte;
}
// pour les feuilles de style
function filtre_background_image_dist ($img, $couleur, $pos="") {
if (!function_exists("imagecreatetruecolor")
OR !include_spip('filtres/images_transforme')
OR !function_exists('image_sepia')
OR !function_exists('image_aplatir')
)
return "background-color: #$couleur;";
return "background: url(".url_absolue(extraire_attribut(image_aplatir(image_sepia($img, $couleur),"gif","cccccc", 64, true), "src")).") $pos;";
}
//
// Retourner taille d'une image
// pour les filtres |largeur et |hauteur
//
// http://doc.spip.org/@taille_image
function taille_image($img) {
static $largeur_img =array(), $hauteur_img= array();
$srcWidth = 0;
$srcHeight = 0;
$logo = extraire_attribut($img,'src');
if (!$logo) $logo = $img;
else {
$srcWidth = extraire_attribut($img,'width');
$srcHeight = extraire_attribut($img,'height');
}
// ne jamais operer directement sur une image distante pour des raisons de perfo
// la copie locale a toutes les chances d'etre la ou de resservir
if (preg_match(';^(\w{3,7}://);', $logo)){
include_spip('inc/distant');
$fichier = copie_locale($logo);
$logo = $fichier ? _DIR_RACINE . $fichier : $logo;
}
if (($p=strpos($logo,'?'))!==FALSE)
$logo=substr($logo,0,$p);
$srcsize = false;
if (isset($largeur_img[$logo]))
$srcWidth = $largeur_img[$logo];
if (isset($hauteur_img[$logo]))
$srcHeight = $hauteur_img[$logo];
if (!$srcWidth OR !$srcHeight){
if ($srcsize = @getimagesize($logo)){
if (!$srcWidth) $largeur_img[$logo] = $srcWidth = $srcsize[0];
if (!$srcHeight) $hauteur_img[$logo] = $srcHeight = $srcsize[1];
}
// $logo peut etre une reference a une image temporaire dont a n'a que le log .src
// on s'y refere, l'image sera reconstruite en temps utile si necessaire
elseif(@file_exists($f = "$logo.src")
AND lire_fichier($f,$valeurs)
AND $valeurs=unserialize($valeurs)) {
if (!$srcWidth) $largeur_img[$mem] = $srcWidth = $valeurs["largeur_dest"];
if (!$srcHeight) $hauteur_img[$mem] = $srcHeight = $valeurs["hauteur_dest"];
}
}
return array($srcHeight, $srcWidth);
}
// http://doc.spip.org/@largeur
function largeur($img) {
if (!$img) return;
list ($h,$l) = taille_image($img);
return $l;
}
// http://doc.spip.org/@hauteur
function hauteur($img) {
if (!$img) return;
list ($h,$l) = taille_image($img);
return $h;
}
// Echappement des entites HTML avec correction des entites "brutes"
// (generees par les butineurs lorsqu'on rentre des caracteres n'appartenant
// pas au charset de la page [iso-8859-1 par defaut])
//
// Attention on limite cette correction aux caracteres "hauts" (en fait > 99
// pour aller plus vite que le > 127 qui serait logique), de maniere a
// preserver des echappements de caracteres "bas" (par exemple [ ou ")
// et au cas particulier de &amp; qui devient &amp;amp; dans les url
// http://doc.spip.org/@corriger_entites_html
function corriger_entites_html($texte) {
if (strpos($texte,'&amp;') === false) return $texte;
return preg_replace(',&amp;(#[0-9][0-9][0-9]+;|amp;),iS', '&\1', $texte);
}
// idem mais corriger aussi les &amp;eacute; en &eacute;
// http://doc.spip.org/@corriger_toutes_entites_html
function corriger_toutes_entites_html($texte) {
if (strpos($texte,'&amp;') === false) return $texte;
return preg_replace(',&amp;(#?[a-z0-9]+;),iS', '&\1', $texte);
}
// http://doc.spip.org/@proteger_amp
function proteger_amp($texte){
return str_replace('&','&amp;',$texte);
}
// http://doc.spip.org/@entites_html
function entites_html($texte, $tout=false) {
if (!is_string($texte) OR !$texte
OR !preg_match(",[&\"'<>],S", $texte) # strpbrk($texte, "&\"'<>")!==false
) return $texte;
include_spip('inc/texte');
$texte = htmlspecialchars(echappe_retour(echappe_html($texte,'',true),'','proteger_amp'));
if ($tout)
return corriger_toutes_entites_html($texte);
else
return corriger_entites_html($texte);
}
// Transformer les &eacute; dans le charset local
// http://doc.spip.org/@filtrer_entites
function filtrer_entites($texte) {
if (strpos($texte,'&') === false) return $texte;
// filtrer
$texte = html2unicode($texte);
// remettre le tout dans le charset cible
return unicode2charset($texte);
}
// caracteres de controle - http://www.w3.org/TR/REC-xml/#charsets
// http://doc.spip.org/@supprimer_caracteres_illegaux
function supprimer_caracteres_illegaux($texte) {
$from = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\xB\xC\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
$to = str_repeat('-', strlen($from));
return strtr($texte, $from, $to);
}
// Supprimer caracteres windows et les caracteres de controle ILLEGAUX
// http://doc.spip.org/@corriger_caracteres
function corriger_caracteres ($texte) {
include_spip('inc/charsets');
$texte = corriger_caracteres_windows($texte);
$texte = supprimer_caracteres_illegaux($texte);
return $texte;
}
// Encode du HTML pour transmission XML
// http://doc.spip.org/@texte_backend
function texte_backend($texte) {
static $apostrophe = array("&#8217;", "'"); # n'allouer qu'une fois
// si on a des liens ou des images, les passer en absolu
$texte = liens_absolus($texte);
// echapper les tags &gt; &lt;
$texte = preg_replace(',&(gt|lt);,S', '&amp;\1;', $texte);
// importer les &eacute;
$texte = filtrer_entites($texte);
// " -> &quot; et tout ce genre de choses
$u = $GLOBALS['meta']['pcre_u'];
$texte = str_replace("&nbsp;", " ", $texte);
$texte = preg_replace('/\s{2,}/S'.$u, " ", $texte);
$texte = entites_html($texte);
// verifier le charset
$texte = charset2unicode($texte);
// Caracteres problematiques en iso-latin 1
if ($GLOBALS['meta']['charset'] == 'iso-8859-1') {
$texte = str_replace(chr(156), '&#156;', $texte);
$texte = str_replace(chr(140), '&#140;', $texte);
$texte = str_replace(chr(159), '&#159;', $texte);
}
// l'apostrophe curly pose probleme a certains lecteure de RSS
// et le caractere apostrophe alourdit les squelettes avec PHP
// ==> on les remplace par l'entite HTML
return str_replace($apostrophe, "'", $texte);
}
// Comme ci-dessus, mais avec addslashes final pour squelettes avec PHP (rss)
function texte_backendq($texte) {
return addslashes(texte_backend($texte));
}
// Enleve le numero des titres numerotes ("1. Titre" -> "Titre")
// http://doc.spip.org/@supprimer_numero
function supprimer_numero($texte) {
return preg_replace(
",^[[:space:]]*([0-9]+)([.)]|".chr(194).'?'.chr(176).")[[:space:]]+,S",
"", $texte);
}
// et la fonction inverse
// http://doc.spip.org/@recuperer_numero
function recuperer_numero($texte) {
if (preg_match(
",^[[:space:]]*([0-9]+)([.)]|".chr(194).'?'.chr(176).")[[:space:]]+,S",
$texte, $regs))
return intval($regs[1]);
else
return '';
}
// Suppression basique et brutale de tous les <...>
// http://doc.spip.org/@supprimer_tags
function supprimer_tags($texte, $rempl = "") {
$texte = preg_replace(",<[^>]*>,US", $rempl, $texte);
// ne pas oublier un < final non ferme
// mais qui peut aussi etre un simple signe plus petit que
$texte = str_replace('<', ' ', $texte);
return $texte;
}
// Convertit les <...> en la version lisible en HTML
// http://doc.spip.org/@echapper_tags
function echapper_tags($texte, $rempl = "") {
$texte = preg_replace("/<([^>]*)>/", "&lt;\\1&gt;", $texte);
return $texte;
}
// Convertit un texte HTML en texte brut
// http://doc.spip.org/@textebrut
function textebrut($texte) {
$u = $GLOBALS['meta']['pcre_u'];
$texte = preg_replace('/\s+/S'.$u, " ", $texte);
$texte = preg_replace("/<(p|br)( [^>]*)?".">/iS", "\n\n", $texte);
$texte = preg_replace("/^\n+/", "", $texte);
$texte = preg_replace("/\n+$/", "", $texte);
$texte = preg_replace("/\n +/", "\n", $texte);
$texte = supprimer_tags($texte);
$texte = preg_replace("/(&nbsp;| )+/S", " ", $texte);
// nettoyer l'apostrophe curly qui pose probleme a certains rss-readers, lecteurs de mail...
$texte = str_replace("&#8217;","'",$texte);
return $texte;
}
// Remplace les liens SPIP en liens ouvrant dans une nouvelle fenetre (target=blank)
// http://doc.spip.org/@liens_ouvrants
function liens_ouvrants ($texte) {
return preg_replace(",<a ([^>]*https?://[^>]*class=[\"']spip_(out|url)\b[^>]+)>,",
"<a \\1 target=\"_blank\">", $texte);
}
// Transformer les sauts de paragraphe en simples passages a la ligne
// http://doc.spip.org/@PtoBR
function PtoBR($texte){
$u = $GLOBALS['meta']['pcre_u'];
$texte = preg_replace("@</p>@iS", "\n", $texte);
$texte = preg_replace("@<p\b.*>@UiS", "<br />", $texte);
$texte = preg_replace("@^\s*<br />@S".$u, "", $texte);
return $texte;
}
// Couper les "mots" de plus de $l caracteres (souvent des URLs)
// http://doc.spip.org/@lignes_longues
function lignes_longues($texte, $l = 70) {
if ($l<1) return $texte;
if (!preg_match("/[\w,\/.]{".$l."}/UmsS", $texte))
return $texte;
// Passer en utf-8 pour ne pas avoir de coupes trop courtes avec les &#xxxx;
// qui prennent 7 caracteres
#include_spip('inc/charsets');
$texte = str_replace("&nbsp;","<&nbsp>",$texte);
$texte = html2unicode($texte, true);
$texte = str_replace("<&nbsp>","&nbsp;",$texte);
$texte = unicode_to_utf_8(charset2unicode(
$texte, $GLOBALS['meta']['charset'], true));
// echapper les tags (on ne veut pas casser les a href=...)
$tags = array();
if (preg_match_all('/<.+>|&(?:amp;)?#x?[0-9]+;|&(?:amp;)?[a-zA-Z1-4]{2,6};/UumsS', $texte, $t, PREG_SET_ORDER)) {
foreach ($t as $n => $tag) {
$tags[$n] = $tag[0];
$texte = str_replace($tag[0], "<---$n--->", $texte);
}
}
// casser les mots longs qui restent
// note : on pourrait preferer couper sur les / , etc.
if (preg_match_all("/[\w,\/.]{".$l."}/UmsS", $texte, $longs, PREG_SET_ORDER)) {
foreach ($longs as $long) {
$texte = str_replace($long[0], $long[0].' ', $texte);
}
}
// retablir les tags
if (preg_match_all('/<---[\s0-9]+--->/UumsS', $texte, $t, PREG_SET_ORDER)) {
foreach ($t as $tag) {
$n = intval(preg_replace(',[^0-9]+,U','',$tag[0]));
$texte = str_replace($tag[0], $tags[$n], $texte);
}
}
return importer_charset($texte, 'utf-8');
}
// Majuscules y compris accents, en HTML
// http://doc.spip.org/@majuscules
function majuscules($texte) {
if (!strlen($texte)) return '';
// Cas du turc
if ($GLOBALS['spip_lang'] == 'tr') {
# remplacer hors des tags et des entites
if (preg_match_all(',<[^<>]+>|&[^;]+;,S', $texte, $regs, PREG_SET_ORDER))
foreach ($regs as $n => $match)
$texte = str_replace($match[0], "@@SPIP_TURC$n@@", $texte);
$texte = str_replace('i', '&#304;', $texte);
if ($regs)
foreach ($regs as $n => $match)
$texte = str_replace("@@SPIP_TURC$n@@", $match[0], $texte);
}
// Cas general
return "<span style='text-transform: uppercase;'>$texte</span>";
}
// "127.4 ko" ou "3.1 Mo"
// http://doc.spip.org/@taille_en_octets
function taille_en_octets ($taille) {
if ($taille < 1024) {$taille = _T('taille_octets', array('taille' => $taille));}
else if ($taille < 1024*1024) {
$taille = _T('taille_ko', array('taille' => ((floor($taille / 102.4))/10)));
} else {
$taille = _T('taille_mo', array('taille' => ((floor(($taille / 1024) / 102.4))/10)));
}
return $taille;
}
// Rend une chaine utilisable sans dommage comme attribut HTML
// http://doc.spip.org/@attribut_html
function attribut_html($texte,$textebrut = true) {
$u = $GLOBALS['meta']['pcre_u'];
if ($textebrut)
$texte = preg_replace(array(",\n,",",\s(?=\s),msS".$u),array(" ",""),textebrut($texte));
$texte = texte_backend($texte);
$texte = str_replace(array("'",'"'),array('&#39;', '&#34;'), $texte);
return preg_replace(array("/&(amp;|#38;)/","/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/"),array("&","&#38;") , $texte);
}
// Vider les url nulles comme 'http://' ou 'mailto:'
// et leur appliquer un htmlspecialchars() + gerer les &amp;
// http://doc.spip.org/@vider_url
function vider_url($url, $entites = true) {
# un message pour abs_url
$GLOBALS['mode_abs_url'] = 'url';
$url = trim($url);
if (preg_match(",^(http:?/?/?|mailto:?)$,iS", $url))
return '';
if ($entites) $url = entites_html($url);
return $url;
}
// Extraire une date de n'importe quel champ (a completer...)
// http://doc.spip.org/@extraire_date
function extraire_date($texte) {
// format = 2001-08
if (preg_match(",([1-2][0-9]{3})[^0-9]*(1[0-2]|0?[1-9]),",$texte,$regs))
return $regs[1]."-".sprintf("%02d", $regs[2])."-01";
}
// Maquiller une adresse e-mail
// http://doc.spip.org/@antispam
function antispam($texte) {
include_spip('inc/acces');
$masque = creer_pass_aleatoire(3);
return preg_replace("/@/", " $masque ", $texte);
}
// http://doc.spip.org/@securiser_acces
function securiser_acces($id_auteur, $cle, $dir, $op='', $args='')
{
include_spip('inc/acces');
if ($op) $dir .= " $op $args";
return verifier_low_sec($id_auteur, $cle, $dir);
}
// sinon{texte, rien} : affiche "rien" si la chaine est vide,
// affiche la chaine si non vide ;
// attention c'est compile directement dans inc/references
// http://doc.spip.org/@sinon
function sinon ($texte, $sinon='') {
if ($texte OR (!is_array($texte) AND strlen($texte)))
return $texte;
else
return $sinon;
}
// |choixsivide{vide,pasvide} affiche pasvide si la chaine n'est pas vide...
// http://doc.spip.org/@choixsivide
function choixsivide($a, $vide, $pasvide) {
return $a ? $pasvide : $vide;
}
// |choixsiegal{aquoi,oui,non} affiche oui si la chaine est egal a aquoi ...
// http://doc.spip.org/@choixsiegal
function choixsiegal($a1,$a2,$v,$f) {
return ($a1 == $a2) ? $v : $f;
}
//
// Date, heure, saisons
//
// on normalise la date, si elle vient du contexte (public/parametrer.php), on force le jour
// http://doc.spip.org/@normaliser_date
function normaliser_date($date, $forcer_jour = false) {
$date = vider_date($date);
if ($date) {
if (preg_match("/^[0-9]{8,10}$/", $date))
$date = date("Y-m-d H:i:s", $date);
if (preg_match("#^([12][0-9]{3})([-/]00)?( [-0-9:]+)?$#", $date, $regs))
$date = $regs[1]."-00-00".$regs[3];
else if (preg_match("#^([12][0-9]{3}[-/][01]?[0-9])([-/]00)?( [-0-9:]+)?$#", $date, $regs))
$date = preg_replace("@/@","-",$regs[1])."-00".$regs[3];
else
$date = date("Y-m-d H:i:s", strtotime($date));
if ($forcer_jour)
$date = str_replace('-00', '-01', $date);
}
return $date;
}
// http://doc.spip.org/@vider_date
function vider_date($letexte) {
if (strncmp("0000-00-00", $letexte,10)==0) return '';
if (strncmp("0001-01-01", $letexte,10)==0) return '';
if (strncmp("1970-01-01", $letexte,10)==0) return ''; // eviter le bug GMT-1
return $letexte;
}
// http://doc.spip.org/@recup_heure
function recup_heure($date){
static $d = array(0,0,0);
if (!preg_match('#([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $date, $r))
return $d;
array_shift($r);
return $r;
}
// http://doc.spip.org/@heures
function heures($numdate) {
$date_array = recup_heure($numdate);
if ($date_array)
list($heures, $minutes, $secondes) = $date_array;
return $heures;
}
// http://doc.spip.org/@minutes
function minutes($numdate) {
$date_array = recup_heure($numdate);
if ($date_array)
list($heures, $minutes, $secondes) = $date_array;
return $minutes;
}
// http://doc.spip.org/@secondes
function secondes($numdate) {
$date_array = recup_heure($numdate);
if ($date_array)
list($heures,$minutes,$secondes) = $date_array;
return $secondes;
}
// http://doc.spip.org/@heures_minutes
function heures_minutes($numdate) {
return _T('date_fmt_heures_minutes', array('h'=> heures($numdate), 'm'=> minutes($numdate)));
}
// http://doc.spip.org/@recup_date
function recup_date($numdate, $forcer_jour = true){
if (!$numdate) return '';
$heures = $minutes = $secondes = 0;
if (preg_match('#([0-9]{1,2})/([0-9]{1,2})/([0-9]{4}|[0-9]{1,2})#', $numdate, $regs)) {
$jour = $regs[1];
$mois = $regs[2];
$annee = $regs[3];
if ($annee < 90){
$annee = 2000 + $annee;
} elseif ($annee<100) {
$annee = 1900 + $annee ;
}
list($heures, $minutes, $secondes) = recup_heure($numdate);
}
elseif (preg_match('#([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})#',$numdate, $regs)) {
$annee = $regs[1];
$mois = $regs[2];
$jour = $regs[3];
list($heures, $minutes, $secondes) = recup_heure($numdate);
}
elseif (preg_match('#([0-9]{4})-([0-9]{2})#', $numdate, $regs)){
$annee = $regs[1];
$mois = $regs[2];
$jour ='';
list($heures, $minutes, $secondes) = recup_heure($numdate);
}
elseif (preg_match('#^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$#', $numdate, $regs)){
$annee = $regs[1];
$mois = $regs[2];
$jour = $regs[3];
$heures = $regs[4];
$minutes = $regs[5];
$secondes = $regs[6];
} else $annee = $mois = $jour ='';
if ($annee > 4000) $annee -= 9000;
if (substr($jour, 0, 1) == '0') $jour = substr($jour, 1);
if ($forcer_jour AND $jour == '0') $jour = '1';
if ($forcer_jour AND $mois == '0') $mois = '1';
if ($annee OR $mois OR $jour OR $heures OR $minutes OR $secondes)
return array($annee, $mois, $jour, $heures, $minutes, $secondes);
}
// une date pour l'interface : utilise date_relative si le decalage
// avec time() est de moins de douze heures, sinon la date complete
// http://doc.spip.org/@date_interface
function date_interface($date, $decalage_maxi = 43200/* 12*3600 */) {
return sinon(
date_relative($date, $decalage_maxi),
affdate_heure($date)
);
}
// http://doc.spip.org/@date_relative
function date_relative($date, $decalage_maxi=0,$ref_date=null) {
if (is_null($ref_date))
$ref_time = time();
else
$ref_time = strtotime($ref_date);
if (!$date) return;
$decal = date("U",$ref_time) - date("U", strtotime($date));
if ($decalage_maxi AND ($decal > $decalage_maxi OR $decal < 0))
return '';
if ($decal < 0) {
$il_y_a = "date_dans";
$decal = -1 * $decal;
} else {
$il_y_a = "date_il_y_a";
}
if ($decal > 3600 * 24 * 30 * 6)
return affdate_court($date);
if ($decal > 3600 * 24 * 30) {
$mois = floor ($decal / (3600 * 24 * 30));
if ($mois < 2)
$delai = "$mois "._T("date_un_mois");
else
$delai = "$mois "._T("date_mois");
}
else if ($decal > 3600 * 24 * 7) {
$semaines = floor ($decal / (3600 * 24 * 7));
if ($semaines < 2)
$delai = "$semaines "._T("date_une_semaine");
else
$delai = "$semaines "._T("date_semaines");
}
else if ($decal > 3600 * 24) {
$jours = floor ($decal / (3600 * 24));
if ($jours < 2)
return $il_y_a=="date_dans"?_T("date_demain"):_T("date_hier");
else
$delai = "$jours "._T("date_jours");
}
else if ($decal >= 3600) {
$heures = floor ($decal / 3600);
if ($heures < 2)
$delai = "$heures "._T("date_une_heure");
else
$delai = "$heures "._T("date_heures");
}
else if ($decal >= 60) {
$minutes = floor($decal / 60);
if ($minutes < 2)
$delai = "$minutes "._T("date_une_minute");
else
$delai = "$minutes "._T("date_minutes");
} else {
$secondes = ceil($decal);
if ($secondes < 2)
$delai = "$secondes "._T("date_une_seconde");
else
$delai = "$secondes "._T("date_secondes");
}
return _T($il_y_a, array("delai"=> $delai));
}
// http://doc.spip.org/@date_relativecourt
function date_relativecourt($date, $decalage_maxi=0) {
if (!$date) return;
$decal = date("U",strtotime(date('Y-m-d'))-strtotime(date('Y-m-d',strtotime($date))));
if ($decalage_maxi AND ($decal > $decalage_maxi OR $decal < 0))
return '';
if ($decal < -24*3600) {
$retour = date_relative($date, $decalage_maxi);
}
elseif ($decal < 0) {
$retour = _T("date_demain");
}
else if ($decal < (3600 * 24) ) {
$retour = _T("date_aujourdhui");
}
else if ($decal < (3600 * 24 *2) ) {
$retour = _T("date_hier");
}
else {
$retour = date_relative($date, $decalage_maxi);
}
return $retour;
}
// http://doc.spip.org/@affdate_base
function affdate_base($numdate, $vue, $param = '') {
global $spip_lang;
$date_array = recup_date($numdate, false);
if (!$date_array) return;
list($annee, $mois, $jour, $heures, $minutes, $secondes)= $date_array;
// 1er, 21st, etc.
$journum = $jour;
if ($jour == 0) {
$jour = '';
} else {
$njour = intval($jour);
if ($jourth = _T('date_jnum'.$jour))
$jour = $jourth;
}
$mois = intval($mois);
if ($mois > 0 AND $mois < 13) {
$nommois = _T('date_mois_'.$mois);
if ($jour)
$jourmois = _T('date_de_mois_'.$mois, array('j'=>$jour, 'nommois'=>$nommois));
else
$jourmois = $nommois;
} else $nommois = '';
if ($annee < 0) {
$annee = -$annee." "._T('date_avant_jc');
$avjc = true;
}
else $avjc = false;
switch ($vue) {
case 'saison':
if ($mois > 0){
$saison = 1;
if (($mois == 3 AND $jour >= 21) OR $mois > 3) $saison = 2;
if (($mois == 6 AND $jour >= 21) OR $mois > 6) $saison = 3;
if (($mois == 9 AND $jour >= 21) OR $mois > 9) $saison = 4;
if (($mois == 12 AND $jour >= 21) OR $mois > 12) $saison = 1;
}
return _T('date_saison_'.$saison);
case 'court':
if ($avjc) return $annee;
$a = date('Y');
if ($annee < ($a - 100) OR $annee > ($a + 100)) return $annee;
if ($annee != $a) return _T('date_fmt_mois_annee', array ('mois'=>$mois, 'nommois'=>ucfirst($nommois), 'annee'=>$annee));
return _T('date_fmt_jour_mois', array ('jourmois'=>$jourmois, 'jour'=>$jour, 'mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee));
case 'jourcourt':
if ($avjc) return $annee;
$a = date('Y');
if ($annee < ($a - 100) OR $annee > ($a + 100)) return $annee;
if ($annee != $a) return _T('date_fmt_jour_mois_annee', array ('jourmois'=>$jourmois, 'jour'=>$jour, 'mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee));
return _T('date_fmt_jour_mois', array ('jourmois'=>$jourmois, 'jour'=>$jour, 'mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee));
case 'entier':
if ($avjc) return $annee;
if ($jour)
return _T('date_fmt_jour_mois_annee', array ('jourmois'=>$jourmois, 'jour'=>$jour, 'mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee));
elseif ($mois)
return trim(_T('date_fmt_mois_annee', array ('mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee)));
else
return $annee;
case 'nom_mois':
return $nommois;
case 'mois':
return sprintf("%02s",$mois);
case 'jour':
return $jour;
case 'journum':
return $journum;
case 'nom_jour':
if (!$mois OR !$njour)
return '';
$nom = mktime(1,1,1,$mois,$njour,$annee);
$nom = 1+date('w',$nom);
$param = $param ? '_'.$param : '';
return _T('date_jour_'.$nom.$param);
case 'mois_annee':
if ($avjc) return $annee;
return trim(_T('date_fmt_mois_annee', array('mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee)));
case 'annee':
return $annee;
// Cas d'une vue non definie : retomber sur le format
// de date propose par http://www.php.net/date
default:
return date($vue, strtotime($numdate));
}
}
// http://doc.spip.org/@nom_jour
function nom_jour($numdate, $forme = '') {
if(!($forme == 'abbr' OR $forme == 'initiale')) $forme = '';
return affdate_base($numdate, 'nom_jour', $forme);
}
// http://doc.spip.org/@jour
function jour($numdate) {
return affdate_base($numdate, 'jour');
}
// http://doc.spip.org/@journum
function journum($numdate) {
return affdate_base($numdate, 'journum');
}
// http://doc.spip.org/@mois
function mois($numdate) {
return affdate_base($numdate, 'mois');
}
// http://doc.spip.org/@nom_mois
function nom_mois($numdate) {
return affdate_base($numdate, 'nom_mois');
}
// http://doc.spip.org/@annee
function annee($numdate) {
return affdate_base($numdate, 'annee');
}
// http://doc.spip.org/@saison
function saison($numdate) {
return affdate_base($numdate, 'saison');
}
// http://doc.spip.org/@affdate
function affdate($numdate, $format='entier') {
return affdate_base($numdate, $format);
}
// http://doc.spip.org/@affdate_court
function affdate_court($numdate) {
return affdate_base($numdate, 'court');
}
// http://doc.spip.org/@affdate_jourcourt
function affdate_jourcourt($numdate) {
return affdate_base($numdate, 'jourcourt');
}
// http://doc.spip.org/@affdate_mois_annee
function affdate_mois_annee($numdate) {
return affdate_base($numdate, 'mois_annee');
}
// http://doc.spip.org/@affdate_heure
function affdate_heure($numdate) {
$date_array = recup_date($numdate);
if (!$date_array) return;
list($annee, $mois, $jour, $heures, $minutes, $sec)= $date_array;
return _T('date_fmt_jour_heure', array('jour' => affdate($numdate), 'heure' => _T('date_fmt_heures_minutes', array('h'=> $heures, 'm'=> $minutes))));
}
//
// Alignements en HTML (Old-style, preferer CSS)
//
// Cette fonction cree le paragraphe s'il n'existe pas (texte sur un seul para)
// http://doc.spip.org/@aligner
function aligner($letexte, $justif='') {
$letexte = trim($letexte);
if (!strlen($letexte)) return '';
// Paragrapher proprement
$letexte = paragrapher($letexte, true);
// Inserer les alignements
if ($justif)
$letexte = str_replace(
'<p class="spip">', '<p class="spip" align="'.$justif.'">',
$letexte);
return $letexte;
}
// http://doc.spip.org/@justifier
function justifier($letexte) {
return aligner($letexte,'justify');
}
// http://doc.spip.org/@aligner_droite
function aligner_droite($letexte) {
return aligner($letexte,'right');
}
// http://doc.spip.org/@aligner_gauche
function aligner_gauche($letexte) {
return aligner($letexte,'left');
}
// http://doc.spip.org/@centrer
function centrer($letexte) {
return aligner($letexte,'center');
}
// http://doc.spip.org/@style_align
function style_align($bof) {
global $spip_lang_left;
return "text-align: $spip_lang_left";
}
//
// Export iCal
//
// http://doc.spip.org/@filtrer_ical
function filtrer_ical($texte) {
#include_spip('inc/charsets');
$texte = html2unicode($texte);
$texte = unicode2charset(charset2unicode($texte, $GLOBALS['meta']['charset'], 1), 'utf-8');
$texte = preg_replace("/\n/", " ", $texte);
$texte = preg_replace("/,/", "\,", $texte);
return $texte;
}
// http://doc.spip.org/@date_ical
function date_ical($date, $addminutes = 0) {
list($heures, $minutes, $secondes) = recup_heure($date);
list($annee, $mois, $jour) = recup_date($date);
return date("Ymd\THis",
mktime($heures, $minutes+$addminutes,$secondes,$mois,$jour,$annee));
}
// date_iso retourne la date au format "RFC 3339" / "ISO 8601"
// voir http://www.php.net/manual/fr/ref.datetime.php#datetime.constants
// http://doc.spip.org/@date_iso
function date_iso($date_heure) {
list($annee, $mois, $jour) = recup_date($date_heure);
list($heures, $minutes, $secondes) = recup_heure($date_heure);
$time = @mktime($heures, $minutes, $secondes, $mois, $jour, $annee);
return gmdate('Y-m-d\TH:i:s\Z', $time);
}
// date_822 retourne la date au format "RFC 822"
// utilise pour <pubdate> dans certains feeds RSS
// http://doc.spip.org/@date_822
function date_822($date_heure) {
list($annee, $mois, $jour) = recup_date($date_heure);
list($heures, $minutes, $secondes) = recup_heure($date_heure);
$time = mktime($heures, $minutes, $secondes, $mois, $jour, $annee);
return date('r', $time);
}
// http://doc.spip.org/@date_anneemoisjour
function date_anneemoisjour($d) {
if (!$d) $d = date("Y-m-d");
return substr($d, 0, 4) . substr($d, 5, 2) .substr($d, 8, 2);
}
// http://doc.spip.org/@date_anneemois
function date_anneemois($d) {
if (!$d) $d = date("Y-m-d");
return substr($d, 0, 4) . substr($d, 5, 2);
}
// http://doc.spip.org/@date_debut_semaine
function date_debut_semaine($annee, $mois, $jour) {
$w_day = date("w", mktime(0,0,0,$mois, $jour, $annee));
if ($w_day == 0) $w_day = 7; // Gaffe: le dimanche est zero
$debut = $jour-$w_day+1;
return date("Ymd", mktime(0,0,0,$mois,$debut,$annee));
}
// http://doc.spip.org/@date_fin_semaine
function date_fin_semaine($annee, $mois, $jour) {
$w_day = date("w", mktime(0,0,0,$mois, $jour, $annee));
if ($w_day == 0) $w_day = 7; // Gaffe: le dimanche est zero
$debut = $jour-$w_day+1;
return date("Ymd", mktime(0,0,0,$mois,$debut+6,$annee));
}
// http://doc.spip.org/@agenda_connu
function agenda_connu($type)
{
return in_array($type, array('jour','mois','semaine','periode')) ? ' ' : '';
}
// Cette fonction memorise dans un tableau indexe par son 5e arg
// un evenement decrit par les 4 autres (date, descriptif, titre, URL).
// Appellee avec une date nulle, elle renvoie le tableau construit.
// l'indexation par le 5e arg autorise plusieurs calendriers dans une page
// http://doc.spip.org/@agenda_memo
function agenda_memo($date=0 , $descriptif='', $titre='', $url='', $cal='')
{
static $agenda = array();
if (!$date) return $agenda;
$idate = date_ical($date);
$cal = trim($cal); // func_get_args (filtre alterner) rajoute \n !!!!
$agenda[$cal][(date_anneemoisjour($date))][] = array(
'CATEGORIES' => $cal,
'DTSTART' => $idate,
'DTEND' => $idate,
'DESCRIPTION' => texte_script($descriptif),
'SUMMARY' => texte_script($titre),
'URL' => $url);
// toujours retourner vide pour qu'il ne se passe rien
return "";
}
// Cette fonction recoit:
// - un nombre d'evenements,
// - une chaine a afficher si ce nombre est nul,
// - un type de calendrier
// -- et une suite de noms N.
// Elle demande a la fonction precedente son tableau
// et affiche selon le type les elements indexes par N dans ce tableau.
// Si le suite de noms est vide, tout le tableau est pris
// Ces noms N sont aussi des classes CSS utilisees par http_calendrier_init
// Cette fonction recupere aussi par _request les parametres
// jour, mois, annee, echelle, partie_cal (a ameliorer)
// http://doc.spip.org/@agenda_affiche
function agenda_affiche($i)
{
include_spip('inc/agenda');
$args = func_get_args();
// date ou nombre d'evenements (on pourrait l'afficher)
$nb = array_shift($args);
$evt = array_shift($args);
$type = array_shift($args);
spip_log("evt $nb");
if (!$nb) {
$d = array(time());
} else {
$agenda = agenda_memo(0);
$evt = array();
foreach (($args ? $args : array_keys($agenda)) as $k) {
if (is_array($agenda[$k]))
foreach($agenda[$k] as $d => $v) {
$evt[$d] = $evt[$d] ? (array_merge($evt[$d], $v)) : $v;
}
}
$d = array_keys($evt);
}
if (count($d)){
$mindate = min($d);
$start = strtotime($mindate);
} else {
$mindate = ($j=_request('jour')) * ($m=_request('mois')) * ($a=_request('annee'));
if ($mindate)
$start = mktime(0,0,0, $m, $j, $a);
else $start = mktime(0,0,0);
}
if ($type != 'periode')
$evt = array('', $evt);
else {
$min = substr($mindate,6,2);
$max = $min + ((strtotime(max($d)) - $start) / (3600 * 24));
if ($max < 31) $max = 0;
$evt = array('', $evt, $min, $max);
$type = 'mois';
}
return http_calendrier_init($start, $type, _request('echelle'), _request('partie_cal'), self('&'), $evt);
}
//
// Recuperation de donnees dans le champ extra
// Ce filtre n'a de sens qu'avec la balise #EXTRA
//
// http://doc.spip.org/@extra
function extra($letexte, $champ) {
$champs = unserialize($letexte);
return $champs[$champ];
}
// postautobr : transforme les sauts de ligne en _
// http://doc.spip.org/@post_autobr
function post_autobr($texte, $delim="\n_ ") {
$texte = str_replace("\r\n", "\r", $texte);
$texte = str_replace("\r", "\n", $texte);
if (preg_match(",\n+$,", $texte, $fin))
$texte = substr($texte, 0, -strlen($fin = $fin[0]));
else
$fin = '';
$texte = echappe_html($texte, '', true);
$debut = '';
$suite = $texte;
while ($t = strpos('-'.$suite, "\n", 1)) {
$debut .= substr($suite, 0, $t-1);
$suite = substr($suite, $t);
$car = substr($suite, 0, 1);
if (($car<>'-') AND ($car<>'_') AND ($car<>"\n") AND ($car<>"|") AND ($car<>"}")
AND !preg_match(',^\s*(\n|</?(quote|div)|$),S',($suite))
AND !preg_match(',</?(quote|div)> *$,iS', $debut)) {
$debut .= $delim;
} else
$debut .= "\n";
if (preg_match(",^\n+,", $suite, $regs)) {
$debut.=$regs[0];
$suite = substr($suite, strlen($regs[0]));
}
}
$texte = $debut.$suite;
$texte = echappe_retour($texte);
return $texte.$fin;
}
define('_EXTRAIRE_MULTI', "@<multi>(.*?)</multi>@sS");
// Extraire et transformer les blocs multi ; on indique la langue courante
// pour ne pas mettre de span@lang=fr si on est deja en fr
// http://doc.spip.org/@extraire_multi
function extraire_multi($letexte, $lang=null, $echappe_span=false) {
if (preg_match_all(_EXTRAIRE_MULTI, $letexte, $regs, PREG_SET_ORDER)) {
if (!$lang) $lang = $GLOBALS['spip_lang'];
foreach ($regs as $reg) {
// chercher la version de la langue courante
$trads = extraire_trads($reg[1]);
if ($l = approcher_langue($trads, $lang)) {
$trad = $trads[$l];
} else {
include_spip('inc/texte');
// langue absente, prendre la premiere dispo
// mais typographier le texte selon les regles de celle-ci
// Attention aux blocs multi sur plusieurs lignes
$l = key($trads);
$trad = $trads[$l];
$typographie = charger_fonction(lang_typo($l), 'typographie');
$trad = $typographie($trad);
$trad = explode("\n", $trad);
foreach($trad as $i => $ligne) {
if (strlen($ligne)) {
$e = true;
$ligne = code_echappement($ligne, 'multi');
$ligne = str_replace("'", '"', inserer_attribut($ligne, 'lang', $l));
if (lang_dir($l) !== lang_dir($lang))
$ligne = str_replace("'", '"', inserer_attribut($ligne, 'dir', lang_dir($l)));
$trad[$i] = $ligne;
}
}
$trad = join("\n", $trad);
if (!$echappe_span)
$trad = echappe_retour($trad, 'multi');
}
$letexte = str_replace($reg[0], $trad, $letexte);
}
}
return $letexte;
}
// convertit le contenu d'une balise multi en un tableau
// http://doc.spip.org/@extraire_trad
function extraire_trads($bloc) {
$lang = '';
// ce reg fait planter l'analyse multi s'il y a de l'{italique} dans le champ
// while (preg_match("/^(.*?)[{\[]([a-z_]+)[}\]]/siS", $bloc, $regs)) {
while (preg_match("/^(.*?)[\[]([a-z_]+)[\]]/siS", $bloc, $regs)) {
$texte = trim($regs[1]);
if ($texte OR $lang)
$trads[$lang] = $texte;
$bloc = substr($bloc, strlen($regs[0]));
$lang = $regs[2];
}
$trads[$lang] = $bloc;
return $trads;
}
//
// Ce filtre retourne la donnee si c'est la premiere fois qu'il la voit ;
// possibilite de gerer differentes "familles" de donnees |unique{famille}
# |unique{famille,1} affiche le nombre d'elements affiches (preferer toutefois #TOTAL_UNIQUE)
# ameliorations possibles :
# 1) si la donnee est grosse, mettre son md5 comme cle
# 2) purger $mem quand on change de squelette (sinon bug inclusions)
//
// http://www.spip.net/@unique
// http://doc.spip.org/@unique
function unique($donnee, $famille='', $cpt = false) {
static $mem;
// permettre de vider la pile et de la restaurer
// pour le calcul de introduction...
if ($famille=='_spip_raz_'){
$tmp = $mem;
$mem = array();
return $tmp;
} elseif ($famille=='_spip_set_'){
$mem = $donnee;
return;
}
if ($cpt)
return count($mem[$famille]);
if (!($mem[$famille][$donnee]++))
return $donnee;
}
//
// Filtre |alterner
//
// Exemple [(#COMPTEUR_BOUCLE|alterner{'bleu','vert','rouge'})]
//
// http://doc.spip.org/@alterner
function alterner($i) {
// recuperer les arguments (attention fonctions un peu space)
$num = func_num_args();
$args = func_get_args();
if($num == 2 && is_array($args[1])) {
$args = $args[1];
array_unshift($args,'');
$num = count($args);
}
// renvoyer le i-ieme argument, modulo le nombre d'arguments
return $args[(intval($i)-1)%($num-1)+1];
}
// recuperer un attribut d'une balise html
// ($complet demande de retourner $r)
// la regexp est mortelle : cf. tests/filtres/extraire_attribut.php
// Si on a passe un tableau de balises, renvoyer un tableau de resultats
// (dans ce cas l'option $complet n'est pas disponible)
// http://doc.spip.org/@extraire_attribut
function extraire_attribut($balise, $attribut, $complet = false) {
if (is_array($balise)) {
array_walk($balise,
create_function('&$a,$key,$t',
'$a = extraire_attribut($a,$t);'
),
$attribut);
return $balise;
}
if (preg_match(
',(^.*?<(?:(?>\s*)(?>[\w:.-]+)(?>(?:=(?:"[^"]*"|\'[^\']*\'|[^\'"]\S*))?))*?)(\s+'
.$attribut
.'(?:=\s*("[^"]*"|\'[^\']*\'|[^\'"]\S*))?)()([^>]*>.*),isS',
$balise, $r)) {
if ($r[3][0] == '"' || $r[3][0] == "'") {
$r[4] = substr($r[3], 1, -1);
$r[3] = $r[3][0];
} elseif ($r[3]!=='') {
$r[4] = $r[3];
$r[3] = '';
} else {
$r[4] = trim($r[2]);
}
$att = filtrer_entites(str_replace("&#39;", "'", $r[4]));
}
else
$att = NULL;
if ($complet)
return array($att, $r);
else
return $att;
}
// modifier (ou inserer) un attribut html dans une balise
// http://doc.spip.org/@inserer_attribut
function inserer_attribut($balise, $attribut, $val, $proteger=true, $vider=false) {
// preparer l'attribut
// supprimer les &nbsp; etc mais pas les balises html
// qui ont un sens dans un attribut value d'un input
if ($proteger) $val = attribut_html($val,false);
// echapper les ' pour eviter tout bug
$val = str_replace("'", "&#39;", $val);
if ($vider AND strlen($val)==0)
$insert = '';
else
$insert = " $attribut='$val'";
list($old, $r) = extraire_attribut($balise, $attribut, true);
if ($old !== NULL) {
// Remplacer l'ancien attribut du meme nom
$balise = $r[1].$insert.$r[5];
}
else {
// preferer une balise " />" (comme <img />)
if (preg_match(',/>,', $balise))
$balise = preg_replace(",\s?/>,S", $insert." />", $balise, 1);
// sinon une balise <a ...> ... </a>
else
$balise = preg_replace(",\s?>,S", $insert.">", $balise, 1);
}
return $balise;
}
// http://doc.spip.org/@vider_attribut
function vider_attribut ($balise, $attribut) {
return inserer_attribut($balise, $attribut, '', false, true);
}
// Un filtre pour determiner le nom du mode des librement inscrits,
// a l'aide de la liste globale des statuts (tableau mode => nom du mode)
// Utile pour le formulaire d'inscription.
// Si un mode est fourni, verifier que la configuration l'accepte.
// Si mode inconnu laisser faire, c'est une extension non std
// mais verifier que la syntaxe est compatible avec SQL
// http://doc.spip.org/@tester_config
function tester_config($id, $mode='') {
$s = array_search($mode, $GLOBALS['liste_des_statuts']);
switch ($s) {
case 'info_redacteurs' :
return (($GLOBALS['meta']['accepter_inscriptions'] == 'oui') ? $mode : '');
case 'info_visiteurs' :
return (($GLOBALS['meta']['accepter_visiteurs'] == 'oui' OR $GLOBALS['meta']['forums_publics'] == 'abo') ? $mode : '');
default:
if ($mode AND $mode == addslashes($mode))
return $mode;
if ($GLOBALS['meta']["accepter_inscriptions"] == "oui")
return $GLOBALS['liste_des_statuts']['info_redacteurs'];
if ($GLOBALS['meta']["accepter_visiteurs"] == "oui")
return $GLOBALS['liste_des_statuts']['info_visiteurs'];
return '';
}
}
//
// Quelques fonctions de calcul arithmetique
//
// http://doc.spip.org/@plus
function plus($a,$b) {
return $a+$b;
}
// http://doc.spip.org/@moins
function moins($a,$b) {
return $a-$b;
}
// http://doc.spip.org/@mult
function mult($a,$b) {
return $a*$b;
}
// http://doc.spip.org/@div
function div($a,$b) {
return $b?$a/$b:0;
}
// http://doc.spip.org/@modulo
function modulo($nb, $mod, $add=0) {
return ($mod?$nb%$mod:0)+$add;
}
// Verifier la conformite d'une ou plusieurs adresses email
// retourne false ou la normalisation de la derniere adresse donnee
// http://doc.spip.org/@email_valide
function email_valide($adresses) {
// Si c'est un spammeur autant arreter tout de suite
if (preg_match(",[\n\r].*(MIME|multipart|Content-),i", $adresses)) {
spip_log("Tentative d'injection de mail : $adresses");
return false;
}
foreach (explode(',', $adresses) as $v) {
// nettoyer certains formats
// "Marie Toto <Marie@toto.com>"
$adresse = trim(preg_replace(",^[^<>\"]*<([^<>\"]+)>$,i", "\\1", $v));
// RFC 822
if (!preg_match('#^[^()<>@,;:\\"/[:space:]]+(@([-_0-9a-z]+\.)*[-_0-9a-z]+)$#i', $adresse))
return false;
}
return $adresse;
}
// http://doc.spip.org/@afficher_enclosures
function afficher_enclosures($tags) {
$s = array();
foreach (extraire_balises($tags, 'a') as $tag) {
if (extraire_attribut($tag, 'rel') == 'enclosure'
AND $t = extraire_attribut($tag, 'href')) {
$s[] = preg_replace(',>[^<]+</a>,S',
'>'
.http_img_pack(chemin_image('attachment-16.png'), $t,
'title="'.attribut_html($t).'"')
.'</a>', $tag);
}
}
return join('&nbsp;', $s);
}
// http://doc.spip.org/@afficher_tags
function afficher_tags($tags, $rels='tag,directory') {
$s = array();
foreach (extraire_balises($tags, 'a') as $tag) {
$rel = extraire_attribut($tag, 'rel');
if (strstr(",$rels,", ",$rel,"))
$s[] = $tag;
}
return join(', ', $s);
}
// Passe un <enclosure url="fichier" length="5588242" type="audio/mpeg"/>
// au format microformat <a rel="enclosure" href="fichier" ...>fichier</a>
// attention length="zz" devient title="zz", pour rester conforme
// http://doc.spip.org/@enclosure2microformat
function enclosure2microformat($e) {
if (!$url = filtrer_entites(extraire_attribut($e, 'url')))
$url = filtrer_entites(extraire_attribut($e, 'href'));
$type = extraire_attribut($e, 'type');
$length = extraire_attribut($e, 'length');
$fichier = basename($url);
return '<a rel="enclosure"'
. ($url? ' href="'.htmlspecialchars($url).'"' : '')
. ($type? ' type="'.htmlspecialchars($type).'"' : '')
. ($length? ' title="'.htmlspecialchars($length).'"' : '')
. '>'.$fichier.'</a>';
}
// La fonction inverse
// http://doc.spip.org/@microformat2enclosure
function microformat2enclosure($tags) {
$enclosures = array();
foreach (extraire_balises($tags, 'a') as $e)
if (extraire_attribut($e, 'rel') == 'enclosure') {
$url = filtrer_entites(extraire_attribut($e, 'href'));
$type = extraire_attribut($e, 'type');
if (!$length = intval(extraire_attribut($e, 'title')))
$length = intval(extraire_attribut($e, 'length')); # vieux data
$fichier = basename($url);
$enclosures[] = '<enclosure'
. ($url? ' url="'.htmlspecialchars($url).'"' : '')
. ($type? ' type="'.htmlspecialchars($type).'"' : '')
. ($length? ' length="'.$length.'"' : '')
. ' />';
}
return join("\n", $enclosures);
}
// Creer les elements ATOM <dc:subject> a partir des tags
// http://doc.spip.org/@tags2dcsubject
function tags2dcsubject($tags) {
$subjects = '';
foreach (extraire_balises($tags, 'a') as $e) {
if (extraire_attribut($e, rel) == 'tag') {
$subjects .= '<dc:subject>'
. texte_backend(textebrut($e))
. '</dc:subject>'."\n";
}
}
return $subjects;
}
// retourne la premiere balise du type demande
// ex: [(#DESCRIPTIF|extraire_balise{img})]
// Si on a passe un tableau de textes, renvoyer un tableau de resultats
// http://doc.spip.org/@extraire_balise
function extraire_balise($texte, $tag='a') {
if (is_array($texte)) {
array_walk($texte,
create_function('&$a,$key,$t', '$a = extraire_balise($a,$t);'),
$tag);
return $texte;
}
if (preg_match(
",<$tag\b[^>]*(/>|>.*</$tag\b[^>]*>|>),UimsS",
$texte, $regs))
return $regs[0];
}
// extraire toutes les balises du type demande, sous forme de tableau
// Si on a passe un tableau de textes, renvoyer un tableau de resultats
// http://doc.spip.org/@extraire_balises
function extraire_balises($texte, $tag='a') {
if (is_array($texte)) {
array_walk($texte,
create_function('&$a,$key,$t', '$a = extraire_balises($a,$t);'),
$tag);
return $texte;
}
if (preg_match_all(
",<${tag}\b[^>]*(/>|>.*</${tag}\b[^>]*>|>),UimsS",
$texte, $regs, PREG_PATTERN_ORDER))
return $regs[0];
else
return array();
}
// comme in_array mais renvoie son 3e arg si le 2er arg n'est pas un tableau
// prend ' ' comme representant de vrai et '' de faux
// http://doc.spip.org/@in_any
function in_any($val, $vals, $def='') {
if (!is_array($vals) AND $v=unserialize($vals)) $vals = $v;
return (!is_array($vals) ? $def : (in_array($val, $vals) ? ' ' : ''));
}
// valeur_numerique("3*2") => 6
// n'accepte que les *, + et - (a ameliorer si on l'utilise vraiment)
// http://doc.spip.org/@valeur_numerique
function valeur_numerique($expr) {
if (preg_match(',^[0-9]+(\s*[+*-]\s*[0-9]+)*$,S', trim($expr)))
eval("\$a = $expr;");
return intval($a);
}
// http://doc.spip.org/@regledetrois
function regledetrois($a,$b,$c)
{
return round($a*$b/$c);
}
// Fournit la suite de Input-Hidden correspondant aux parametres de
// l'URL donnee en argument, compatible avec les types_urls depuis [14447].
// cf. tests/filtres/form_hidden.html
// http://doc.spip.org/@form_hidden
function form_hidden($action) {
$contexte = array();
include_spip('inc/urls');
if ($p = urls_decoder_url($action, '')
AND reset($p)) {
$fond = array_shift($p);
$contexte = array_shift($p);
$contexte['page'] = $fond;
$action = preg_replace('/([?]'.preg_quote($fond).'[^&=]*[0-9]+)(&|$)/', '?&', $action);
}
// on va remplir un tableau de valeurs en prenant bien soin de ne pas
// ecraser les elements de la forme mots[]=1&mots[]=2
$values = array();
// d'abord avec celles de l'url
if (false !== ($p = strpos($action, '?'))) {
foreach(preg_split('/&(amp;)?/S',substr($action,$p+1)) as $c){
list($var,$val) = explode('=', $c, 2);
if ($var) {
$val = rawurldecode($val);
$var = rawurldecode($var); // decoder les [] eventuels
if (preg_match(',\[\]$,S', $var))
$values[] = array($var, $val);
else if (!isset($values[$var]))
$values[$var] = array($var, $val);
}
}
}
// ensuite avec celles du contexte, sans doublonner !
foreach($contexte as $var=>$val)
if (preg_match(',\[\]$,S', $var))
$values[] = array($var, $val);
else if (!isset($values[$var]))
$values[$var] = array($var, $val);
// puis on rassemble le tout
$hidden = array();
foreach($values as $value) {
list($var,$val) = $value;
$hidden[] = '<input name="'
. entites_html($var)
.'"'
. (is_null($val)
? ''
: ' value="'.entites_html($val).'"'
)
. ' type="hidden" />';
}
return join("\n", $hidden);
}
// http://doc.spip.org/@filtre_bornes_pagination_dist
function filtre_bornes_pagination_dist($courante, $nombre, $max = 10) {
if($max<=0 OR $max>=$nombre)
return array(1, $nombre);
$premiere = max(1, $courante-floor(($max-1)/2));
$derniere = min($nombre, $premiere+$max-2);
$premiere = $derniere == $nombre ? $derniere-$max+1 : $premiere;
return array($premiere, $derniere);
}
// Ces trois fonctions permettent de simuler les filtres |reset et |end
// pour extraire la premiere ou la derniere valeur d'un tableau ; utile
// pour la pagination (mais peut-etre a refaire plus simplement)
// http://doc.spip.org/@filtre_valeur_tableau
function filtre_valeur_tableau($array, $index) {
if (!is_array($array)
OR !isset($array[$index]))
return null;
return $array[$index];
}
// http://doc.spip.org/@filtre_reset
function filtre_reset($array) {
return !is_array($array) ? null : reset($array);
}
// http://doc.spip.org/@filtre_end
function filtre_end($array) {
return !is_array($array) ? null : end($array);
}
// http://doc.spip.org/@filtre_push
function filtre_push($array, $val) {
if($array == '' OR !array_push($array, $val)) return '';
return $array;
}
// http://doc.spip.org/@filtre_find
function filtre_find($array, $val) {
return (is_array($array) AND in_array($val, $array));
}
//
// fonction standard de calcul de la balise #PAGINATION
// on peut la surcharger en definissant filtre_pagination dans mes_fonctions
//
// http://doc.spip.org/@filtre_pagination_dist
function filtre_pagination_dist($total, $nom, $position, $pas, $liste = true, $modele='', $connect='', $env=array()) {
static $ancres = array();
if ($pas<1) return '';
$ancre = 'pagination'.$nom; // #pagination_articles
$debut = 'debut'.$nom; // 'debut_articles'
// n'afficher l'ancre qu'une fois
if (!isset($ancres[$ancre]))
$bloc_ancre = $ancres[$ancre] = "<a name='$ancre' id='$ancre'></a>";
else $bloc_ancre = '';
// liste = false : on ne veut que l'ancre
if (!$liste)
return $ancres[$ancre];
$pagination = array(
'debut' => $debut,
'url' => parametre_url(self(),'fragment',''), // nettoyer l'id ahah eventuel
'total' => $total,
'position' => intval($position),
'pas' => $pas,
'nombre_pages' => floor(($total-1)/$pas)+1,
'page_courante' => floor(intval($position)/$pas)+1,
'ancre' => $ancre,
'bloc_ancre' => $bloc_ancre
);
if (is_array($env))
$pagination = array_merge($env,$pagination);
// Pas de pagination
if ($pagination['nombre_pages']<=1)
return '';
if ($modele) $modele = '_'.$modele;
return recuperer_fond("modeles/pagination$modele", $pagination, array('trim'=>true), $connect);
}
// passer les url relatives a la css d'origine en url absolues
// http://doc.spip.org/@urls_absolues_css
function urls_absolues_css($contenu, $source) {
$path = suivre_lien(url_absolue($source),'./');
return preg_replace_callback(
",url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),Uims",
create_function('$x',
'return "url(\"".suivre_lien("'.$path.'",$x[1])."\")";'
), $contenu);
}
// recuperere le chemin d'une css existante et :
// 1. regarde si une css inversee droite-gauche existe dans le meme repertoire
// 2. sinon la cree (ou la recree) dans _DIR_VAR/cache_css/
// SI on lui donne a manger une feuille nommee _rtl.css il va faire l'inverse
// http://doc.spip.org/@direction_css
function direction_css ($css, $voulue='') {
if (!preg_match(',(_rtl)?\.css$,i', $css, $r)) return $css;
// si on a precise le sens voulu en argument, le prendre en compte
if ($voulue = strtolower($voulue)) {
if ($voulue != 'rtl' AND $voulue != 'ltr')
$voulue = lang_dir($voulue);
}
else
$voulue = lang_dir();
$r = count($r) > 1;
$right = $r ? 'left' : 'right'; // 'right' de la css lue en entree
$dir = $r ? 'rtl' : 'ltr';
$ndir = $r ? 'ltr' : 'rtl';
if ($voulue == $dir)
return $css;
if (
// url absolue
preg_match(",^http:,i",$css)
// ou qui contient un ?
OR (($p=strpos($css,'?'))!==FALSE)) {
$distant = true;
$cssf = parse_url($css);
$cssf = $cssf['path'].($cssf['query']?"?".$cssf['query']:"");
$cssf = preg_replace(',[?:&=],', "_", $cssf);
}
else {
$distant = false;
$cssf = $css;
// 1. regarder d'abord si un fichier avec la bonne direction n'est pas aussi
//propose (rien a faire dans ce cas)
$f = preg_replace(',(_rtl)?\.css$,i', '_'.$ndir.'.css', $css);
if (@file_exists($f))
return $f;
}
// 2.
$dir_var = sous_repertoire (_DIR_VAR, 'cache-css');
$f = $dir_var
. preg_replace(',.*/(.*?)(_rtl)?\.css,', '\1', $cssf)
. '.' . substr(md5($cssf), 0,4) . '_' . $ndir . '.css';
// la css peut etre distante (url absolue !)
if ($distant){
include_spip('inc/distant');
$contenu = recuperer_page($css);
if (!$contenu) return $css;
}
else {
if ((@filemtime($f) > @filemtime($css))
AND ($GLOBALS['var_mode'] != 'recalcul'))
return $f;
if (!lire_fichier($css, $contenu))
return $css;
}
$contenu = str_replace(
array('right', 'left', '@@@@L E F T@@@@'),
array('@@@@L E F T@@@@', 'right', 'left'),
$contenu);
// reperer les @import auxquels il faut propager le direction_css
preg_match_all(",\@import\s*url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),Uims",$contenu,$regs);
$src = array();$src_direction_css = array();$src_faux_abs=array();
$d = dirname($css);
foreach($regs[1] as $k=>$import_css){
$css_direction = direction_css("$d/$import_css",$voulue);
// si la css_direction est dans le meme path que la css d'origine, on tronque le path, elle sera passee en absolue
if (substr($css_direction,0,strlen($d)+1)=="$d/") $css_direction = substr($css_direction,strlen($d)+1);
// si la css_direction commence par $dir_var on la fait passer pour une absolue
elseif (substr($css_direction,0,strlen($dir_var))==$dir_var) {
$css_direction = substr($css_direction,strlen($dir_var));
$src_faux_abs["/@@@@@@/".$css_direction] = $css_direction;
$css_direction = "/@@@@@@/".$css_direction;
}
$src[] = $regs[0][$k];
$src_direction_css[] = str_replace($import_css,$css_direction,$regs[0][$k]);
}
$contenu = str_replace($src,$src_direction_css,$contenu);
$contenu = urls_absolues_css($contenu, $css);
// virer les fausses url absolues que l'on a mis dans les import
if (count($src_faux_abs))
$contenu = str_replace(array_keys($src_faux_abs),$src_faux_abs,$contenu);
if (!ecrire_fichier($f, $contenu))
return $css;
return $f;
}
// recuperere le chemin d'une css existante et :
// cree (ou recree) dans _DIR_VAR/cache_css/ une css dont les url relatives sont passees en url absolues
// http://doc.spip.org/@url_absolue_css
function url_absolue_css ($css) {
if (!preg_match(',\.css$,i', $css, $r)) return $css;
$url_absolue_css = url_absolue($css);
$f = basename($css,'.css');
$f = sous_repertoire (_DIR_VAR, 'cache-css')
. preg_replace(",(.*?)(_rtl|_ltr)?$,","\\1-urlabs-" . substr(md5("$css-urlabs"), 0,4) . "\\2",$f)
. '.css';
if ((@filemtime($f) > @filemtime($css))
AND ($GLOBALS['var_mode'] != 'recalcul'))
return $f;
if ($url_absolue_css==$css){
if (strncmp($GLOBALS['meta']['adresse_site'],$css,$l=strlen($GLOBALS['meta']['adresse_site']))!=0
OR !lire_fichier(_DIR_RACINE . substr($css,$l), $contenu)){
include_spip('inc/distant');
if (!$contenu = recuperer_page($css))
return $css;
}
}
elseif (!lire_fichier($css, $contenu))
return $css;
// passer les url relatives a la css d'origine en url absolues
$contenu = urls_absolues_css($contenu, $css);
// ecrire la css
if (!ecrire_fichier($f, $contenu))
return $css;
return $f;
}
// filtre table_valeur
// permet de recuperer la valeur d'un tableau pour une cle donnee
// prend en entree un tableau serialise ou non (ce qui permet d'enchainer le filtre)
// http://doc.spip.org/@table_valeur
function table_valeur($table,$cle,$defaut=''){
$table= is_string($table)?unserialize($table):$table;
$table= is_array($table)?$table:array();
return isset($table[$cle])?$table[$cle]:$defaut;
}
// filtre match pour faire des tests avec expression reguliere
// [(#TEXTE|match{^ceci$,Uims})]
// retourne le fragment de chaine qui "matche"
// il est possible de passer en 3eme argument optionnel le numero de parenthese capturante
// accepte egalement la syntaxe #TRUC|match{truc(...)$,1} ou le modificateur n'est pas passe en second argument
// http://doc.spip.org/@match
function match($texte, $expression, $modif="UimsS",$capte=0) {
if (intval($modif) AND $capte==0){
$capte = $modif;
$modif = "UimsS";
}
$expression=str_replace("\/","/",$expression);
$expression=str_replace("/","\/",$expression);
if (preg_match('/' . $expression . '/' . $modif,$texte, $r)) {
if (isset($r[$capte]))
return $r[$capte];
else
return true;
}
return false;
}
// filtre replace pour faire des operations avec expression reguliere
// [(#TEXTE|replace{^ceci$,cela,UimsS})]
// http://doc.spip.org/@replace
function replace($texte, $expression, $replace='', $modif="UimsS") {
$expression=str_replace("\/","/", $expression);
$expression=str_replace("/","\/",$expression);
return preg_replace('/' . $expression . '/' . $modif, $replace, $texte);
}
// cherche les documents numerotes dans un texte traite par propre()
// et affecte les doublons['documents']
// http://doc.spip.org/@traiter_doublons_documents
// http://doc.spip.org/@traiter_doublons_documents
function traiter_doublons_documents(&$doublons, $letexte) {
// Verifier dans le texte & les notes (pas beau, helas)
$t = $letexte.$GLOBALS['les_notes'];
if (strstr($t, 'spip_document_') // evite le preg_match_all si inutile
AND preg_match_all(
',<[^>]+\sclass=["\']spip_document_([0-9]+)[\s"\'],imsS',
$t, $matches, PREG_PATTERN_ORDER))
$doublons['documents'] .= "," . join(',', $matches[1]);
return $letexte;
}
// filtre vide qui ne renvoie rien
// http://doc.spip.org/@vide
function vide($texte){
return "";
}
//
// Filtres pour le modele/emb (embed document)
//
// A partir d'un #ENV, retourne des <param ...>
// http://doc.spip.org/@env_to_params
function env_to_params ($texte, $ignore_params=array()) {
$ignore_params = array_merge (
array('id', 'lang', 'id_document', 'date', 'date_redac', 'align', 'fond', '', 'recurs', 'emb', 'dir_racine'),
$ignore_params);
$tableau = unserialize($texte);
$texte = "";
foreach ($tableau as $i => $j)
if (is_string($j) AND !in_array($i,$ignore_params))
$texte .= "<param name='".$i."'\n\tvalue='".$j."' />";
return $texte;
}
// A partir d'un #ENV, retourne des attributs
// http://doc.spip.org/@env_to_attributs
function env_to_attributs ($texte, $ignore_params=array()) {
$ignore_params = array_merge (
array('id', 'lang', 'id_document', 'date', 'date_redac', 'align', 'fond', '', 'recurs', 'emb', 'dir_racine'),
$ignore_params);
$tableau = unserialize($texte);
$texte = "";
foreach ($tableau as $i => $j)
if (is_string($j) AND !in_array($i,$ignore_params))
$texte .= $i."='".$j."' ";
return $texte;
}
// Concatener des chaines
// #TEXTE|concat{texte1,texte2,...}
// http://doc.spip.org/@concat
function concat(){
$args = func_get_args();
return join('', $args);
}
// http://doc.spip.org/@charge_scripts
function charge_scripts($scripts) {
$flux = "";
$args = is_array($scripts)?$scripts:explode("|",$scripts);
foreach($args as $script) {
if(preg_match(",^\w+$,",$script)) {
$path = find_in_path("javascript/$script.js");
if($path) $flux .= spip_file_get_contents($path);
}
}
return $flux;
}
// produit une balise img avec un champ alt d'office si vide
// attention le htmlentities et la traduction doivent etre appliques avant.
// http://doc.spip.org/@http_wrapper
function http_wrapper($img){
if (strpos($img,'/')===FALSE) // on ne prefixe par _NOM_IMG_PACK que si c'est un nom de fichier sans chemin
$f = chemin_image($img);
else { // sinon, le path a ete fourni
$f = $img;
}
return $f;
}
// http://doc.spip.org/@http_img_pack
function http_img_pack($img, $alt, $atts='', $title='') {
$img = http_wrapper($img);
if (strpos($atts, 'width')===FALSE){
// utiliser directement l'info de taille presente dans le nom
if (preg_match(',-([0-9]+)[.](png|gif)$,',$img,$regs)){
$size = array(intval($regs[1]),intval($regs[1]));
}
else
$size = @getimagesize($img);
$atts.=" width='".$size[0]."' height='".$size[1]."'";
}
return "<img src='" . $img
. ("'\nalt=\"" .
str_replace('"','', textebrut($alt ? $alt : ($title ? $title : '')))
. '" ')
. ($title ? "title=\"$title\" " : '')
. $atts
. " />";
}
// http://doc.spip.org/@http_style_background
function http_style_background($img, $att='')
{
return " style='background: url(\"".http_wrapper($img)."\")" .
($att ? (' ' . $att) : '') . ";'";
}
//[(#ENV*|unserialize|foreach)]
// http://doc.spip.org/@filtre_foreach_dist
function filtre_foreach_dist($balise_deserializee, $modele = 'foreach') {
$texte = '';
if(is_array($balise_deserializee))
foreach($balise_deserializee as $k => $v) {
$res = recuperer_fond('modeles/'.$modele,
array_merge(array('cle' => $k), (is_array($v) ? $v : array('valeur' => $v)))
);
$texte .= $res;
}
return $texte;
}
// renvoie la liste des plugins actifs du site
// si le premier parametre est un prefix de cette liste, renvoie vrai, faux sinon
// la valeur du second parametre si celui-ci renvoie a une information connue
// cf liste_plugin_actifs() pour connaitre les informations affichables
// appelee par la balise #PLUGIN
// http://doc.spip.org/@filtre_info_plugin_dist
function filtre_info_plugin_dist($plugin, $type_info) {
include_spip('inc/plugin');
$plugin = strtoupper($plugin);
$plugins_actifs = liste_plugin_actifs();
if (!$plugin)
return serialize(array_keys($plugins_actifs));
elseif (empty($plugins_actifs[$plugin]))
return '';
elseif ($type_info == 'est_actif')
return $plugins_actifs[$plugin] ? 1 : 0;
elseif (isset($plugins_actifs[$plugin][$type_info]))
return $plugins_actifs[$plugin][$type_info];
else {
$get_infos = charger_fonction('get_infos','plugins');
if (!$infos = $get_infos($plugins_actifs[$plugin]['dir']))
return '';
if ($type_info == 'tout')
return $infos;
else
return strval($infos[$type_info]);
}
}
// http://doc.spip.org/@puce_changement_statut
function puce_changement_statut($id_objet, $statut, $id_rubrique, $type, $ajax=false){
$puce_statut = charger_fonction('puce_statut','inc');
return $puce_statut($id_objet, $statut, $id_rubrique, $type, $ajax=false);
}
// Encoder un contexte pour l'ajax, le signer avec une cle, le crypter
// avec le secret du site, le gziper si possible...
// l'entree peut etre serialisee (le #ENV** des fonds ajax et ajax_stat)
// http://doc.spip.org/@encoder_contexte_ajax
function encoder_contexte_ajax($c,$form='', $emboite=NULL) {
if (is_string($c)
AND !is_null(@unserialize($c)))
$c = unserialize($c);
// supprimer les parametres debut_x
// pour que la pagination ajax ne soit pas plantee
// si on charge la page &debut_x=1 : car alors en cliquant sur l'item 0,
// le debut_x=0 n'existe pas, et on resterait sur 1
foreach ($c as $k => $v)
if (strpos($k,'debut_') === 0)
unset($c[$k]);
include_spip("inc/securiser_action");
$cle = calculer_cle_action($form.(is_array($c)?serialize($c):$c));
$c = serialize(array($c,$cle));
if ((defined('_CACHE_CONTEXTES_AJAX') AND _CACHE_CONTEXTES_AJAX)
AND $dir = sous_repertoire(_DIR_CACHE, 'contextes')) {
// stocker les contextes sur disque et ne passer qu'un hash dans l'url
$md5 = md5($c);
ecrire_fichier("$dir/c$md5",$c);
$c = $md5;
} else {
if (function_exists('gzdeflate') && function_exists('gzinflate'))
$c = gzdeflate($c);
$c = _xor($c);
$c = base64_encode($c);
}
if ($emboite === NULL) return $c;
return !trim($emboite) ? '' :
"<div class='ajaxbloc env-$c'>\n$emboite</div><!-- ajaxbloc -->\n";
}
// la procedure inverse de encoder_contexte_ajax()
// http://doc.spip.org/@decoder_contexte_ajax
function decoder_contexte_ajax($c,$form='') {
include_spip("inc/securiser_action");
if (( (defined('_CACHE_CONTEXTES_AJAX') AND _CACHE_CONTEXTES_AJAX) OR strlen($c)==32)
AND $dir = sous_repertoire(_DIR_CACHE, 'contextes')
AND lire_fichier("$dir/c$c",$contexte)) {
$c = $contexte;
} else {
$c = @base64_decode($c);
$c = _xor($c);
if (function_exists('gzdeflate') && function_exists('gzinflate'))
$c = @gzinflate($c);
}
list($env, $cle) = @unserialize($c);
if ($cle == calculer_cle_action($form.(is_array($env)?serialize($env):$env)))
return $env;
return false;
}
// encrypter/decrypter un message
// http://www.php.net/manual/fr/language.operators.bitwise.php#81358
// http://doc.spip.org/@_xor
function _xor($message, $key=null){
if (is_null($key)) {
include_spip("inc/securiser_action");
$key = pack("H*", calculer_cle_action('_xor'));
}
$keylen = strlen($key);
$messagelen = strlen($message);
for($i=0; $i<$messagelen; $i++)
$message[$i] = ~($message[$i]^$key[$i%$keylen]);
return $message;
}
// Les vrai fonctions sont dans le plugin forum, mais on evite ici une erreur du compilateur
// en absence du plugin
function url_reponse_forum($texte){return $texte;}
function url_rss_forum($texte){return $texte;}
/**
* une fonction pour generer des menus avec liens
* ou un <strong class='on'> non clicable lorsque l'item est selectionne
*
* @param string $url
* @param string $libelle
* le texte du lien
* @param bool $on
* etat expose (genere un strong) ou non (genere un lien)
* @param string $class
* @param string $title
* @param string $rel
* @param string $evt
* complement a la balise a pour gerer un evenement javascript, de la forme " onclick='...'"
* @return string
*/
function lien_ou_expose($url,$libelle=NULL,$on=false,$class="",$title="",$rel="", $evt=''){
if ($on) {
$bal = "strong";
$att = "class='on'";
} else {
$bal = 'a';
$att = "href='$url'"
.($title?" title='".attribut_html($title)."'":'')
.($class?" class='".attribut_html($class)."'":'')
.($rel?" rel='".attribut_html($rel)."'":'')
.$evt;
}
if (NULL == $libelle)
$libelle = $url;
return "<$bal $att>$libelle</$bal>";
}
/**
* une fonction pour generer une balise img a partir d'un nom de fichier
*
* @param string $img
* @param string $alt
* @param string $class
* @return string
*/
function filtre_balise_img_dist($img,$alt="",$class=""){
$taille = taille_image($img);
list($hauteur,$largeur) = $taille;
if (!$hauteur OR !$largeur)
return "";
return
"<img src='$img' width='$largeur' height='$hauteur'"
." alt='".attribut_html($alt)."'"
.($class?" class='".attribut_html($class)."'":'')
.' />';
}
/**
* Afficher un message "un truc"/"N trucs"
*
* @param int $nb
* @return string
*/
function singulier_ou_pluriel($nb,$chaine_un,$chaine_plusieurs,$var='nb'){
if (!$nb=intval($nb)) return "";
if ($nb>1) return _T($chaine_plusieurs, array($var => $nb));
else return _T($chaine_un);
}
/**
* Fonction de base pour une icone dans un squelette
* structure html : <span><a><img><b>texte</b></span>
*
* @param <type> $lien
* url
* @param <type> $texte
* texte du lien / alt de l'image
* @param <type> $fond
* objet avec ou sans son extension et sa taille (article, article-24, article-24.png)
* @param string $fonction
* new/del/edit
* @param <type> $class
* classe supplementaire (horizontale, verticale, ajax ...)
* @param <type> $javascript
* "onclick='...'" par exemple
* @return string
*/
function icone_base($lien, $texte, $fond, $fonction="", $class="",$javascript=""){
if (in_array($fonction,array("del","supprimer.gif")))
$class .= ' danger';
elseif ($fonction == "rien.gif")
$fonction = "";
// remappage des icone : article-24.png+new => article-new-24.png
if ($icone_renommer = charger_fonction('icone_renommer','inc',true))
list($fond,$fonction) = $icone_renommer($fond,$fonction);
// ajouter le type d'objet dans la class de l'icone
$class .= " " . substr(basename($fond),0,-4);
$alt = attribut_html($texte);
$title = " title=\"$alt\""; // est-ce pertinent de doubler le alt par un title ?
$ajax = "";
if (strpos($class,"ajax")!==false)
$ajax=" class='ajax'";
$size = 24;
if (preg_match("/-([0-9]{1,3})[.](gif|png)$/i",$fond,$match))
$size = $match[1];
if ($fonction){
// 2 images pour composer l'icone : le fond (article) en background,
// la fonction (new) en image
$icone = http_img_pack($fonction, $alt, "width='$size' height='$size'\n" .
http_style_background($fond, "no-repeat center center"));
}
else {
$icone = http_img_pack($fond, $alt, "width='$size' height='$size'");
}
$icone = "<span class='icone s$size $class'>"
. "<a href='$lien'$title$ajax$javascript>"
. $icone
. "<b>$texte</b>"
. "</a></span>\n";
return $icone;
}
function filtre_icone_verticale_dist($lien, $texte, $fond, $fonction="", $class="",$javascript=""){
return icone_base($lien,$texte,$fond,$fonction,"verticale $class",$javascript);
}
function filtre_icone_horizontale_dist($lien, $texte, $fond, $fonction="", $class="",$javascript=""){
return icone_base($lien,$texte,$fond,$fonction,"horizontale $class",$javascript);
}
/**
* Filtre icone pour compatibilite
* mappe sur icone_base
*/
function filtre_icone_dist($lien, $texte, $fond, $align="", $fonction="", $class="",$javascript=""){
return icone_base($lien,$texte,$fond,$fonction,"verticale $align $class",$javascript);
}
/**
* filtre explode pour les squelettes permettant d'ecrire
* #GET{truc}|explode{-}
*
* @param strong $a
* @param string $b
* @return array
*/
function filtre_explode_dist($a,$b){return explode($b,$a);}
/**
* filtre implode pour les squelettes permettant d'ecrire
* #GET{truc}|implode{-}
*
* @param array $a
* @param string $b
* @return string
*/
function filtre_implode_dist($a,$b){return is_array($a)?implode($b,$a):$a;}
/**
* Produire les styles prives qui associent item de menu avec icone en background
* @return string
*/
function bando_images_background(){
include_spip('inc/bandeau');
// recuperer tous les boutons et leurs images
$boutons = definir_barre_boutons(definir_barre_contexte(),true,false);
$res = "";
foreach($boutons as $page => $detail){
if ($detail->icone AND strlen(trim($detail->icone)))
$res .="\n.navigation_avec_icones #bando1_$page {background-image:url(".$detail->icone.");}";
$selecteur = ($page=='outils_rapides'?"":".navigation_avec_icones ");
if (is_array($detail->sousmenu))
foreach($detail->sousmenu as $souspage=>$sousdetail)
if ($sousdetail->icone AND strlen(trim($sousdetail->icone)))
$res .="\n$selecteur.bando2_$souspage {background-image:url(".$sousdetail->icone.");}";
}
return $res;
}
/**
* Trouver une eventuelle css de surcharge dans le theme prive
* a inclure dans les styles prives
*
* @return <type>
*/
function bando_style_prive_theme() {
if ($f = find_in_theme('style_prive_theme.html'))
return substr(preg_replace(',[.]html$,Ui','',$f),strlen(_DIR_RACINE));
return '';
}
/**
* Generer un bouton_action
* utilise par #BOUTON_ACTION
*
* @param string $libelle
* @param string $url
* @param string $class
* @param string $confirm
* @param string $title
* @return string
*/
function bouton_action($libelle, $url, $class="", $confirm="", $title=""){
$onclick = $confirm?" onclick='return confirm(\"" . attribut_html($confirm) . "\");'":"";
$title = $title ? " title='$title'" : "";
return "<form class='bouton_action_post $class' method='post' action='$url'><div>".form_hidden($url)
."<button type='submit' class='submit'$title$onclick>$libelle</button></div></form>";
}
/**
* Proteger les champs passes dans l'url et utiliser dans {tri ...}
* preserver l'espace pour interpreter ensuite num xxx et multi xxx
* @param string $t
* @return string
*/
function tri_protege_champ($t){
return preg_replace(',[^\s\w.+],','',$t);
}
/**
* Interpreter les multi xxx et num xxx utilise comme tri
* pour la clause order
* 'multi xxx' devient simplement 'multi' qui est calcule dans le select
* @param string $t
* @return string
*/
function tri_champ_order($t){
if (strncmp($t,'num ',4)==0){
$t = substr($t,4);
$t = preg_replace(',\s,','',$t);
$t = "0+$t";
return $t;
}
elseif(strncmp($t,'multi ',6)==0){
return "multi";
}
return preg_replace(',\s,','',$t);
}
/**
* Interpreter les multi xxx et num xxx utilise comme tri
* pour la clause select
* 'multi xxx' devient select "...." as multi
* les autres cas ne produisent qu'une chaine vide '' en select
*
* @param string $t
* @return string
*/
function tri_champ_select($t){
if(strncmp($t,'multi ',6)==0){
$t = substr($t,6);
$t = preg_replace(',\s,','',$t);
$t = sql_multi($t,$GLOBALS['spip_lang']);
return $t;
}
return "''";
}
/**
* Donner n'importe quelle information sur un objet de maniere generique.
*
* La fonction va gerer en interne deux cas particuliers les plus utilises :
* l'URL et le titre (qui n'est pas forcemment le champ SQL "titre").
*
* On peut ensuite personnaliser les autres infos en creant une fonction
* generer_<nom_info>_entite($id_objet, $type_objet, $ligne).
* $ligne correspond a la ligne SQL de tous les champs de l'objet, les fonctions
* de personnalisation n'ont donc pas a refaire de requete.
*
* @param int $id_objet
* @param string $type_objet
* @param string $info
* @return string
*/
function generer_info_entite($id_objet, $type_objet, $info){
// On verifie qu'on a tout ce qu'il faut
$id_objet = intval($id_objet);
if (!($id_objet and $type_objet and $info))
return '';
// Si on demande l'url, on retourne direct la fonction
if ($info == 'url')
return generer_url_entite($id_objet, $type_objet);
// Si on demande le titre, on le gere en interne
if ($demande_titre = ($info == 'titre')){
global $table_titre;
$champ_titre = $table_titre[table_objet($type_objet)];
if (!$champ_titre) $champ_titre = 'titre';
$champ_titre = ", $champ_titre";
}
// Sinon on va tout chercher dans la table et on garde en memoire
static $objets;
// On ne fait la requete que si on a pas deja l'objet ou si on demande le titre mais qu'on ne l'a pas encore
if (!$objets[$type_objet][$id_objet] or ($demande_titre and !$objets[$type_objet][$id_objet]['titre'])){
include_spip('base/abstract_sql');
include_spip('base/connect_sql');
$objets[$type_objet][$id_objet] = sql_fetsel(
'*'.$champ_titre,
table_objet_sql($type_objet),
id_table_objet($type_objet).' = '.intval($id_objet)
);
}
$ligne = $objets[$type_objet][$id_objet];
if ($demande_titre)
$info_generee = $objets[$type_objet][$id_objet]['titre'];
// Si la fonction generer_TRUC_entite existe, on l'utilise
else if ($generer = charger_fonction("generer_${info}_entite", '', true))
$info_generee = $generer($id_objet, $type_objet, $ligne);
// Sinon on prend le champ SQL
else
$info_generee = $ligne[$info];
// On va ensuite chercher les traitements automatiques a faire
global $table_des_traitements;
$maj = strtoupper($info);
$traitement = $table_des_traitements[$maj];
$table_objet = table_objet($type_objet);
if (is_array($traitement)){
$traitement = $traitement[isset($traitement[$table_objet]) ? $table_objet : 0];
$traitement = str_replace('%s', '"'.str_replace('"', '\\"', $info_generee).'"', $traitement);
eval("\$info_generee = $traitement;");
}
return $info_generee;
}
/**
* Wrap un texte avec des balises
* wrap('mot','<b>') => '<b>mot</b>'
* @param string $texte
* @param string $wrap
* @return string
*/
function wrap($texte,$wrap) {
$balises = extraire_balises($wrap);
if (preg_match_all(",<([a-z]\w*)\b[^>]*>,UimsS",$wrap, $regs, PREG_PATTERN_ORDER)) {
$texte = $wrap . $texte;
$regs = array_reverse($regs[1]);
$wrap = "</".implode("></",$regs).">";
$texte = $texte . $wrap;
}
return $texte;
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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;
/**
* #BOITE_OUVRIR{titre[,type]}
* Racourci pour ouvrir une boite (info, simple, pour noisette ...)
*
* @param <type> $p
* @return <type>
*/
function balise_BOITE_OUVRIR_dist($p) {
$_titre = interprete_argument_balise(1,$p);
$_class = interprete_argument_balise(2,$p);
$_head_class = interprete_argument_balise(3,$p);
$_titre = ($_titre?$_titre:"''");
$_class = ($_class?", $_class":", 'simple'");
$_head_class = ($_head_class?", $_head_class":"");
$f = chercher_filtre('boite_ouvrir');
$p->code = "$f($_titre$_class$_head_class)";
$p->interdire_scripts = false;
return $p;
}
/**
* #BOITE_PIED{class}
* Racourci pour passer au pied de la boite, avant sa fermeture
*
* @param <type> $p
* @return <type>
*/
function balise_BOITE_PIED_dist($p) {
$_class = interprete_argument_balise(1,$p);
$_class = ($_class?"$_class":"");
$f = chercher_filtre('boite_pied');
$p->code = "$f($_class)";
$p->interdire_scripts = false;
return $p;
}
/**
* #BOITE_FERMER
* Racourci pour fermer une boite ouverte
*
* @param <type> $p
* @return <type>
*/
function balise_BOITE_FERMER_dist($p) {
$f = chercher_filtre('boite_fermer');
$p->code = "$f()";
$p->interdire_scripts = false;
return $p;
}
/**
* Ouvrir une boite
* peut etre surcharge par filtre_boite_ouvrir_dist, filtre_boite_ouvrir
*
* @param string $titre
* @param string $class
* @return <type>
*/
function boite_ouvrir($titre, $class='', $head_class=''){
$class = "box $class";
$head_class = "hd $head_class";
// dans l'espace prive, titrer en h3 si pas de balise <hn>
if (test_espace_prive() AND strlen($titre) AND strpos($titre,'<h')===false)
$titre = "<h3>$titre</h3>";
return '<div class="'.$class.'">'
.'<b class="top"><b class="tl"></b><b class="tr"></b></b>'
.'<div class="inner">'
.($titre?'<div class="'.$head_class.'">'.$titre.'</div>':'')
.'<div class="bd">';
}
/**
* Passer au pied d'une boite
* peut etre surcharge par filtre_boite_pied_dist, filtre_boite_pied
*
* @param <type> $class
* @return <type>
*/
function boite_pied($class='act'){
$class = "ft $class";
return '</div>'
.'<div class="'.$class.'">';
}
/**
* Fermer une boite
* peut etre surcharge par filtre_boite_fermer_dist, filtre_boite_fermer
*
* @return <type>
*/
function boite_fermer(){
return '</div></div>'
.'<b class="bottom"><b class="bl"></b><b class="br"></b></b>'
.'</div>';
}
?>
\ No newline at end of file
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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_boites');
/**
* Fonctions utilises au calcul des squelette du prive.
*/
/**
* Bloquer l'acces a une page en renvoyant vers 403
* @param bool $ok
*/
function interdire_acces($ok=false) {
if ($ok) return '';
ob_end_clean(); // vider tous les tampons
$echec = charger_fonction('403','exec');
$echec();
#include_spip('inc/headers');
#redirige_formulaire(generer_url_ecrire('403','acces='._request('exec')));
exit;
}
// http://doc.spip.org/@chercher_rubrique
function chercher_rubrique($msg,$id, $id_parent, $type, $id_secteur, $restreint,$actionable = false, $retour_sans_cadre=false){
global $spip_lang_right;
include_spip('inc/autoriser');
if (intval($id) && !autoriser('modifier', $type, $id))
return "";
if (!sql_countsel('spip_rubriques'))
return "";
$chercher_rubrique = charger_fonction('chercher_rubrique', 'inc');
$form = $chercher_rubrique($id_parent, $type, $restreint, ($type=='rubrique')?$id:0);
if ($id_parent == 0) $logo = "racine-24.png";
elseif ($id_secteur == $id_parent) $logo = "secteur-24.png";
else $logo = "rubrique-24.png";
$confirm = "";
if ($type=='rubrique') {
// si c'est une rubrique-secteur contenant des breves, demander la
// confirmation du deplacement
$contient_breves = sql_countsel('spip_breves', "id_rubrique=$id");
if ($contient_breves > 0) {
$scb = ($contient_breves>1? 's':'');
$scb = _T('avis_deplacement_rubrique',
array('contient_breves' => $contient_breves,
'scb' => $scb));
$confirm .= "\n<div class='confirmer_deplacement verdana2'><div class='choix'><input type='checkbox' name='confirme_deplace' value='oui' id='confirme-deplace' /><label for='confirme-deplace'>" . $scb . "</label></div></div>\n";
} else
$confirm .= "<input type='hidden' name='confirme_deplace' value='oui' />\n";
}
$form .= $confirm;
if ($actionable){
if (strpos($form,'<select')!==false) {
$form .= "<div style='text-align: $spip_lang_right;'>"
. '<input class="fondo" type="submit" value="'._T('bouton_choisir').'"/>'
. "</div>";
}
$form = "<input type='hidden' name='editer_$type' value='oui' />\n" . $form;
$form = generer_action_auteur("editer_$type", $id, self(), $form, " method='post' class='submit_plongeur'");
}
if ($retour_sans_cadre)
return $form;
include_spip('inc/presentation');
return debut_cadre_couleur($logo, true, "", $msg) . $form .fin_cadre_couleur(true);
}
// http://doc.spip.org/@avoir_visiteurs
function avoir_visiteurs($past=false, $accepter=true) {
if ($GLOBALS['meta']["forums_publics"] == 'abo') return true;
if ($accepter AND $GLOBALS['meta']["accepter_visiteurs"] <> 'non') return true;
if (sql_countsel('spip_articles', "accepter_forum='abo'"))return true;
if (!$past) return false;
return sql_countsel('spip_auteurs', "statut NOT IN ('0minirezo','1comite', 'nouveau', '5poubelle')");
}
?>
\ No newline at end of file
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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'); // par precaution
/**
* Transforme une couleur vectorielle R,G,B en hexa
*
* @param int $red
* @param int $green
* @param int $blue
* @return string
*/
function _couleur_dec_to_hex($red, $green, $blue) {
$red = dechex($red);
$green = dechex($green);
$blue = dechex($blue);
if (strlen($red) == 1) $red = "0".$red;
if (strlen($green) == 1) $green = "0".$green;
if (strlen($blue) == 1) $blue = "0".$blue;
return "$red$green$blue";
}
/**
* Transforme une couleur hexa en vectorielle R,G,B
*
* @param string $couleur
* @return array
*/
function _couleur_hex_to_dec($couleur) {
$couleur = couleur_html_to_hex($couleur);
$couleur = preg_replace(",^#,","",$couleur);
$retour["red"] = hexdec(substr($couleur, 0, 2));
$retour["green"] = hexdec(substr($couleur, 2, 2));
$retour["blue"] = hexdec(substr($couleur, 4, 2));
return $retour;
}
function statut_effacer_images_temporaires($stat){
static $statut = false; // par defaut on grave toute les images
if ($stat==='get') return $statut;
$statut = $stat?true:false;
}
// http://doc.spip.org/@cherche_image_nommee
function cherche_image_nommee($nom, $formats = array ('gif', 'jpg', 'png')) {
if (strncmp(_DIR_IMG, $nom,$n=strlen(_DIR_IMG))==0) {
$nom = substr($nom,$n);
} else if (strncmp(_DIR_IMG_PACK, $nom,$n=strlen(_DIR_IMG_PACK))==0) {
$nom = substr($nom,$n);
} else if (strncmp(_DIR_IMG_ICONE_DIST, $nom,$n=strlen(_DIR_IMG_ICONES_DIST))==0) {
$nom = substr($nom,$n);
}
$pos = strrpos($nom, "/");
if ($pos > 0) {
$chemin = substr($nom, 0, $pos+1);
$nom = substr($nom, $pos+1);
} else {
$chemin = "";
}
reset($formats);
while (list(, $format) = each($formats)) {
if (@file_exists(_DIR_IMG . "$chemin$nom.$format")){
return array((_DIR_IMG . $chemin), $nom, $format);
} else if (@file_exists(_DIR_IMG_PACK . "$chemin$nom.$format")){
return array((_DIR_IMG_PACK . $chemin), $nom, $format);
} else if (@file_exists(_DIR_IMG_ICONES_DIST . "$chemin$nom.$format")){
return array((_DIR_IMG_ICONES_DIST . $chemin), $nom, $format);
}
}
}
// Fonctions de traitement d'image
// uniquement pour GD2
// http://doc.spip.org/@image_valeurs_trans
function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_creation = NULL, $find_in_path = false) {
static $images_recalcul = array();
if (strlen($img)==0) return false;
$source = trim(extraire_attribut($img, 'src'));
if (strlen($source) < 1){
$source = $img;
$img = "<img src='$source' />";
}
// les protocoles web prennent au moins 3 lettres
if (preg_match(';^(\w{3,7}://);', $source)){
include_spip('inc/distant');
$fichier = _DIR_RACINE . copie_locale($source);
if (!$fichier) return "";
} else {
// enlever le timestamp eventuel
$source=preg_replace(',[?][0-9]+$,','',$source);
$fichier = $source;
}
$terminaison_dest = "";
if (preg_match(",^(?>.*)(?<=\.(gif|jpg|png)),", $fichier, $regs)) {
$terminaison = $regs[1];
$terminaison_dest = $terminaison;
if ($terminaison == "gif") $terminaison_dest = "png";
}
if ($forcer_format!==false) $terminaison_dest = $forcer_format;
if (!$terminaison_dest) return false;
$term_fonction = $terminaison;
if ($term_fonction == "jpg") $term_fonction = "jpeg";
$nom_fichier = substr($fichier, 0, strlen($fichier) - 4);
$fichier_dest = $nom_fichier;
if (($find_in_path AND $f=find_in_path($fichier) AND $fichier=$f)
OR @file_exists($f = $fichier)){
// on passe la balise img a taille image qui exraira les attributs si possible
// au lieu de faire un acces disque sur le fichier
list ($ret["hauteur"],$ret["largeur"]) = taille_image($find_in_path?$f:$img);
$date_src = @filemtime($f);
}
elseif (@file_exists($f = "$fichier.src")
AND lire_fichier($f,$valeurs)
AND $valeurs=unserialize($valeurs)
AND isset($valeurs["hauteur_dest"])
AND isset($valeurs["largeur_dest"])) {
$ret["hauteur"] = $valeurs["hauteur_dest"];
$ret["largeur"] = $valeurs["largeur_dest"];
$date_src = $valeurs["date"];
}
// pas de fichier source par la
else
return false;
// pas de taille mesurable
if (!($ret["hauteur"] OR $ret["largeur"]))
return false;
// cas general :
// on a un dossier cache commun et un nom de fichier qui varie avec l'effet
// cas particulier de reduire :
// un cache par dimension, et le nom de fichier est conserve, suffixe par la dimension aussi
$cache = "cache-gd2";
if (substr($effet,0,7)=='reduire') {
list(,$maxWidth,$maxHeight) = explode('-',$effet);
list ($destWidth,$destHeight) = _image_ratio($ret['largeur'], $ret['hauteur'], $maxWidth, $maxHeight);
$ret['largeur_dest'] = $destWidth;
$ret['hauteur_dest'] = $destHeight;
$effet = "L{$destWidth}xH$destHeight";
$cache = "cache-vignettes";
$fichier_dest = basename($fichier_dest);
if (($ret['largeur']<=$maxWidth)&&($ret['hauteur']<=$maxHeight)){
// on garde la terminaison initiale car image simplement copiee
// et on postfixe son nom avec un md5 du path
$terminaison_dest = $terminaison;
$fichier_dest .= '-'.substr(md5("$fichier"),0,5);
}
else
$fichier_dest .= '-'.substr(md5("$fichier-$effet"),0,5);
$cache = sous_repertoire(_DIR_VAR, $cache);
$cache = sous_repertoire($cache, $effet);
# cherche un cache existant
/*foreach (array('gif','jpg','png') as $fmt)
if (@file_exists($cache . $fichier_dest . '.' . $fmt)) {
$terminaison_dest = $fmt;
}*/
}
else {
$fichier_dest = md5("$fichier-$effet");
$cache = sous_repertoire(_DIR_VAR, $cache);
}
$fichier_dest = $cache . $fichier_dest . "." .$terminaison_dest;
$GLOBALS["images_calculees"][] = $fichier_dest;
$creer = true;
// si recalcul des images demande, recalculer chaque image une fois
if (isset($GLOBALS['var_images']) && $GLOBALS['var_images'] && !isset($images_recalcul[$fichier_dest])){
$images_recalcul[$fichier_dest] = true;
}
else {
if (@file_exists($f = $fichier_dest)){
if (filemtime($f)>=$date_src)
$creer = false;
}
else if (@file_exists($f = "$fichier_dest.src")
AND lire_fichier($f,$valeurs)
AND $valeurs=unserialize($valeurs)
AND $valeurs["date"]>=$date_src)
$creer = false;
}
if ($creer) {
if (!@file_exists($fichier)) {
if (!@file_exists("$fichier.src")) {
spip_log("Image absente : $fichier");
return false;
}
# on reconstruit l'image source absente a partir de la chaine des .src
reconstruire_image_intermediaire($fichier);
}
}
// todo: si une image png est nommee .jpg, le reconnaitre avec le bon $f
$ret["fonction_imagecreatefrom"] = "imagecreatefrom".$term_fonction;
$ret["fichier"] = $fichier;
$ret["fonction_image"] = "_image_image".$terminaison_dest;
$ret["fichier_dest"] = $fichier_dest;
$ret["format_source"] = $terminaison;
$ret["format_dest"] = $terminaison_dest;
$ret["date_src"] = $date_src;
$ret["creer"] = $creer;
$ret["class"] = extraire_attribut($img, 'class');
$ret["alt"] = extraire_attribut($img, 'alt');
$ret["style"] = extraire_attribut($img, 'style');
$ret["tag"] = $img;
if ($fonction_creation){
$ret["reconstruction"] = $fonction_creation;
# ecrire ici comment creer le fichier, car il est pas sur qu'on l'ecrira reelement
# cas de image_reduire qui finalement ne reduit pas l'image source
# ca evite d'essayer de le creer au prochain hit si il n'est pas la
#ecrire_fichier($ret['fichier_dest'].'.src',serialize($ret),true);
}
$ret = pipeline('image_preparer_filtre',array(
'args'=>array(
'img'=>$img,
'effet'=>$effet,
'forcer_format'=>$forcer_format,
'fonction_creation'=>$fonction_creation,
'find_in_path'=>$find_in_path,
),
'data'=>$ret)
);
if (!function_exists($ret["fonction_imagecreatefrom"])) return false;
return $ret;
}
// http://doc.spip.org/@image_imagepng
function _image_imagepng($img,$fichier) {
if (!function_exists('imagepng')) return false;
$tmp = $fichier.".tmp";
$ret = imagepng($img,$tmp);
$taille_test = getimagesize($tmp);
if ($taille_test[0] < 1) return false;
spip_unlink($fichier); // le fichier peut deja exister
@rename($tmp, $fichier);
return $ret;
}
// http://doc.spip.org/@image_imagegif
function _image_imagegif($img,$fichier) {
if (!function_exists('imagegif')) return false;
$tmp = $fichier.".tmp";
$ret = imagegif($img,$tmp);
$taille_test = getimagesize($tmp);
if ($taille_test[0] < 1) return false;
spip_unlink($fichier); // le fichier peut deja exister
@rename($tmp, $fichier);
return $ret;
}
// http://doc.spip.org/@image_imagejpg
function _image_imagejpg($img,$fichier,$qualite=_IMG_GD_QUALITE) {
if (!function_exists('imagejpeg')) return false;
$tmp = $fichier.".tmp";
$ret = imagejpeg($img,$tmp, $qualite);
$taille_test = getimagesize($tmp);
if ($taille_test[0] < 1) return false;
spip_unlink($fichier); // le fichier peut deja exister
@rename($tmp, $fichier);
return $ret;
}
// http://doc.spip.org/@image_imageico
function _image_imageico($img, $fichier) {
$gd_image_array = array($img);
return ecrire_fichier($fichier, phpthumb_functions::GD2ICOstring($gd_image_array));
}
// $qualite est utilise pour la qualite de compression des jpeg
// http://doc.spip.org/@image_gd_output
function _image_gd_output($img,$valeurs, $qualite=_IMG_GD_QUALITE){
$fonction = "_image_image".$valeurs['format_dest'];
$ret = false;
#un flag pour reperer les images gravees
$lock =
!statut_effacer_images_temporaires('get') // si la fonction n'a pas ete activee, on grave tout
OR (@file_exists($valeurs['fichier_dest']) AND !@file_exists($valeurs['fichier_dest'].'.src'));
if (
function_exists($fonction)
&& ($ret = $fonction($img,$valeurs['fichier_dest'],$qualite)) # on a reussi a creer l'image
&& isset($valeurs['reconstruction']) # et on sait comment la resonctruire le cas echeant
&& !$lock
)
if (@file_exists($valeurs['fichier_dest'])){
// dans tous les cas mettre a jour la taille de l'image finale
list ($valeurs["hauteur_dest"],$valeurs["largeur_dest"]) = taille_image($valeurs['fichier_dest']);
$valeurs['date'] = @filemtime($valeurs['fichier_dest']); // pour la retrouver apres disparition
ecrire_fichier($valeurs['fichier_dest'].'.src',serialize($valeurs),true);
}
return $ret;
}
// http://doc.spip.org/@reconstruire_image_intermediaire
function reconstruire_image_intermediaire($fichier_manquant){
$reconstruire = array();
$fichier = $fichier_manquant;
while (
!@file_exists($fichier)
AND lire_fichier($src = "$fichier.src",$source)
AND $valeurs=unserialize($source)
AND ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
) {
spip_unlink($src); // si jamais on a un timeout pendant la reconstruction, elle se fera naturellement au hit suivant
$reconstruire[] = $valeurs['reconstruction'];
}
while (count($reconstruire)){
$r = array_pop($reconstruire);
$fonction = $r[0];
$args = $r[1];
call_user_func_array($fonction, $args);
}
// cette image intermediaire est commune a plusieurs series de filtre, il faut la conserver
// mais l'on peut nettoyer les miettes de sa creation
ramasse_miettes($fichier_manquant);
}
// http://doc.spip.org/@ramasse_miettes
function ramasse_miettes($fichier){
if (!lire_fichier($src = "$fichier.src",$source)
OR !$valeurs=unserialize($source)) return;
spip_unlink($src); # on supprime la reference a sa source pour marquer cette image comme non intermediaire
while (
($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
AND (substr($fichier,0,strlen(_DIR_VAR))==_DIR_VAR) # et est dans local
AND (lire_fichier($src = "$fichier.src",$source)) # le fichier a une source connue (c'est donc une image calculee intermediaire)
AND ($valeurs=unserialize($source)) # et valide
) {
# on efface le fichier
spip_unlink($fichier);
# mais laisse le .src qui permet de savoir comment reconstruire l'image si besoin
#spip_unlink($src);
}
}
// http://doc.spip.org/@image_graver
function image_graver($img){
// appeler le filtre post_image_filtrer qui permet de faire
// des traitements auto a la fin d'une serie de filtres
$img = pipeline('post_image_filtrer',$img);
$fichier = extraire_attribut($img, 'src');
if (($p=strpos($fichier,'?'))!==FALSE)
$fichier=substr($fichier,0,$p);
if (strlen($fichier) < 1)
$fichier = $img;
# si jamais le fichier final n'a pas ete calcule car suppose temporaire
if (!@file_exists($fichier))
reconstruire_image_intermediaire($fichier);
ramasse_miettes($fichier);
return $img; // on ne change rien
}
// Transforme une image a palette indexee (256 couleurs max) en "vraies" couleurs RGB
// http://doc.spip.org/@imagepalettetotruecolor
function imagepalettetotruecolor(&$img) {
if ($img AND !imageistruecolor($img) AND function_exists('imagecreatetruecolor')) {
$w = imagesx($img);
$h = imagesy($img);
$img1 = imagecreatetruecolor($w,$h);
//Conserver la transparence si possible
if(function_exists('ImageCopyResampled')) {
if (function_exists("imageAntiAlias")) imageAntiAlias($img1,true);
@imagealphablending($img1, false);
@imagesavealpha($img1,true);
@ImageCopyResampled($img1, $img, 0, 0, 0, 0, $w, $h, $w, $h);
} else {
imagecopy($img1,$img,0,0,0,0,$w,$h);
}
$img = $img1;
}
}
// http://doc.spip.org/@image_tag_changer_taille
function _image_tag_changer_taille($tag,$width,$height,$style=false){
if ($style===false) $style = extraire_attribut($tag,'style');
// enlever le width et height du style
$style = preg_replace(",(^|;)\s*(width|height)\s*:\s*[^;]+,ims","",$style);
if ($style AND $style{0}==';') $style=substr($style,1);
// mettre des attributs de width et height sur les images,
// ca accelere le rendu du navigateur
// ca permet aux navigateurs de reserver la bonne taille
// quand on a desactive l'affichage des images.
$tag = inserer_attribut($tag,'width',$width);
$tag = inserer_attribut($tag,'height',$height);
$style = "height:".$height."px;width:".$width."px;".$style;
// attributs deprecies. Transformer en CSS
if ($espace = extraire_attribut($tag, 'hspace')){
$style = "margin:${espace}px;".$style;
$tag = inserer_attribut($tag,'hspace','');
}
$tag = inserer_attribut($tag,'style',$style);
return $tag;
}
// function d'ecriture du de la balise img en sortie des filtre image
// reprend le tag initial et surcharge les tags modifies
function _image_ecrire_tag($valeurs,$surcharge=array()){
$tag = str_replace(">","/>",str_replace("/>",">",$valeurs['tag'])); // fermer les tags img pas bien fermes;
// le style
$style = $valeurs['style'];
if (isset($surcharge['style'])){
$style = $surcharge['style'];
unset($surcharge['style']);
}
// traiter specifiquement la largeur et la hauteur
$width = $valeurs['largeur'];
if (isset($surcharge['width'])){
$width = $surcharge['width'];
unset($surcharge['width']);
}
$height = $valeurs['hauteur'];
if (isset($surcharge['height'])){
$height = $surcharge['height'];
unset($surcharge['height']);
}
$tag = _image_tag_changer_taille($tag,$width,$height,$style);
// traiter specifiquement le src qui peut etre repris dans un onmouseout
// on remplace toute les ref a src dans le tag
$src = extraire_attribut($tag,'src');
if (isset($surcharge['src'])){
$tag = str_replace($src,$surcharge['src'],$tag);
// si il y a des & dans src, alors ils peuvent provenir d'un &amp
// pas garanti comme methode, mais mieux que rien
if (strpos($src,'&') !== false)
$tag = str_replace(str_replace("&","&amp;",$src),$surcharge['src'],$tag);
$src = $surcharge['src'];
unset($surcharge['src']);
}
$class = $valeurs['class'];
if (isset($surcharge['class'])){
$class = $surcharge['class'];
unset($surcharge['class']);
}
if(strlen($class))
$tag = inserer_attribut($tag,'class',$class);
if (count($surcharge))
foreach($surcharge as $attribut=>$valeur)
$tag = inserer_attribut($tag,$attribut,$valeur);
return $tag;
}
function _image_creer_vignette($valeurs, $maxWidth, $maxHeight, $process='AUTO', $force=false, $test_cache_only = false) {
// ordre de preference des formats graphiques pour creer les vignettes
// le premier format disponible, selon la methode demandee, est utilise
$image = $valeurs['fichier'];
$format = $valeurs['format_source'];
$destdir = dirname($valeurs['fichier_dest']);
$destfile = basename($valeurs['fichier_dest'],".".$valeurs["format_dest"]);
$format_sortie = $valeurs['format_dest'];
// liste des formats qu'on sait lire
$img = isset($GLOBALS['meta']['formats_graphiques'])
? (strpos($GLOBALS['meta']['formats_graphiques'], $format)!==false)
: false;
// si le doc n'est pas une image, refuser
if (!$force AND !$img) return;
$destination = "$destdir/$destfile";
// chercher un cache
$vignette = '';
if ($test_cache_only AND !$vignette) return;
// utiliser le cache ?
if (!$test_cache_only)
if ($force OR !$vignette OR (@filemtime($vignette) < @filemtime($image))) {
$creation = true;
// calculer la taille
if (($srcWidth=$valeurs['largeur']) && ($srcHeight=$valeurs['hauteur'])){
if (!($destWidth=$valeurs['largeur_dest']) || !($destHeight=$valeurs['hauteur_dest']))
list ($destWidth,$destHeight) = _image_ratio($valeurs['largeur'], $valeurs['hauteur'], $maxWidth, $maxHeight);
}
elseif ($process == 'convert' OR $process == 'imagick') {
$destWidth = $maxWidth;
$destHeight = $maxHeight;
} else {
spip_log("echec $process sur $image");
return;
}
// Si l'image est de la taille demandee (ou plus petite), simplement
// la retourner
if ($srcWidth
AND $srcWidth <= $maxWidth AND $srcHeight <= $maxHeight) {
$vignette = $destination.'.'.$format;
@copy($image, $vignette);
}
// imagemagick en ligne de commande
else if ($process == 'convert') {
define('_CONVERT_COMMAND', 'convert');
define ('_RESIZE_COMMAND', _CONVERT_COMMAND.' -quality '._IMG_CONVERT_QUALITE.' -resize %xx%y! %src %dest');
$vignette = $destination.".".$format_sortie;
$commande = str_replace(
array('%x', '%y', '%src', '%dest'),
array(
$destWidth,
$destHeight,
escapeshellcmd($image),
escapeshellcmd($vignette)
),
_RESIZE_COMMAND);
spip_log($commande);
exec($commande);
if (!@file_exists($vignette)) {
spip_log("echec convert sur $vignette");
return; // echec commande
}
}
else
// imagick (php4-imagemagick)
if ($process == 'imagick') {
$vignette = "$destination.".$format_sortie;
$handle = imagick_readimage($image);
imagick_resize($handle, $destWidth, $destHeight, IMAGICK_FILTER_LANCZOS, _IMG_IMAGICK_QUALITE / 100);
imagick_write($handle, $vignette);
if (!@file_exists($vignette)) {
spip_log("echec imagick sur $vignette");
return;
}
}
else
// netpbm
if ($process == "netpbm") {
define('_PNMSCALE_COMMAND', 'pnmscale'); // chemin a changer dans mes_options
if (_PNMSCALE_COMMAND == '') return;
$vignette = $destination.".".$format_sortie;
$pnmtojpeg_command = str_replace("pnmscale", "pnmtojpeg", _PNMSCALE_COMMAND);
if ($format == "jpg") {
$jpegtopnm_command = str_replace("pnmscale", "jpegtopnm", _PNMSCALE_COMMAND);
exec("$jpegtopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
if (!($s = @filesize($vignette)))
spip_unlink($vignette);
if (!@file_exists($vignette)) {
spip_log("echec netpbm-jpg sur $vignette");
return;
}
} else if ($format == "gif") {
$giftopnm_command = str_replace("pnmscale", "giftopnm", _PNMSCALE_COMMAND);
exec("$giftopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
if (!($s = @filesize($vignette)))
spip_unlink($vignette);
if (!@file_exists($vignette)) {
spip_log("echec netpbm-gif sur $vignette");
return;
}
} else if ($format == "png") {
$pngtopnm_command = str_replace("pnmscale", "pngtopnm", _PNMSCALE_COMMAND);
exec("$pngtopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
if (!($s = @filesize($vignette)))
spip_unlink($vignette);
if (!@file_exists($vignette)) {
spip_log("echec netpbm-png sur $vignette");
return;
}
}
}
// gd ou gd2
else if ($process == 'gd1' OR $process == 'gd2') {
if (_IMG_GD_MAX_PIXELS && $srcWidth*$srcHeight>_IMG_GD_MAX_PIXELS){
spip_log("vignette gd1/gd2 impossible : ".$srcWidth*$srcHeight."pixels");
return;
}
$destFormat = $format_sortie;
if (!$destFormat) {
spip_log("pas de format pour $image");
return;
}
$fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
if (!function_exists($fonction_imagecreatefrom))
return '';
$srcImage = @$fonction_imagecreatefrom($image);
if (!$srcImage) {
spip_log("echec gd1/gd2");
return;
}
// Initialisation de l'image destination
if ($process == 'gd2' AND $destFormat != "gif")
$destImage = ImageCreateTrueColor($destWidth, $destHeight);
if (!$destImage)
$destImage = ImageCreate($destWidth, $destHeight);
// Recopie de l'image d'origine avec adaptation de la taille
$ok = false;
if (($process == 'gd2') AND function_exists('ImageCopyResampled')) {
if ($format == "gif") {
// Si un GIF est transparent,
// fabriquer un PNG transparent
$transp = imagecolortransparent($srcImage);
if ($transp > 0) $destFormat = "png";
}
if ($destFormat == "png") {
// Conserver la transparence
if (function_exists("imageAntiAlias")) imageAntiAlias($destImage,true);
@imagealphablending($destImage, false);
@imagesavealpha($destImage,true);
}
$ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
}
if (!$ok)
$ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
// Sauvegarde de l'image destination
$valeurs['fichier_dest'] = $vignette = "$destination.$destFormat";
$valeurs['format_dest'] = $format = $destFormat;
_image_gd_output($destImage,$valeurs);
if ($srcImage)
ImageDestroy($srcImage);
ImageDestroy($destImage);
}
}
$size = @getimagesize($vignette);
// Gaffe: en safe mode, pas d'acces a la vignette,
// donc risque de balancer "width='0'", ce qui masque l'image sous MSIE
if ($size[0] < 1) $size[0] = $destWidth;
if ($size[1] < 1) $size[1] = $destHeight;
$retour['width'] = $largeur = $size[0];
$retour['height'] = $hauteur = $size[1];
$retour['fichier'] = $vignette;
$retour['format'] = $format;
$retour['date'] = @filemtime($vignette);
// renvoyer l'image
return $retour;
}
// Calculer le ratio
// http://doc.spip.org/@image_ratio
function _image_ratio ($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
$ratioWidth = $srcWidth/$maxWidth;
$ratioHeight = $srcHeight/$maxHeight;
if ($ratioWidth <=1 AND $ratioHeight <=1) {
$destWidth = $srcWidth;
$destHeight = $srcHeight;
} else if ($ratioWidth < $ratioHeight) {
$destWidth = $srcWidth/$ratioHeight;
$destHeight = $maxHeight;
}
else {
$destWidth = $maxWidth;
$destHeight = $srcHeight/$ratioWidth;
}
return array (ceil($destWidth), ceil($destHeight),
max($ratioWidth,$ratioHeight));
}
// Calculer le ratio ajuste sur la plus petite dimension
// http://doc.spip.org/@ratio_passe_partout
function ratio_passe_partout ($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
$ratioWidth = $srcWidth/$maxWidth;
$ratioHeight = $srcHeight/$maxHeight;
if ($ratioWidth <=1 AND $ratioHeight <=1) {
$destWidth = $srcWidth;
$destHeight = $srcHeight;
} else if ($ratioWidth > $ratioHeight) {
$destWidth = $srcWidth/$ratioHeight;
$destHeight = $maxHeight;
}
else {
$destWidth = $maxWidth;
$destHeight = $srcHeight/$ratioWidth;
}
return array (ceil($destWidth), ceil($destHeight),
min($ratioWidth,$ratioHeight));
}
// http://doc.spip.org/@process_image_reduire
function process_image_reduire($fonction,$img,$taille,$taille_y,$force,$cherche_image,$process){
$image = false;
if (($process == 'AUTO') AND isset($GLOBALS['meta']['image_process']))
$process = $GLOBALS['meta']['image_process'];
# determiner le format de sortie
$format_sortie = false; // le choix par defaut sera bon
if ($process == "netpbm") $format_sortie = "jpg";
else if ($process == 'gd1' OR $process == 'gd2') {
$image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}",$format_sortie,$fonction);
// on verifie que l'extension choisie est bonne (en principe oui)
$gd_formats = explode(',',$GLOBALS['meta']["gd_formats"]);
if (!in_array($image['format_dest'],$gd_formats)
OR ($image['format_dest']=='gif' AND !function_exists('ImageGif'))
) {
if ($image['format_source'] == 'jpg')
$formats_sortie = array('jpg','png','gif');
else // les gif sont passes en png preferentiellement pour etre homogene aux autres filtres images
$formats_sortie = array('png','jpg','gif');
// Choisir le format destination
// - on sauve de preference en JPEG (meilleure compression)
// - pour le GIF : les GD recentes peuvent le lire mais pas l'ecrire
# bug : gd_formats contient la liste des fichiers qu'on sait *lire*,
# pas *ecrire*
$format_sortie = "";
foreach ($formats_sortie as $fmt) {
if (in_array($fmt, $gd_formats)) {
if ($fmt <> "gif" OR function_exists('ImageGif'))
$format_sortie = $fmt;
break;
}
}
$image = false;
}
}
if (!$image)
$image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}",$format_sortie,$fonction);
if (!$image OR !$image['largeur'] OR !$image['hauteur']){
spip_log("image_reduire_src:pas de version locale de $img");
// on peut resizer en mode html si on dispose des elements
if ($srcw = extraire_attribut($img, 'width')
AND $srch = extraire_attribut($img, 'height')) {
list($w,$h) = _image_ratio($srcw, $srch, $taille, $taille_y);
return _image_tag_changer_taille($img,$w,$h);
}
// la on n'a pas d'infos sur l'image source... on refile le truc a css
// sous la forme style='max-width: NNpx;'
return inserer_attribut($img, 'style',
"max-width: ${taille}px; max-height: ${taille_y}px");
}
// si l'image est plus petite que la cible retourner une copie cachee de l'image
if (($image['largeur']<=$taille)&&($image['hauteur']<=$taille_y)){
if ($image['creer']){
@copy($image['fichier'], $image['fichier_dest']);
}
return _image_ecrire_tag($image,array('src'=>$image['fichier_dest']));
}
if ($image['creer']==false && !$force)
return _image_ecrire_tag($image,array('src'=>$image['fichier_dest'],'width'=>$image['largeur_dest'],'height'=>$image['hauteur_dest']));
if ($cherche_image){
$cherche = cherche_image_nommee(substr($image['fichier'],0,-4), array($image["format_source"]));
if (!$cherche) return $img;
//list($chemin,$nom,$format) = $cherche;
}
if (in_array($image["format_source"],array('jpg','gif','png'))){
$destWidth = $image['largeur_dest'];
$destHeight = $image['hauteur_dest'];
$logo = $image['fichier'];
$date = $image["date_src"];
$preview = _image_creer_vignette($image, $taille, $taille_y,$process,$force);
if ($preview && $preview['fichier']) {
$logo = $preview['fichier'];
$destWidth = $preview['width'];
$destHeight = $preview['height'];
$date = $preview['date'];
}
// dans l'espace prive mettre un timestamp sur l'adresse
// de l'image, de facon a tromper le cache du navigateur
// quand on fait supprimer/reuploader un logo
// (pas de filemtime si SAFE MODE)
$date = test_espace_prive() ? ('?date='.$date) : '';
return _image_ecrire_tag($image,array('src'=>"$logo$date",'width'=>$destWidth,'height'=>$destHeight));
}
else
# SVG par exemple ? BMP, tiff ... les redacteurs osent tout!
return $img;
}
//
// Produire des fichiers au format .ico
// avec du code recupere de :
//
//////////////////////////////////////////////////////////////
/// phpThumb() by James Heinrich <info@silisoftware.com> //
// available at http://phpthumb.sourceforge.net ///
//////////////////////////////////////////////////////////////
class phpthumb_functions {
// http://doc.spip.org/@GetPixelColor
function GetPixelColor(&$img, $x, $y) {
if (!is_resource($img)) {
return false;
}
return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
}
// http://doc.spip.org/@LittleEndian2String
function LittleEndian2String($number, $minbytes=1) {
$intstring = '';
while ($number > 0) {
$intstring = $intstring.chr($number & 255);
$number >>= 8;
}
return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
}
// http://doc.spip.org/@GD2ICOstring
function GD2ICOstring(&$gd_image_array) {
foreach ($gd_image_array as $key => $gd_image) {
$ImageWidths[$key] = ImageSX($gd_image);
$ImageHeights[$key] = ImageSY($gd_image);
$bpp[$key] = ImageIsTrueColor($gd_image) ? 32 : 24;
$totalcolors[$key] = ImageColorsTotal($gd_image);
$icXOR[$key] = '';
for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {
for ($x = 0; $x < $ImageWidths[$key]; $x++) {
$argb = phpthumb_functions::GetPixelColor($gd_image, $x, $y);
$a = round(255 * ((127 - $argb['alpha']) / 127));
$r = $argb['red'];
$g = $argb['green'];
$b = $argb['blue'];
if ($bpp[$key] == 32) {
$icXOR[$key] .= chr($b).chr($g).chr($r).chr($a);
} elseif ($bpp[$key] == 24) {
$icXOR[$key] .= chr($b).chr($g).chr($r);
}
if ($a < 128) {
@$icANDmask[$key][$y] .= '1';
} else {
@$icANDmask[$key][$y] .= '0';
}
}
// mask bits are 32-bit aligned per scanline
while (strlen($icANDmask[$key][$y]) % 32) {
$icANDmask[$key][$y] .= '0';
}
}
$icAND[$key] = '';
foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {
for ($i = 0; $i < strlen($scanlinemaskbits); $i += 8) {
$icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, '0', STR_PAD_LEFT)));
}
}
}
foreach ($gd_image_array as $key => $gd_image) {
$biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);
// BITMAPINFOHEADER - 40 bytes
$BitmapInfoHeader[$key] = '';
$BitmapInfoHeader[$key] .= "\x28\x00\x00\x00"; // DWORD biSize;
$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4); // LONG biWidth;
// The biHeight member specifies the combined
// height of the XOR and AND masks.
$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG biHeight;
$BitmapInfoHeader[$key] .= "\x01\x00"; // WORD biPlanes;
$BitmapInfoHeader[$key] .= chr($bpp[$key])."\x00"; // wBitCount;
$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // DWORD biCompression;
$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4); // DWORD biSizeImage;
$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // LONG biXPelsPerMeter;
$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // LONG biYPelsPerMeter;
$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // DWORD biClrUsed;
$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // DWORD biClrImportant;
}
$icondata = "\x00\x00"; // idReserved; // Reserved (must be 0)
$icondata .= "\x01\x00"; // idType; // Resource Type (1 for icons)
$icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2); // idCount; // How many images?
$dwImageOffset = 6 + (count($gd_image_array) * 16);
foreach ($gd_image_array as $key => $gd_image) {
// ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em)
$icondata .= chr($ImageWidths[$key]); // bWidth; // Width, in pixels, of the image
$icondata .= chr($ImageHeights[$key]); // bHeight; // Height, in pixels, of the image
$icondata .= chr($totalcolors[$key]); // bColorCount; // Number of colors in image (0 if >=8bpp)
$icondata .= "\x00"; // bReserved; // Reserved ( must be 0)
$icondata .= "\x01\x00"; // wPlanes; // Color Planes
$icondata .= chr($bpp[$key])."\x00"; // wBitCount; // Bits per pixel
$dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
$icondata .= phpthumb_functions::LittleEndian2String($dwBytesInRes, 4); // dwBytesInRes; // How many bytes in this resource?
$icondata .= phpthumb_functions::LittleEndian2String($dwImageOffset, 4); // dwImageOffset; // Where in the file is this image?
$dwImageOffset += strlen($BitmapInfoHeader[$key]);
$dwImageOffset += strlen($icXOR[$key]);
$dwImageOffset += strlen($icAND[$key]);
}
foreach ($gd_image_array as $key => $gd_image) {
$icondata .= $BitmapInfoHeader[$key];
$icondata .= $icXOR[$key];
$icondata .= $icAND[$key];
}
return $icondata;
}
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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_images_lib_mini'); // par precaution
// http://doc.spip.org/@couleur_html_to_hex
function couleur_html_to_hex($couleur){
$couleurs_html=array(
'aqua'=>'00FFFF','black'=>'000000','blue'=>'0000FF','fuchsia'=>'FF00FF','gray'=>'808080','green'=>'008000','lime'=>'00FF00','maroon'=>'800000',
'navy'=>'000080','olive'=>'808000','purple'=>'800080','red'=>'FF0000','silver'=>'C0C0C0','teal'=>'008080','white'=>'FFFFFF','yellow'=>'FFFF00');
if (isset($couleurs_html[$lc=strtolower($couleur)]))
return $couleurs_html[$lc];
return $couleur;
}
// http://doc.spip.org/@couleur_foncer
function couleur_foncer ($couleur, $coeff=0.5) {
$couleurs = _couleur_hex_to_dec($couleur);
$red = $couleurs["red"] - round(($couleurs["red"])*$coeff);
$green = $couleurs["green"] - round(($couleurs["green"])*$coeff);
$blue = $couleurs["blue"] - round(($couleurs["blue"])*$coeff);
$couleur = _couleur_dec_to_hex($red, $green, $blue);
return $couleur;
}
// http://doc.spip.org/@couleur_eclaircir
function couleur_eclaircir ($couleur, $coeff=0.5) {
$couleurs = _couleur_hex_to_dec($couleur);
$red = $couleurs["red"] + round((255 - $couleurs["red"])*$coeff);
$green = $couleurs["green"] + round((255 - $couleurs["green"])*$coeff);
$blue = $couleurs["blue"] + round((255 - $couleurs["blue"])*$coeff);
$couleur = _couleur_dec_to_hex($red, $green, $blue);
return $couleur;
}
// selectionner les images qui vont subir une transformation sur un critere de taille
// ls images exclues sont marquees d'une class no_image_filtrer qui bloque les filtres suivants
// dans la fonction image_filtrer
// http://doc.spip.org/@image_select
function image_select($img,$width_min=0, $height_min=0, $width_max=10000, $height_max=1000){
if (!$img) return $img;
list ($h,$l) = taille_image($img);
$select = true;
if ($l<$width_min OR $l>$width_max OR $h<$height_min OR $h>$height_max)
$select = false;
$class = extraire_attribut($img,'class');
$p = strpos($class,'no_image_filtrer');
if (($select==false) AND ($p===FALSE)){
$class .= " no_image_filtrer";
$img = inserer_attribut($img,'class',$class);
}
if (($select==true) AND ($p!==FALSE)){
$class = preg_replace(",\s*no_image_filtrer,","",$class);
$img = inserer_attribut($img,'class',$class);
}
return $img;
}
// http://doc.spip.org/@image_passe_partout
function image_passe_partout($img,$taille_x = -1, $taille_y = -1,$force = false,$cherche_image=false,$process='AUTO'){
if (!$img) return '';
list ($hauteur,$largeur) = taille_image($img);
if ($taille_x == -1)
$taille_x = isset($GLOBALS['meta']['taille_preview'])?$GLOBALS['meta']['taille_preview']:150;
if ($taille_y == -1)
$taille_y = $taille_x;
if ($taille_x == 0 AND $taille_y > 0)
$taille_x = 1; # {0,300} -> c'est 300 qui compte
elseif ($taille_x > 0 AND $taille_y == 0)
$taille_y = 1; # {300,0} -> c'est 300 qui compte
elseif ($taille_x == 0 AND $taille_y == 0)
return '';
list($destWidth,$destHeight,$ratio) = ratio_passe_partout($largeur,$hauteur,$taille_x,$taille_y);
$fonction = array('image_passe_partout', func_get_args());
return process_image_reduire($fonction,$img,$destWidth,$destHeight,$force,$cherche_image,$process);
}
// http://doc.spip.org/@image_reduire
function image_reduire($img, $taille = -1, $taille_y = -1, $force=false, $cherche_image=false, $process='AUTO') {
// Determiner la taille x,y maxi
// prendre le reglage de previsu par defaut
if ($taille == -1)
$taille = isset($GLOBALS['meta']['taille_preview'])?$GLOBALS['meta']['taille_preview']:150;
if ($taille_y == -1)
$taille_y = $taille;
if ($taille == 0 AND $taille_y > 0)
$taille = 100000; # {0,300} -> c'est 300 qui compte
elseif ($taille > 0 AND $taille_y == 0)
$taille_y = 100000; # {300,0} -> c'est 300 qui compte
elseif ($taille == 0 AND $taille_y == 0)
return '';
$fonction = array('image_reduire', func_get_args());
return process_image_reduire($fonction,$img,$taille,$taille_y,$force,$cherche_image,$process);
}
// Reduire une image d'un certain facteur
// http://doc.spip.org/@image_reduire_par
function image_reduire_par ($img, $val=1, $force=false) {
list ($hauteur,$largeur) = taille_image($img);
$l = round($largeur/$val);
$h = round($hauteur/$val);
if ($l > $h) $h = 0;
else $l = 0;
$img = image_reduire($img, $l, $h, $force);
return $img;
}
?>
\ No newline at end of file
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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');
// Fichier des filtres d'incrustation d'un document selon son type MIME
// Les 7 familles de base ne font rien sauf celle des textes
function filtre_image_dist($t) {return '';}
function filtre_audio_dist($t) {return '';}
function filtre_video_dist($t) {return '';}
function filtre_application_dist($t) {return '';}
function filtre_message_dist($t) {return '';}
function filtre_multipart_dist($t) {return '';}
// http://doc.spip.org/@filtre_text_txt_dist
function filtre_text_dist($t) {
return '<pre>' . echapper_tags($t) . '</pre>';
}
// http://doc.spip.org/@filtre_text_csv_dist
function filtre_text_csv_dist($t)
{
$virg = substr_count($t, ',');
$pvirg = substr_count($t, ';');
$tab = substr_count($t, "\t");
if ($virg > $pvirg)
{ $sep = ','; $hs = '&#44;';}
else { $sep = ';'; $hs = '&#59;'; $virg = $pvirg;}
if ($tab > $virg) {$sep = "\t"; $hs = "\t";}
$t = preg_replace('/\r?\n/', "\n",
preg_replace('/[\r\n]+/', "\n", $t));
// un separateur suivi de 3 guillemets attention !
// attention au ; suceptible d'etre confondu avec un separateur
// on substitue un # et on remplacera a la fin
$t = preg_replace("/([\n$sep])\"\"\"/",'\\1"&#34#',$t);
$t = str_replace('""','&#34#',$t);
preg_match_all('/"[^"]*"/', $t, $r);
foreach($r[0] as $cell)
$t = str_replace($cell,
str_replace($sep, $hs,
str_replace("\n", "<br />",
substr($cell,1,-1))),
$t);
list($entete, $corps) = explode("\n",$t,2);
$caption = '';
// sauter la ligne de tete formee seulement de separateurs
if (substr_count($entete, $sep) == strlen($entete)) {
list($entete, $corps) = explode("\n",$corps,2);
}
// si une seule colonne, en faire le titre
if (preg_match("/^([^$sep]+)$sep+\$/", $entete, $l)) {
$caption = "\n||" . $l[1] . "|";
list($entete, $corps) = explode("\n",$corps,2);
}
// si premiere colonne vide, le raccourci doit quand meme produire <th...
if ($entete[0] == $sep) $entete = ' ' . $entete;
$lignes = explode("\n", $corps);
// retrait des lignes vides finales
while(preg_match("/^$sep*$/", $lignes[count($lignes)-1]))
unset($lignes[count($lignes)-1]);
// calcul du nombre de colonne a chaque ligne
$nbcols = array();
$max = $mil = substr_count($entete, $sep);
foreach($lignes as $k=>$v) {
if ($max <> ($nbcols[$k]= substr_count($v, $sep))) {
if ($max > $nbcols[$k])
$mil = $nbcols[$k];
else { $mil = $max; $max = $nbcols[$k];}
}
}
// Si pas le meme nombre, cadrer au nombre max
if ($mil <> $max)
foreach($nbcols as $k=>$v) {
if ($v < $max) $lignes[$k].= str_repeat($sep, $max-$v);
}
// et retirer les colonnes integralement vides
while(true) {
$nbcols = ($entete[strlen($entete)-1]===$sep);
foreach($lignes as $v) $nbcols &= ($v[strlen($v)-1]===$sep);
if (!$nbcols) break;
$entete = substr($entete,0,-1);
foreach($lignes as $k=>$v) $lignes[$k] = substr($v,0,-1);
}
$corps = join("\n", $lignes) . "\n";
$corps = $caption .
"\n|{{" .
str_replace($sep,'}}|{{',$entete) .
"}}|" .
"\n|" .
str_replace($sep,'|',str_replace("\n", "|\n|",$corps));
$corps = str_replace('&#34#','&#34;',$corps);
include_spip('inc/texte');
return propre($corps);
}
// Incrustation de HTML, si on est capable de le securiser
// sinon, afficher le source
// http://doc.spip.org/@filtre_text_html_dist
function filtre_text_html_dist($t)
{
if (!preg_match(',^(.*?)<body[^>]*>(.*)</body>,is', $t, $r))
return filtre_text_txt_dist($t);
list(,$h,$t) = $r;
$style = '';
// recuperer les styles internes
if (preg_match_all(',<style>(.*?)</style>,is', $h, $r, PREG_PATTERN_ORDER))
$style = join("\n",$r[1]);
// ... et externes
include_spip('inc/distant');
if (preg_match_all(',<link[^>]+type=.text/css[^>]*>,is', $h, $r, PREG_PATTERN_ORDER))
foreach($r[0] as $l) {
preg_match("/href='([^']*)'/", str_replace('"',"'",$l), $m);
$style .= "\n/* $l */\n"
. str_replace('<','',recuperer_page($m[1]));
}
// Pourquoi SafeHtml transforme-t-il en texte les scripts dans Body ?
$t = safehtml(preg_replace(',<script.*?</script>,is','',$t));
return (!$style ? '' : "\n<style>$style</style>") . $t;
}
// http://doc.spip.org/@filtre_audio_x_pn_realaudio
function filtre_audio_x_pn_realaudio($id)
{
return "
<param name='controls' value='PositionSlider' />
<param name='controls' value='ImageWindow' />
<param name='controls' value='PlayButton' />
<param name='console' value='Console$id' />
<param name='nojava' value='true' />";
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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;
//
// Filtres d'URLs
//
// Nettoyer une URL contenant des ../
//
// resolve_url('/.././/truc/chose/machin/./.././.././hopla/..');
// inspire (de loin) par PEAR:NetURL:resolvePath
//
// http://doc.spip.org/@resolve_path
function resolve_path($url) {
list($url, $query) = explode('?', $url,2);
while (preg_match(',/\.?/,', $url, $regs) # supprime // et /./
OR preg_match(',/[^/]*/\.\./,S', $url, $regs) # supprime /toto/../
OR preg_match(',^/\.\./,S', $url, $regs)) # supprime les /../ du haut
$url = str_replace($regs[0], '/', $url);
if ($query)
$url .= '?'.$query;
return '/'.preg_replace(',^/,S', '', $url);
}
//
// Suivre un lien depuis une adresse donnee -> nouvelle adresse
//
// suivre_lien('http://rezo.net/sous/dir/../ect/ory/fi.html..s#toto',
// 'a/../../titi.coco.html/tata#titi');
// http://doc.spip.org/@suivre_lien
function suivre_lien($url, $lien) {
if (preg_match(',^(mailto|javascript):,iS', $lien))
return $lien;
if (preg_match(',^([a-z0-9]+://.*?)(/.*)?$,iS', $lien, $r))
return $r[1].resolve_path($r[2]);
# L'url site spip est un lien absolu aussi
if ($lien == $GLOBALS['meta']['adresse_site']){
return $lien;
}
# lien relatif, il faut verifier l'url de base
# commencer par virer la chaine de get de l'url de base
if (preg_match(',^(.*?://[^/]+)(/.*?/?)?([^/#?]*)([?][^#]*)?(#.*)?$,S', $url, $regs)) {
$debut = $regs[1];
$dir = !strlen($regs[2]) ? '/' : $regs[2];
$mot = $regs[3];
$get = isset($regs[4])?$regs[4]:"";
$hash = isset($regs[5])?$regs[5]:"";
}
switch (substr($lien,0,1)) {
case '/':
return $debut . resolve_path($lien);
case '#':
return $debut . resolve_path($dir.$mot.$get.$lien);
case '':
return $debut . resolve_path($dir.$mot.$get.$hash);
default:
return $debut . resolve_path($dir.$lien);
}
}
// un filtre pour transformer les URLs relatives en URLs absolues ;
// ne s'applique qu'aux #URL_XXXX
// http://doc.spip.org/@url_absolue
function url_absolue($url, $base='') {
if (strlen($url = trim($url)) == 0)
return '';
if (!$base)
$base = url_de_base() . (_DIR_RACINE ? _DIR_RESTREINT_ABS : '');
return suivre_lien($base, $url);
}
// un filtre pour transformer les URLs relatives en URLs absolues ;
// ne s'applique qu'aux textes contenant des liens
// http://doc.spip.org/@liens_absolus
function liens_absolus($texte, $base='') {
if (preg_match_all(',(<(a|link)[[:space:]]+[^<>]*href=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
$texte, $liens, PREG_SET_ORDER)) {
foreach ($liens as $lien) {
$abs = url_absolue($lien[3], $base);
if ($abs <> $lien[3] and !preg_match('/^#/',$lien[3]))
$texte = str_replace($lien[0], $lien[1].$abs.$lien[4], $texte);
}
}
if (preg_match_all(',(<(img|script)[[:space:]]+[^<>]*src=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
$texte, $liens, PREG_SET_ORDER)) {
foreach ($liens as $lien) {
$abs = url_absolue($lien[3], $base);
if ($abs <> $lien[3])
$texte = str_replace($lien[0], $lien[1].$abs.$lien[4], $texte);
}
}
return $texte;
}
//
// Ce filtre public va traiter les URL ou les <a href>
//
// http://doc.spip.org/@abs_url
function abs_url($texte, $base='') {
if ($GLOBALS['mode_abs_url'] == 'url')
return url_absolue($texte, $base);
else
return liens_absolus($texte, $base);
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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;
// ajouter define('_CREER_DIR_PLAT', true); dans mes_options pour restaurer
// le fonctionnement des faux repertoires en .plat
define('_CREER_DIR_PLAT', false);
if (!defined('_TEST_FILE_EXISTS')) define('_TEST_FILE_EXISTS', preg_match(',(online|free)[.]fr$,', $_ENV["HTTP_HOST"]));
#define('_SPIP_LOCK_MODE',0); // ne pas utiliser de lock (deconseille)
#define('_SPIP_LOCK_MODE',1); // utiliser le flock php
#define('_SPIP_LOCK_MODE',2); // utiliser le nfslock de spip
if (_SPIP_LOCK_MODE==2)
include_spip('inc/nfslock');
$GLOBALS['liste_verrous'] = array();
// http://doc.spip.org/@spip_fopen_lock
function spip_fopen_lock($fichier,$mode,$verrou){
if (_SPIP_LOCK_MODE==1){
if ($fl = @fopen($fichier,$mode))
// verrou
@flock($fl, $verrou);
return $fl;
}
elseif(_SPIP_LOCK_MODE==2) {
if (($verrou = spip_nfslock($fichier)) && ($fl = @fopen($fichier,$mode))){
$GLOBALS['liste_verrous'][$fl] = array($fichier,$verrou);
return $fl;
}
else return false;
}
return @fopen($fichier,$mode);
}
// http://doc.spip.org/@spip_fclose_unlock
function spip_fclose_unlock($handle){
if (_SPIP_LOCK_MODE==1){
@flock($handle, LOCK_UN);
}
elseif(_SPIP_LOCK_MODE==2) {
spip_nfsunlock(reset($GLOBALS['liste_verrous'][$handle]),end($GLOBALS['liste_verrous'][$handle]));
unset($GLOBALS['liste_verrous'][$handle]);
}
return @fclose($handle);
}
// http://doc.spip.org/@spip_file_get_contents
function spip_file_get_contents ($fichier) {
if (substr($fichier, -3) != '.gz') {
if (function_exists('file_get_contents')
AND (
// quand on est sous window on ne sait pas si file_get_contents marche
// on essaye : si ca retourne du contenu alors c'est bon
// sinon on fait un file() pour avoir le coeur net
($contenu = @file_get_contents ($fichier))
OR _OS_SERVEUR != 'windows')
)
return $contenu;
else
$contenu = @file($fichier);
} else
$contenu = @gzfile($fichier);
return is_array($contenu)?join('', $contenu):(string)$contenu;
}
// options = array(
// 'phpcheck' => 'oui' # verifier qu'on a bien du php
// dezippe automatiquement les fichiers .gz
// http://doc.spip.org/@lire_fichier
function lire_fichier ($fichier, &$contenu, $options=false) {
$contenu = '';
// inutile car si le fichier n'existe pas, le lock va renvoyer false juste apres
// economisons donc les acces disque, sauf chez free qui rale pour un rien
if (_TEST_FILE_EXISTS AND !@file_exists($fichier))
return false;
#spip_timer('lire_fichier');
// pas de @ sur spip_fopen_lock qui est silencieux de toute facon
if ($fl = spip_fopen_lock($fichier, 'r', LOCK_SH)) {
// lire le fichier avant tout
$contenu = spip_file_get_contents($fichier);
// le fichier a-t-il ete supprime par le locker ?
// on ne verifie que si la tentative de lecture a echoue
// pour discriminer un contenu vide d'un fichier absent
// et eviter un acces disque
if (!$contenu AND !@file_exists($fichier)) {
spip_fclose_unlock($fl);
return false;
}
// liberer le verrou
spip_fclose_unlock($fl);
// Verifications
$ok = true;
if ($options['phpcheck'] == 'oui')
$ok &= (preg_match(",[?]>\n?$,", $contenu));
#spip_log("$fread $fichier ".spip_timer('lire_fichier'));
if (!$ok)
spip_log("echec lecture $fichier");
return $ok;
}
return false;
}
//
// Ecrire un fichier de maniere un peu sure
// $ecrire_quand_meme ne sert plus mais est conservee dans l'appel pour compatibilite
//
// zippe les fichiers .gz
// http://doc.spip.org/@ecrire_fichier
function ecrire_fichier ($fichier, $contenu, $ecrire_quand_meme = false, $truncate=true) {
#spip_timer('ecrire_fichier');
// verrouiller le fichier destination
if ($fp = spip_fopen_lock($fichier, 'a',LOCK_EX)) {
// ecrire les donnees, compressees le cas echeant
// (on ouvre un nouveau pointeur sur le fichier, ce qui a l'avantage
// de le recreer si le locker qui nous precede l'avait supprime...)
if (substr($fichier, -3) == '.gz')
$contenu = gzencode($contenu);
// si c'est une ecriture avec troncation , on fait plutot une ecriture complete a cote suivie unlink+rename
// pour etre sur d'avoir une operation atomique
// y compris en NFS : http://www.ietf.org/rfc/rfc1094.txt
// sauf sous wintruc ou ca ne marche pas
$ok = false;
if ($truncate AND _OS_SERVEUR != 'windows'){
include_spip('inc/acces');
$id = creer_uniqid();
// on ouvre un pointeur sur un fichier temporaire en ecriture +raz
if ($fp2 = spip_fopen_lock("$fichier.$id", 'w',LOCK_EX)) {
$s = @fputs($fp2, $contenu, $a = strlen($contenu));
$ok = ($s == $a);
spip_fclose_unlock($fp2);
spip_fclose_unlock($fp);
// unlink direct et pas spip_unlink car on avait deja le verrou
@unlink($fichier);
// le rename aussitot, atomique quand on est pas sous windows
// au pire on arrive en second en cas de concourance, et le rename echoue
// --> on a la version de l'autre process qui doit etre identique
@rename("$fichier.$id",$fichier);
// precaution en cas d'echec du rename
if (!_TEST_FILE_EXISTS OR @file_exists("$fichier.$id"))
@unlink("$fichier.$id");
if ($ok)
$ok = file_exists($fichier);
}
else
// echec mais penser a fermer ..
spip_fclose_unlock($fp);
}
// sinon ou si methode precedente a echoueee
// on se rabat sur la methode ancienne
if (!$ok){
// ici on est en ajout ou sous windows, cas desespere
if ($truncate)
@ftruncate($fp,0);
$s = @fputs($fp, $contenu, $a = strlen($contenu));
$ok = ($s == $a);
spip_fclose_unlock($fp);
}
// liberer le verrou et fermer le fichier
@chmod($fichier, _SPIP_CHMOD & 0666);
if ($ok) return $ok;
}
include_spip('inc/autoriser');
if (autoriser('chargerftp'))
raler_fichier($fichier);
spip_unlink($fichier);
return false;
}
/**
* Ecrire un contenu dans un fichier encapsule en php pour en empecher l'acces en l'absence
* de htaccess
* @param string $fichier
* @param <type> $contenu
* @param <type> $ecrire_quand_meme
* @param <type> $truncate
*/
function ecrire_fichier_securise ($fichier, $contenu, $ecrire_quand_meme = false, $truncate=true) {
if (substr($fichier,-4) !== '.php')
spip_log('Erreur de programmation: '.$fichier.' doit finir par .php');
$contenu = "<"."?php die ('Acces interdit'); ?".">\n" . $contenu;
return ecrire_fichier($fichier, $contenu, $ecrire_quand_meme, $truncate);
}
/**
* Lire un fichier encapsule en php
* @param <type> $fichier
* @param <type> $contenu
* @param <type> $options
*/
function lire_fichier_securise ($fichier, &$contenu, $options=false) {
if ($res = lire_fichier($fichier,$contenu,$options)){
$contenu = substr($contenu,strlen("<"."?php die ('Acces interdit'); ?".">\n"));
}
return $res;
}
// http://doc.spip.org/@raler_fichier
function raler_fichier($fichier)
{
include_spip('inc/minipres');
$dir = dirname($fichier);
http_status(401);
echo minipres(_T('texte_inc_meta_2'), "<h4 style='color: red'>"
. _T('texte_inc_meta_1', array('fichier' => $fichier))
. " <a href='"
. generer_url_ecrire('install', "etape=chmod&test_dir=$dir")
. "'>"
. _T('texte_inc_meta_2')
. "</a> "
. _T('texte_inc_meta_3',
array('repertoire' => joli_repertoire($dir)))
. "</h4>\n");
exit;
}
//
// Retourne Vrai si son premier argument a ete cree il y a moins de N secondes
//
// http://doc.spip.org/@jeune_fichier
function jeune_fichier($fichier, $n)
{
if (!file_exists($fichier)) return false;
if (!$c = @filemtime($fichier)) return false;
return (time()-$n <= $c);
}
//
// Supprimer le fichier de maniere sympa (flock)
//
// http://doc.spip.org/@supprimer_fichier
function supprimer_fichier($fichier, $lock=true) {
if (!@file_exists($fichier))
return true;
if ($lock) {
// verrouiller le fichier destination
if (!$fp = spip_fopen_lock($fichier, 'a', LOCK_EX))
return false;
// liberer le verrou
spip_fclose_unlock($fp);
}
// supprimer
return @unlink($fichier);
}
// Supprimer brutalement, si le fichier existe
// http://doc.spip.org/@spip_unlink
function spip_unlink($f) {
if (!is_dir($f))
supprimer_fichier($f,false);
else {
@unlink("$f/.ok");
@rmdir($f);
}
}
//
// Retourne $base/${subdir}/ si le sous-repertoire peut etre cree,
// $base/${subdir}_ sinon ; $nobase signale qu'on ne veut pas de $base/
// On peut aussi ne donner qu'un seul argument,
// subdir valant alors ce qui suit le dernier / dans $base
//
// http://doc.spip.org/@sous_repertoire
function sous_repertoire($base, $subdir='', $nobase = false, $tantpis=false) {
static $dirs = array();
$base = str_replace("//", "/", $base);
# suppr le dernier caractere si c'est un / ou un _
$base = rtrim($base, '/_');
if (!strlen($subdir)) {
$n = strrpos($base, "/");
if ($n === false) return $nobase ? '' : ($base .'/');
$subdir = substr($base, $n+1);
$base = substr($base, 0, $n+1);
} else {
$base .= '/';
$subdir = str_replace("/", "", $subdir);
}
$baseaff = $nobase ? '' : $base;
if (isset($dirs[$base.$subdir]))
return $baseaff.$dirs[$base.$subdir];
if (_CREER_DIR_PLAT AND @file_exists("$base${subdir}.plat"))
return $baseaff.($dirs[$base.$subdir] = "${subdir}_");
$path = $base.$subdir; # $path = 'IMG/distant/pdf' ou 'IMG/distant_pdf'
if (file_exists("$path/.ok"))
return $baseaff.($dirs[$base.$subdir] = "$subdir/");
@mkdir($path, _SPIP_CHMOD);
@chmod($path, _SPIP_CHMOD);
$ok = false;
if ($test = @fopen("$path/dir_test.php", "w")) {
@fputs($test, '<'.'?php $ok = true; ?'.'>');
@fclose($test);
@include("$path/dir_test.php");
spip_unlink("$path/dir_test.php");
}
if ($ok) {
@touch ("$path/.ok");
spip_log("creation $base$subdir/");
return $baseaff.($dirs[$base.$subdir] = "$subdir/");
}
// en cas d'echec c'est peut etre tout simplement que le disque est plein :
// l'inode du fichier dir_test existe, mais impossible d'y mettre du contenu
// => sauf besoin express (define dans mes_options), ne pas creer le .plat
if (_CREER_DIR_PLAT
AND $f = @fopen("$base${subdir}.plat", "w"))
fclose($f);
else {
spip_log("echec creation $base${subdir}");
if ($tantpis) return '';
if (!_DIR_RESTREINT)
$base = preg_replace(',^' . _DIR_RACINE .',', '',$base);
if ($test) $base .= $subdir;
raler_fichier($base . '/.ok');
}
spip_log("faux sous-repertoire $base${subdir}");
return $baseaff.($dirs[$base.$subdirs] = "${subdir}_");
}
//
// Cette fonction parcourt recursivement le repertoire $dir, et renvoie les
// fichiers dont le chemin verifie le pattern (preg) donne en argument.
// En cas d'echec retourne un array() vide
//
// Usage: array preg_files('ecrire/data/', '[.]lock$');
//
// Attention, afin de conserver la compatibilite avec les repertoires '.plat'
// si $dir = 'rep/sous_rep_' au lieu de 'rep/sous_rep/' on scanne 'rep/' et on
// applique un pattern '^rep/sous_rep_'
// si $recurs vaut false, la fonction ne descend pas dans les sus repertoires
//
// http://doc.spip.org/@preg_files
function preg_files($dir, $pattern=-1 /* AUTO */, $maxfiles = 10000, $recurs=array()) {
$nbfiles = 0;
if ($pattern == -1)
$pattern = "^$dir";
$fichiers = array();
// revenir au repertoire racine si on a recu dossier/truc
// pour regarder dossier/truc/ ne pas oublier le / final
$dir = preg_replace(',/[^/]*$,', '', $dir);
if ($dir == '') $dir = '.';
if (@is_dir($dir) AND is_readable($dir) AND $d = @opendir($dir)) {
while (($f = readdir($d)) !== false && ($nbfiles<$maxfiles)) {
if ($f[0] != '.' # ignorer . .. .svn etc
AND $f != 'CVS'
AND $f != 'remove.txt'
AND is_readable($f = "$dir/$f")) {
if (is_file($f)) {
if (preg_match(";$pattern;iS", $f))
{
$fichiers[] = $f;
$nbfiles++;
}
}
else if (is_dir($f) AND is_array($recurs)){
$rp = @realpath($f);
if (!is_string($rp) OR !strlen($rp)) $rp=$f; # realpath n'est peut etre pas autorise
if (!isset($recurs[$rp])) {
$recurs[$rp] = true;
$beginning = $fichiers;
$end = preg_files("$f/", $pattern,
$maxfiles-$nbfiles, $recurs);
$fichiers = array_merge((array)$beginning, (array)$end);
$nbfiles = count($fichiers);
}
}
}
}
closedir($d);
}
sort($fichiers);
return $fichiers;
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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/afficher_objets');
// Fonction appelee dans une boucle, calculer les invariants au premier appel.
// obsolete, utilise uniquement par afficher_objets
// http://doc.spip.org/@inc_formater_article_dist
function inc_formater_article_dist($row, $own='')
{
global $spip_lang_right, $spip_display;
static $pret = false;
static $chercher_logo, $img_admin, $formater_auteur, $nb, $langue_defaut, $afficher_langue, $puce_statut;
$id_article = $row['id_article'];
if (!autoriser('voir','article',$id_article)) return '';
if (!$pret) {
$chercher_logo = ($spip_display != 1 AND $spip_display != 4 AND $GLOBALS['meta']['image_process'] != "non");
if ($chercher_logo)
$chercher_logo = charger_fonction('chercher_logo', 'inc');
$formater_auteur = charger_fonction('formater_auteur', 'inc');
$img_admin = http_img_pack(chemin_image('auteur-0minirezo-16.png'), "", "", _T('titre_image_admin_article'));
if (($GLOBALS['meta']['multi_rubriques'] == 'oui' AND (!isset($GLOBALS['id_rubrique']))) OR $GLOBALS['meta']['multi_articles'] == 'oui') {
$afficher_langue = true;
$langue_defaut = !isset($GLOBALS['langue_rubrique'])
? $GLOBALS['meta']['langue_site']
: $GLOBALS['langue_rubrique'];
}
$puce_statut = charger_fonction('puce_statut', 'inc');
$pret = true;
}
if ($chercher_logo) {
if ($logo = $chercher_logo($id_article, 'id_article', 'on')) {
list($fid, $dir, $nom, $format) = $logo;
include_spip('inc/filtres_images_mini');
$logo = image_reduire("<img src='$fid' alt='' />", 26, 20);
}
} else $logo ='';
$titre = sinon($row['titre'], _T('ecrire:info_sans_titre'));
$id_rubrique = $row['id_rubrique'];
$date = $row['date'];
$statut = $row['statut'];
$descriptif = $row['descriptif'];
$lang_dir = lang_dir(($lang = $row['lang']) ? changer_typo($lang):'');
$lien = "<div>"
. "<a href='"
. generer_url_ecrire("articles","id_article=$id_article")
. "'"
. (!$descriptif ? '' :
(' title="'.attribut_html(typo($descriptif)).'"'))
. " dir='$lang_dir'>"
. (!$logo ? '' :
("<span style='float: $spip_lang_right; margin-top: -2px; margin-bottom: -2px;'>" . $logo . "</span>"))
. (acces_restreint_rubrique($id_rubrique) ? $img_admin : '')
. typo(supprime_img($titre,''))
. (!($afficher_langue AND $lang != $GLOBALS['meta']['langue_site'] AND strlen($lang)) ? '' :
(" <span class='spip_xx-small' style='color: #666666' dir='$lang_dir'>(".traduire_nom_langue($lang).")</span>"))
. (!$row['petition'] ? '' :
("</a> <a href='" . generer_url_ecrire('controle_petition', "id_article=$id_article") . "' class='spip_xx-small' style='color: red'>"._T('lien_petitions')))
. "</a>"
. "</div>";
if ($spip_display == 4) return array($lien);
$puce = $puce_statut($id_article, $statut, $id_rubrique,'article');
$auteurs = auteurs_article($id_article);
foreach ($auteurs as $k => $r) {
list(, $mail, $nom,,) = $formater_auteur($r['id_auteur']);
$auteurs[$k]= "$mail&nbsp;$nom";
}
$date = affdate_jourcourt($date);
if (!$date) $date = '&nbsp;';
$num = afficher_numero_edit($id_article, 'id_article', 'article');
// Afficher le numero (JMB)
return array($puce, $lien, join('<br />', $auteurs), $date, $num);
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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/lien');
//
// Construit un tableau des 5 informations principales sur un auteur,
// avec des liens vers les scripts associes:
// 1. l'icone du statut, avec lien vers la page de tous ceux ayant ce statut
// 2. l'icone du mail avec un lien mailto ou a defaut la messagerie de Spip
// 3. le nom, avec lien vers la page complete des informations
// 4. le mot "site" avec le lien vers le site Web personnelle
// 5. le nombre d'objets publies
//
// Un auteur sans autorisation de modification de soi est un visiteur;
// il n'a pas de messagerie interne, et n'a publie que des messages de forum
// http://doc.spip.org/@inc_formater_auteur_dist
function inc_formater_auteur_dist($id_auteur, $row=NULL) {
global $connect_id_auteur, $connect_statut;
$id_auteur = intval($id_auteur);
if ($row===NULL)
$row = sql_fetsel("*, " . sql_date_proche('en_ligne', -15, 'DAY') . " AS ici", "spip_auteurs", "id_auteur=$id_auteur");
$vals = array();
$statut = $row['statut'];
$href = generer_url_ecrire("auteurs","statut=$statut");
$vals[] = "<a href='$href'>" . bonhomme_statut($row) . '</a>';
if (($id_auteur == $connect_id_auteur) OR !$row['ici'])
$vals[]= '&nbsp;';
else $vals[]= formater_auteur_mail($row, $id_auteur);
if (!$nom = typo($row['nom']))
$nom = "<span style='color: red'>" . _T('texte_vide') . '</span>';
$chercher_logo = ($spip_display != 1
AND $spip_display != 4
AND $GLOBALS['meta']['image_process'] != "non")
? charger_fonction('chercher_logo', 'inc')
: false;
if ($chercher_logo
AND $logo = $chercher_logo($id_auteur, 'id_auteur', 'on')) {
list($fid) = $logo;
include_spip('inc/filtres_images_mini');
$logo = image_reduire("<img src='$fid' alt='' style='float:right;' />", 26, 20);
}
else $logo ='';
$vals[] = "<a href='"
. generer_url_ecrire('auteur_infos', "id_auteur=$id_auteur")
. "'"
. (!$row['bio'] ? '' : (" title=\"" . attribut_html(couper(textebrut($row["bio"]), 200)) ."\""))
. ">$nom</a>" . $logo;
$url = traiter_lien_explicite($row["url_site"]);
$vals[] = !$url ? "&nbsp;"
: "<a href='$url'>".couper(sinon(typo($row['nom_site']), $row["url_site"]),30)."</a>";
$contributions = array();
if (autoriser('modifier', 'auteur', $id_auteur, $row)) {
$in = sql_in('statut',
($connect_statut == "0minirezo"
? array('prepa', 'prop', 'publie', 'refuse')
: array('prop', 'publie')));
if ($cpt = sql_countsel("spip_auteurs_liens AS L LEFT JOIN spip_articles AS A ON (A.id_article=L.id_objet AND objet='article')", "L.id_auteur=$id_auteur AND $in")){
$contributions[] = ($cpt>1?$cpt.' '._T('info_article_2'):_T('info_1_article'));
}
}
$contributions = pipeline('compter_contributions_auteur',array('args'=>array('id_auteur'=>$id_auteur,'row'=>$row),'data'=>$contributions));
$vals[] = (is_array($contributions) AND count($contributions))?implode('<br />',$contributions):"&nbsp;";
return $vals;
}
// http://doc.spip.org/@formater_auteur_mail
function formater_auteur_mail($row, $id_auteur)
{
if (!in_array($row['statut'], array('0minirezo', '1comite')))
return '';
if ($row['imessage'] != 'non'
AND $GLOBALS['meta']['messagerie_agenda'] != 'non')
$href = generer_action_auteur("editer_message","normal/$id_auteur");
else if (strlen($row['email'])
AND autoriser('voir', 'auteur', $id_auteur))
$href = 'mailto:' . $row['email'];
else return '';
return "<a href='$href' title=\""
. _T('info_envoyer_message_prive')
. "\" class='message'>&nbsp;</a>";
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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://doc.spip.org/@repercuter_gadgets
function repercuter_gadgets() {
if (!_SPIP_AJAX) return '';
// comme on cache fortement ce menu,
// son url change en fonction de sa date de modif
$toutsite = "./?exec=menu_rubriques\\x26date=" . $GLOBALS['meta']['date_calcul_rubriques'];
return
"\ninit_gadgets('$toutsite','','','');\n";
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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;
// --------------------------
// Gestion des taches de fond
// --------------------------
// Deux difficultes:
// - la plupart des hebergeurs ne fournissent pas le Cron d'Unix
// - les scripts usuels standard sont limites a 30 secondes
// Solution:
// Toute connexion a SPIP s'acheve par un appel a la fonction cron()
// qui appelle la fonction surchargeable genie dans inc/
// Sa definition standard ci-dessous prend dans une liste de taches
// la plus prioritaire, leurs dates etant donnees par leur fichier-verrou.
// Une fonction executant une tache doit retourner un nombre:
// - nul, si la tache n'a pas a etre effecutee
// - positif, si la tache a ete effectuee
// - negatif, si la tache doit etre poursuivie ou recommencee
// Elle recoit en argument la date de la derniere execution de la tache.
// On peut appeler cette fonction avec d'autres taches (pour etendre Spip)
// specifiee par des fonctions respectant le protocole ci-dessus
// On peut modifier la frequence de chaque tache et leur ordre d'analyse
// en modifiant les variables ci-dessous.
//----------
// Les taches sont dans un tableau ('nom de la tache' => periodicite)
// Cette fonction execute la tache la plus urgente
// (celle dont la date de derniere execution + la periodicite est minimale)
// La date de la derniere intervention est donnee par un fichier homonyme,
// de suffixe ".lock", modifie a chaque intervention et des le debut
// de celle-ci afin qu'un processus concurrent ne la demarre pas aussi.
// Les taches les plus longues sont tronconnees, ce qui impose d'antidater
// le fichier de verrouillage (avec la valeur absolue du code de retour).
// La fonction executant la tache est un homonyme de prefixe "genie_".
// Le fichier homonyme du repertoire "genie/" est automatiquement lu
// et il est suppose definir cette fonction.
// http://doc.spip.org/@inc_genie_dist
function inc_genie_dist($taches = array()) {
if (!$taches)
$taches = taches_generales();
// Quelle est la tache la plus urgente ?
$tache = '';
$tmin = $t = time();
foreach ($taches as $nom => $periode) {
$celock = _DIR_TMP . $nom . '.lock';
$date_lock = @filemtime($celock);
if ($date_lock + $periode < $tmin) {
$tmin = $date_lock + $periode;
$tache = $nom;
$lock = $celock;
$last = $date_lock;
}
// debug : si la date du fichier est superieure a l'heure actuelle,
// c'est que les serveurs Http et de fichiers sont desynchro.
// Ca peut mettre en peril les taches cron : signaler dans le log
// (On laisse toutefois flotter sur une heure, pas la peine de s'exciter
// pour si peu)
else if ($date_lock > $t + 3600)
spip_log("Erreur de date du fichier $lock : $date_lock > $t !");
}
if ($tache) {
spip_timer('tache');
touch($lock);
$cron = charger_fonction($tache, 'genie');
$retour = $cron($last);
// si la tache a eu un effet : log
if ($retour) {
spip_log("cron: $tache (" . spip_timer('tache') . ") $retour");
if ($retour < 0)
@touch($lock, 0 - $retour);
}
}
}
//
// Construction de la liste des taches.
// la cle est la tache,
// la valeur le temps minimal, en secondes, entre deux memes taches
// NE PAS METTRE UNE VALEUR INFERIEURE A 30
// les serveurs Http n'accordant en general pas plus de 30 secondes
// a leur sous-processus
//
// http://doc.spip.org/@taches_generales
function taches_generales($taches_generales = array()) {
// MAJ des rubriques publiques (cas de la publication post-datee)
// est fait au coup par coup a present
// $taches_generales['rubriques'] = 3600;
// Optimisation de la base
$taches_generales['optimiser'] = 3600*48;
// cache (chaque 20 minutes => 1/16eme du repertoire cache)
$taches_generales['invalideur'] = 1200;
// nouveautes
if ($GLOBALS['meta']['adresse_neuf'] AND $GLOBALS['meta']['jours_neuf']
AND ($GLOBALS['meta']['quoi_de_neuf'] == 'oui'))
$taches_generales['mail']= 3600 * 24 * $GLOBALS['meta']['jours_neuf'];
// maintenance (ajax, verifications diverses)
$taches_generales['maintenance'] = 3600 * 2;
// verifier si une mise a jour de spip est disponible (2 fois par semaine suffit largement)
$taches_generales['mise_a_jour'] = 3*24*3600;
return pipeline('taches_generales_cron',$taches_generales);
}
// Pas de fichier a part pour une fonction aussi petite:
// - elle peut retirer les fichiers perimes
// - elle fait appliquer le quota
// En cas de quota sur le CACHE/, nettoyer les fichiers les plus vieux
// http://doc.spip.org/@genie_invalideur_dist
function genie_invalideur_dist($t) {
include_spip('inc/invalideur');
$encore = appliquer_quota_cache();
// si le cache est trop gonfle, redemander la main pour poursuivre
if ($encore)
return (0 - $t);
return 1;
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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/minipres');
// Creer IMG/pdf/
// http://doc.spip.org/@creer_repertoire_documents
function creer_repertoire_documents($ext) {
$rep = sous_repertoire(_DIR_IMG, $ext);
if (!$ext OR !$rep) {
spip_log("creer_repertoire_documents '$rep' interdit");
exit;
}
// Cette variable de configuration peut etre posee par un plugin
// par exemple acces_restreint
if ($GLOBALS['meta']["creer_htaccess"] == 'oui') {
include_spip('inc/acces');
verifier_htaccess($rep);
}
return $rep;
}
// Efface le repertoire de maniere recursive !
// http://doc.spip.org/@effacer_repertoire_temporaire
function effacer_repertoire_temporaire($nom) {
$d = opendir($nom);
while (($f = readdir($d)) !== false) {
if (is_file("$nom/$f"))
spip_unlink("$nom/$f");
else if ($f <> '.' AND $f <> '..'
AND is_dir("$nom/$f"))
effacer_repertoire_temporaire("$nom/$f");
}
closedir($d);
@rmdir($nom);
}
// http://doc.spip.org/@copier_document
function copier_document($ext, $orig, $source) {
$orig = preg_replace(',\.\.+,', '.', $orig); // pas de .. dans le nom du doc
$dir = creer_repertoire_documents($ext);
$dest = preg_replace("/[^._=-\w\d]+/", "_",
translitteration(preg_replace("/\.([^.]+)$/", "",
preg_replace("/<[^>]*>/", '', basename($orig)))));
// ne pas accepter de noms de la forme -r90.jpg qui sont reserves
// pour les images transformees par rotation (action/documenter)
$dest = preg_replace(',-r(90|180|270)$,', '', $dest);
// Si le document "source" est deja au bon endroit, ne rien faire
if ($source == ($dir . $dest . '.' . $ext))
return $source;
// sinon tourner jusqu'a trouver un numero correct
$n = 0;
while (@file_exists($newFile = $dir . $dest .($n++ ? ('-'.$n) : '').'.'.$ext));
return deplacer_fichier_upload($source, $newFile);
}
//
// Deplacer un fichier
//
// http://doc.spip.org/@deplacer_fichier_upload
function deplacer_fichier_upload($source, $dest, $move=false) {
// Securite
if (substr($dest,0,strlen(_DIR_RACINE))==_DIR_RACINE)
$dest = _DIR_RACINE.preg_replace(',\.\.+,', '.', substr($dest,strlen(_DIR_RACINE)));
else
$dest = preg_replace(',\.\.+,', '.', $dest);
if ($move) $ok = @rename($source, $dest);
else $ok = @copy($source, $dest);
if (!$ok) $ok = @move_uploaded_file($source, $dest);
if ($ok)
@chmod($dest, _SPIP_CHMOD & ~0111);
else {
$f = @fopen($dest,'w');
if ($f) {
fclose ($f);
} else {
include_spip('inc/flock');
raler_fichier($dest);
}
spip_unlink($dest);
}
return $ok ? $dest : false;
}
// Erreurs d'upload
// renvoie false si pas d'erreur
// et true si erreur = pas de fichier
// pour les autres erreurs affiche le message d'erreur et meurt
// http://doc.spip.org/@check_upload_error
function check_upload_error($error, $msg='') {
global $spip_lang_right;
if (!$error) return false;
spip_log("Erreur upload $error -- cf. http://php.net/manual/fr/features.file-upload.errors.php");
switch ($error) {
case 4: /* UPLOAD_ERR_NO_FILE */
return true;
# on peut affiner les differents messages d'erreur
case 1: /* UPLOAD_ERR_INI_SIZE */
$msg = _T('upload_limit',
array('max' => ini_get('upload_max_filesize')));
break;
case 2: /* UPLOAD_ERR_FORM_SIZE */
$msg = _T('upload_limit',
array('max' => ini_get('upload_max_filesize')));
break;
case 3: /* UPLOAD_ERR_PARTIAL */
$msg = _T('upload_limit',
array('max' => ini_get('upload_max_filesize')));
break;
default: /* autre */
if (!$msg)
$msg = _T('pass_erreur').' '. $error
. '<br />' . propre("[->http://php.net/manual/fr/features.file-upload.errors.php]");
break;
}
spip_log ("erreur upload $error");
if(_request("iframe")=="iframe") {
echo "<div class='upload_answer upload_error'>$msg</div>";
exit;
}
echo minipres($msg,
"<div style='text-align: $spip_lang_right'><a href='" . rawurldecode($GLOBALS['redirect']) . "'><button type='button'>" . _T('ecrire:bouton_suivant') . "</button></a></div>");
exit;
}
// Erreur appelee depuis public.php (la precedente ne fonctionne plus
// depuis qu'on est sortis de spip_image.php, apparemment).
// http://doc.spip.org/@erreur_upload_trop_gros
function erreur_upload_trop_gros() {
include_spip('inc/filtres');
$msg = "<p>"
.taille_en_octets($_SERVER["CONTENT_LENGTH"])
.'<br />'
._T('upload_limit',
array('max' => ini_get('upload_max_filesize')))
."</p>";
echo minipres(_T('pass_erreur'),"<div class='upload_answer upload_error'>".$msg."</div>");
exit;
}
//
// Gestion des fichiers ZIP
//
// http://doc.spip.org/@accepte_fichier_upload
function accepte_fichier_upload ($f) {
if (!preg_match(",.*__MACOSX/,", $f)
AND !preg_match(",^\.,", basename($f))) {
$ext = corriger_extension((strtolower(substr(strrchr($f, "."), 1))));
return sql_countsel('spip_types_documents', "extension=" . sql_quote($ext) . " AND upload='oui'");
}
}
# callback pour le deballage d'un zip telecharge
# http://www.phpconcept.net/pclzip/man/en/?options-pclzip_cb_pre_extractfunction
// http://doc.spip.org/@callback_deballe_fichier
function callback_deballe_fichier($p_event, &$p_header) {
if (accepte_fichier_upload($p_header['filename'])) {
$p_header['filename'] = _tmp_dir . basename($p_header['filename']);
return 1;
} else {
return 0;
}
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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;
// envoyer le navigateur sur une nouvelle adresse
// en evitant les attaques par la redirection (souvent indique par 1 $_GET)
// http://doc.spip.org/@redirige_par_entete
function redirige_par_entete($url, $equiv='', $status = 302) {
if (!in_array($status,array(301,302)))
$status = 302;
$url = trim(strtr($url, "\n\r", " "));
# en theorie on devrait faire ca tout le temps, mais quand la chaine
# commence par ? c'est imperatif, sinon l'url finale n'est pas la bonne
if ($url[0]=='?')
$url = url_de_base().$url;
if ($url[0]=='#')
$url = self('&').$url;
if ($x = _request('transformer_xml'))
$url = parametre_url($url, 'transformer_xml', $x, '&');
if (defined('_AJAX') AND _AJAX)
$url = parametre_url($url, 'var_ajax_redir', 1, '&');
// ne pas laisser passer n'importe quoi dans l'url
$url = str_replace(array('<','"'),array('&lt;','&quot;'),$url);
// interdire les url inline avec des pseudo-protocoles :
if (
(preg_match(",data:,i",$url) AND preg_match("/base64\s*,/i",$url))
OR preg_match(",(javascript|mailto):,i",$url)
)
$url ="./";
// Il n'y a que sous Apache que setcookie puis redirection fonctionne
include_spip('inc/cookie');
if ((!$equiv AND !spip_cookie_envoye()) OR ((strncmp("Apache", $_SERVER['SERVER_SOFTWARE'],6)==0) OR defined('_SERVER_APACHE'))) {
@header("Location: " . $url);
$equiv="";
} else {
@header("Refresh: 0; url=" . $url);
$equiv = "<meta http-equiv='Refresh' content='0; url=$url'>";
}
include_spip('inc/lang');
if ($status!=302)
http_status($status);
echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">',"\n",
html_lang_attributes(),'
<head>',
$equiv,'
<title>HTTP '.$status.'</title>
</head>
<body>
<h1>HTTP '.$status.'</h1>
<a href="',
quote_amp($url),
'">',
_T('navigateur_pas_redirige'),
'</a></body></html>';
spip_log("redirige $status: $url");
exit;
}
// http://doc.spip.org/@redirige_formulaire
function redirige_formulaire($url, $equiv = '', $format='message') {
if (!_AJAX
AND !headers_sent()
AND !_request('var_ajax')) {
redirige_par_entete(str_replace('&amp;','&',$url), $equiv);
}
// si c'est une ancre, fixer simplement le window.location.hash
elseif($format=='ajaxform' AND preg_match(',^#[0-9a-z\-_]+$,i',$url)) {
return array(
// on renvoie un lien masque qui sera traite par ajaxCallback.js
"<a href='$url' name='ajax_ancre' style='display:none;'>anchor</a>",
// et rien dans le message ok
'');
}
else {
// ne pas laisser passer n'importe quoi dans l'url
$url = str_replace(array('<','"'),array('&lt;','&quot;'),$url);
$url = strtr($url, "\n\r", " ");
# en theorie on devrait faire ca tout le temps, mais quand la chaine
# commence par ? c'est imperatif, sinon l'url finale n'est pas la bonne
if ($url[0]=='?')
$url = url_de_base().$url;
$url = str_replace('&amp;','&',$url);
spip_log("redirige formulaire ajax: $url");
include_spip('inc/filtres');
if ($format=='ajaxform')
return array(
// on renvoie un lien masque qui sera traite par ajaxCallback.js
'<a href="'.quote_amp($url).'" name="ajax_redirect" style="display:none;">'._T('navigateur_pas_redirige').'</a>',
// et un message au cas ou
'<br /><a href="'.quote_amp($url).'">'._T('navigateur_pas_redirige').'</a>'
);
else // format message texte, tout en js inline
return
// ie poste les formulaires dans une iframe, il faut donc rediriger son parent
"<script type='text/javascript'>if (parent.window){parent.window.document.location.replace(\"$url\");} else {document.location.replace(\"$url\");}</script>"
. http_img_pack('searching.gif','')
. '<br />'
. '<a href="'.quote_amp($url).'">'._T('navigateur_pas_redirige').'</a>';
}
}
// http://doc.spip.org/@redirige_url_ecrire
function redirige_url_ecrire($script='', $args='', $equiv='') {
return redirige_par_entete(generer_url_ecrire($script, $args, true), $equiv);
}
// http://doc.spip.org/@http_status
function http_status($status) {
global $REDIRECT_STATUS, $flag_sapi_name;
static $status_string = array(
200 => '200 OK',
204 => '204 No Content',
301 => '301 Moved Permanently',
302 => '302 Found',
304 => '304 Not Modified',
401 => '401 Unauthorized',
403 => '403 Forbidden',
404 => '404 Not Found',
503 => '503 Service Unavailable'
);
if ($REDIRECT_STATUS && $REDIRECT_STATUS == $status) return;
$php_cgi = ($flag_sapi_name AND preg_match(",cgi,i", @php_sapi_name()));
if ($php_cgi)
header("Status: ".$status_string[$status]);
else
header("HTTP/1.0 ".$status_string[$status]);
}
// Retourne ce qui va bien pour que le navigateur ne mette pas la page en cache
// http://doc.spip.org/@http_no_cache
function http_no_cache() {
if (headers_sent())
{ spip_log("http_no_cache arrive trop tard"); return;}
$charset = empty($GLOBALS['meta']['charset']) ? 'utf-8' : $GLOBALS['meta']['charset'];
// selon http://developer.apple.com/internet/safari/faq.html#anchor5
// il faudrait aussi pour Safari
// header("Cache-Control: post-check=0, pre-check=0", false)
// mais ca ne respecte pas
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
header("Content-Type: text/html; charset=$charset");
header("Expires: 0");
header("Last-Modified: " .gmdate("D, d M Y H:i:s"). " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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/boutons');
include_spip('base/connect_sql');
function inc_icone_renommer_dist($fond,$fonction){
$size = 24;
if (preg_match("/(?:-([0-9]{1,3}))?([.](gif|png))?$/i",$fond,$match)
AND ($match[0] OR $match[1])) {
if ($match[1])
$size = $match[1];
$type = substr($fond,0,-strlen($match[0]));
if (!$match[2])
$fond .= ".png";
}
else {
$type = $fond;
$fond .= ".png";
}
$rtl = false;
if (preg_match(',[-_]rtl$,i',$type,$match)){
$rtl = true;
$type = substr($type,0,-strlen($match[0]));
}
// objet_type garde invariant tout ce qui ne commence par par id_, spip_
// et ne finit pas par un s, sauf si c'est une exception declaree
$type = objet_type($type);
$dir = "images/";
$f = "$type-$size.png";
if ($icone = find_in_theme($dir.$f)){
$dir = dirname($icone);
$fond = $icone;
if ($rtl
AND $fr = "$type-rtl-$size.png"
AND file_exists($dir.'/'.$fr))
$type = "$type-rtl";
$action = $fonction;
if ($action=="supprimer.gif"){
$action = "del";
}
elseif ($action=="creer.gif"){
$action = "new";
}
elseif ($action=="edit.gif"){
$action = "edit";
}
if (!in_array($action,array('del','new','edit')))
$action = "";
if ($action){
if ($fa = "$type-$action-$size.png"
AND file_exists($dir.'/'.$fa)){
$fond = $dir .'/'. $fa;
$fonction = "";
}
else {
$fonction = "$action-$size.png";
}
}
// c'est bon !
return array($fond,$fonction);
}
return array($fond,$fonction);
}
?>
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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');
// http://doc.spip.org/@inc_iconifier_dist
function inc_iconifier_dist($objet, $id, $script, $visible=false, $flag_modif=true) {
// compat avec anciens appels
$objet = objet_type($objet);
return recuperer_fond('prive/editer/logo',array('objet'=>$objet,'id_objet'=>$id,'editable'=>$flag_modif));
}
?>
X
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2010 *
* 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;
# Les information d'une rubrique selectionnee dans le mini navigateur
// http://doc.spip.org/@inc_informer_dist
function inc_informer_dist($id, $col, $exclus, $rac, $type, $do='aff')
{
global $spip_display,$spip_lang_right ;
include_spip('inc/texte');
if ($type == "rubrique") {
$row = sql_fetsel("titre, descriptif", "spip_rubriques", "id_rubrique = $id");
if ($row) {
$titre = typo($row["titre"]);
$descriptif = propre($row["descriptif"]);
} else {
$titre = _T('info_racine_site');
}
} else
$titre = '';
$res = '';
if ($type == "rubrique" AND $spip_display != 1 AND $spip_display!=4 AND isset($GLOBALS['meta']['image_process']))
if ($GLOBALS['meta']['image_process'] != "non") {
$chercher_logo = charger_fonction('chercher_logo', 'inc');
if ($res = $chercher_logo($id, 'id_rubrique', 'on')) {
list($fid, $dir, $nom, $format) = $res;
include_spip('inc/filtres_images_mini');
$res = image_reduire("<img src='$fid' alt='' />", 100, 48);
if ($res)
$res = "<div style='float: $spip_lang_right; margin-$spip_lang_right: -5px; margin-top: -5px;'>$res</div>";
}
}
$rac = htmlentities($rac);
# ce lien provoque la selection (directe) de la rubrique cliquee
# et l'affichage de son titre dans le bandeau
$titre = strtr(str_replace("'", "&#8217;",
str_replace('"', "&#34;", textebrut($titre))),
"\n\r", " ");
$js_func = $do . '_selection_titre';
return "<div style='display: none;'>"
. "<input type='text' id='".$rac."_sel' value='$id' />"
. "<input type='text' id='".$rac."_sel2' value=\""
. entites_html($titre)
. "\" />"
. "</div>"
. "<div class='informer' style='padding: 5px; border-top: 0px;'>"
. (!$res ? '' : $res)
. "<p><b>".safehtml($titre)."</b></p>"
. (!$descriptif ? '' : "<div>".safehtml($descriptif)."</div>")
. "<div style='text-align: $spip_lang_right;'>"
. "<input type='submit' class='fondo' value='"
. _T('bouton_choisir')
. "'\nonclick=\"$js_func('$titre',$id,'selection_rubrique','id_parent'); return false;\" />"
. "</div>"
. "</div>";
}
?>