source: spip-zone/_core_/plugins/revisions/inc/suivi_versions.php @ 45623

Last change on this file since 45623 was 45623, checked in by cedric@…, 9 years ago

support des revisions sur les jointure : il suffit de definir 'jointure_{table}' comme champ a versionner (avec table = version abregee 'mots', 'auteurs'...)
Il faut que les liens soient gérés par l'api editer_lien pour que les pipelines pre_edition_lien et post_edition_lien soient appelés er declenchent la gestion de revision.
Pour l'affichage des diff, une fonction afficher_diff_jointure generique est utilisee pour les jointures, mais il est possible de definir sa propre fonction d'affichage afficher_diff_jointure_xxx comme pour les champs standards.

File size: 5.0 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2011                                                *
7 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8 *                                                                         *
9 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11\***************************************************************************/
12
13if (!defined("_ECRIRE_INC_VERSION")) return;
14
15include_spip('inc/revisions');
16include_spip('inc/diff');
17
18/**
19 * Afficher un diff correspondant a une revision d'un objet
20 *
21 * @param int $id_objet
22 * @param string $objet
23 * @param int $id_version
24 * @param bool $court
25 * @return string
26 */
27function revisions_diff ($id_objet,$objet, $id_version, $court=false){
28        $textes = revision_comparee($id_objet,$objet, $id_version, 'diff');
29        if (!is_array($textes)) return $textes;
30        $rev = '';
31        $nb = 0;
32        foreach ($textes as $var => $t) {
33                if ($n=strlen($t)) {
34                        if ($court)
35                                $nb += $n;
36                        else {
37                                $aff = propre_diff($t);
38                                if ($GLOBALS['les_notes']) {
39                                        $aff .= '<p>'.$GLOBALS['les_notes'].'</p>';
40                                        $GLOBALS['les_notes'] = '';
41                                }
42                                $rev .= "<blockquote>$aff</blockquote>";
43                        }
44                }
45        }
46        return $court ? _T('taille_octets', array('taille' => $nb)) : $rev;
47}
48
49/**
50 * Retrouver le champ d'un objet, pour une version demandee
51 * @param string $objet
52 * @param int $id_objet
53 * @param int $id_version
54 * @param string $champ
55 * @param array $champs
56 */
57function retrouver_champ_version_objet($objet,$id_objet,$id_version,$champ,&$champs){
58        if (isset($champs[$champ]))
59                return;
60
61        // Remonter dans le temps pour trouver le champ en question
62        // pour la version demandee
63        $id_ref = $id_version-1;
64        $prev = array();
65        while (!isset($prev[$champ]) AND $id_ref>0) {
66                $prev = recuperer_version($id_objet,$objet, $id_ref--);
67        }
68        if (isset($prev[$champ]))
69                $champs[$champ] = $prev[$champ];
70        else {
71                // le champ n'a jamais ete versionne :
72                // il etait initialement vide
73                if (strncmp($champ,'jointure_',9)==0)
74                        $champs[$champ] = '';
75                else
76                        $champs[$champ] = '';
77        }
78}
79
80/**
81 * retourne un array() des champs modifies a la version id_version
82 * le format =
83 *    - diff => seulement les modifs (page revisions)
84 *    - apercu => idem, mais en plus tres cout s'il y en a bcp
85 *    - complet => tout, avec surlignage des modifications (page revision)
86 *
87 * http://doc.spip.org/@revision_comparee
88 *
89 * @param int $id_objet
90 * @param string $objet
91 * @param int $id_version
92 * @param string $format
93 * @param null $id_diff
94 * @return array
95 */
96function revision_comparee($id_objet, $objet, $id_version, $format='diff', $id_diff=NULL) {
97        include_spip('inc/diff');
98
99        // chercher le numero de la version precedente
100        if (!$id_diff) {
101                $id_diff = sql_getfetsel("id_version", "spip_versions", "id_objet=" . intval($id_objet) . " AND id_version < " . intval($id_version)." AND objet=".sql_quote($objet), "", "id_version DESC", "1");
102        }
103
104        if ($id_version && $id_diff) {
105
106                // si l'ordre est inverse, on remet a l'endroit
107                if ($id_diff > $id_version) {
108                        $t = $id_version;
109                        $id_version = $id_diff;
110                        $id_diff = $t;
111                }
112
113                $old = recuperer_version($id_objet,$objet, $id_diff);
114                $new = recuperer_version($id_objet,$objet, $id_version);
115
116                $textes = array();
117
118                // Mode "diff": on ne s'interesse qu'aux champs presents dans $new
119                // Mode "complet": on veut afficher tous les champs
120                switch ($format) {
121                        case 'complet':
122                                $champs = liste_champs_versionnes(table_objet_sql($objet));
123                                break;
124                        case 'diff':
125                        case 'apercu':
126                        default:
127                                $champs = array_keys($new);
128                                break;
129                }
130
131                foreach ($champs as $champ) {
132                        // Remonter dans le temps pour trouver le champ en question
133                        // pour chaque version
134                        retrouver_champ_version_objet($objet,$id_objet,$id_version,$champ,$new);
135                        retrouver_champ_version_objet($objet,$id_objet,$id_diff,$champ,$old);
136
137                        if (!strlen($new[$champ]) && !strlen($old[$champ])) continue;
138
139                        // si on n'a que le vieux, ou que le nouveau, on ne
140                        // l'affiche qu'en mode "complet"
141                        if ($format == 'complet')
142                                $textes[$champ] = strlen($new[$champ])
143                                        ? $new[$champ] : $old[$champ];
144
145                        // si on a les deux, le diff nous interesse, plus ou moins court
146                        if (isset($new[$champ]) AND isset($old[$champ])) {
147                                if (!$afficher_diff = charger_fonction($objet."_".$champ,'afficher_diff',true)
148                                  AND !$afficher_diff = charger_fonction($champ,'afficher_diff',true))
149                                        $afficher_diff = charger_fonction(strncmp($champ,'jointure_',9)==0?'jointure':'champ','afficher_diff');
150
151                                $textes[$champ] = $afficher_diff($champ,$old[$champ],$new[$champ],$format);
152                        }
153                }
154        }
155
156        // que donner par defaut ? (par exemple si id_version=1)
157        if (!$textes)
158                $textes = recuperer_version($id_objet,$objet, $id_version);
159
160        return $textes;
161}
162
163?>
Note: See TracBrowser for help on using the repository browser.