3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2017 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
14 * Fonctions utilisées au calcul des squelette du privé.
16 * @package SPIP\Core\Filtres
18 if (!defined('_ECRIRE_INC_VERSION')) {
22 include_spip('inc/filtres_boites');
23 include_spip('inc/boutons');
24 include_spip('inc/pipelines_ecrire');
28 * Retourne les paramètres de personnalisation css de l'espace privé
30 * Ces paramètres sont (ltr et couleurs) ce qui permet une écriture comme :
31 * generer_url_public('style_prive', parametres_css_prive())
32 * qu'il est alors possible de récuperer dans le squelette style_prive.html avec
34 * #SET{claire,##ENV{couleur_claire,edf3fe}}
35 * #SET{foncee,##ENV{couleur_foncee,3874b0}}
36 * #SET{left,#ENV{ltr}|choixsiegal{left,left,right}}
37 * #SET{right,#ENV{ltr}|choixsiegal{left,right,left}}
41 function parametres_css_prive() {
44 $args['v'] = $GLOBALS['spip_version_code'];
45 $args['p'] = substr(md5($GLOBALS['meta']['plugin']), 0, 4);
46 $args['themes'] = implode(',', lister_themes_prives());
47 $args['ltr'] = $GLOBALS['spip_lang_left'];
48 // un md5 des menus : si un menu change il faut maj la css
49 $args['md5b'] = (function_exists('md5_boutons_plugins') ?
md5_boutons_plugins() : '');
51 $c = (is_array($GLOBALS['visiteur_session'])
52 and is_array($GLOBALS['visiteur_session']['prefs']))
53 ?
$GLOBALS['visiteur_session']['prefs']['couleur']
56 $couleurs = charger_fonction('couleurs', 'inc');
57 parse_str($couleurs($c), $c);
58 $args = array_merge($args, $c);
60 if (_request('var_mode') == 'recalcul' or (defined('_VAR_MODE') and _VAR_MODE
== 'recalcul')) {
61 $args['var_mode'] = 'recalcul';
64 return http_build_query($args);
69 * Afficher le sélecteur de rubrique
71 * Il permet de placer un objet dans la hiérarchie des rubriques de SPIP
73 * @uses inc_chercher_rubrique_dist()
75 * @param string $titre
76 * @param int $id_objet
77 * @param int $id_parent
78 * @param string $objet
79 * @param int $id_secteur
80 * @param bool $restreint
81 * @param bool $actionable
82 * true : fournit le selecteur dans un form directement postable
83 * @param bool $retour_sans_cadre
86 function chercher_rubrique(
94 $retour_sans_cadre = false
97 include_spip('inc/autoriser');
98 if (intval($id_objet) && !autoriser('modifier', $objet, $id_objet)) {
101 if (!sql_countsel('spip_rubriques')) {
104 $chercher_rubrique = charger_fonction('chercher_rubrique', 'inc');
105 $form = $chercher_rubrique($id_parent, $objet, $restreint, ($objet == 'rubrique') ?
$id_objet : 0);
107 if ($id_parent == 0) {
108 $logo = "racine-24.png";
109 } elseif ($id_secteur == $id_parent) {
110 $logo = "secteur-24.png";
112 $logo = "rubrique-24.png";
116 if ($objet == 'rubrique') {
117 // si c'est une rubrique-secteur contenant des breves, demander la
118 // confirmation du deplacement
119 $contient_breves = sql_countsel('spip_breves', "id_rubrique=" . intval($id_objet));
121 if ($contient_breves > 0) {
122 $scb = ($contient_breves > 1 ?
's' : '');
123 $scb = _T('avis_deplacement_rubrique',
125 'contient_breves' => $contient_breves,
128 $confirm .= "\n<div class='confirmer_deplacement verdana2'>"
129 . "<div class='choix'><input type='checkbox' name='confirme_deplace' value='oui' id='confirme-deplace' /><label for='confirme-deplace'>"
131 "</label></div></div>\n";
133 $confirm .= "<input type='hidden' name='confirme_deplace' value='oui' />\n";
138 if (strpos($form, '<select') !== false) {
139 $form .= "<div style='text-align: " . $GLOBALS['spip_lang_right'] . ";'>"
140 . '<input class="fondo" type="submit" value="' . _T('bouton_choisir') . '"/>'
143 $form = "<input type='hidden' name='editer_$objet' value='oui' />\n" . $form;
144 if ($action = charger_fonction("editer_$objet", "action", true)) {
145 $form = generer_action_auteur("editer_$objet", $id_objet, self(), $form,
146 " method='post' class='submit_plongeur'");
148 $form = generer_action_auteur("editer_objet", "$objet/$id_objet", self(), $form,
149 " method='post' class='submit_plongeur'");
153 if ($retour_sans_cadre) {
157 include_spip('inc/presentation');
159 return debut_cadre_couleur($logo, true, "", $titre) . $form . fin_cadre_couleur(true);
165 * Tester si le site peut avoir des visiteurs
168 * si true, prendre en compte le fait que le site a *deja* des visiteurs
169 * comme le droit d'en avoir de nouveaux
170 * @param bool $accepter
173 function avoir_visiteurs($past = false, $accepter = true) {
174 if ($GLOBALS['meta']["forums_publics"] == 'abo') {
177 if ($accepter and $GLOBALS['meta']["accepter_visiteurs"] <> 'non') {
180 if (sql_countsel('spip_articles', "accepter_forum='abo'")) {
187 return sql_countsel('spip_auteurs',
188 "statut NOT IN ('0minirezo','1comite', '5poubelle')
189 AND (statut<>'nouveau' OR prefs NOT IN ('0minirezo','1comite', '5poubelle'))");
193 * Lister les status d'article visibles dans l'espace prive
194 * en fonction du statut de l'auteur
196 * Pour l'extensibilie de SPIP, on se repose sur autoriser('voir','article')
197 * en testant un à un les status présents en base
199 * On mémorise en static pour éviter de refaire plusieurs fois.
201 * @param string $statut_auteur
204 function statuts_articles_visibles($statut_auteur) {
205 static $auth = array();
206 if (!isset($auth[$statut_auteur])) {
207 $auth[$statut_auteur] = array();
208 $statuts = array_map('reset', sql_allfetsel('distinct statut', 'spip_articles'));
209 foreach ($statuts as $s) {
210 if (autoriser('voir', 'article', 0, array('statut' => $statut_auteur), array('statut' => $s))) {
211 $auth[$statut_auteur][] = $s;
216 return $auth[$statut_auteur];
220 * Traduire le statut technique de l'auteur en langage compréhensible
222 * Si $statut=='nouveau' et que le statut en attente est fourni,
223 * le prendre en compte en affichant que l'auteur est en attente
225 * @param string $statut
226 * @param string $attente
229 function traduire_statut_auteur($statut, $attente = "") {
231 if ($statut == 'nouveau') {
234 $plus = " (" . _T('info_statut_auteur_a_confirmer') . ")";
236 return _T('info_statut_auteur_a_confirmer');
241 "info_administrateurs" => _T('item_administrateur_2'),
242 "info_redacteurs" => _T('intem_redacteur'),
243 "info_visiteurs" => _T('item_visiteur'),
244 '5poubelle' => _T('texte_statut_poubelle'), // bouh
246 if (isset($recom[$statut])) {
247 return $recom[$statut] . $plus;
250 // retrouver directement par le statut sinon
251 if ($t = array_search($statut, $GLOBALS['liste_des_statuts'])) {
252 if (isset($recom[$t])) {
253 return $recom[$t] . $plus;
256 return _T($t) . $plus;
259 // si on a pas reussi a le traduire, retournons la chaine telle quelle
260 // c'est toujours plus informatif que rien du tout
265 * Afficher la mention des autres auteurs ayant modifié un objet
267 * @param int $id_objet
268 * @param string $objet
271 function afficher_qui_edite($id_objet, $objet) {
272 static $qui = array();
273 if (isset($qui[$objet][$id_objet])) {
274 return $qui[$objet][$id_objet];
277 if ($GLOBALS['meta']['articles_modif'] == 'non') {
278 return $qui[$objet][$id_objet] = '';
281 include_spip('inc/drapeau_edition');
282 $modif = mention_qui_edite($id_objet, $objet);
284 return $qui[$objet][$id_objet] = '';
287 include_spip('base/objets');
288 $infos = lister_tables_objets_sql(table_objet_sql($objet));
289 if (isset($infos['texte_signale_edition'])) {
290 return $qui[$objet][$id_objet] = _T($infos['texte_signale_edition'], $modif);
293 return $qui[$objet][$id_objet] = _T('info_qui_edite', $modif);
297 * Lister les statuts des auteurs
299 * @param string $quoi
300 * - redacteurs : retourne les statuts des auteurs au moins redacteur,
301 * tels que defini par AUTEURS_MIN_REDAC
302 * - visiteurs : retourne les statuts des autres auteurs, cad les visiteurs
303 * et autres statuts perso
304 * - tous : retourne tous les statuts connus
305 * @param bool $en_base
306 * si true, ne retourne strictement que les status existants en base
307 * dans tous les cas, les statuts existants en base sont inclus
310 function auteurs_lister_statuts($quoi = 'tous', $en_base = true) {
311 if (!defined('AUTEURS_MIN_REDAC')) {
312 define('AUTEURS_MIN_REDAC', "0minirezo,1comite,5poubelle");
317 $statut = AUTEURS_MIN_REDAC
;
318 $statut = explode(',', $statut);
320 $check = array_map('reset', sql_allfetsel('DISTINCT statut', 'spip_auteurs', sql_in('statut', $statut)));
321 $retire = array_diff($statut, $check);
322 $statut = array_diff($statut, $retire);
325 return array_unique($statut);
329 $exclus = AUTEURS_MIN_REDAC
;
330 $exclus = explode(',', $exclus);
332 // prendre aussi les statuts de la table des status qui ne sont pas dans le define
333 $statut = array_diff(array_values($GLOBALS['liste_des_statuts']), $exclus);
335 $s_complement = array_map('reset',
336 sql_allfetsel('DISTINCT statut', 'spip_auteurs', sql_in('statut', $exclus, 'NOT')));
338 return array_unique(array_merge($statut, $s_complement));
342 $statut = array_values($GLOBALS['liste_des_statuts']);
343 $s_complement = array_map('reset',
344 sql_allfetsel('DISTINCT statut', 'spip_auteurs', sql_in('statut', $statut, 'NOT')));
345 $statut = array_merge($statut, $s_complement);
347 $check = array_map('reset', sql_allfetsel('DISTINCT statut', 'spip_auteurs', sql_in('statut', $statut)));
348 $retire = array_diff($statut, $check);
349 $statut = array_diff($statut, $retire);
352 return array_unique($statut);
356 // on arrive jamais ici
357 return array_values($GLOBALS['liste_des_statuts']);
361 * Déterminer la rubrique pour la création d'un objet heuristique
363 * Rubrique courante si possible,
364 * - sinon rubrique administrée pour les admin restreint
365 * - sinon première rubrique de premier niveau autorisée que l'on trouve
367 * @param int $id_rubrique Identifiant de rubrique (si connu)
368 * @param string $objet Objet en cours de création
369 * @return int Identifiant de la rubrique dans laquelle créer l'objet
371 function trouver_rubrique_creer_objet($id_rubrique, $objet) {
373 if (!$id_rubrique and defined('_CHOIX_RUBRIQUE_PAR_DEFAUT') and _CHOIX_RUBRIQUE_PAR_DEFAUT
) {
374 $in = !count($GLOBALS['connect_id_rubrique'])
376 : (" AND " . sql_in('id_rubrique', $GLOBALS['connect_id_rubrique']));
378 // on tente d'abord l'ecriture a la racine dans le cas des rubriques uniquement
379 if ($objet == 'rubrique') {
382 $id_rubrique = sql_getfetsel('id_rubrique', 'spip_rubriques', "id_parent=0$in", '', "id_rubrique DESC", 1);
385 if (!autoriser("creer{$objet}dans", 'rubrique', $id_rubrique)) {
386 // manque de chance, la rubrique n'est pas autorisee, on cherche un des secteurs autorises
387 $res = sql_select("id_rubrique", "spip_rubriques", "id_parent=0");
388 while (!autoriser("creer{$objet}dans", 'rubrique', $id_rubrique) && $row_rub = sql_fetch($res)) {
389 $id_rubrique = $row_rub['id_rubrique'];
398 * Afficher le lien de redirection d'un article virtuel si il y a lieu
399 * (rien si l'article n'est pas redirige)
401 * @param string $virtuel
404 function lien_article_virtuel($virtuel) {
405 include_spip('inc/lien');
406 if (!$virtuel = virtuel_redirige($virtuel)) {
410 return propre("[->" . $virtuel . "]");
415 * Filtre pour générer un lien vers un flux RSS privé
417 * Le RSS est protegé par un hash de faible sécurité
420 * - `[(#VAL{a_suivre}|bouton_spip_rss)]`
421 * - `[(#VAL{signatures}|bouton_spip_rss{#ARRAY{id_article,#ID_ARTICLE}})]`
424 * @uses param_low_sec()
427 * @param string $lang
428 * @param string $title
432 function bouton_spip_rss($op, $args = array(), $lang = '', $title = 'RSS') {
433 include_spip('inc/acces');
434 $clic = http_img_pack('feed.png', 'RSS', '', $title);
435 $args = param_low_sec($op, $args, $lang, 'rss');
436 $url = generer_url_public('rss', $args);
438 return "<a style='float: " . $GLOBALS['spip_lang_right'] . ";' href='$url'>$clic</a>";
443 * Vérifier la présence d'alertes pour les auteur
445 * @param int $id_auteur
448 function alertes_auteur($id_auteur) {
452 if (isset($GLOBALS['meta']['message_crash_tables'])
453 and autoriser('detruire', null, null, $id_auteur)
455 include_spip('genie/maintenance');
456 if ($msg = message_crash_tables()) {
461 if (isset($GLOBALS['meta']['message_crash_plugins'])
462 and $GLOBALS['meta']['message_crash_plugins']
463 and autoriser('configurer', '_plugins', null, $id_auteur)
464 and is_array($msg = unserialize($GLOBALS['meta']['message_crash_plugins']))
466 $msg = implode(', ', array_map('joli_repertoire', array_keys($msg)));
467 $alertes[] = _T('plugins_erreur', array('plugins' => $msg));
470 $a = isset($GLOBALS['meta']['message_alertes_auteurs']) ?
$GLOBALS['meta']['message_alertes_auteurs'] : '';
472 and is_array($a = unserialize($a))
476 if (isset($a[$GLOBALS['visiteur_session']['statut']])) {
477 $alertes = array_merge($alertes, $a[$GLOBALS['visiteur_session']['statut']]);
478 unset($a[$GLOBALS['visiteur_session']['statut']]);
482 $alertes = array_merge($alertes, $a['']);
487 ecrire_meta("message_alertes_auteurs", serialize($a));
491 if (isset($GLOBALS['meta']['plugin_erreur_activation'])
492 and autoriser('configurer', '_plugins', null, $id_auteur)
494 include_spip('inc/plugin');
495 $alertes[] = plugin_donne_erreurs();
502 'id_auteur' => $id_auteur,
503 'exec' => _request('exec'),
509 if ($alertes = array_filter($alertes)) {
510 return "<div class='wrap-messages-alertes'><div class='messages-alertes'>" .
511 join(' | ', $alertes)
517 * Filtre pour afficher les rubriques enfants d'une rubrique
519 * @param int $id_rubrique
522 function filtre_afficher_enfant_rub_dist($id_rubrique) {
523 include_spip('inc/presenter_enfants');
525 return afficher_enfant_rub(intval($id_rubrique));
529 * Afficher un petit "i" pour lien vers autre page
531 * @param string $lien
533 * @param string $titre
534 * Titre au survol de l'icone pointant le lien
535 * @param string $titre_lien
536 * Si present, ajoutera en plus apres l'icone
537 * un lien simple, vers la meme URL,
538 * avec le titre indique
542 function afficher_plus_info($lien, $titre = "+", $titre_lien = "") {
543 $titre = attribut_html($titre);
544 $icone = "\n<a href='$lien' title='$titre' class='plus_info'>" .
545 http_img_pack("information-16.png", $titre) . "</a>";
550 return $icone . "\n<a href='$lien'>$titre_lien</a>";
555 * Lister les id objet_source associés à l'objet id_objet
556 * via la table de lien objet_lien
558 * Utilisé pour les listes de #FORMULAIRE_EDITER_LIENS
560 * @param string $objet_source
561 * @param string $objet
562 * @param int $id_objet
563 * @param string $objet_lien
566 function lister_objets_lies($objet_source, $objet, $id_objet, $objet_lien) {
567 include_spip('action/editer_liens');
569 // quand $objet == $objet_lien == $objet_source on reste sur le cas par defaut de $objet_lien == $objet_source
570 if ($objet_lien == $objet and $objet_lien !== $objet_source) {
571 $res = objet_trouver_liens(array($objet => $id_objet), array($objet_source => '*'));
573 $res = objet_trouver_liens(array($objet_source => '*'), array($objet => $id_objet));
575 while ($row = array_shift($res)) {
576 $l[] = $row[$objet_source];