PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/ecrire/inc/modifier.php

https://github.com/denisbz/SPIP
PHP | 253 lines | 144 code | 31 blank | 78 comment | 24 complexity | 814e8b0ab5160c00ea593ea00c349fa3 MD5 | raw file
  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Systeme de publication pour l'internet *
  4. * *
  5. * Copyright (c) 2001-2011 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
  9. * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. if (!defined('_ECRIRE_INC_VERSION')) return;
  12. /**
  13. * Une fonction generique pour la collecte des posts
  14. * dans action/editer_xxx
  15. *
  16. * @param array $white_list
  17. * @param array $black_list
  18. * @param array|null $set
  19. * @param bool $tous Recuperer tous les champs de white_list meme ceux n'ayant pas ete postes
  20. * @return array
  21. */
  22. function collecter_requests($white_list, $black_list, $set=null, $tous=false){
  23. $c = $set;
  24. if (!$c){
  25. $c = array();
  26. foreach($white_list as $champ) {
  27. // on ne collecte que les champs reellement envoyes par defaut.
  28. // le cas d'un envoi de valeur NULL peut du coup poser probleme.
  29. $val = _request($champ);
  30. if ($tous OR $val !== NULL) {
  31. $c[$champ] = $val;
  32. }
  33. }
  34. // on ajoute toujours la lang en saisie possible
  35. // meme si pas prevu au depart pour l'objet concerne
  36. if ($l = _request('changer_lang')){
  37. $c['lang'] = $l;
  38. }
  39. }
  40. foreach($black_list as $champ) {
  41. unset($c[$champ]);
  42. }
  43. return $c;
  44. }
  45. /**
  46. * Une fonction generique pour l'API de modification de contenu
  47. * $options est un array() avec toutes les options
  48. * renvoie false si rien n'a ete modifie, true sinon
  49. *
  50. * Attention, pour eviter des hacks on interdit les champs
  51. * (statut, id_secteur, id_rubrique, id_parent),
  52. * mais la securite doit etre assuree en amont
  53. *
  54. * http://doc.spip.org/@modifier_contenu
  55. *
  56. * @param string $type
  57. * @param int $id
  58. * @param array $options
  59. * @param array $c
  60. * @param string $serveur
  61. * @return bool
  62. */
  63. function modifier_contenu($type, $id, $options, $c=null, $serveur='') {
  64. if (!$id = intval($id)) {
  65. spip_log('Erreur $id non defini', 'warn');
  66. return false;
  67. }
  68. include_spip('inc/filtres');
  69. $table_objet = table_objet($type,$serveur);
  70. $spip_table_objet = table_objet_sql($type,$serveur);
  71. $id_table_objet = id_table_objet($type,$serveur);
  72. $trouver_table = charger_fonction('trouver_table', 'base');
  73. $desc = $trouver_table($spip_table_objet, $serveur);
  74. // Appels incomplets (sans $c)
  75. if (!is_array($c)) {
  76. spip_log('erreur appel modifier_contenu('.$type.'), manque $c');
  77. return false;
  78. }
  79. // Securite : certaines variables ne sont jamais acceptees ici
  80. // car elles ne relevent pas de autoriser(xxx, modifier) ;
  81. // il faut passer par instituer_XX()
  82. // TODO: faut-il passer ces variables interdites
  83. // dans un fichier de description separe ?
  84. unset($c['statut']);
  85. unset($c['id_parent']);
  86. unset($c['id_rubrique']);
  87. unset($c['id_secteur']);
  88. // Gerer les champs non vides
  89. if (is_array($options['nonvide']))
  90. foreach ($options['nonvide'] as $champ => $sinon)
  91. if ($c[$champ] === '')
  92. $c[$champ] = $sinon;
  93. // N'accepter que les champs qui existent
  94. // TODO: ici aussi on peut valider les contenus
  95. // en fonction du type
  96. $champs = array();
  97. foreach($desc['field'] as $champ => $ignore)
  98. if (isset($c[$champ]))
  99. $champs[$champ] = $c[$champ];
  100. // Nettoyer les valeurs
  101. $champs = array_map('corriger_caracteres', $champs);
  102. // Envoyer aux plugins
  103. $champs = pipeline('pre_edition',
  104. array(
  105. 'args' => array(
  106. 'table' => $spip_table_objet, // compatibilite
  107. 'table_objet' => $table_objet,
  108. 'spip_table_objet' => $spip_table_objet,
  109. 'type' =>$type,
  110. 'id_objet' => $id,
  111. 'champs' => $options['champs'],
  112. 'serveur' => $serveur,
  113. 'action' => 'modifier'
  114. ),
  115. 'data' => $champs
  116. )
  117. );
  118. if (!$champs) return false;
  119. // marquer le fait que l'objet est travaille par toto a telle date
  120. if ($GLOBALS['meta']['articles_modif'] != 'non') {
  121. include_spip('inc/drapeau_edition');
  122. signale_edition ($id, $GLOBALS['visiteur_session'], $type);
  123. }
  124. // Verifier si les mises a jour sont pertinentes, datees, en conflit etc
  125. include_spip('inc/editer');
  126. $conflits = controler_md5($champs, $_POST, $type, $id, $serveur);
  127. if ($champs) {
  128. // cas particulier de la langue : passer par instituer_langue_objet
  129. if (isset($champs['lang'])){
  130. if ($changer_lang=$champs['lang']){
  131. $id_rubrique = 0;
  132. if ($desc['field']['id_rubrique']){
  133. $parent = ($type=='rubrique')?'id_parent':'id_rubrique';
  134. $id_rubrique = sql_getfetsel($parent, $spip_table_objet, "$id_table_objet=".intval($id));
  135. }
  136. $instituer_langue_objet = charger_fonction('instituer_langue_objet','action');
  137. $champs['lang'] = $instituer_langue_objet($type,$id, $id_rubrique, $changer_lang);
  138. }
  139. // on laisse 'lang' dans $champs,
  140. // ca permet de passer dans le pipeline post_edition et de journaliser
  141. // et ca ne gene pas qu'on refasse un sql_updateq dessus apres l'avoir
  142. // deja pris en compte
  143. }
  144. // la modif peut avoir lieu
  145. // faut-il ajouter date_modif ?
  146. if ($options['date_modif']
  147. AND !isset($champs[$options['date_modif']]))
  148. $champs[$options['date_modif']] = date('Y-m-d H:i:s');
  149. // allez on commit la modif
  150. sql_updateq($spip_table_objet, $champs, "$id_table_objet=$id", $serveur);
  151. // on verifie si elle est bien passee
  152. $moof = sql_fetsel(array_keys($champs), $spip_table_objet, "$id_table_objet=$id", array(), array(), '', array(), $serveur);
  153. if ($moof != $champs) {
  154. foreach($moof as $k=>$v)
  155. if ($v !== $champs[$k]
  156. // ne pas alerter si le champ est numerique est que les valeurs sont equivalentes
  157. AND (!is_numeric($v) OR intval($v)!=intval($champs[$k]))
  158. ) {
  159. $conflits[$k]['post'] = $champs[$k];
  160. $conflits[$k]['save'] = $v;
  161. }
  162. }
  163. // Invalider les caches
  164. if ($options['invalideur']) {
  165. include_spip('inc/invalideur');
  166. if (is_array($options['invalideur']))
  167. array_map('suivre_invalideur',$options['invalideur']);
  168. else
  169. suivre_invalideur($options['invalideur']);
  170. }
  171. // Notifications, gestion des revisions...
  172. // en standard, appelle |nouvelle_revision ci-dessous
  173. pipeline('post_edition',
  174. array(
  175. 'args' => array(
  176. 'table' => $spip_table_objet,
  177. 'table_objet' => $table_objet,
  178. 'spip_table_objet' => $spip_table_objet,
  179. 'type' =>$type,
  180. 'id_objet' => $id,
  181. 'champs' => $options['champs'],
  182. 'serveur' => $serveur,
  183. 'action' => 'modifier'
  184. ),
  185. 'data' => $champs
  186. )
  187. );
  188. }
  189. // S'il y a un conflit, prevenir l'auteur de faire un copier/coller
  190. if ($conflits) {
  191. $redirect = url_absolue(
  192. parametre_url(rawurldecode(_request('redirect')), $id_table_objet, $id)
  193. );
  194. signaler_conflits_edition($conflits, $redirect);
  195. exit;
  196. }
  197. // journaliser l'affaire
  198. // message a affiner :-)
  199. include_spip('inc/filtres_mini');
  200. $qui = sinon($GLOBALS['visiteur_session']['nom'], $GLOBALS['ip']);
  201. journal(_L($qui.' a &#233;dit&#233; l&#8217;'.$type.' '.$id.' ('.join('+',array_diff(array_keys($champs), array('date_modif'))).')'), array(
  202. 'faire' => 'modifier',
  203. 'quoi' => $type,
  204. 'id' => $id
  205. ));
  206. return true;
  207. }
  208. /**
  209. * Wrapper pour remplacer tous les obsoletes revision_xxx
  210. * @param string $objet
  211. * @param int $id_objet
  212. * @param array $c
  213. * @return mixed|string
  214. */
  215. function revision_objet($objet,$id_objet,$c=null){
  216. $objet = objet_type($objet); // securite
  217. if (include_spip('action/editer_'.$objet) AND function_exists($f=$objet.'_modifier'))
  218. return $f($id_objet,$c);
  219. include_spip('action/editer_objet');
  220. return objet_modifier($objet,$id_objet,$c);
  221. }
  222. ?>