OwlCyberSecurity - MANAGER
Edit File: editer_liens.php.tar
home/bourgleram/www/ecrire/action/editer_liens.php 0000705 00000050070 15252540246 0016371 0 ustar 00 <?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ /** * API d'édition de liens * * @package SPIP\Liens\API */ if (!defined('_ECRIRE_INC_VERSION')) return; /** * Teste l'existence de la table de liaison xxx_liens d'un objet * * @api * @param string $objet * Objet à tester * @return array|bool * - false si l'objet n'est pas associable. * - array(clé primaire, nom de la table de lien) si associable */ function objet_associable($objet){ $trouver_table = charger_fonction('trouver_table','base'); $table_sql = table_objet_sql($objet); $l=""; if ($primary = id_table_objet($objet) AND $trouver_table($l = $table_sql."_liens") AND !preg_match(',[^\w],',$primary) AND !preg_match(',[^\w],',$l)) return array($primary,$l); spip_log("Objet $objet non associable : ne dispose pas d'une cle primaire $primary OU d'une table liens $l"); return false; } /** * Associer un ou des objets à 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 * ou de la forme array("NOT",$id_objets) pour une selection par exclusion * * Les objets sources sont les pivots qui portent les liens * 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 * * @api * @param array $objets_source * @param array|string $objets_lies * @param array $qualif * @return bool|int */ function objet_associer($objets_source, $objets_lies, $qualif = null){ $modifs = objet_traiter_liaisons('lien_insert', $objets_source, $objets_lies); if ($qualif) objet_qualifier_liens($objets_source, $objets_lies, $qualif); return $modifs; // pas d'erreur } /** * Dissocier un (ou des) objet(s) des objets listés * * $objets_source et $objets 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 * * Les objets sources sont les pivots qui portent les liens * et pour lesquels une table spip_xxx_liens existe * (auteurs, documents, mots) * * 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 * * @api * @param array $objets_source * @param array|string $objets_lies * @return bool|int */ function objet_dissocier($objets_source,$objets_lies){ return objet_traiter_liaisons('lien_delete',$objets_source,$objets_lies); } /** * Qualifier le lien entre un (ou des) objet(s) et des objets listés * * $objets_source et $objets 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 * * Les objets sources sont les pivots qui portent les liens * et pour lesquels une table spip_xxx_liens existe * (auteurs, documents, mots) * * 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 * * @api * @param array $objets_source * @param array|string $objets_lies * @param array $qualif * @return bool|int */ function objet_qualifier_liens($objets_source,$objets_lies,$qualif){ return objet_traiter_liaisons('lien_set',$objets_source,$objets_lies,$qualif); } /** * Trouver les liens entre objets * * $objets_source et $objets 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 * * Les objets sources sont les pivots qui portent les liens * et pour lesquels une table spip_xxx_liens existe * (auteurs, documents, mots) * * 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 * * renvoie une liste de tableaux decrivant chaque lien * dans lequel objet_source et objet_lie sont aussi affectes avec l'id de chaque * par facilite * ex : * array( * array('id_document'=>23,'objet'=>'article','id_objet'=>12,'vu'=>'oui', * 'document'=>23,'article'=>12) * ) * * @api * @param array $objets_source * @param array|string $objets_lies * @return array */ function objet_trouver_liens($objets_source,$objets_lies){ return objet_traiter_liaisons('lien_find',$objets_source,$objets_lies); } /** * Nettoyer les liens morts vers des objets qui n'existent plus * * $objets_source et $objets 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 * * Les objets sources sont les pivots qui portent les liens * et pour lesquels une table spip_xxx_liens existe * (auteurs, documents, mots) * * 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 * * @api * @param array $objets_source * @param array|string $objets_lies * @return int */ function objet_optimiser_liens($objets_source,$objets_lies){ return objet_traiter_liaisons('lien_optimise',$objets_source,$objets_lies); } /** * Dupliquer tous les liens entrant ou sortants d'un objet * vers un autre (meme type d'objet, mais id different) * si $types est fourni, seuls les liens depuis/vers les types listes seront copies * si $exclure_types est fourni, les liens depuis/vers les types listes seront ignores * * @api * @param string $objet * @param int $id_source * @param int $id_cible * @param array $types * @param array $exclure_types * @return int * Nombre de liens copiés */ function objet_dupliquer_liens($objet,$id_source,$id_cible,$types=null,$exclure_types=null){ include_spip('base/objets'); $tables = lister_tables_objets_sql(); $n = 0; foreach($tables as $table_sql => $infos){ if ( (is_null($types) OR in_array($infos['type'],$types)) AND (is_null($exclure_types) OR !in_array($infos['type'],$exclure_types)) ){ if (objet_associable($infos['type'])){ $liens = (($infos['type']==$objet)? objet_trouver_liens(array($objet=>$id_source),'*') : objet_trouver_liens(array($infos['type']=>'*'),array($objet=>$id_source))); foreach($liens as $lien){ $n++; if ($infos['type']==$objet){ objet_associer(array($objet=>$id_cible),array($lien['objet']=>$lien[$lien['objet']]),$lien); } else { objet_associer(array($infos['type']=>$lien[$infos['type']]),array($objet=>$id_cible),$lien); } } } } } return $n; } /** * Fonctions techniques * ne pas les appeler directement */ /** * 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 * * Les objets sources sont les pivots qui portent les liens * 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 * * @internal * @param string $operation * @param array $objets_source * @param array $objets_lies * @param array $set * @return bool|int|array */ function objet_traiter_liaisons($operation,$objets_source,$objets_lies, $set = null){ // accepter une syntaxe minimale pour supprimer tous les liens if ($objets_lies=='*') $objets_lies = array('*'=>'*'); $modifs = 0; // compter le nombre de modifications $echec = null; foreach($objets_source as $objet=>$ids){ if ($a = objet_associable($objet)) { list($primary,$l) = $a; if (!is_array($ids)) $ids = array($ids); elseif(reset($ids)=="NOT"){ // si on demande un array('NOT',...) => recuperer la liste d'ids correspondants $where = lien_where($primary,$ids,'*','*'); $ids = sql_allfetsel($primary,$l,$where); $ids = array_map('reset',$ids); } foreach($ids as $id) { $res = $operation($objet,$primary,$l,$id,$objets_lies,$set); if ($res===false) { spip_log("objet_traiter_liaisons [Echec] : $operation sur $objet/$primary/$l/$id",_LOG_ERREUR); $echec = true; } else $modifs=($modifs?(is_array($res)?array_merge($modifs,$res):$modifs+$res):$res); } } else $echec = true; } return ($echec?false:$modifs); // pas d'erreur } /** * Sous fonction insertion * qui traite les liens pour un objet source dont la clé primaire * et la table de lien sont fournies * * $objets et de la forme * array($objet=>$id_objets,...) * * Retourne le nombre d'insertions realisees * * @internal * @param string $objet_source * @param string $primary * @param sgring $table_lien * @param int $id * @param array $objets * @return bool|int */ function lien_insert($objet_source,$primary,$table_lien,$id,$objets) { $ins = 0; $echec = null; foreach($objets as $objet => $id_objets){ if (!is_array($id_objets)) $id_objets = array($id_objets); foreach($id_objets as $id_objet) { $objet = ($objet=='*')?$objet:objet_type($objet); # securite // 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', ), '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)); if ($e!==false) { $ins++; lien_propage_date_modif($objet,$id_objet); lien_propage_date_modif($objet_source,$id); // 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', ), 'data' => $id_objet ) ); } else $echec = true; } } } return ($echec?false:$ins); } /** * 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 */ function lien_where($primary, $id_source, $objet, $id_objet){ if ((!is_array($id_source) AND !strlen($id_source)) OR !strlen($objet) OR (!is_array($id_objet) AND !strlen($id_objet))) return array("0=1"); // securite $not=""; if (is_array($id_source) AND reset($id_source)=="NOT"){ $not = array_shift($id_source); $id_source = reset($id_source); } $where = array(); 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) $where[] = "0=1"; // idiot mais quand meme $not=""; if (is_array($id_objet) AND reset($id_objet)=="NOT"){ $not = array_shift($id_objet); $id_objet = reset($id_objet); } if ($objet!=='*') $where[] = "objet=".sql_quote($objet); if ($id_objet!=='*') $where[] = (is_array($id_objet)?sql_in('id_objet',array_map('intval',$id_objet),$not):"id_objet" . ($not?"<>":"=") . intval($id_objet)); elseif ($not) $where[] = "0=1"; // idiot mais quand meme return $where; } /** * Sous fonction suppression * qui traite les liens pour un objet source dont la clé primaire * et la table de lien sont fournies * * $objets et de la forme * array($objet=>$id_objets,...) * un * pour $id,$objet,$id_objets permet de traiter par lot * * @internal * @param string $objet_source * @param string $primary * @param sgring $table_lien * @param int $id * @param array $objets * @return bool|int */ function lien_delete($objet_source,$primary,$table_lien,$id,$objets){ $retire = array(); $dels = 0; $echec = false; 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) { // id_objet peut valoir '*' $where = lien_where($primary, $id, $objet, $id_objet); // lire les liens existants pour propager la date de modif $liens = sql_allfetsel("$primary,id_objet,objet",$table_lien,$where); // iterer sur les liens pour permettre aux plugins de gerer foreach($liens as $l){ // 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', ), 'data' => $l['id_objet'] ) ); if ($id_o=intval($id_o)){ $where = lien_where($primary, $l[$primary], $l['objet'], $id_o); $e = sql_delete($table_lien, $where); if ($e!==false){ $dels+=$e; lien_propage_date_modif($l['objet'],$id_o); lien_propage_date_modif($objet_source,$l[$primary]); } else $echec = true; $retire[] = array('source'=>array($objet_source=>$l[$primary]),'lien'=>array($l['objet']=>$id_o),'type'=>$l['objet'],'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', ), 'data' => $id_o ) ); } } } } pipeline('trig_supprimer_objets_lies',$retire); return ($echec?false:$dels); } /** * Sous fonction optimisation * qui nettoie les liens morts (vers un objet inexistant) * pour un objet source dont la clé primaire * et la table de lien sont fournies * * $objets et de la forme * array($objet=>$id_objets,...) * un * pour $id,$objet,$id_objets permet de traiter par lot * * @internal * @param string $objet_source * @param string $primary * @param sgring $table_lien * @param int $id * @param array $objets * @return bool|int */ function lien_optimise($objet_source,$primary,$table_lien,$id,$objets){ include_spip('genie/optimiser'); $echec = false; $dels = 0; 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) { $where = lien_where($primary, $id, $objet, $id_objet); # les liens vers un objet inexistant $r = sql_select("DISTINCT objet",$table_lien,$where); while ($t = sql_fetch($r)){ $type = $t['objet']; $spip_table_objet = table_objet_sql($type); $id_table_objet = id_table_objet($type); $res = sql_select("L.$primary AS id,L.id_objet", // la condition de jointure inclue L.objet='xxx' pour ne joindre que les bonnes lignes // du coups toutes les lignes avec un autre objet ont un id_xxx=NULL puisque LEFT JOIN // il faut les eliminier en repetant la condition dans le where L.objet='xxx' "$table_lien AS L LEFT JOIN $spip_table_objet AS O ON (O.$id_table_objet=L.id_objet AND L.objet=".sql_quote($type).")", "L.objet=".sql_quote($type)." AND O.$id_table_objet IS NULL"); // sur une cle primaire composee, pas d'autres solutions que de virer un a un while ($row = sql_fetch($res)){ $e = sql_delete($table_lien, array("$primary=".$row['id'],"id_objet=".$row['id_objet'],"objet=".sql_quote($type))); if ($e!=false){ $dels+=$e; spip_log("Entree ".$row['id']."/".$row['id_objet']."/$type supprimee dans la table $table_lien",_LOG_INFO_IMPORTANTE); } } } # les liens depuis un objet inexistant $table_source = table_objet_sql($objet_source); // filtrer selon $id, $objet, $id_objet eventuellement fournis // (en general '*' pour chaque) $where = lien_where("L.$primary", $id, $objet, $id_objet); $where[] = "O.$primary IS NULL"; $res = sql_select("L.$primary AS id", "$table_lien AS L LEFT JOIN $table_source AS O ON L.$primary=O.$primary", $where); $dels+= optimiser_sansref($table_lien, $primary, $res); } } return ($echec?false:$dels); } /** * Sous fonction qualification * qui traite les liens pour un objet source dont la clé primaire * et la table de lien sont fournies * * $objets et de la forme * array($objet=>$id_objets,...) * un * pour $id,$objet,$id_objets permet de traiter par lot * * exemple : * $qualif = array('vu'=>'oui'); * * @internal * @param string $objet_source * @param string $primary * @param sgring $table_lien * @param int $id * @param array $objets * @param array $qualif * @return bool|int */ function lien_set($objet_source,$primary,$table_lien,$id,$objets,$qualif){ $echec = null; $ok = 0; if (!$qualif) return false; // nettoyer qualif qui peut venir directement d'un objet_trouver_lien : unset($qualif[$primary]); unset($qualif[$objet_source]); if (isset($qualif['objet'])) { unset($qualif[$qualif['objet']]); } unset($qualif['objet']); unset($qualif['id_objet']); 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) { $where = lien_where($primary, $id, $objet, $id_objet); $e = sql_updateq($table_lien,$qualif,$where); if ($e===false) $echec = true; else $ok++; } } return ($echec?false:$ok); } /** * Sous fonction trouver * qui cherche les liens pour un objet source dont la clé primaire * et la table de lien sont fournies * * $objets et de la forme * array($objet=>$id_objets,...) * un * pour $id,$objet,$id_objets permet de traiter par lot * * * @internal * @param string $objet_source * @param string $primary * @param sgring $table_lien * @param int $id * @param array $objets * @return array */ function lien_find($objet_source,$primary,$table_lien,$id,$objets){ $trouve = array(); foreach($objets as $objet => $id_objets){ $objet = ($objet=='*')?$objet:objet_type($objet); # securite // lien_where prend en charge les $id_objets sous forme int ou array $where = lien_where($primary, $id, $objet, $id_objets); $liens = sql_allfetsel('*',$table_lien,$where); // ajouter les entrees objet_source et objet cible par convenance foreach($liens as $l) { $l[$objet_source] = $l[$primary]; $l[$objet] = $l['id_objet']; $trouve[] = $l; } } return $trouve; } /** * Propager la date_modif sur les objets dont un lien a été modifié * * @internal * @param string $objet * @param array|int $ids */ function lien_propage_date_modif($objet,$ids){ $trouver_table = charger_fonction('trouver_table','base'); $table = table_objet_sql($objet); if ($desc = $trouver_table($table) AND isset($desc['field']['date_modif'])){ $primary = id_table_objet($objet); $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); } } ?> home/bourgleram/www/prive/formulaires/editer_liens.php 0000705 00000022166 15252770342 0017327 0 ustar 00 <?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2016 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ /** * Gestion du formulaire d'édition de liens * * @package SPIP\Formulaires **/ if (!defined('_ECRIRE_INC_VERSION')) return; /** * Retrouve la source et l'objet de la liaison * * À partir des 3 premiers paramètres transmis au formulaire, * la fonction retrouve : * - l'objet dont on utilise sa table de liaison (table_source) * - l'objet et id_objet sur qui on lie des éléments (objet, id_objet) * - l'objet que l'on veut lier dessus (objet_lien) * * @param string $a * @param string|int $b * @param int|string $c * @return array * ($table_source,$objet,$id_objet,$objet_lien) */ function determine_source_lien_objet($a,$b,$c){ $table_source = $objet_lien = $objet = $id_objet = null; // auteurs, article, 23 : // associer des auteurs à l'article 23, sur la table pivot spip_auteurs_liens if (is_numeric($c) AND !is_numeric($b)){ $table_source = table_objet($a); $objet_lien = objet_type($a); $objet = objet_type($b); $id_objet = $c; } // article, 23, auteurs // associer des auteurs à l'article 23, sur la table pivot spip_articles_liens if (is_numeric($b) AND !is_numeric($c)){ $table_source = table_objet($c); $objet_lien = objet_type($a); $objet = objet_type($a); $id_objet = $b; } return array($table_source,$objet,$id_objet,$objet_lien); } /** * Chargement du formulaire d'édition de liens * * #FORMULAIRE_EDITER_LIENS{auteurs,article,23} * pour associer des auteurs à l'article 23, sur la table pivot spip_auteurs_liens * #FORMULAIRE_EDITER_LIENS{article,23,auteurs} * pour associer des auteurs à l'article 23, sur la table pivot spip_articles_liens * #FORMULAIRE_EDITER_LIENS{articles,auteur,12} * pour associer des articles à l'auteur 12, sur la table pivot spip_articles_liens * #FORMULAIRE_EDITER_LIENS{auteur,12,articles} * pour associer des articles à l'auteur 12, sur la table pivot spip_auteurs_liens * * @param string $a * @param string|int $b * @param int|string $c * @param bool $editable * @return array */ function formulaires_editer_liens_charger_dist($a,$b,$c,$editable=true){ list($table_source,$objet,$id_objet,$objet_lien) = determine_source_lien_objet($a,$b,$c); if (!$table_source OR !$objet OR !$objet_lien OR !$id_objet) return false; $objet_source = objet_type($table_source); $table_sql_source = table_objet_sql($objet_source); // verifier existence de la table xxx_liens include_spip('action/editer_liens'); if (!objet_associable($objet_lien)) return false; // L'éditabilité :) est définie par un test permanent (par exemple "associermots") ET le 4ème argument include_spip('inc/autoriser'); $editable = ($editable and autoriser('associer'.$table_source, $objet, $id_objet) and autoriser('modifier',$objet,$id_objet)); if (!$editable AND !count(objet_trouver_liens(array($objet_lien=>'*'),array(($objet_lien==$objet_source?$objet:$objet_source)=>'*')))) return false; $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", '_objet_lien' => $objet_lien, 'id_lien_ajoute'=>_request('id_lien_ajoute'), 'objet'=>$objet, 'id_objet'=>$id_objet, 'objet_source'=>$objet_source, 'table_source' => $table_source, 'recherche'=>'', 'visible'=>0, 'ajouter_lien'=>'', 'supprimer_lien'=>'', '_oups' => _request('_oups'), 'editable' => $editable, ); return $valeurs; } /** * Traiter le post des informations d'édition de liens * * Les formulaires postent dans trois variables ajouter_lien et supprimer_lien * et remplacer_lien * * Les deux premieres peuvent etre de trois formes differentes : * 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) * * remplacer_lien doit etre 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 * * @param string $a * @param string|int $b * @param int|string $c * @param bool $editable * @return array */ function formulaires_editer_liens_traiter_dist($a,$b,$c,$editable=true){ $res = array('editable'=>$editable?true:false); list($table_source,$objet,$id_objet,$objet_lien) = determine_source_lien_objet($a,$b,$c); if (!$table_source OR !$objet OR !$objet_lien) return $res; if (_request('tout_voir')) set_request('recherche',''); include_spip('inc/autoriser'); if (autoriser('modifier',$objet,$id_objet)) { // annuler les suppressions du coup d'avant ! if (_request('annuler_oups') AND $oups = _request('_oups') AND $oups = unserialize($oups)){ if ($oups_objets = charger_fonction("editer_liens_oups_{$table_source}_{$objet}_{$objet_lien}","action",true)){ $oups_objets($oups); } else { $objet_source = objet_type($table_source); include_spip('action/editer_liens'); foreach($oups as $oup) { if ($objet_lien==$objet_source) objet_associer(array($objet_source=>$oup[$objet_source]), array($objet=>$oup[$objet]),$oup); else objet_associer(array($objet=>$oup[$objet]), array($objet_source=>$oup[$objet_source]),$oup); } } # oups ne persiste que pour la derniere action, si suppression set_request('_oups'); } $supprimer = _request('supprimer_lien'); $ajouter = _request('ajouter_lien'); // il est possible de preciser dans une seule variable un remplacement : // remplacer_lien[old][new] if ($remplacer = _request('remplacer_lien')){ foreach($remplacer as $k=>$v){ if ($old = lien_verifier_action($k,'')){ foreach(is_array($v)?$v:array($v) as $kn=>$vn) if ($new = lien_verifier_action($kn,$vn)){ $supprimer[$old] = 'x'; $ajouter[$new] = '+'; } } } } if ($supprimer){ if ($supprimer_objets = charger_fonction("editer_liens_supprimer_{$table_source}_{$objet}_{$objet_lien}","action",true)){ $oups = $supprimer_objets($supprimer); } else { 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; 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)); } 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)); } } } } set_request('_oups',$oups?serialize($oups):null); } if ($ajouter){ if ($ajouter_objets = charger_fonction("editer_liens_ajouter_{$table_source}_{$objet}_{$objet_lien}","action",true)){ $ajout_ok = $ajouter_objets($ajouter); } else { $ajout_ok = false; include_spip('action/editer_liens'); foreach($ajouter as $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)); set_request('id_lien_ajoute',$ids); } } } # oups ne persiste que pour la derniere action, si suppression # une suppression suivie d'un ajout dans le meme hit est un remplacement # non annulable ! if ($ajout_ok) set_request('_oups'); } } return $res; } /** * Retrouver l'action de liaision demandée * * Les formulaires envoient une action dans un tableau ajouter_lien * ou supprimer_lien * * L'action est de la forme : objet1-id1-objet2-id2 * * 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é * * @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)){ if (is_numeric($k)) return $v; if (_request($k)) return $v; } return ''; } ?>