]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/Diff.php
Less messages
[SourceForge/phpwiki.git] / lib / plugin / Diff.php
1 <?php
2
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 along
19  * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
36     function getName()
37     {
38         return _("Diff");
39     }
40
41     function getDescription()
42     {
43         return _("Display differences between revisions");
44     }
45
46     // Establish default values for each of this plugin's arguments.
47     // todo: makes only sense with more args.
48     function getDefaultArguments()
49     {
50         return array('pagename' => '[pagename]',
51             'versions' => false,
52             'version' => false,
53             'previous' => 'major', // author, minor or major
54         );
55     }
56
57     function PageInfoRow($label, $rev, &$request)
58     {
59
60         global $WikiTheme, $WikiNameRegexp;
61
62         $row = HTML::tr(HTML::td(array('align' => 'right'), $label));
63         if ($rev) {
64             $author = $rev->get('author');
65             $dbi = $request->getDbh();
66
67             $iswikipage = (isWikiWord($author) && $dbi->isWikiPage($author));
68             $authorlink = $iswikipage ? WikiLink($author) : $author;
69
70             $linked_version = WikiLink($rev, 'existing', $rev->getVersion());
71             $row->pushContent(HTML::td(fmt("version %s", $linked_version)),
72                 HTML::td($WikiTheme->getLastModifiedMessage($rev,
73                     false)),
74                 HTML::td(fmt("by %s", $authorlink)));
75         } else {
76             $row->pushContent(HTML::td(array('colspan' => '3'), _("None")));
77         }
78         return $row;
79     }
80
81     function run($dbi, $argstr, &$request, $basepage)
82     {
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("Page ā€œ%sā€ does not exist.",
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         } else {
110             $new = $current;
111             $new_version = _("current version");
112         }
113
114         if (preg_match('/^\d+$/', $previous)) {
115             if (!($old = $page->getRevision($previous)))
116                 NoSuchRevision($request, $page, $previous);
117             $old_version = fmt("version %d", $previous);
118             $others = array('major', 'minor', 'author');
119         } else {
120             switch ($previous) {
121                 case 'author':
122                     $old = $new;
123                     while ($old = $page->getRevisionBefore($old)) {
124                         if ($old->get('author') != $new->get('author'))
125                             break;
126                     }
127                     $old_version = _("revision by previous author");
128                     $others = array('major', 'minor');
129                     break;
130                 case 'minor':
131                     $previous = 'minor';
132                     $old = $page->getRevisionBefore($new);
133                     $old_version = _("previous revision");
134                     $others = array('major', 'author');
135                     break;
136                 case 'major':
137                 default:
138                     $old = $new;
139                     while ($old && $old->get('is_minor_edit'))
140                         $old = $page->getRevisionBefore($old);
141                     if ($old)
142                         $old = $page->getRevisionBefore($old);
143                     $old_version = _("predecessor to the previous major change");
144                     $others = array('minor', 'author');
145                     break;
146             }
147         }
148
149         $new_link = WikiLink($new, '', $new_version);
150         $old_link = $old ? WikiLink($old, '', $old_version) : $old_version;
151         $page_link = WikiLink($page);
152
153         $html = HTML(HTML::p(fmt("Differences between %s and %s of %s.",
154             $new_link, $old_link, $page_link)));
155
156         $otherdiffs = HTML::p(_("Other diffs:"));
157         $label = array('major' => _("Previous Major Revision"),
158             'minor' => _("Previous Revision"),
159             'author' => _("Previous Author"));
160         foreach ($others as $other) {
161             $args = array('pagename' => $pagename, 'previous' => $other);
162             if ($version)
163                 $args['version'] = $version;
164             if (count($otherdiffs->getContent()) > 1)
165                 $otherdiffs->pushContent(", ");
166             else
167                 $otherdiffs->pushContent(" ");
168             $otherdiffs->pushContent(Button($args, $label[$other]));
169         }
170         $html->pushContent($otherdiffs);
171
172         if ($old and $old->getVersion() == 0)
173             $old = false;
174
175         $html->pushContent(HTML::Table($this->PageInfoRow(_("Newer page:"), $new,
176                 $request),
177             $this->PageInfoRow(_("Older page:"), $old,
178                 $request)));
179
180         if ($new && $old) {
181             $diff = new Diff($old->getContent(), $new->getContent());
182
183             if ($diff->isEmpty()) {
184                 $html->pushContent(HTML::hr(),
185                     HTML::p(_("Content of versions "), $old->getVersion(),
186                         _(" and "), $new->getVersion(), _(" is identical.")));
187                 // If two consecutive versions have the same content, it is because the page was
188                 // renamed, or metadata changed: ACL, owner, markup.
189                 // We give the reason by printing the summary.
190                 if (($new->getVersion() - $old->getVersion()) == 1) {
191                     $html->pushContent(HTML::p(_("Version "), $new->getVersion(),
192                         _(" was created because: "), $new->get('summary')));
193                 }
194             } else {
195                 $fmt = new HtmlUnifiedDiffFormatter;
196                 $html->pushContent($fmt->format($diff));
197             }
198         }
199
200         return $html;
201     }
202 }
203
204 // Local Variables:
205 // mode: php
206 // tab-width: 8
207 // c-basic-offset: 4
208 // c-hanging-comment-ender-p: nil
209 // indent-tabs-mode: nil
210 // End: