[PLUGINS] +acces restreint
[ptitvelo/web/www.git] / www / plugins / accesrestreint_3_5 / inc / accesrestreint.php
diff --git a/www/plugins/accesrestreint_3_5/inc/accesrestreint.php b/www/plugins/accesrestreint_3_5/inc/accesrestreint.php
new file mode 100644 (file)
index 0000000..ee3f1b3
--- /dev/null
@@ -0,0 +1,258 @@
+<?php
+/**
+ * Plugin Acces Restreint 3.0 pour Spip 2.0
+ * Licence GPL (c) 2006-2008 Cedric Morin
+ *
+ */
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+// Liste des zones a laquelle appartient le visiteur, au format '1,2,3'
+// Cette fonction est appelee a chaque hit et peut etre completee (pipeline)
+/**
+ * Liste des zones a laquelle appartient le visiteur, au format '1,2,3'.
+ * Cette fonction est appelee a chaque hit et peut etre completee (pipeline)
+ *
+ * @param string $zones '1,2,3'
+ * @param int $id_auteur
+ * @return string '1,2,3'
+ */
+function accesrestreint_liste_zones_autorisees($zones='', $id_auteur=NULL) {
+       $id = NULL;
+       if (!is_null($id_auteur))
+               $id = $id_auteur;
+       elseif (isset($GLOBALS['visiteur_session']['id_auteur']) && $GLOBALS['visiteur_session']['id_auteur'])
+               $id = $GLOBALS['visiteur_session']['id_auteur'];
+       if (!is_null($id)) {
+               $new = accesrestreint_liste_zones_appartenance_auteur($id);
+               if ($zones AND $new) {
+                       $zones = array_unique(array_merge(explode(',',$zones),$new));
+                       sort($zones);
+                       $zones = join(',', $zones);
+               } else if ($new) {
+                       $zones = join(',', $new);
+               }
+       }
+       return $zones;
+}
+
+/**
+ * liste des rubriques contenues dans une zone, directement.
+ * pour savoir quelles rubriques on peut decocher
+ * si id_zone = '' : toutes les rub en acces restreint
+ *
+ * @param int|string $id_zone
+ * @return array
+ */
+function accesrestreint_liste_contenu_zone_rub_direct($id_zone){
+       $liste_rubriques=array();
+       // liste des rubriques directement liees a la zone
+       $where = array();
+       if (is_numeric($id_zone))
+               $where[] = "z.id_zone=".intval($id_zone);
+       elseif ($id_zone)
+               $where = $id_zone;
+
+       if (is_array($where))
+               $where[] = "zr.objet='rubrique'";
+       else
+               $where = "($where) AND zr.objet='rubrique'";
+
+       include_spip('base/abstract_sql');
+       $liste_rubriques = sql_allfetsel('id_objet','spip_zones_liens AS zr INNER JOIN spip_zones AS z ON zr.id_zone=z.id_zone',$where);
+       $liste_rubriques = array_map('reset',$liste_rubriques);
+       $liste_rubriques = array_unique($liste_rubriques);
+       return $liste_rubriques;
+}
+
+/**
+ * liste des rubriques contenues dans une zone, directement ou par heritage.
+ *
+ * @param int/string $id_zone
+ * @return array
+ */
+function accesrestreint_liste_contenu_zone_rub($id_zone){
+       include_spip('inc/rubriques');
+       $liste_rubriques = accesrestreint_liste_contenu_zone_rub_direct($id_zone);
+       if (!count($liste_rubriques))
+               return $liste_rubriques;
+       $liste_rubriques = calcul_branche_in(join(',',$liste_rubriques));
+       if (!strlen($liste_rubriques))
+               return array();
+       $liste_rubriques = explode(',',$liste_rubriques);
+       return $liste_rubriques;
+}
+
+
+/**
+ * liste des rubriques d'une zone et leurs rubriques parentes.
+ *
+ * @param int/string $id_zone
+ * @return array
+ */
+function accesrestreint_liste_parentee_zone_rub($id_zone){
+       include_spip('inc/rubriques');
+       $liste_rubriques = accesrestreint_liste_contenu_zone_rub_direct($id_zone);
+       if (!count($liste_rubriques))
+               return $liste_rubriques;
+
+       $id = $liste_rubriques;
+       while ($parents = sql_allfetsel('id_parent', 'spip_rubriques',
+       sql_in('id_rubrique', $id))) {
+               $parents = array_map('array_shift', $parents);
+               $parents = array_diff($parents, array(0));
+               $id = $parents;
+               $liste_rubriques = array_merge($liste_rubriques, $parents);
+       }
+       
+       return $liste_rubriques;
+}
+
+/**
+ * Lister les zones auxquelles un auteur appartient
+ *
+ * @param int $id_auteur
+ * @return array
+ */
+function accesrestreint_liste_zones_appartenance_auteur($id_auteur){
+       static $liste_zones = array();
+       if (!isset($liste_zones[$id_auteur])){
+               include_spip('base/abstract_sql');
+               $liste_zones[$id_auteur] = sql_allfetsel("id_zone","spip_zones_liens","objet='auteur' AND id_objet=".intval($id_auteur));
+               $liste_zones[$id_auteur] = array_map('reset',$liste_zones[$id_auteur]);
+       }
+       return $liste_zones[$id_auteur];
+}
+
+/**
+ * Verifier si un auteur appartient a une zone.
+ * utilise la fonction precedente qui met en cache son resultat
+ * on optimise en fonction de l'hypothese que le nombre de zones est toujours reduit
+ *
+ * @param unknown_type $id_zone
+ * @param unknown_type $id_auteur
+ * @return unknown
+ */
+function accesrestreint_test_appartenance_zone_auteur($id_zone,$id_auteur){
+       return in_array($id_zone,accesrestreint_liste_zones_appartenance_auteur($id_auteur));
+}
+
+/**
+ * liste des auteurs contenus dans une zone
+ *
+ * @param int $id_zone
+ * @return array
+ */
+function accesrestreint_liste_contenu_zone_auteur($id_zone) {
+       $liste_auteurs=array();
+       include_spip('base/abstract_sql');
+       $liste_auteurs = sql_allfetsel("id_objet","spip_zones_liens","objet='auteur' AND id_zone=".intval($id_zone));
+       $liste_auteurs = array_map('reset',$liste_auteurs);
+       return $liste_auteurs;
+}
+
+/**
+ * fonctions de filtrage rubrique
+ * -> condition NOT IN
+ * Cette fonction renvoie la liste des rubriques interdites
+ * au visiteur courant
+ * d'ou le recours a $GLOBALS['accesrestreint_zones_autorisees']
+ *
+ * @param bool $publique Selectionner les rubriques interdites dans l'espace public (true) ou prive (false)
+ * @param int $id_auteur Identifiant de l'auteur
+ * @param bool $quelquesoit_visibilite Si true, on ne s'occupe pas de savoir si une zone est restreinte sur le prive ou sur le public.
+ * @return array
+ */
+function accesrestreint_liste_rubriques_exclues($publique=true, $id_auteur=NULL, $quelquesoit_visibilite = false) {
+       // cache static
+       static $liste_rub_exclues = array();
+       static $liste_rub_inclues = array();
+       if ($quelquesoit_visibilite) { $publique = 'tout'; }
+
+       if (is_null($id_auteur) AND isset($GLOBALS['visiteur_session']['id_auteur']))
+               $id_auteur = $GLOBALS['visiteur_session']['id_auteur'];
+       if (!isset($liste_rub_exclues[$id_auteur][$publique]) || !is_array($liste_rub_exclues[$id_auteur][$publique])) {
+
+               $where = array();
+               // Ne selectionner que les zones pertinentes
+               if (!$quelquesoit_visibilite) {
+                       if ($publique)
+                               $where[] = "publique='oui'";
+                       else
+                               $where[] = "privee='oui'";
+               }
+
+               // Si le visiteur est autorise sur certaines zones publiques,
+               // on selectionne les rubriques correspondant aux autres zones,
+               // sinon on selectionne toutes celles correspondant a une zone.
+               include_spip('base/abstract_sql');
+               if ($GLOBALS['accesrestreint_zones_autorisees']
+                 AND $id_auteur==$GLOBALS['visiteur_session']['id_auteur'])
+                       $where[] = sql_in('zr.id_zone',$GLOBALS['accesrestreint_zones_autorisees'],'NOT');
+               elseif ($id_auteur)
+                       $where[] = sql_in('zr.id_zone',accesrestreint_liste_zones_autorisees('',$id_auteur),'NOT');
+
+               // liste les rubriques (+branches) des zones dont ne fait pas parti l'auteur
+               $liste_rub_exclues[$id_auteur][$publique] = accesrestreint_liste_contenu_zone_rub($where);
+               #$liste_rub_exclues[$publique] = array_unique($liste_rub_exclues[$publique]);
+       }
+       $final_liste_rub_exclues = $liste_rub_exclues[$id_auteur][$publique];
+       
+       if (defined("AR_TYPE_RESTRICTION") AND AR_TYPE_RESTRICTION == "faible") {
+               // AR_TYPE_RESTRICTION definit le type de restriction pour traiter les elements communs a plusieurs zone
+               // Une restriction exclusive (ou forte) donne l'acces aux rubriques restreintes par 
+               // plusieurs zone aux seuls membres de toutes les zones concernees.
+               // Une restriction faible donne acces a une rubrique, meme restreinte par
+               // plusieurs zones, aux membres de chaque zone concernee.
+               // valeurs : 'faible', 'forte, ou 'exclusive'           
+
+               // Autrement dit, si une rubrique 2 est enfant d'une rubrique 1,
+               // et qu'il existe une zone 1 (rubrique 1) et une zone 2 (rubrique 2) :
+               // - un auteur present dans la zone 1 (uniquement) ne pourra pas voir la rubrique 2
+               //   lorsque la restriction est "forte". Il le pourra avec une restriction "faible"
+               //
+               // - A l'inverse, un auteur present uniquement dans la zone 2 ne pourra pas voir
+               //   la rubrique 1 meme si la restriction est "faible" car la parentee n'est pas concernee.
+               //   il faut (si souhaite) dans ce cas definir en plus AR_TYPE_RESTRICTION_PARENTEE a "faible"
+               //   pour l'autoriser.
+               if (!isset($liste_rub_inclues[$id_auteur][$publique]) OR !is_array($liste_rub_inclues[$id_auteur][$publique])) {
+
+                       $where = array();
+                       // Ne selectionner que les zones pertinentes
+                       if (!$quelquesoit_visibilite) {
+                               if ($publique)
+                                       $where[] = "publique='oui'";
+                               else
+                                       $where[] = "privee='oui'";
+                       }
+
+                       // Calcul des rubriques dans des zones autorisees
+                       include_spip('base/abstract_sql');
+                       if ($GLOBALS['accesrestreint_zones_autorisees']
+                         AND $id_auteur==$GLOBALS['visiteur_session']['id_auteur'])
+                               $where[] = sql_in('zr.id_zone',$GLOBALS['accesrestreint_zones_autorisees']);
+                       elseif ($id_auteur)
+                               $where[] = sql_in('zr.id_zone',accesrestreint_liste_zones_autorisees('',$id_auteur));
+
+                       // liste les rubriques (+branches) des zones de l'auteur
+                       $liste_rub_inclues[$id_auteur][$publique] = accesrestreint_liste_contenu_zone_rub($where);
+
+                       // pour autoriser la vue des rubriques parentes
+                       // memes si elles sont restreintes par une autre zone
+                       if (defined("AR_TYPE_RESTRICTION_PARENTEE") AND AR_TYPE_RESTRICTION_PARENTEE == "faible") {
+                               $liste_rub_inclues[$id_auteur][$publique] =
+                                       array_merge($liste_rub_inclues[$id_auteur][$publique],
+                                               accesrestreint_liste_parentee_zone_rub($where));
+                       }
+               }
+
+               // Ne pas exclure les elements qui sont autorises
+               $final_liste_rub_exclues = array_diff($final_liste_rub_exclues,
+                       array_intersect($final_liste_rub_exclues,$liste_rub_inclues[$id_auteur][$publique]));
+       }
+
+       return $final_liste_rub_exclues;
+}
+
+
+?>