]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/Diff.php
Replace tabs by spaces; remove EOL spaces
[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$");
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                      'versions' => false,
54                      'version'  => false,
55                      'previous' => 'major', // author, minor or major
56                      );
57     }
58
59     function PageInfoRow ($label, $rev, &$request) {
60
61         global $WikiTheme, $WikiNameRegexp;
62
63         $row = HTML::tr(HTML::td(array('align' => 'right'), $label));
64         if ($rev) {
65             $author = $rev->get('author');
66             $dbi = $request->getDbh();
67
68             $iswikipage = (isWikiWord($author) && $dbi->isWikiPage($author));
69             $authorlink = $iswikipage ? WikiLink($author) : $author;
70
71             $linked_version = WikiLink($rev, 'existing', $rev->getVersion());
72             $row->pushContent(HTML::td(fmt("version %s", $linked_version)),
73                               HTML::td($WikiTheme->getLastModifiedMessage($rev,
74                                                                       false)),
75                               HTML::td(fmt("by %s", $authorlink)));
76         } else {
77             $row->pushContent(HTML::td(array('colspan' => '3'), _("None")));
78         }
79         return $row;
80     }
81
82     function run($dbi, $argstr, &$request, $basepage) {
83         extract($this->getArgs($argstr, $request));
84         if (is_array($versions)) {
85             // Version selection from pageinfo.php display:
86             rsort($versions);
87             list ($version, $previous) = $versions;
88         }
89
90         // Check if user is allowed to get the Page.
91         if (!mayAccessPage ('view', $pagename)) {
92                 return $this->error(sprintf(_("Illegal access to page %s: no read access"),
93                                         $pagename));
94         }
95
96         // abort if page doesn't exist
97         $page = $request->getPage($pagename);
98         $current = $page->getCurrentRevision();
99         if ($current->getVersion() < 1) {
100             $html = HTML(HTML::p(fmt("I'm sorry, there is no such page as %s.",
101                                      WikiLink($pagename, 'unknown'))));
102             return $html; //early return
103         }
104
105         if ($version) {
106             if (!($new = $page->getRevision($version)))
107                 NoSuchRevision($request, $page, $version);
108             $new_version = fmt("version %d", $version);
109         }
110         else {
111             $new = $current;
112             $new_version = _("current version");
113         }
114
115         if (preg_match('/^\d+$/', $previous)) {
116             if ( !($old = $page->getRevision($previous)) )
117                 NoSuchRevision($request, $page, $previous);
118             $old_version = fmt("version %d", $previous);
119             $others = array('major', 'minor', 'author');
120         }
121         else {
122             switch ($previous) {
123             case 'author':
124                 $old = $new;
125                 while ($old = $page->getRevisionBefore($old)) {
126                     if ($old->get('author') != $new->get('author'))
127                         break;
128                 }
129                 $old_version = _("revision by previous author");
130                 $others = array('major', 'minor');
131                 break;
132             case 'minor':
133                 $previous='minor';
134                 $old = $page->getRevisionBefore($new);
135                 $old_version = _("previous revision");
136                 $others = array('major', 'author');
137                 break;
138             case 'major':
139             default:
140                 $old = $new;
141                 while ($old && $old->get('is_minor_edit'))
142                     $old = $page->getRevisionBefore($old);
143                 if ($old)
144                     $old = $page->getRevisionBefore($old);
145                 $old_version = _("predecessor to the previous major change");
146                 $others = array('minor', 'author');
147                 break;
148             }
149         }
150
151         $new_link = WikiLink($new, '', $new_version);
152         $old_link = $old ? WikiLink($old, '', $old_version) : $old_version;
153         $page_link = WikiLink($page);
154
155         $html = HTML(HTML::p(fmt("Differences between %s and %s of %s.",
156                                  $new_link, $old_link, $page_link)));
157
158         $otherdiffs = HTML::p(_("Other diffs:"));
159         $label = array('major' => _("Previous Major Revision"),
160                        'minor' => _("Previous Revision"),
161                        'author'=> _("Previous Author"));
162         foreach ($others as $other) {
163             $args = array('pagename' => $pagename, 'previous' => $other);
164             if ($version)
165                 $args['version'] = $version;
166             if (count($otherdiffs->getContent()) > 1)
167                 $otherdiffs->pushContent(", ");
168             else
169                 $otherdiffs->pushContent(" ");
170             $otherdiffs->pushContent(Button($args, $label[$other]));
171         }
172         $html->pushContent($otherdiffs);
173
174
175         if ($old and $old->getVersion() == 0)
176             $old = false;
177
178         $html->pushContent(HTML::Table($this->PageInfoRow(_("Newer page:"), $new,
179                                                           $request),
180                                        $this->PageInfoRow(_("Older page:"), $old,
181                                                           $request)));
182
183         if ($new && $old) {
184             $diff = new Diff($old->getContent(), $new->getContent());
185
186             if ($diff->isEmpty()) {
187                 $html->pushContent(HTML::hr(),
188                                    HTML::p(_("Content of versions "), $old->getVersion(),
189                                            _(" and "), $new->getVersion(), _(" is identical.")));
190                 // If two consecutive versions have the same content, it is because the page was
191                 // renamed, or metadata changed: ACL, owner, markup.
192                 // We give the reason by printing the summary.
193                 if (($new->getVersion() - $old->getVersion()) == 1) {
194                     $html->pushContent(HTML::p(_("Version "), $new->getVersion(),
195                                                _(" was created because: "), $new->get('summary')));
196                 }
197             } else {
198                 $fmt = new HtmlUnifiedDiffFormatter;
199                 $html->pushContent($fmt->format($diff));
200             }
201         }
202
203         return $html;
204     }
205 };
206
207 // For emacs users
208 // Local Variables:
209 // mode: php
210 // tab-width: 8
211 // c-basic-offset: 4
212 // c-hanging-comment-ender-p: nil
213 // indent-tabs-mode: nil
214 // End:
215 ?>