Browse Source

Déplacement de champs extras core et interface à la racine de plugins.

svn/root/tags/v3.12.4
marcimat@rezo.net 7 years ago
commit
a305f69026
  1. 27
      .gitattributes
  2. 143
      base/cextras.php
  3. 307
      cextras_fonctions.php
  4. 55
      cextras_options.php
  5. 357
      cextras_pipelines.php
  6. BIN
      images/cextras-64.png
  7. 416
      inc/cextras.php
  8. 593
      inc/cextras_autoriser.php
  9. 23
      lang/cextras.xml
  10. 17
      lang/cextras_ar.php
  11. 23
      lang/cextras_en.php
  12. 23
      lang/cextras_es.php
  13. 21
      lang/cextras_fr.php
  14. 17
      lang/cextras_it.php
  15. 23
      lang/cextras_nl.php
  16. 23
      lang/cextras_ru.php
  17. 23
      lang/cextras_sk.php
  18. 27
      lang/paquet-cextras.xml
  19. 16
      lang/paquet-cextras_de.php
  20. 19
      lang/paquet-cextras_en.php
  21. 18
      lang/paquet-cextras_es.php
  22. 17
      lang/paquet-cextras_fr.php
  23. 16
      lang/paquet-cextras_it.php
  24. 19
      lang/paquet-cextras_nl.php
  25. 19
      lang/paquet-cextras_ru.php
  26. 19
      lang/paquet-cextras_sk.php
  27. 29
      paquet.xml

27
.gitattributes vendored

@ -0,0 +1,27 @@
* text=auto !eol
base/cextras.php -text
/cextras_fonctions.php -text
/cextras_options.php -text
/cextras_pipelines.php -text
images/cextras-64.png -text
inc/cextras.php -text
inc/cextras_autoriser.php -text
lang/cextras.xml -text
lang/cextras_ar.php -text
lang/cextras_en.php -text
lang/cextras_es.php -text
lang/cextras_fr.php -text
lang/cextras_it.php -text
lang/cextras_nl.php -text
lang/cextras_ru.php -text
lang/cextras_sk.php -text
lang/paquet-cextras.xml -text
lang/paquet-cextras_de.php -text
lang/paquet-cextras_en.php -text
lang/paquet-cextras_es.php -text
lang/paquet-cextras_fr.php -text
lang/paquet-cextras_it.php -text
lang/paquet-cextras_nl.php -text
lang/paquet-cextras_ru.php -text
lang/paquet-cextras_sk.php -text
/paquet.xml -text

143
base/cextras.php

@ -0,0 +1,143 @@
<?php
/**
* Déclaration colonnes SQL des champs extras
*
* @package SPIP\Cextras\Pipelines
**/
// sécurité
if (!defined("_ECRIRE_INC_VERSION")) return;
/**
* Déclarer les nouveaux champs et les nouvelles infos des objets éditoriaux
*
* La fonction déclare tous les champs extras (saisies de type sql).
*
* Elle déclare aussi, en fonction des options choisies pour les champs
* - la recherche dans le champs, avec une certaine pondération,
* - le versionnage de champ
*
* @note
* Ne pas utiliser dans le code de cette fonction
* table_objet() qui ferait une réentrance et des calculs faux.
*
* @pipeline declarer_tables_objets_sql
* @param array $tables
* Description des tables
* @return array
* Description complétée des tables
*/
function cextras_declarer_tables_objets_sql($tables){
include_spip('inc/cextras');
// recuperer les champs crees par les plugins
// array($table => array(Liste de saisies))
include_spip('inc/saisies');
// si saisies a ete supprime par ftp, on sort tranquilou sans tuer SPIP.
// champs extras sera ensuite desactive par admin plugins.
if (!function_exists('saisies_lister_avec_sql')) {
return $tables;
}
$saisies_tables = pipeline('declarer_champs_extras', array());
foreach ($saisies_tables as $table => $saisies) {
if (isset($tables[$table])) {
$saisies = champs_extras_saisies_lister_avec_sql($saisies);
foreach ($saisies as $saisie) {
$nom = $saisie['options']['nom'];
if (!isset($tables[$table]['field'][$nom])) {
$tables[$table]['field'][$nom] = $saisie['options']['sql'];
}
// on l'ajoute dans la liste des champs editables
if (isset($tables[$table]['champs_editables'])
and !in_array($nom, $tables[$table]['champs_editables'])){
$tables[$table]['champs_editables'][] = $nom;
}
// ajouter le champ dans les analyses de recherche si demande
// l'option rechercher peut valoir 'on', true, ou 5 (entier) pour l'indice de ponderation
// par defaut, la ponderation est de 2.
if (isset($saisie['options']['rechercher']) and $saisie['options']['rechercher']) {
$ponderation = $saisie['options']['rechercher'];
if ($ponderation === 'on' OR $ponderation === true) {
// le plugin d'interface donne la valeur de ponderation dans une option separee.
if (isset($saisie['options']['rechercher_ponderation']) and $saisie['options']['rechercher_ponderation']) {
$ponderation = intval($saisie['options']['rechercher_ponderation']);
} else {
$ponderation = 2;
}
} else {
$ponderation = intval($ponderation);
}
$tables[$table]['rechercher_champs'][$nom] = $ponderation;
}
// option de versionnage ?
if (isset($saisie['options']['versionner']) and $saisie['options']['versionner']) {
// on l'ajoute dans la liste des champs versionnables
if (isset($tables[$table]['champs_versionnes'])
and !in_array($nom, $tables[$table]['champs_versionnes'])) {
$tables[$table]['champs_versionnes'][] = $nom;
}
}
}
}
}
return $tables;
}
/**
* Déclarer les nouvelles infos sur les champs extras ajoutés
* en ce qui concerne les traitements automatiques sur les balises.
*
* @pipeline declarer_tables_interfaces
* @param array $interfaces
* Déclarations d'interface pour le compilateur
* @return array
* Déclarations d'interface pour le compilateur
**/
function cextras_declarer_tables_interfaces($interfaces){
include_spip('inc/cextras');
include_spip('inc/saisies');
// si saisies a ete supprime par ftp, on sort tranquilou sans tuer SPIP.
// champs extras sera ensuite desactive par admin plugins.
if (!function_exists('saisies_lister_avec_sql')) {
return $tables;
}
// recuperer les champs crees par les plugins
$saisies_tables = pipeline('declarer_champs_extras', array());
if (!$saisies_tables) {
return $interfaces;
}
foreach ($saisies_tables as $table=>$saisies) {
$saisies = champs_extras_saisies_lister_avec_sql($saisies);
$saisies = saisies_lister_avec_traitements($saisies);
foreach ($saisies as $saisie) {
$traitement = $saisie['options']['traitements'];
$balise = strtoupper($saisie['options']['nom']);
// definir
if (!isset($interfaces['table_des_traitements'][$balise])) {
$interfaces['table_des_traitements'][$balise] = array();
}
// le traitement peut etre le nom d'un define
$traitement = defined($traitement) ? constant($traitement) : $traitement;
// SPIP 3 permet de declarer par la table sql directement.
$interfaces['table_des_traitements'][$balise][$table] = $traitement;
}
}
// ajouter les champs au tableau spip
return $interfaces;
}

307
cextras_fonctions.php

@ -0,0 +1,307 @@
<?php
/**
* Déclarations de balises pour les squelettes
*
* @package SPIP\Cextras\Fonctions
**/
// sécurité
if (!defined("_ECRIRE_INC_VERSION")) return;
/**
* Retourne la description de la saisie du champ demandé
* permettant ainsi d'exploiter ses données.
*
* @example
* ```
* <BOUCLE_x(TABLE)>
* - #CHAMP_EXTRA{nom_du_champ}
* - #CHAMP_EXTRA{nom_du_champ,label}
* </BOUCLE_x>
* ```
*
* @balise
* @note
* Lève une erreur de squelette si le nom de champs extras
* n'est pas indiqué en premier paramètre de la balise
*
* @param Champ $p
* AST au niveau de la balise
* @return Champ
* AST complété par le code PHP de la balise
**/
function balise_CHAMP_EXTRA_dist($p) {
// prendre nom de la cle primaire de l'objet pour calculer sa valeur
$id_boucle = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle;
$objet = $p->boucles[$id_boucle]->id_table;
// recuperer les parametres : colonne sql (champ)
if (!$colonne = interprete_argument_balise(1, $p)) {
$msg = array('zbug_balise_sans_argument', array('balise' => ' CHAMP_EXTRA'));
erreur_squelette($msg, $p);
}
$demande = sinon(interprete_argument_balise(2, $p), "''");
$p->code = "calculer_balise_CHAMP_EXTRA('$objet', $colonne, $demande)";
return $p;
}
/**
* Retourne la description d'un champ extra indiqué
*
* Retourne le tableau de description des options de saisies
* ou un des attributs de ce tableau
*
* @param string $objet
* Type d'objet
* @param string $colonne
* Nom de la colonne SQL
* @param string $demande
* Nom du paramètre demandé.
* Non renseigné, tout le tableau de description est retourné
* @return mixed
* - Tableau si toute la description est demandée
* - Indéfini si un élément spécifique de la description est demandé.
* - Chaine vide si le champs extra n'est pas trouvé
*/
function calculer_balise_CHAMP_EXTRA($objet, $colonne, $demande='') {
// Si la balise n'est pas dans une boucle, on cherche un objet explicite dans le premier argument
// de la forme "trucs/colonne" ou "spip_trucs/colonne"
if (!$objet and $decoupe = explode('/', $colonne) and count($decoupe) == 2){
$objet = $decoupe[0];
$colonne = $decoupe[1];
}
// recuperer la liste des champs extras existants
include_spip('cextras_pipelines');
if (!$saisies = champs_extras_objet( $table = table_objet_sql($objet) )) {
return '';
}
include_spip('inc/saisies');
if (!$saisie = saisies_chercher($saisies, $colonne)) {
return '';
}
if (!$demande) {
return $saisie['options']; // retourne la description de la saisie...
}
if (array_key_exists($demande, $saisie['options'])) {
return $saisie['options'][$demande];
}
return '';
}
/**
* Retourne les choix possibles d'un champ extra donné
*
* @example
* ```
* #LISTER_CHOIX{champ}
* #LISTER_CHOIX{champ, " > "}
* // ** pour retourner un tableau (cle => valeur),
* // ou tableau groupe => tableau (cle => valeur) si déclaration de groupements.
* #LISTER_CHOIX**{champ}
* ```
*
* @balise
* @param Champ $p
* AST au niveau de la balise
* @return Champ
* AST complété par le code PHP de la balise
**/
function balise_LISTER_CHOIX_dist($p) {
// prendre nom de la cle primaire de l'objet pour calculer sa valeur
$id_boucle = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle;
// s'il n'y a pas de nom de boucle, on ne peut pas fonctionner
if (!isset($p->boucles[$id_boucle])) {
$msg = array('zbug_champ_hors_boucle', array('champ' => ' LISTER_CHOIX'));
erreur_squelette($msg, $p);
$p->code = "''";
return $p;
}
$objet = $p->boucles[$id_boucle]->id_table;
// recuperer les parametres : colonne sql (champ)
if (!$colonne = interprete_argument_balise(1, $p)) {
$msg = array('zbug_balise_sans_argument', array('balise' => ' LISTER_CHOIX'));
erreur_squelette($msg, $p);
$p->code = "''";
return $p;
}
$separateur = interprete_argument_balise(2, $p);
if (!$separateur) $separateur = "', '";
// generer le code d'execution
$applatir = ($p->etoile == "**") ? 'false' : 'true';
$p->code = "calculer_balise_LISTER_CHOIX('$objet', $colonne, $applatir)";
// retourne un array si #LISTER_CHOIX**
// sinon fabrique une chaine avec le separateur designe.
if ($p->etoile != "**") {
$p->code = "(is_array(\$a = $p->code) ? join($separateur, \$a) : " . $p->code . ")";
}
return $p;
}
/**
* Retourne les choix possibles d'un champ extra indiqué
*
* @note
* Le plugin saisies tolère maintenant des sélections avec
* un affichage par groupe (optgroup / options) avec une syntaxe
* spécifique. Ici nous devons pouvoir applatir
* toutes les cle => valeur.
*
* @param string $objet
* Type d'objet
* @param string $colonne
* Nom de la colonne SQL
* @param bool $applatir
* true pour applatir les choix possibles au premier niveau
* même si on a affaire à une liste de choix triée par groupe
* @return string|array
* - Tableau des couples (clé => valeur) des choix
* - Chaîne vide si le champs extra n'est pas trouvé
*/
function calculer_balise_LISTER_CHOIX($objet, $colonne, $applatir = true) {
if ($options = calculer_balise_CHAMP_EXTRA($objet, $colonne)) {
if (isset($options['datas']) and $options['datas']) {
include_spip('inc/saisies');
$choix = saisies_chaine2tableau($options['datas']);
// applatir les sous-groupes si présents
if ($applatir) {
$choix = saisies_aplatir_tableau($choix);
}
return $choix;
}
}
return '';
}
/**
* Liste les valeurs des champs de type liste (enum, radio, case)
*
* Ces champs enregistrent en base la valeur de la clé
* Il faut donc transcrire clé -> valeur
*
* @example
* ```
* #LISTER_VALEURS{champ}
* #LISTER_VALEURS{champ, " > "}
* #LISTER_VALEURS**{champ} // retourne un tableau cle/valeur
* ```
*
* @note
* Pour des raisons d'efficacité des requetes SQL
* le paramètre "champ" ne peut être calculé
* ``#LISTER_VALEURS{#GET{champ}}`` ne peut pas fonctionner.
*
* Si cette restriction est trop limitative, on verra par la suite
* pour l'instant, on laisse comme ca...
*
* @balise
* @param Champ $p
* AST au niveau de la balise
* @return Champ
* AST complété par le code PHP de la balise
*/
function balise_LISTER_VALEURS_dist($p) {
// prendre nom de la cle primaire de l'objet pour calculer sa valeur
$id_boucle = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle;
// s'il n'y a pas de nom de boucle, on ne peut pas fonctionner
if (!isset($p->boucles[$id_boucle])) {
$msg = array('zbug_champ_hors_boucle', array('champ' => ' LISTER_VALEURS'));
erreur_squelette($msg, $p);
$p->code = "''";
return $p;
}
$objet = $p->boucles[$id_boucle]->id_table;
$_id_objet = $p->boucles[$id_boucle]->primary;
$id_objet = champ_sql($_id_objet, $p);
// recuperer les parametres : colonne sql (champ)
if (!$colonne = interprete_argument_balise(1, $p)) {
$msg = array('zbug_balise_sans_argument', array('balise' => ' LISTER_VALEURS'));
erreur_squelette($msg, $p);
$p->code = "''";
return $p;
}
$separateur = interprete_argument_balise(2, $p);
if (!$separateur) $separateur = "', '";
// demander la colonne dans la requete SQL
// $colonne doit etre un texte 'nom_du_champ'
if ($p->param[0][1][0]->type != 'texte') {
$msg = array('cextras:zbug_balise_argument_non_texte', array('nb'=>1, 'balise' => ' LISTER_VALEURS'));
erreur_squelette($msg, $p);
$p->code = "''";
return $p;
}
$texte_colonne = $p->param[0][1][0]->texte;
$valeur = champ_sql($texte_colonne, $p);
// generer le code d'execution
$p->code = "calculer_balise_LISTER_VALEURS('$objet', $colonne, $valeur)";
// retourne un array si #LISTER_VALEURS**
// sinon fabrique une chaine avec le separateur designe.
if ($p->etoile != "**") {
$p->code = "(is_array(\$a = $p->code) ? join($separateur, \$a) : " . $p->code . ")";
}
return $p;
}
/**
* Retourne liste des valeurs choisies pour un champ extra indiqué
*
* @param string $objet
* Type d'objet
* @param string $colonne
* Nom de la colonne SQL
* @param string $cles
* Valeurs enregistrées pour ce champ dans la bdd pour l'objet en cours
*
* @return string|array
* - Tableau des couples (clé => valeur) des choix
* - Chaîne vide si le champs extra n'est pas trouvé
**/
function calculer_balise_LISTER_VALEURS($objet, $colonne, $cles) {
// exploser les cles !
$cles = explode(',', $cles);
// si pas de cles, on part aussi gentiment
if (!$cles) return array();
// recuperer les choix possibles
$choix = calculer_balise_LISTER_CHOIX($objet, $colonne);
// sortir gentiment si pas de champs declares
// on ne peut pas traduire les cles
if (!$choix) return $cles;
// correspondances...
$vals = array_intersect_key($choix, array_flip($cles));
// et voici les valeurs !
return $vals ? $vals : $cles;
}

55
cextras_options.php

@ -0,0 +1,55 @@
<?php
/**
* Options globales chargées à chaque hit
*
* @package SPIP\Cextras\Options
**/
// sécurité
if (!defined("_ECRIRE_INC_VERSION")) return;
// utiliser ces pipelines a part
// afin d'etre certain d'arriver apres les autres plugins
// sinon toutes les tables ne sont pas declarees
// et les champs supplementaires ne peuvent pas se declarer comme il faut
if (!isset($GLOBALS['spip_pipeline']['declarer_tables_objets_sql'])) {
$GLOBALS['spip_pipeline']['declarer_tables_objets_sql'] = '';
}
if (!isset($GLOBALS['spip_pipeline']['declarer_tables_interfaces'])) {
$GLOBALS['spip_pipeline']['declarer_tables_interfaces'] = '';
}
$GLOBALS['spip_pipeline']['declarer_tables_objets_sql'] .= '||cextras_declarer_champs_apres_les_autres';
$GLOBALS['spip_pipeline']['declarer_tables_interfaces'] .= '||cextras_declarer_champs_interfaces_apres_les_autres';
/**
* Ajouter les déclaration dechamps extras sur les objets éditoriaux
*
* @pipeline declarer_tables_objets_sql
* @see cextras_declarer_tables_objets_sql()
* @param array $tables
* Description des objets éditoriaux
* @return array
* Description des objets éditoriaux
**/
function cextras_declarer_champs_apres_les_autres($tables) {
include_spip('base/cextras');
return cextras_declarer_tables_objets_sql($tables);
}
/**
* Ajouter les déclaration d'interface des champs extras pour le compilateur
*
* @pipeline declarer_tables_interfaces
* @see cextras_declarer_tables_interfaces()
* @param array $interface
* Description des interfaces pour le compilateur
* @return array
* Description des interfaces pour le compilateur
**/
function cextras_declarer_champs_interfaces_apres_les_autres($interface) {
include_spip('base/cextras');
return cextras_declarer_tables_interfaces($interface);
}

357
cextras_pipelines.php

@ -0,0 +1,357 @@
<?php
/**
* Utilisations de pipelines
*
* @package SPIP\Cextras\Pipelines
**/
// sécurité
if (!defined("_ECRIRE_INC_VERSION")) return;
/**
* Retourne la liste des saisies de champs extras concernant un objet donné
*
* @pipeline_appel declarer_champs_extras
* @param string $table
* Nom d'une table SQL éditoriale
* @return array
* Liste des saisies de champs extras de l'objet
**/
function champs_extras_objet($table) {
static $saisies_tables = array();
if (!$saisies_tables) {
$saisies_tables = pipeline('declarer_champs_extras', array());
}
return isset($saisies_tables[$table]) ? $saisies_tables[$table] : array();
}
/**
* Filtrer par autorisation les saisies transmises
*
* Chacune des saisies est parcourue et si le visiteur n'a pas l'autorisation
* de la voir, elle est enlevée de la liste.
* La fonction ne retourne donc que la liste des saisies que peut voir
* la personne.
*
* @param string $faire
* Type d'autorisation testée : 'voir', 'modifier'
* @param string $quoi
* Type d'objet tel que 'article'
* @param array $saisies
* Liste des saisies à filtrer
* @param array $args
* Arguments pouvant être utiles à l'autorisation
* @return array
* Liste des saisies filtrées
**/
function champs_extras_autorisation($faire, $quoi='', $saisies=array(), $args=array()) {
if (!$saisies) return array();
include_spip('inc/autoriser');
foreach ($saisies as $cle=>$saisie) {
$id = isset($args['id']) ? $args['id'] : $args['id_objet'];
if (!autoriser($faire . 'extra', $quoi, $id, '', array(
'type' => $quoi,
'id_objet' => $id,
'contexte' => isset($args['contexte']) ? $args['contexte'] : array(),
'table' => table_objet_sql($quoi),
'saisie' => $saisie,
'champ' => $saisie['options']['nom'],
))) {
// on n'est pas autorise
unset($saisies[$cle]);
}
else
{
// on est autorise
// on teste les sous-elements
if (isset($saisie['saisies']) and $saisie['saisies']) {
$saisies['saisies'] = champs_extras_autorisation($faire, $quoi, $saisie['saisies'], $args);
}
}
}
return $saisies;
}
/**
* Ajoute pour chaque saisie de type SQL un drapeau (input hidden)
* permettant de retrouver les saisies editées.
*
* Particulièrement utile pour les checkbox qui ne renvoient
* rien si on les décoche.
*
* @param array $saisies
* Liste de saisies
* @return array $saisies
* Saisies complétées des drapeaux d'édition
**/
function champs_extras_ajouter_drapeau_edition($saisies) {
$saisies_sql = champs_extras_saisies_lister_avec_sql($saisies);
foreach ($saisies_sql as $saisie) {
$nom = $saisie['options']['nom'];
$saisies[] = array(
'saisie' => 'hidden',
'options' => array(
'nom' => "cextra_$nom",
'defaut' => 1
)
);
}
return $saisies;
}
// ---------- pipelines -----------
/**
* Ajouter les champs extras sur les formulaires CVT editer_xx
*
* Liste les champs extras de l'objet, et s'il y en a les ajoute
* sur le formulaire d'édition en ayant filtré uniquement les saisies
* que peut voir le visiteur et en ayant ajouté des champs hidden
* servant à champs extras.
*
* @pipeline editer_contenu_objet
* @param array $flux Données du pipeline
* @return array Données du pipeline
**/
function cextras_editer_contenu_objet($flux){
// recuperer les saisies de l'objet en cours
$objet = $flux['args']['type'];
include_spip('inc/cextras');
if ($saisies = champs_extras_objet( table_objet_sql($objet) )) {
// filtrer simplement les saisies que la personne en cours peut voir
$saisies = champs_extras_autorisation('modifier', $objet, $saisies, $flux['args']);
// pour chaque saisie presente, de type champs extras (hors fieldset et autres)
// ajouter un flag d'edition
$saisies = champs_extras_ajouter_drapeau_edition($saisies);
// ajouter au formulaire
$ajout = recuperer_fond('inclure/generer_saisies', array_merge($flux['args']['contexte'], array('saisies'=>$saisies)));
// div par défaut en 3.1+, mais avant ul / li
$balise = saisie_balise_structure_formulaire('ul');
$flux['data'] = preg_replace(
'%(<!--extra-->)%is',
"<$balise class='editer-groupe champs_extras'>$ajout</$balise>\n" . '$1',
$flux['data']
);
}
return $flux;
}
/**
* Ajouter les champs extras soumis par les formulaire CVT editer_xx
*
* Pour chaque champs extras envoyé par le formulaire d'édition,
* ajoute les valeurs dans l'enregistrement à effectuer.
*
* @pipeline pre_edition
* @param array $flux Données du pipeline
* @return array Données du pipeline
**/
function cextras_pre_edition($flux){
include_spip('inc/cextras');
include_spip('inc/saisies_lister');
$table = $flux['args']['table'];
if ($saisies = champs_extras_objet( $table )) {
// Restreindre les champs postés en fonction des autorisations de les modifier
// au cas où un malin voudrait en envoyer plus que le formulaire ne demande
$saisies = champs_extras_autorisation('modifier', objet_type($table), $saisies, $flux['args']);
$saisies = champs_extras_saisies_lister_avec_sql($saisies);
foreach ($saisies as $saisie) {
$nom = $saisie['options']['nom'];
if (_request('cextra_' . $nom)) {
$extra = _request($nom);
if (is_array($extra)) {
$extra = join(',' , $extra);
}
$flux['data'][$nom] = corriger_caracteres($extra);
}
}
}
return $flux;
}
/**
* Ajouter les champs extras sur la visualisation de l'objet
*
* S'il y a des champs extras sur l'objet, la fonction les ajoute
* à la vue de l'objet, en enlevant les saisies que la personne n'a
* pas l'autorisation de voir.
*
* @pipeline afficher_contenu_objet
* @param array $flux Données du pipeline
* @return array Données du pipeline
**/
function cextras_afficher_contenu_objet($flux){
// recuperer les saisies de l'objet en cours
$objet = $flux['args']['type'];
include_spip('inc/cextras');
if ($saisies = champs_extras_objet( $table = table_objet_sql($objet) )) {
// ajouter au contexte les noms et valeurs des champs extras
$saisies_sql = champs_extras_saisies_lister_avec_sql($saisies);
$valeurs = sql_fetsel(array_keys($saisies_sql), $table, id_table_objet($table) . '=' . sql_quote($flux['args']['id_objet']));
if (!$valeurs) {
$valeurs = array();
} else {
// on applique les eventuels traitements definis
// /!\ La saisies-vues/_base applique |propre par defaut si elle ne trouve pas de saisie
// Dans ce cas, certains traitements peuvent être effectués 2 fois !
$saisies_traitees = saisies_lister_avec_traitements($saisies_sql);
unset($saisies_sql);
// Fournir $connect et $Pile[0] au traitement si besoin (l'evil eval)
$connect = '';
$Pile = array(0 => (isset($flux['args']['contexte']) ? $flux['args']['contexte'] : array()));
foreach ($saisies_traitees as $saisie) {
$traitement = $saisie['options']['traitements'];
$traitement = defined($traitement) ? constant($traitement) : $traitement;
$nom = $saisie['options']['nom'];
list($avant, $apres) = explode('%s', $traitement);
eval('$val = ' . $avant . ' $valeurs[$nom] ' . $apres . ';');
$valeurs[$nom] = $val;
}
}
$contexte = isset($flux['args']['contexte']) ? $flux['args']['contexte'] : array();
$contexte = array_merge($contexte, $valeurs);
// restreindre la vue selon les autorisations
$saisies = champs_extras_autorisation('voir', $objet, $saisies, $flux['args']);
// ajouter les vues
$flux['data'] .= recuperer_fond('inclure/voir_saisies', array_merge($contexte, array(
'saisies' => $saisies,
'valeurs' => $valeurs,
)));
}
return $flux;
}
/**
* Vérification de la validité des champs extras
*
* Lorsqu'un formulaire 'editer_xx' se présente, la fonction effectue,
* pour chaque champs extra les vérifications prévues dans la
* définition de la saisie, et retourne les éventuelles erreurs rencontrées.
*
* @pipeline formulaire_verifier
* @param array $flux Données du pipeline
* @return array Données du pipeline
**/
function cextras_formulaire_verifier($flux){
$form = $flux['args']['form'];
if (strncmp($form, 'editer_', 7) !== 0) {
return $flux;
}
$objet = substr($form, 7);
if ($saisies = champs_extras_objet( $table = table_objet_sql($objet) )) {
include_spip('inc/autoriser');
include_spip('inc/saisies');
// restreindre les saisies selon les autorisations
$id_objet = $flux['args']['args'][0]; // ? vraiment toujours ?
$saisies = champs_extras_autorisation('modifier', $objet, $saisies, array_merge($flux['args'], array(
'id' => $id_objet,
'contexte' => array()))); // nous ne connaissons pas le contexte dans ce pipeline
// restreindre les vérifications aux saisies enregistrables
$saisies = champs_extras_saisies_lister_avec_sql($saisies);
$verifier = charger_fonction('verifier', 'inc', true);
foreach ($saisies as $saisie) {
// verifier obligatoire
$nom = $saisie['options']['nom'];
if (isset($saisie['options']['obligatoire']) and $saisie['options']['obligatoire']
and !_request($nom))
{
$flux['data'][$nom] = _T('info_obligatoire');
// verifier (api) + normalisation
} elseif ($verifier
AND isset($saisie['verifier']['type'])
AND $verif = $saisie['verifier']['type'])
{
$options = isset($saisie['verifier']['options']) ? $saisie['verifier']['options'] : array();
$normaliser = null;
$valeur = _request($nom);
if ($erreur = $verifier($valeur, $verif, $options, $normaliser)) {
$flux['data'][$nom] = $erreur;
// si une valeur de normalisation a ete transmis, la prendre.
} elseif (!is_null($normaliser)) {
set_request($nom, $normaliser);
} else {
// [FIXME] exceptions connues de vérifications (pour les dates entre autres)
// en attendant une meilleure solution !
//
// Lorsque le champ n'est pas rempli dans le formulaire
// alors qu'une normalisation est demandée,
// verifier() sort sans indiquer d'erreur (c'est normal).
//
// Sauf que la donnée alors soumise à SQL sera une chaine vide,
// ce qui ne correspond pas toujours à ce qui est attendu.
if ((is_string($valeur) and !strlen($valeur) or (is_array($valeur) and $saisie['saisie']=='date'))
and isset($options['normaliser'])
and $norme = $options['normaliser']) {
// Charger la fonction de normalisation théoriquement dans verifier/date
// et si on en trouve une, obtenir la valeur normalisée
// qui est théoriquement la valeur par défaut, puisque $valeur est vide
include_spip("verifier/$verif");
if ($normaliser = charger_fonction("${verif}_${norme}", "normaliser", true)) {
$erreur = null;
$defaut = $normaliser($valeur, $options, $erreur);
if (is_null($erreur)) {
set_request($nom, $defaut);
} else {
// on affecte l'erreur, mais il est probable que
// l'utilisateur ne comprenne pas grand chose
$flux['data'][$nom] = $erreur;
}
} else {
include_spip('inc/cextras');
extras_log("Fonction de normalisation pour ${verif}_${norme} introuvable");
}
}
}
}
}
}
return $flux;
}
/**
* Insertion dans le pipeline revisions_chercher_label (Plugin révisions)
* Trouver le bon label à afficher sur les champs dans les listes de révisions
*
* Si un champ est un champ extra, son label correspond au label défini du champs extra
*
* @pipeline revisions_chercher_label
* @param array $flux Données du pipeline
* @return array Données du pipeline
**/
function cextras_revisions_chercher_label($flux){
$table = table_objet_sql($flux['args']['objet']);
$saisies_tables = champs_extras_objet($table);
foreach($saisies_tables as $champ){
if($champ['options']['nom'] == $flux['args']['champ']){
$flux['data'] = $champ['options']['label'];
break;
}
}
return $flux;
}

BIN
images/cextras-64.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

416
inc/cextras.php

@ -0,0 +1,416 @@
<?php
/**
* Déclaration d'autorisations pour les champs extras
*
* @package SPIP\Cextras\Fonctions
**/
// sécurité
if (!defined("_ECRIRE_INC_VERSION")) return;
/**
* Log une information
*
* @param mixed $contenu
* Contenu à loger
* @param bool $important
* Est-ce une info importante à loger ?
*/
function extras_log($contenu, $important=false) {
if ($important) {
spip_log($contenu, 'extras.'. _LOG_INFO);
} else {
spip_log($contenu, 'extras.'. _LOG_INFO_IMPORTANTE);
}
}
/**
* Retourne la liste des objets valides utilisables
*
* C'est à dire les objets dont on peut afficher les champs dans les
* formulaires, ce qui correspond aux objets éditoriaux déclarés
* comme avec l'option principale.
*
* @return array
* Couples (table sql => description de l'objet éditorial)
*/
function cextras_objets_valides(){
$objets = array();
$tables = lister_tables_objets_sql();
ksort($tables);
foreach($tables as $table => $desc) {
if (($desc['editable'] == 'oui') and ($desc['principale'] == 'oui')) {
$objets[$table] = $desc;
}
}
return $objets;
}
/**
* Liste les saisies ayant une definition SQL
*
* S'assurer de l'absence de clé, qui fait croire à saisies que le tableau est déjà à plat
* alors que ce n'est pas forcément encore le cas (ie: il peut y avoir des fieldset à prendre
* en compte).
*
* @param Array $saisies liste de saisies
* @return array Liste de ces saisies triees par nom ayant une option sql définie
*/
function champs_extras_saisies_lister_avec_sql($saisies) {
if (!function_exists('saisies_lister_avec_sql')) {
include_spip('inc/saisies');
}
return saisies_lister_avec_sql(array_values($saisies));
}
/**
* Liste les saisies ayant des traitements
*
* Retourne uniquement les saisies ayant traitements à appliquer sur
* les champs tel que des traitements typo ou traitements raccourcis.
*
* @param array $saisies
* Liste de saisies
* @param String $tri
* Tri par défaut des résultats (s'ils ne sont pas deja triés) ('nom', 'identifiant')
* @return array
* Liste de ces saisies triées par nom ayant des traitements définis
**/
function saisies_lister_avec_traitements($saisies, $tri = 'nom') {
return saisies_lister_avec_option('traitements', $saisies, $tri);
}
/**
* Créer les champs extras (colonnes en base de données)
* definies par le lot de saisies donné
*
* @param string $table
* Nom de la table SQL
* @param array $saisies
* Description des saisies
* @return bool|void
* False si pas de table ou aucune saisie de type SQL
**/
function champs_extras_creer($table, $saisies) {
if (!$table) {
return false;
}
if (!is_array($saisies) OR !count($saisies)) {
return false;
}
// uniquement les saisies décrivant SQL
$saisies = champs_extras_saisies_lister_avec_sql($saisies);
if (!$saisies) {
return false;
}
$desc = lister_tables_objets_sql($table);
// parcours des saisies et ajout des champs extras nouveaux dans
// la description de la table
foreach ($saisies as $saisie) {
$nom = $saisie['options']['nom'];
// le champ ne doit pas deja exister !
if (!isset($desc['field'][$nom])) {
$desc['field'][$nom] = $saisie['options']['sql'];
}
}
// executer la mise a jour
include_spip('base/create');
creer_ou_upgrader_table($table, $desc, true, true);
}
/**
* Supprimer les champs extras (colonne dans la base de données)
* definies par le lot de saisies donné
*
* @param string $table
* Nom de la table SQL
* @param array $saisies
* Description des saisies
* @return bool
* False si pas de table, aucune saisie de type SQL, ou une suppression en erreur
* True si toutes les suppressions sont OK
**/
function champs_extras_supprimer($table, $saisies) {
if (!$table) {
return false;
}
if (!is_array($saisies) OR !count($saisies)) {
return false;
}
$saisies = champs_extras_saisies_lister_avec_sql($saisies);
if (!$saisies) {
return false;
}
$desc = lister_tables_objets_sql($table);
$ok = true;
foreach ($saisies as $saisie) {
$nom = $saisie['options']['nom'];
if (isset($desc['field'][$nom])) {
$ok &= sql_alter("TABLE $table DROP COLUMN $nom");
}
}
return $ok;
}
/**
* Modifier les champs extras (colonne dans la base de données)
* definies par le lot de saisies donné
*
* Permet de changer la structure SQL ou le nom de la colonne
* des saisies
*
* @param string $table
* Nom de la table SQL
* @param array $saisies_nouvelles
* Description des saisies nouvelles
* @param array $saisies_anciennes
* Description des saisies anciennes
* @return bool
* True si les changement SQL sont correctement effectués
**/
function champs_extras_modifier($table, $saisies_nouvelles, $saisies_anciennes) {
$ok = true;
foreach ($saisies_nouvelles as $id => $n) {
$n_nom = $n['options']['nom'];
if (isset($n['options']['sql'])) {
$n_sql = $n['options']['sql'];
$a_nom = $saisies_anciennes[$id]['options']['nom'];
$a_sql = $saisies_anciennes[$id]['options']['sql'];
if ($n_nom != $a_nom OR $n_sql != $n_sql) {
$ok &= sql_alter("TABLE $table CHANGE COLUMN $a_nom $n_nom $n_sql");
}
}
}
return $ok;
}
/**
* Complète un tableau de mise à jour de plugin afin d'installer les champs extras.
*
* @example
* ```
* cextras_api_upgrade(motus_declarer_champs_extras(), $maj['create']);
* ```
*
* @param array $declaration_champs_extras
* Liste de champs extras à installer, c'est à dire la liste de saisies
* présentes dans le pipeline declarer_champs_extras() du plugin qui demande l'installation
* @param array $maj_item
* Un des éléments du tableau d'upgrade $maj,
* il sera complété des actions d'installation des champs extras demandés
*
* @return bool
* false si les déclarations sont mal formées
* true sinon
**/
function cextras_api_upgrade($declaration_champs_extras, &$maj_item) {
if (!is_array($declaration_champs_extras)) {
return false;
}
if (!is_array($maj_item)) {
$maj_item = array();
}
foreach($declaration_champs_extras as $table=>$champs) {
$maj_item[] = array('champs_extras_creer',$table, $champs);
}
return true;
}
/**
* Supprime les champs extras declarés
*
* @example
* ```
* cextras_api_vider_tables(motus_declarer_champs_extras());
* ```
*
* @param array $declaration_champs_extras
* Liste de champs extras à désinstaller, c'est à dire la liste de saisies
* présentes dans le pipeline declarer_champs_extras() du plugin qui demande la désinstallation
*
* @return bool
* false si déclaration mal formée
* true sinon
**/
function cextras_api_vider_tables($declaration_champs_extras) {
if (!is_array($declaration_champs_extras)) {
return false;
}
foreach($declaration_champs_extras as $table=>$champs) {
champs_extras_supprimer($table, $champs);
}
return true;
}
/*
*
* Rechercher les champs non declares mais existants
* dans la base de donnee en cours
* (code d'origine : _fil_)
*
*/
/**
* Liste les tables et les champs que le plugin et spip savent gérer
* mais qui ne sont pas déclarés à SPIP
*
* @param string $connect
* Nom du connecteur de base de données
* @return array
* Tableau (table => couples(colonne => description SQL))
*/
function extras_champs_utilisables($connect='') {
$tout = extras_champs_anormaux($connect);
$objets = cextras_objets_valides();
$utilisables = array_intersect_key($tout, $objets);
ksort($utilisables);
return $utilisables;
}
/**
* Liste les champs anormaux par rapport aux définitions de SPIP
*
* @note
* Aucune garantie que $connect autre que la connexion principale fasse quelque chose
*
* @param string $connect
* Nom du connecteur de base de données
* @return array
* Tableau (table => couples(colonne => description SQL))
*/
function extras_champs_anormaux($connect='') {
static $tout = false;
if ($tout !== false) {
return $tout;
}
// recuperer les tables et champs de la base de donnees
// les vrais de vrai dans la base sql...
$tout = extras_base($connect);
// recuperer les champs SPIP connus
// si certains ne sont pas declares alors qu'ils sont presents
// dans la base sql, on pourra proposer de les utiliser comme champs
// extras (plugin interface).
include_spip('base/objets');
$tables_spip = lister_tables_objets_sql();
// chercher ce qui est different
$ntables = array();
$nchamps = array();
// la table doit être un objet editorial
$tout = array_intersect_key($tout, $tables_spip);
foreach ($tout as $table => $champs) {
// la table doit être un objet editorial principal
if ($tables_spip[$table]['principale'] == 'oui') {
// pour chaque champ absent de la déclaration, on le note dans $nchamps.
foreach($champs as $champ => $desc) {
if (!isset($tables_spip[$table]['field'][$champ])) {
if (!isset($nchamps[$table])) {
$nchamps[$table] = array();
}
$nchamps[$table][$champ] = $desc;
}
}
}
}
if($nchamps) {
$tout = $nchamps;
} else {
$tout = array();
}
return $tout;
}
/**
* Établit la liste de tous les champs de toutes les tables de la connexion
* sql donnée
*
* Ignore la table 'spip_test'
*
* @param string $connect
* Nom du connecteur de base de données
* @return array
* Tableau (table => couples(colonne => description SQL))
*/
function extras_base($connect='') {
$champs = array();
foreach (extras_tables($connect) as $table) {
if ($table != 'spip_test') {
$champs[$table] = extras_champs($table, $connect);
}
}
return $champs;
}
/**
* Liste les tables SQL disponibles de la connexion sql donnée
*
* @param string $connect
* Nom du connecteur de base de données
* @return array
* Liste de tables SQL
*/
function extras_tables($connect='') {
$a = array();
$taille_prefixe = strlen( $GLOBALS['connexions'][$connect ? $connect : 0]['prefixe'] );
if ($s = sql_showbase(null, $connect)) {
while ($t = sql_fetch($s, $connect)) {
$t = 'spip' . substr(array_pop($t), $taille_prefixe);
$a[] = $t;
}
}
return $a;
}
/**
* Liste les champs dispos dans la table SQL de la connexion sql donnée
*
* @param string $table
* Nom de la table SQL
* @param string $connect
* Nom du connecteur de base de données
* @return array
* Couples (colonne => description SQL)
*/
function extras_champs($table, $connect) {
$desc = sql_showtable($table, true, $connect);
if (is_array($desc['field'])) {
return $desc['field'];
} else {
return array();
}
}

593
inc/cextras_autoriser.php

@ -0,0 +1,593 @@
<?php
/**
* Déclaration d'autorisations pour les champs extras
*
* @package SPIP\Cextras\Autorisations
**/
// sécurité
if (!defined("_ECRIRE_INC_VERSION")) return;
/**
* Fonction d'appel pour le pipeline autoriser
* @pipeline autoriser
*/
function cextras_autoriser(){}
/**
* Retourne si une saisie peut s'afficher ou non
*
* Teste les options de restrictions de la saisie si il y en a
* et calcule en fonction l'autorisation
*
* @param array $saisie
* Saisie que l'on traite.
* @param string $action
* Le type d'action : voir | modifier
* @param string $table
* La table d'application : spip_articles
* @param int $id
* Identifiant de la table : 3
* @param array $qui
* Description de l'auteur en cours
* @param Array $opt
* Options de l'autorisation
* @return Bool
* La saisie peut elle s'afficher ?
**/
function champs_extras_restrictions($saisie, $action, $table, $id, $qui, $opt) {
if (!$saisie) {
return true;
}
if (!isset($saisie['options']['restrictions']) OR !$saisie['options']['restrictions']) {
return true;
}
if (!in_array($action, array('voir', 'modifier'))) {
return true;
}
$restrictions = $saisie['options']['restrictions'];
// tester si des options d'autorisations sont definies pour cette saisie
// et les appliquer.
// peut être 'voir' ou 'modifier'
// dedans peut être par type d'auteur 'webmestre' (sur verification d'autorisation webmestre), 'admin', 'admin_complet'
// peut être par secteur parent.
// peut être par branche parente.
// peut être par groupe parent.
// restriction par type d'auteur
if (isset($restrictions[$action]['auteur']) and $auteur = $restrictions[$action]['auteur']) {
switch ($auteur) {
case 'webmestre':
if (!autoriser('webmestre')) {
return false;
}
break;
case 'admin':
if ($qui['statut'] != '0minirezo') {
return false;
}
break;
case 'admin_complet':
if ($qui['statut'] != '0minirezo' || ($qui['statut'] == '0minirezo' AND $qui['restreint'])){
return false;
}
break;
}
}
// pour les autres autorisations, dès qu'une est valide, on part.
// cela permet de dire que l'on peut restreindre au secteur 1 et à la branche 3,
// branche en dehors du secteur 1
// le cumul des autorisations rendrait impossible cela
unset($restrictions['voir']);
unset($restrictions['modifier']);
// enlever tous les false (0, '')
$restrictions = array_filter($restrictions);
if ($restrictions) {
foreach ($restrictions as $type => $ids) {
$ids = explode(':', $ids);
$cible = rtrim($type, 's');
$restriction = charger_fonction("restreindre_extras_objet_sur_$cible", "inc", true);
if ($restriction and $restriction($opt['type'], $opt['id_objet'], $opt, $ids, $cible)) {
return true;
}
}
// aucune des restrictions n'a ete validee
return false;
}
return true;
}
/**
* Autorisation de voir un champ extra
*
* Cherche une autorisation spécifique pour le champ si elle existe
* (autoriser_{objet}_voirextra_{colonne}_dist), sinon applique
* l'autorisation prévue par la description de la saisie
*
* @example
* ```
* autoriser('voirextra','auteur', $id_auteur,'',
* array('champ'=>'prenom', 'saisie'=>$saisie, ...));
* ```
* Appelle ``autoriser_auteur_voirextra_prenom_dist()`` si la fonction existe...
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_voirextra_dist($faire, $type, $id, $qui, $opt){
if (isset($opt['saisie'])) {
// tester des fonctions d'autorisations plus precises declarees
if ($opt['champ']) {
$f = 'autoriser_' . $opt['type'] . '_voirextra_' . $opt['champ'];
if (function_exists($f) OR function_exists($f .= '_dist')) {
return $f($faire, $type, $id, $qui, $opt);
}
}
return champs_extras_restrictions($opt['saisie'], substr($faire, 0, -5), $opt['table'], $id, $qui, $opt);
}
return true;
}
/**
* Autorisation de modifier un champ extra
*
* Cherche une autorisation spécifique pour le champ si elle existe
* (autoriser_{objet}_modifierextra_{colonne}_dist), sinon applique
* l'autorisation prévue par la description de la saisie
*
* @example
* ```
* autoriser('modifierextra','auteur', $id_auteur,'',
* array('champ'=>'prenom', 'saisie'=>$saisie, ...));
* ```
* Appelle ``autoriser_auteur_modifierextra_prenom_dist()`` si elle existe
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_modifierextra_dist($faire, $type, $id, $qui, $opt){
if (isset($opt['saisie'])) {
// tester des fonctions d'autorisations plus precises declarees
if ($opt['champ']) {
$f = 'autoriser_' . $opt['type'] . '_modifierextra_' . $opt['champ'];
if (function_exists($f) OR function_exists($f .= '_dist')) {
return $f($faire, $type, $id, $qui, $opt);
}
}
return champs_extras_restrictions($opt['saisie'], substr($faire, 0, -5), $opt['table'], $id, $qui, $opt);
}
return true;
}
/**
* Fonction d'aide pour créer des autorisations de champs spécifiques
*
* Permet d'indiquer que tels champs extras se limitent à telle ou telle rubrique
* et cela en créant à la volée les fonctions d'autorisations adéquates.
*
* @example
* ```
* restreindre_extras('article', array('nom', 'prenom'), array(8, 12));
* restreindre_extras('site', 'url_doc', 18, true); // recursivement aux sous rubriques
* ```
*
* @param string $objet
* Objet possédant les extras
* @param mixed $noms
* Nom des extras a restreindre
* @param mixed $ids
* Identifiant (des rubriques par defaut) sur lesquelles s'appliquent les champs
* @param string $cible
* Type de la fonction de test qui sera appelee, par defaut "rubrique". Peut aussi etre "secteur", "groupe" ou des fonctions definies
* @param bool $recursif
* Application recursive sur les sous rubriques ? ATTENTION, c'est gourmand en requetes SQL :)
* @return bool
* true si on a fait quelque chose
*/
function restreindre_extras($objet, $noms=array(), $ids=array(), $cible='rubrique', $recursif=false) {
if (!$objet or !$noms or !$ids) {
return false;
}
if (!is_array($noms)) { $noms = array($noms); }
if (!is_array($ids)) { $ids = array($ids); }
#$objet = objet_type($objet);
$ids = var_export($ids, true);
$recursif = var_export($recursif, true);
foreach ($noms as $nom) {
$m = "autoriser_" . $objet . "_modifierextra_" . $nom . "_dist";
$v = "autoriser_" . $objet . "_voirextra_" . $nom . "_dist";
$code = "
if (!function_exists('$m')) {
function $m(\$faire, \$quoi, \$id, \$qui, \$opt) {
return _restreindre_extras_objet('$objet', \$id, \$opt, $ids, '$cible', $recursif);
}
}
if (!function_exists('$v')) {
function $v(\$faire, \$quoi, \$id, \$qui, \$opt) {
return autoriser('modifierextra', \$quoi, \$id, \$qui, \$opt);
}
}
";
# var_dump($code);
eval($code);
}
return true;
}
/**
* Fonction d'autorisation interne à la fonction restreindre_extras()
*
* Teste si un objet à le droit d'afficher des champs extras
* en fonction de la rubrique (ou autre defini dans la cible)
* dans laquelle il se trouve et des rubriques autorisées
*
* On met en cache pour éviter de plomber le serveur SQL, vu que la plupart du temps
* un hit demandera systématiquement le même objet/id_objet lorsqu'il affiche
* un formulaire.
*
* @param string $objet
* Objet possédant les extras
* @param int $id_objet
* Identifiant de l'objet possédant les extras
* @param array $opt
* Options des autorisations
* @param mixed $ids
* Identifiant(s) (en rapport avec la cible) sur lesquelles s'appliquent les champs
* @param string $cible
* Type de la fonction de test qui sera appelee, par defaut "rubrique".
* Peut aussi etre "secteur", "groupe" ou des fonctions definies
* @param bool $recursif
* Application recursive sur les sous rubriques ? ATTENTION, c'est
* gourmand en requetes SQL :)
* @return bool
* Autorisé ou non
**/
function _restreindre_extras_objet($objet, $id_objet, $opt, $ids, $cible='rubrique', $recursif=false) {
static $autorise = array();
if ( !isset($autorise[$objet]) ) { $autorise[$objet] = array(); }
$cle = $cible . implode('-', $ids);
if (isset($autorise[$objet][$id_objet][$cle])) {
return $autorise[$objet][$id_objet][$cle];
}
$f = charger_fonction("restreindre_extras_objet_sur_$cible", "inc", true);
if ($f) {
return $autorise[$objet][$id_objet][$cle] =
$f($objet, $id_objet, $opt, $ids, $recursif);
}
// pas trouve... on n'affiche pas... Pan !
return $autorise[$objet][$id_objet][$cle] = false;
}
/**
* Fonction d'autorisation interne à la fonction restreindre_extras()
*
* Teste si un objet à le droit d'afficher des champs extras
* en fonction de la rubrique (ou autre defini dans la cible)
* dans laquelle il se trouve et des rubriques autorisées
*
* Le dernier argument donne la colonne à chercher dans l'objet correspondant
*
* @param string $objet
* Objet possédant les extras
* @param int $id_objet
* Identifiant de l'objet possédant les extras
* @param array $opt
* Options des autorisations
* @param mixed $ids
* Identifiant(s) (en rapport avec la cible) sur lesquelles s'appliquent les champs
* @param bool $_id_cible
* Nom de la colonne SQL cible (id_rubrique, id_secteur, id_groupe...)
* @return bool|int
* - true : autorisé,
* - false : non autorisé,
* - 0 : incertain.
**/
function _restreindre_extras_objet_sur_cible($objet, $id_objet, $opt, $ids, $_id_cible) {
$id_cible = 0;
if (isset($opt['contexte'][$_id_cible])) {
$id_cible = intval($opt['contexte'][$_id_cible]);
}
if (!$id_cible) {
// on tente de le trouver dans la table de l'objet
$table = table_objet_sql($objet);
$id_table = id_table_objet($table);
include_spip('base/objets');
$desc = lister_tables_objets_sql($table);
if (isset($desc['field'][$_id_cible])) {
$id_cible = sql_getfetsel($_id_cible, $table, "$id_table=".sql_quote($id_objet));
}
}
if (!$id_cible) {
// on essaie aussi dans le contexte d'appel de la page
$id_cible = _request($_id_cible);
// on tente en cas de id_secteur de s'appuyer sur un eventuel id_rubrique
if (!$id_cible and $_id_cible == 'id_secteur') {
if ($i = _request('id_rubrique')) {
$id_cible = sql_getfetsel('id_secteur', 'spip_rubriques', 'id_rubrique='.sql_quote($i));
}
}
}
if (!$id_cible) {
return array($id_cible, false);
}
if (in_array($id_cible, $ids)) {
return array($id_cible, true);
}
return array($id_cible, false);
}
/**
* Fonction d'autorisation interne à la fonction restreindre_extras()
* spécifique au test d'appartenance à une branche de rubrique
*
* @note ATTENTION, c'est gourmand en requetes SQL :)
*
* @see inc_restreindre_extras_objet_sur_rubrique_dist()
* @param string $objet