Browse Source

Les deux fichiers surchargés de SPIP, dans leur version modifiée pour voir le diff.

v1
marcimat@rezo.net 10 years ago
parent
commit
b47b0be4be
  1. 355
      action/editer_liens.php
  2. 144
      formulaires/editer_liens.php

355
action/editer_liens.php

@ -13,12 +13,25 @@
/**
* API d'édition de liens
*
* Cette API gère la création, modification et suppressions de liens
* entre deux objets éditoriaux par l'intermédiaire de tables de liaison
* tel que spip_xx_liens.
*
* L'unicité est assurée dans les fonctions sur le trio (id_x, objet, id_objet)
* par défaut, ce qui correspond à la déclaration de clé primaire.
*
* Des rôles peuvent être déclarés pour des liaisons. À ce moment là,
* une colonne spécifique doit être présente dans la table de liens
* et l'unicité est alors assurée sur le quatuor (id_x, objet, id_objet, role)
* et la clé primaire adaptée en conséquence.
*
* @package SPIP\Liens\API
*/
if (!defined('_ECRIRE_INC_VERSION')) return;
// charger la gestion les rôles sur les objets
include_spip('inc/roles');
/**
@ -58,9 +71,14 @@ function objet_associable($objet){
* et pour lesquels une table spip_xxx_liens existe
* (auteurs, documents, mots)
*
* on peut passer optionnellement une qualification du (des) lien(s) qui sera
* alors appliquee dans la foulee.
* En cas de lot de liens, c'est la meme qualification qui est appliquee a tous
* On peut passer optionnellement une qualification du (des) lien(s) qui sera
* alors appliquée dans la foulée. Lorsqu'une des qualification concerne
* un champ de rôle déclaré, la liaison se crée avec ce rôle. Si un champ de
* rôle est déclaré pour ce type de liaison, mais qu'il n'est pas présent
* dans cette qualification, on affecte automatiquement le rôle défini
* par défaut.
*
* En cas de lot de liens, c'est la même qualification qui est appliquée à tous
*
* @api
* @param array $objets_source
@ -69,7 +87,7 @@ function objet_associable($objet){
* @return bool|int
*/
function objet_associer($objets_source, $objets_lies, $qualif = null){
$modifs = objet_traiter_liaisons('lien_insert', $objets_source, $objets_lies);
$modifs = objet_traiter_liaisons('lien_insert', $objets_source, $objets_lies, $qualif);
if ($qualif)
objet_qualifier_liens($objets_source, $objets_lies, $qualif);
@ -92,13 +110,23 @@ function objet_associer($objets_source, $objets_lies, $qualif = null){
* un * pour $objet,$id_objet permet de traiter par lot
* seul le type de l'objet source ne peut pas accepter de joker et doit etre explicite
*
* S'il y a des rôles possibles entre les 2 objets, et qu'aucune condition
* sur la colonne du rôle n'est transmise, on ne supprime que les liens
* avec le rôle par défaut. Si on veut supprimer tous les rôles,
* il faut spécifier $cond => array('role' => '*')
*
* @api
* @param array $objets_source
* @param array|string $objets_lies
* @param array|null $cond
* Condition du where supplémentaires
*
* À l'exception de l'index 'role' qui permet de sélectionner un rôle
* ou tous les rôles (*), en s'affranchissant du vrai nom de la colonne.
* @return bool|int
*/
function objet_dissocier($objets_source,$objets_lies){
return objet_traiter_liaisons('lien_delete',$objets_source,$objets_lies);
function objet_dissocier($objets_source,$objets_lies, $cond=null){
return objet_traiter_liaisons('lien_delete',$objets_source,$objets_lies, $cond);
}
@ -152,12 +180,14 @@ function objet_qualifier_liens($objets_source,$objets_lies,$qualif){
* )
*
* @api
* @param array $objets_source
* @param array|string $objets_lies
* @param array $objets_source Couples (objets_source => identifiants) (objet qui a la table de lien)
* @param array|string $objets_lies Couples (objets_lies => identifiants)
* @param array|null $cond Condition du where supplémentaires
* @return array
* Liste des trouvailles
*/
function objet_trouver_liens($objets_source,$objets_lies){
return objet_traiter_liaisons('lien_find',$objets_source,$objets_lies);
function objet_trouver_liens($objets_source,$objets_lies,$cond=null){
return objet_traiter_liaisons('lien_find',$objets_source,$objets_lies,$cond);
}
@ -229,6 +259,7 @@ function objet_dupliquer_liens($objet,$id_source,$id_cible){
/**
* Fonction générique qui
* applique une operation de liaison entre un ou des objets et des objets listés
*
* $objets_source et $objets_lies sont de la forme
* array($objet=>$id_objets,...)
* $id_objets peut lui meme etre un scalaire ou un tableau pour une liste d'objets du meme type
@ -243,9 +274,18 @@ function objet_dupliquer_liens($objet,$id_source,$id_cible){
*
* @internal
* @param string $operation
* Nom de la fonction PHP qui traitera l'opération
* @param array $objets_source
* Liste de ou des objets source
* De la forme array($objet=>$id_objets,...), où $id_objets peut lui
* même être un scalaire ou un tableau pour une liste d'objets du même type
* @param array $objets_lies
* @param array $set
* Liste de ou des objets liés
* De la forme array($objet=>$id_objets,...), où $id_objets peut lui
* même être un scalaire ou un tableau pour une liste d'objets du même type
* @param null|array $set
* Liste de coupels champs valeur, soit array(champs => valeur)
* En fonction des opérations il peut servir à différentes utilisations
* @return bool|int|array
*/
function objet_traiter_liaisons($operation,$objets_source,$objets_lies, $set = null){
@ -290,45 +330,80 @@ function objet_traiter_liaisons($operation,$objets_source,$objets_lies, $set = n
* $objets et de la forme
* array($objet=>$id_objets,...)
*
* Retourne le nombre d'insertions realisees
* Retourne le nombre d'insertions réalisées
*
* @internal
* @param string $objet_source
* @param string $primary
* @param sgring $table_lien
* @param int $id
* @param array $objets
* @param string $objet_source Objet source de l'insertion (celui qui a la table de liaison)
* @param string $primary Nom de la clé primaire de cet objet
* @param sgring $table_lien Nom de la table de lien de cet objet
* @param int $id Identifiant de l'objet sur lesquels on va insérer des liaisons
* @param array $objets Liste des liaisons à faire, de la forme array($objet=>$id_objets)
* @param array $qualif
* Liste des qualifications à appliquer (qui seront faites par lien_set()),
* dont on cherche un rôle à insérer également.
* Si l'objet dispose d'un champ rôle, on extrait des qualifications
* le rôle s'il est présent, sinon on applique le rôle par défaut.
* @return bool|int
* Nombre d'insertions faites, false si échec.
*/
function lien_insert($objet_source,$primary,$table_lien,$id,$objets) {
function lien_insert($objet_source,$primary,$table_lien,$id,$objets,$qualif) {
$ins = 0;
$echec = null;
if (is_null($qualif)) $qualif = array();
foreach($objets as $objet => $id_objets){
if (!is_array($id_objets)) $id_objets = array($id_objets);
// role, colonne, where par défaut
list($role, $colonne_role, $cond) =
roles_trouver_dans_qualif($objet_source, $objet, $qualif);
foreach($id_objets as $id_objet) {
$objet = ($objet=='*')?$objet:objet_type($objet); # securite
$insertions = array(
'id_objet' => $id_objet,
'objet' => $objet,
$primary => $id
);
// rôle en plus s'il est défini
if ($role) $insertions += array(
$colonne_role => $role
);
$args = array(
'table_lien' => $table_lien,
'objet_source' => $objet_source,
'id_objet_source' => $id,
'objet' => $objet,
'id_objet' => $id_objet,
'role' => $role,
'colonne_role' => $colonne_role,
'action' => 'insert',
);
// Envoyer aux plugins
$id_objet = pipeline('pre_edition_lien',
array(
'args' => array(
'table_lien' => $table_lien,
'objet_source' => $objet_source,
'id_objet_source' => $id,
'objet' => $objet,
'id_objet' => $id_objet,
'action'=>'insert',
),
'args' => $args,
'data' => $id_objet
)
);
if ($id_objet=intval($id_objet)
AND !sql_getfetsel(
$primary,
$table_lien,
array('id_objet='.intval($id_objet), 'objet='.sql_quote($objet), $primary.'='.intval($id))))
{
$e = sql_insertq($table_lien, array('id_objet' => $id_objet, 'objet'=>$objet, $primary=>$id));
/* [todo] POUR la 3.1
// Envoyer aux plugins
$insertions = pipeline('pre_edition_lien',
array(
'args' => $args,
'data' => $insertions
)
);
*/
$where = lien_where($primary, $id, $objet, $id_objet, $cond);
if ($id_objet=intval($insertions['id_objet'])
AND !sql_getfetsel($primary, $table_lien, $where)) {
$e = sql_insertq($table_lien, $insertions);
if ($e!==false) {
$ins++;
lien_propage_date_modif($objet,$id_objet);
@ -336,14 +411,8 @@ function lien_insert($objet_source,$primary,$table_lien,$id,$objets) {
// Envoyer aux plugins
pipeline('post_edition_lien',
array(
'args' => array(
'table_lien' => $table_lien,
'objet_source' => $objet_source,
'id_objet_source' => $id,
'objet' => $objet,
'id_objet' => $id_objet,
'action'=>'insert',
),
'args' => $args,
#'data' => $insertions # [todo] POUR la 3.1
'data' => $id_objet
)
);
@ -360,13 +429,14 @@ function lien_insert($objet_source,$primary,$table_lien,$id,$objets) {
* Fabriquer la condition where en tenant compte des jokers *
*
* @internal
* @param string $primary
* @param int|string|array $id_source
* @param string $objet
* @param int|string|array $id_objet
* @return array
* @param string $primary Nom de la clé primaire
* @param int|string|array $id_source Identifiant de la clé primaire
* @param string $objet Nom de l'objet lié
* @param int|string|array $id_objet Identifiant de l'objet lié
* @param array $cond Conditions par défaut
* @return array Liste des conditions
*/
function lien_where($primary, $id_source, $objet, $id_objet){
function lien_where($primary, $id_source, $objet, $id_objet, $cond=array()){
if ((!is_array($id_source) AND !strlen($id_source))
OR !strlen($objet)
OR (!is_array($id_objet) AND !strlen($id_objet)))
@ -377,7 +447,9 @@ function lien_where($primary, $id_source, $objet, $id_objet){
$not = array_shift($id_source);
$id_source = reset($id_source);
}
$where = array();
$where = $cond;
if ($id_source!=='*')
$where[] = (is_array($id_source)?sql_in(addslashes($primary),array_map('intval',$id_source),$not):addslashes($primary) . ($not?"<>":"=") . intval($id_source));
elseif ($not)
@ -408,44 +480,75 @@ function lien_where($primary, $id_source, $objet, $id_objet){
* array($objet=>$id_objets,...)
* un * pour $id,$objet,$id_objets permet de traiter par lot
*
* On supprime tous les liens entre les objets indiqués par défaut,
* sauf s'il y a des rôles déclarés entre ces 2 objets, auquel cas on ne
* supprime que les liaisons avec le role déclaré par défaut si rien n'est
* précisé dans $cond. Il faut alors passer $cond=array('role'=>'*') pour
* supprimer tous les roles, ou array('role'=>'un_role') pour un role précis.
*
* @internal
* @param string $objet_source
* @param string $primary
* @param sgring $table_lien
* @param int $id
* @param array $objets
* @param array|null $cond
* Conditions where par défaut.
* Un cas particulier est géré lorsque l'index 'role' est présent (ou absent)
* @return bool|int
*/
function lien_delete($objet_source,$primary,$table_lien,$id,$objets){
function lien_delete($objet_source,$primary,$table_lien,$id,$objets,$cond=null){
$retire = array();
$dels = 0;
$echec = false;
if (is_null($cond)) $cond = array();
foreach($objets as $objet => $id_objets){
$objet = ($objet=='*')?$objet:objet_type($objet); # securite
if (!is_array($id_objets) OR reset($id_objets)=="NOT") $id_objets = array($id_objets);
foreach($id_objets as $id_objet) {
list($cond, $colonne_role, $role) = roles_creer_condition_role($objet_source, $objet, $cond);
// id_objet peut valoir '*'
$where = lien_where($primary, $id, $objet, $id_objet);
$where = lien_where($primary, $id, $objet, $id_objet, $cond);
// lire les liens existants pour propager la date de modif
$liens = sql_allfetsel("$primary,id_objet,objet",$table_lien,$where);
$select = "$primary,id_objet,objet";
if ($colonne_role) $select .= ",$colonne_role";
$liens = sql_allfetsel($select,$table_lien,$where);
// iterer sur les liens pour permettre aux plugins de gerer
foreach($liens as $l){
foreach($liens as $l) {
$args = array(
'table_lien' => $table_lien,
'objet_source' => $objet_source,
'id_objet_source' => $l[$primary],
'objet' => $l['objet'],
'id_objet' => $l['id_objet'],
'colonne_role' => $colonne_role,
'role' => ($colonne_role ? $l[$colonne_role] : ''),
'action'=>'delete',
);
// Envoyer aux plugins
$id_o = pipeline('pre_edition_lien',
array(
'args' => array(
'table_lien' => $table_lien,
'objet_source' => $objet_source,
'id_objet_source' => $l[$primary],
'objet' => $l['objet'],
'id_objet' => $l['id_objet'],
'action'=>'delete',
),
'args' => $args,
'data' => $l['id_objet']
)
);
if ($id_o=intval($id_o)){
$where = lien_where($primary, $l[$primary], $l['objet'], $id_o);
/* [TODO] pour SPIP 3.1
// Envoyer aux plugins
$l = pipeline('pre_edition_lien',
array(
'args' => $args,
'data' => $l
)
);*/
if ($id_o=intval($l['id_objet'])) {
$where = lien_where($primary, $l[$primary], $l['objet'], $id_o, $cond);
$e = sql_delete($table_lien, $where);
if ($e!==false){
$dels+=$e;
@ -454,25 +557,33 @@ function lien_delete($objet_source,$primary,$table_lien,$id,$objets){
}
else
$echec = true;
$retire[] = array('source'=>array($objet_source=>$l[$primary]),'lien'=>array($l['objet']=>$id_o),'type'=>$l['objet'],'id'=>$id_o);
$retire[] = array(
'source' => array($objet_source=>$l[$primary]),
'lien' => array($l['objet']=>$id_o),
'type' => $l['objet'],
'role' => ($colonne_role ? $l[$colonne_role] : ''),
'id' => $id_o
);
// Envoyer aux plugins
pipeline('post_edition_lien',
array(
'args' => array(
'table_lien' => $table_lien,
'objet_source' => $objet_source,
'id_objet_source' => $l[$primary],
'objet' => $l['objet'],
'id_objet' => $id_o,
'action'=>'delete',
),
'args' => $args,
'data' => $id_o
)
);
/* [TODO] Pour SPIP 3.1
// Envoyer aux plugins
pipeline('post_edition_lien',
array(
'args' => $args,
'data' => $l
)
);*/
}
}
}
}
pipeline('trig_supprimer_objets_lies',$retire);
return ($echec?false:$dels);
@ -556,13 +667,19 @@ function lien_optimise($objet_source,$primary,$table_lien,$id,$objets){
* $qualif = array('vu'=>'oui');
*
* @internal
* @param string $objet_source
* @param string $primary
* @param sgring $table_lien
* @param int $id
* @param array $objets
* @param string $objet_source Objet source de l'insertion (celui qui a la table de liaison)
* @param string $primary Nom de la clé primaire de cet objet
* @param sgring $table_lien Nom de la table de lien de cet objet
* @param int $id Identifiant de l'objet sur lesquels on va insérer des liaisons
* @param array $objets Liste des liaisons à faire, de la forme array($objet=>$id_objets)
* @param array $qualif
* Liste des qualifications à appliquer.
*
* Si l'objet dispose d'un champ rôle, on extrait des qualifications
* le rôle s'il est présent, sinon on applique les qualifications
* sur le rôle par défaut.
* @return bool|int
* Nombre de modifications faites, false si échec.
*/
function lien_set($objet_source,$primary,$table_lien,$id,$objets,$qualif){
$echec = null;
@ -577,16 +694,59 @@ function lien_set($objet_source,$primary,$table_lien,$id,$objets,$qualif){
}
unset($qualif['objet']);
unset($qualif['id_objet']);
foreach($objets as $objet => $id_objets){
foreach($objets as $objet => $id_objets) {
// role, colonne, where par défaut
list($role, $colonne_role, $cond) =
roles_trouver_dans_qualif($objet_source, $objet, $qualif);
$objet = ($objet=='*')?$objet:objet_type($objet); # securite
if (!is_array($id_objets) OR reset($id_objets)=="NOT") $id_objets = array($id_objets);
foreach($id_objets as $id_objet) {
$where = lien_where($primary, $id, $objet, $id_objet);
$args = array(
'table_lien' => $table_lien,
'objet_source' => $objet_source,
'id_objet_source' => $id,
'objet' => $objet,
'id_objet' => $id_objet,
'role' => $role,
'colonne_role' => $colonne_role,
'action' => 'modifier',
);
// Envoyer aux plugins
$id_objet = pipeline('pre_edition_lien',
array(
'args' => $args,
'data' => $id_objet,
)
);
/* [TODO] pour la 3.1
// Envoyer aux plugins
$qualif = pipeline('pre_edition_lien',
array(
'args' => $args,
'data' => $qualif,
)
);*/
$where = lien_where($primary, $id, $objet, $id_objet, $cond);
$e = sql_updateq($table_lien,$qualif,$where);
if ($e===false)
if ($e===false) {
$echec = true;
else
$ok++;
} else {
// Envoyer aux plugins
pipeline('post_edition_lien',
array(
'args' => $args,
#'data' => $qualif, # [TODO] POUR la 3.1
'data' => $id_objet
)
);
$ok++;
}
}
}
return ($echec?false:$ok);
@ -601,21 +761,31 @@ function lien_set($objet_source,$primary,$table_lien,$id,$objets,$qualif){
* array($objet=>$id_objets,...)
* un * pour $id,$objet,$id_objets permet de traiter par lot
*
*
* Le tableau de condition peut avoir un index 'role' indiquant de
* chercher un rôle précis, ou * pour tous les roles (alors équivalent
* à l'absence de l'index)
*
* @internal
* @param string $objet_source
* @param string $primary
* @param sgring $table_lien
* @param int $id
* @param array $objets
* @param array|null $cond
* Condition du where par défaut
*
* On peut passer un index 'role' pour sélectionner uniquement
* le role défini dedans (et '*' pour tous les rôles).
* @return array
*/
function lien_find($objet_source,$primary,$table_lien,$id,$objets){
function lien_find($objet_source,$primary,$table_lien,$id,$objets,$cond=null){
$trouve = array();
foreach($objets as $objet => $id_objets){
$objet = ($objet=='*')?$objet:objet_type($objet); # securite
// gerer les roles s'il y en a dans $cond
list($cond) = roles_creer_condition_role($objet_source, $objet, $cond, true);
// lien_where prend en charge les $id_objets sous forme int ou array
$where = lien_where($primary, $id, $objet, $id_objets);
$where = lien_where($primary, $id, $objet, $id_objets, $cond);
$liens = sql_allfetsel('*',$table_lien,$where);
// ajouter les entrees objet_source et objet cible par convenance
foreach($liens as $l) {
@ -634,7 +804,16 @@ function lien_find($objet_source,$primary,$table_lien,$id,$objets){
* @param string $objet
* @param array|int $ids
*/
function lien_propage_date_modif($objet,$ids){
function lien_propage_date_modif($objet,$ids) {
static $done = array();
$hash = md5($objet . serialize($ids));
// sql_updateq, peut être un rien lent.
// On évite de l'appeler 2 fois sur les mêmes choses
if (isset($done[$hash])) {
return;
}
$trouver_table = charger_fonction('trouver_table','base');
$table = table_objet_sql($objet);
@ -644,5 +823,7 @@ function lien_propage_date_modif($objet,$ids){
$where = (is_array($ids)?sql_in($primary, array_map('intval',$ids)):"$primary=".intval($ids));
sql_updateq($table, array('date_modif'=>date('Y-m-d H:i:s')), $where);
}
$done[$hash] = true;
}
?>

144
formulaires/editer_liens.php

@ -92,11 +92,24 @@ function formulaires_editer_liens_charger_dist($a,$b,$c,$editable=true){
if (!$editable AND !count(objet_trouver_liens(array($objet_lien=>'*'),array(($objet_lien==$objet_source?$objet:$objet_source)=>'*'))))
return false;
// squelettes de vue et de d'association
// ils sont différents si des rôles sont définis.
$skel_vue = $table_source."_lies";
$skel_ajout = $table_source."_associer";
// description des roles
include_spip('inc/roles');
if ($roles = roles_presents($objet_source, $objet)) {
// on demande de nouveaux squelettes en conséquence
$skel_vue = $table_source."_roles_lies";
$skel_ajout = $table_source."_roles_associer";
}
$valeurs = array(
'id'=>"$table_source-$objet-$id_objet-$objet_lien", // identifiant unique pour les id du form
'_vue_liee' => $table_source."_lies",
'_vue_ajout' => $table_source."_associer",
'_vue_liee' => $skel_vue,
'_vue_ajout' => $skel_ajout,
'_objet_lien' => $objet_lien,
'id_lien_ajoute'=>_request('id_lien_ajoute'),
'objet'=>$objet,
@ -104,6 +117,7 @@ function formulaires_editer_liens_charger_dist($a,$b,$c,$editable=true){
'objet_source'=>$objet_source,
'table_source' => $table_source,
'recherche'=>'',
'roles' => $roles, # description des roles
'visible'=>0,
'ajouter_lien'=>'',
'supprimer_lien'=>'',
@ -117,20 +131,25 @@ function formulaires_editer_liens_charger_dist($a,$b,$c,$editable=true){
/**
* Traiter le post des informations d'édition de liens
*
* Les formulaires postent dans trois variables ajouter_lien et supprimer_lien
* et remplacer_lien
* Les formulaires peuvent poster dans quatre variables
* - ajouter_lien et supprimer_lien
* - remplacer_lien
* - definir_roles
*
* Les deux premieres peuvent etre de trois formes differentes :
* Les deux premières peuvent être de trois formes différentes :
* ajouter_lien[]="objet1-id1-objet2-id2"
* ajouter_lien[objet1-id1-objet2-id2]="nimportequoi"
* ajouter_lien['clenonnumerique']="objet1-id1-objet2-id2"
* Dans ce dernier cas, la valeur ne sera prise en compte
* que si _request('clenonnumerique') est vrai (submit associe a l'input)
* que si _request('clenonnumerique') est vrai (submit associé a l'input)
*
* remplacer_lien doit etre de la forme
* remplacer_lien doit être de la forme
* remplacer_lien[objet1-id1-objet2-id2]="objet3-id3-objet2-id2"
* ou objet1-id1 est celui qu'on enleve et objet3-id3 celui qu'on ajoute
*
* definir_roles doit être de la forme, et sert en complément de ajouter_lien
* definir_roles[objet1-id1-objet2-id2] = array("role", "autre_role")
*
* @param string $a
* @param string|int $b
* @param int|string $c
@ -185,18 +204,19 @@ function formulaires_editer_liens_traiter_dist($a,$b,$c,$editable=true){
if ($supprimer){
include_spip('action/editer_liens');
$oups = array();
foreach($supprimer as $k=>$v) {
if ($lien = lien_verifier_action($k,$v)){
$lien = explode("-",$lien);
list($objet_source,$ids,$objet_lie,$idl) = $lien;
$lien = explode("-", $lien);
list($objet_source,$ids,$objet_lie,$idl,$role) = $lien;
// appliquer une condition sur le rôle si défini ('*' pour tous les roles)
$cond = $role ? array('role' => $role) : array();
if ($objet_lien==$objet_source){
$oups = array_merge($oups, objet_trouver_liens(array($objet_source=>$ids), array($objet_lie=>$idl)));
objet_dissocier(array($objet_source=>$ids), array($objet_lie=>$idl));
$oups = array_merge($oups, objet_trouver_liens(array($objet_source=>$ids), array($objet_lie=>$idl), $cond));
objet_dissocier(array($objet_source=>$ids), array($objet_lie=>$idl), $cond);
}
else{
$oups = array_merge($oups, objet_trouver_liens(array($objet_lie=>$idl), array($objet_source=>$ids)));
objet_dissocier(array($objet_lie=>$idl), array($objet_source=>$ids));
$oups = array_merge($oups, objet_trouver_liens(array($objet_lie=>$idl), array($objet_source=>$ids), $cond));
objet_dissocier(array($objet_lie=>$idl), array($objet_source=>$ids), $cond);
}
}
}
@ -207,13 +227,15 @@ function formulaires_editer_liens_traiter_dist($a,$b,$c,$editable=true){
$ajout_ok = false;
include_spip('action/editer_liens');
foreach($ajouter as $k=>$v){
if ($lien = lien_verifier_action($k,$v)){
if ($lien = lien_verifier_action($k,$v)) {
$ajout_ok = true;
list($objet1,$ids,$objet2,$idl) = explode("-",$lien);
if ($objet_lien==$objet1)
objet_associer(array($objet1=>$ids), array($objet2=>$idl));
else
objet_associer(array($objet2=>$idl), array($objet1=>$ids));
$roles = lien_retrouver_roles_postes($lien);
if ($objet_lien==$objet1) {
lien_ajouter_liaison($objet1, $ids, $objet2, $idl, $roles);
} else {
lien_ajouter_liaison($objet2, $idl, $objet1, $ids, $roles);
}
set_request('id_lien_ajoute',$ids);
}
}
@ -229,7 +251,6 @@ function formulaires_editer_liens_traiter_dist($a,$b,$c,$editable=true){
return $res;
}
/**
* Retrouver l'action de liaision demandée
*
@ -237,24 +258,91 @@ function formulaires_editer_liens_traiter_dist($a,$b,$c,$editable=true){
* ou supprimer_lien
*
* L'action est de la forme : objet1-id1-objet2-id2
* ou de la forme : objet1-id1-objet2-id2-role
*
* L'action peut-être indiquée dans la clé ou dans la valeur.
* Si elle est indiquee dans la valeur et que la clé est non numérique,
* on ne la prend en compte que si un submit avec la clé a été envoyé
*
* @internal
* @param string $k Clé du tableau
* @param string $v Valeur du tableau
* @return string Action demandée si trouvée, sinon ''
*/
function lien_verifier_action($k,$v){
if (preg_match(",^\w+-[\w*]+-[\w*]+-[\w*]+,",$k))
return $k;
if (preg_match(",^\w+-[\w*]+-[\w*]+-[\w*]+,",$v)){
function lien_verifier_action($k,$v) {
$action = '';
if (preg_match(",^\w+-[\w*]+-[\w*]+-[\w*]+(-[\w*])?,",$k))
$action = $k;
if (preg_match(",^\w+-[\w*]+-[\w*]+-[\w*]+(-[\w*])?,",$v)){
if (is_numeric($k))
return $v;
$action = $v;
if (_request($k))
return $v;
$action = $v;
}
// ajout un role null fictif (plus pratique) si pas défini
if ($action and count(explode("-", $action)) == 4) {
$action .= '-';
}
return '';
return $action;
}
/**
* Retrouve le ou les roles postés avec une liaison demandée
*
* @internal
* @param string $lien Action du lien
* @return array Liste des rôles. Tableau vide s'il n'y en a pas.
**/
function lien_retrouver_roles_postes($lien) {
// un role est défini dans la liaison
$defs = explode('-', $lien);
list(,,,,$role) = $defs;
if ($role) return array($role);
// retrouver les rôles postés pour cette liaison, s'il y en a.
$roles = _request('definir_roles');
if (!$roles OR !is_array($roles)) {
return array();
}
// pas avec l'action complete (incluant le role)
if (!isset($roles[$lien]) OR !$roles = $roles[$lien]) {
// on tente avec l'action sans le role
array_pop($defs);
$lien = implode('-', $defs);
if (!isset($roles[$lien]) OR !$roles = $roles[$lien]) {
$roles = array();
}
}
// pas de rôle vide
return array_filter($roles);
}
/**
* Ajoute les liens demandés en prenant éventuellement en compte le rôle
*
* Appelle la fonction objet_associer. L'appelle autant de fois qu'il y
* a de rôles demandés pour cette liaison.
*
* @internal
* @param string $objet_source Objet source de la liaison (qui a la table de liaison)
* @param array|string $ids Identifiants pour l'objet source
* @param string $objet_lien Objet à lier
* @param array|string $idl Identifiants pour l'objet lié
* @return void
**/
function lien_ajouter_liaison($objet_source, $ids, $objet_lien, $idl, $roles) {
// retrouver la colonne de roles s'il y en a a lier
if ($roles and $colonne_role = roles_colonne($objet_source, $objet_lien)) {
foreach ($roles as $role) {
objet_associer(array($objet_source=>$ids), array($objet_lien=>$idl), array($colonne_role => $role));
}
} else {
objet_associer(array($objet_source=>$ids), array($objet_lien=>$idl));
}
}
?>

Loading…
Cancel
Save