]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/Diff.php
Activated Id substitution for Subversion
[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/difflib.php');
31 require_once('lib/diff.php');
32
33 class WikiPlugin_Diff
34 extends WikiPlugin {
35
36     function getName () {
37         return _("Diff");
38     }
39
40     function getDescription () {
41         return _("Display differences between revisions");
42     }
43
44     function getVersion() {
45         return preg_replace("/[Revision: $]/", '',
46                             "\$Revision: 1.4 $");
47     }
48
49     // Establish default values for each of this plugin's arguments.
50     // todo: makes only sense with more args.
51     function getDefaultArguments() {
52         return array('pagename' => '[pagename]',
53                      'name'     => _("World"),
54                      'versions' => false,
55                      'version'  => false,
56                      'previous' => 'major', // author, minor or major
57                      );
58     }
59
60     function PageInfoRow ($label, $rev, &$request) {
61
62         global $WikiTheme, $WikiNameRegexp;
63
64         $row = HTML::tr(HTML::td(array('align' => 'right'), $label));
65         if ($rev) {
66             $author = $rev->get('author');
67             $dbi = $request->getDbh();
68
69             $iswikipage = (isWikiWord($author) && $dbi->isWikiPage($author));
70             $authorlink = $iswikipage ? WikiLink($author) : $author;
71             
72             $linked_version = WikiLink($rev, 'existing', $rev->getVersion());
73             $row->pushContent(HTML::td(fmt("version %s", $linked_version)),
74                               HTML::td($WikiTheme->getLastModifiedMessage($rev,
75                                                                       false)),
76                               HTML::td(fmt("by %s", $authorlink)));
77         } else {
78             $row->pushContent(HTML::td(array('colspan' => '3'), _("None")));
79         }
80         return $row;
81     }
82     
83     function run($dbi, $argstr, &$request, $basepage) {
84         extract($this->getArgs($argstr, $request));
85         if (is_array($versions)) {
86             // Version selection from pageinfo.php display:
87             rsort($versions);
88             list ($version, $previous) = $versions;
89         }
90
91         // abort if page doesn't exist
92         $page = $request->getPage($pagename);
93         $current = $page->getCurrentRevision();
94         if ($current->getVersion() < 1) {
95             $html = HTML(HTML::p(fmt("I'm sorry, there is no such page as %s.",
96                                      WikiLink($pagename, 'unknown'))));
97             return $html; //early return
98         }
99
100         if ($version) {
101             if (!($new = $page->getRevision($version)))
102                 NoSuchRevision($request, $page, $version);
103             $new_version = fmt("version %d", $version);
104         }
105         else {
106             $new = $current;
107             $new_version = _("current version");
108         }
109
110         if (preg_match('/^\d+$/', $previous)) {
111             if ( !($old = $page->getRevision($previous)) )
112                 NoSuchRevision($request, $page, $previous);
113             $old_version = fmt("version %d", $previous);
114             $others = array('major', 'minor', 'author');
115         }
116         else {
117             switch ($previous) {
118             case 'author':
119                 $old = $new;
120                 while ($old = $page->getRevisionBefore($old)) {
121                     if ($old->get('author') != $new->get('author'))
122                         break;
123                 }
124                 $old_version = _("revision by previous author");
125                 $others = array('major', 'minor');
126                 break;
127             case 'minor':
128                 $previous='minor';
129                 $old = $page->getRevisionBefore($new);
130                 $old_version = _("previous revision");
131                 $others = array('major', 'author');
132                 break;
133             case 'major':
134             default:
135                 $old = $new;
136                 while ($old && $old->get('is_minor_edit'))
137                     $old = $page->getRevisionBefore($old);
138                 if ($old)
139                     $old = $page->getRevisionBefore($old);
140                 $old_version = _("predecessor to the previous major change");
141                 $others = array('minor', 'author');
142                 break;
143             }
144         }
145         
146         $new_link = WikiLink($new, '', $new_version);
147         $old_link = $old ? WikiLink($old, '', $old_version) : $old_version;
148         $page_link = WikiLink($page);
149         
150         $html = HTML(HTML::p(fmt("Differences between %s and %s of %s.",
151                                  $new_link, $old_link, $page_link)));
152
153         $otherdiffs = HTML::p(_("Other diffs:"));
154         $label = array('major' => _("Previous Major Revision"),
155                        'minor' => _("Previous Revision"),
156                        'author'=> _("Previous Author"));
157         foreach ($others as $other) {
158             $args = array('pagename' => $pagename, 'previous' => $other);
159             if ($version)
160                 $args['version'] = $version;
161             if (count($otherdiffs->getContent()) > 1)
162                 $otherdiffs->pushContent(", ");
163             else
164                 $otherdiffs->pushContent(" ");
165             $otherdiffs->pushContent(Button($args, $label[$other]));
166         }
167         $html->pushContent($otherdiffs);
168
169         
170         if ($old and $old->getVersion() == 0)
171             $old = false;
172
173         $html->pushContent(HTML::Table($this->PageInfoRow(_("Newer page:"), $new,
174                                                           $request),
175                                        $this->PageInfoRow(_("Older page:"), $old,
176                                                           $request)));
177
178         if ($new && $old) {
179             $diff = new Diff($old->getContent(), $new->getContent());
180             
181             if ($diff->isEmpty()) {
182                 $html->pushContent(HTML::hr(),
183                                    HTML::p('[', _("Versions are identical"),
184                                            ']'));
185             }
186             else {
187                 // New CSS formatted unified diffs (ugly in NS4).
188                 $fmt = new HtmlUnifiedDiffFormatter;
189
190                 // Use this for old table-formatted diffs.
191                 //$fmt = new TableUnifiedDiffFormatter;
192                 $html->pushContent($fmt->format($diff));
193             }
194         }
195
196         //$html = HTML::tt(fmt('%s: %s', $salutation, WikiLink($name, 'auto')),
197         //                 THE_END);
198         
199         return $html;
200     }
201 };
202
203 // $Log: not supported by cvs2svn $
204 // Revision 1.3  2005/09/30 18:53:10  uckelman
205 // 'final' is a reserved keyword as of PHP5, so shouldn't be used as a
206 //  function name here.
207 //
208 // Revision 1.2  2004/06/14 11:31:39  rurban
209 // renamed global $Theme to $WikiTheme (gforge nameclash)
210 // inherit PageList default options from PageList
211 //   default sortby=pagename
212 // use options in PageList_Selectable (limit, sortby, ...)
213 // added action revert, with button at action=diff
214 // added option regex to WikiAdminSearchReplace
215 //
216 // Revision 1.1  2004/02/26 23:02:17  rurban
217 // lib/diff.php converted to a plugin by electrawn,
218 // plugin cleaned up by rurban,
219 // code by dairiki
220 //
221 // Would make sense to see arbitrary diff's between any files or revisions.
222 //
223 //
224
225 // For emacs users
226 // Local Variables:
227 // mode: php
228 // tab-width: 8
229 // c-basic-offset: 4
230 // c-hanging-comment-ender-p: nil
231 // indent-tabs-mode: nil
232 // End:
233 ?>