]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/Diff.php
rcs_id no longer makes sense with Subversion global version number
[SourceForge/phpwiki.git] / lib / plugin / Diff.php
1 <?php // -*-php-*-
2 // rcs_id('$Id$');
3 /**
4  * Copyright 1999, 2000, 2001, 2002, 2004 $ThePhpWikiProgrammingTeam
5  *
6  * This file is part of PhpWiki.
7  *
8  * PhpWiki is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * PhpWiki is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with PhpWiki; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 /**
23  * lib/diff.php converted to a plugin by electrawn,
24  * plugin cleaned up by rurban,
25  * code by dairiki
26  *
27  * Would make sense to see arbitrary diff's between any files or revisions.
28  */
29
30 require_once('lib/diff.php');
31
32 class WikiPlugin_Diff
33 extends WikiPlugin {
34
35     function getName () {
36         return _("Diff");
37     }
38
39     function getDescription () {
40         return _("Display differences between revisions");
41     }
42
43     // Establish default values for each of this plugin's arguments.
44     // todo: makes only sense with more args.
45     function getDefaultArguments() {
46         return array('pagename' => '[pagename]',
47                      'versions' => false,
48                      'version'  => false,
49                      'previous' => 'major', // author, minor or major
50                      );
51     }
52
53     function PageInfoRow ($label, $rev, &$request) {
54
55         global $WikiTheme, $WikiNameRegexp;
56
57         $row = HTML::tr(HTML::td(array('align' => 'right'), $label));
58         if ($rev) {
59             $author = $rev->get('author');
60             $dbi = $request->getDbh();
61
62             $iswikipage = (isWikiWord($author) && $dbi->isWikiPage($author));
63             $authorlink = $iswikipage ? WikiLink($author) : $author;
64
65             $linked_version = WikiLink($rev, 'existing', $rev->getVersion());
66             $row->pushContent(HTML::td(fmt("version %s", $linked_version)),
67                               HTML::td($WikiTheme->getLastModifiedMessage($rev,
68                                                                       false)),
69                               HTML::td(fmt("by %s", $authorlink)));
70         } else {
71             $row->pushContent(HTML::td(array('colspan' => '3'), _("None")));
72         }
73         return $row;
74     }
75
76     function run($dbi, $argstr, &$request, $basepage) {
77         extract($this->getArgs($argstr, $request));
78         if (is_array($versions)) {
79             // Version selection from pageinfo.php display:
80             rsort($versions);
81             list ($version, $previous) = $versions;
82         }
83
84         // Check if user is allowed to get the Page.
85         if (!mayAccessPage ('view', $pagename)) {
86                 return $this->error(sprintf(_("Illegal access to page %s: no read access"),
87                                         $pagename));
88         }
89
90         // abort if page doesn't exist
91         $page = $request->getPage($pagename);
92         $current = $page->getCurrentRevision();
93         if ($current->getVersion() < 1) {
94             $html = HTML(HTML::p(fmt("I'm sorry, there is no such page as %s.",
95                                      WikiLink($pagename, 'unknown'))));
96             return $html; //early return
97         }
98
99         if ($version) {
100             if (!($new = $page->getRevision($version)))
101                 NoSuchRevision($request, $page, $version);
102             $new_version = fmt("version %d", $version);
103         }
104         else {
105             $new = $current;
106             $new_version = _("current version");
107         }
108
109         if (preg_match('/^\d+$/', $previous)) {
110             if ( !($old = $page->getRevision($previous)) )
111                 NoSuchRevision($request, $page, $previous);
112             $old_version = fmt("version %d", $previous);
113             $others = array('major', 'minor', 'author');
114         }
115         else {
116             switch ($previous) {
117             case 'author':
118                 $old = $new;
119                 while ($old = $page->getRevisionBefore($old)) {
120                     if ($old->get('author') != $new->get('author'))
121                         break;
122                 }
123                 $old_version = _("revision by previous author");
124                 $others = array('major', 'minor');
125                 break;
126             case 'minor':
127                 $previous='minor';
128                 $old = $page->getRevisionBefore($new);
129                 $old_version = _("previous revision");
130                 $others = array('major', 'author');
131                 break;
132             case 'major':
133             default:
134                 $old = $new;
135                 while ($old && $old->get('is_minor_edit'))
136                     $old = $page->getRevisionBefore($old);
137                 if ($old)
138                     $old = $page->getRevisionBefore($old);
139                 $old_version = _("predecessor to the previous major change");
140                 $others = array('minor', 'author');
141                 break;
142             }
143         }
144
145         $new_link = WikiLink($new, '', $new_version);
146         $old_link = $old ? WikiLink($old, '', $old_version) : $old_version;
147         $page_link = WikiLink($page);
148
149         $html = HTML(HTML::p(fmt("Differences between %s and %s of %s.",
150                                  $new_link, $old_link, $page_link)));
151
152         $otherdiffs = HTML::p(_("Other diffs:"));
153         $label = array('major' => _("Previous Major Revision"),
154                        'minor' => _("Previous Revision"),
155                        'author'=> _("Previous Author"));
156         foreach ($others as $other) {
157             $args = array('pagename' => $pagename, 'previous' => $other);
158             if ($version)
159                 $args['version'] = $version;
160             if (count($otherdiffs->getContent()) > 1)
161                 $otherdiffs->pushContent(", ");
162             else
163                 $otherdiffs->pushContent(" ");
164             $otherdiffs->pushContent(Button($args, $label[$other]));
165         }
166         $html->pushContent($otherdiffs);
167
168
169         if ($old and $old->getVersion() == 0)
170             $old = false;
171
172         $html->pushContent(HTML::Table($this->PageInfoRow(_("Newer page:"), $new,
173                                                           $request),
174                                        $this->PageInfoRow(_("Older page:"), $old,
175                                                           $request)));
176
177         if ($new && $old) {
178             $diff = new Diff($old->getContent(), $new->getContent());
179
180             if ($diff->isEmpty()) {
181                 $html->pushContent(HTML::hr(),
182                                    HTML::p(_("Content of versions "), $old->getVersion(),
183                                            _(" and "), $new->getVersion(), _(" is identical.")));
184                 // If two consecutive versions have the same content, it is because the page was
185                 // renamed, or metadata changed: ACL, owner, markup.
186                 // We give the reason by printing the summary.
187                 if (($new->getVersion() - $old->getVersion()) == 1) {
188                     $html->pushContent(HTML::p(_("Version "), $new->getVersion(),
189                                                _(" was created because: "), $new->get('summary')));
190                 }
191             } else {
192                 $fmt = new HtmlUnifiedDiffFormatter;
193                 $html->pushContent($fmt->format($diff));
194             }
195         }
196
197         return $html;
198     }
199 };
200
201 // For emacs users
202 // Local Variables:
203 // mode: php
204 // tab-width: 8
205 // c-basic-offset: 4
206 // c-hanging-comment-ender-p: nil
207 // indent-tabs-mode: nil
208 // End:
209 ?>