]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/Diff.php
function run: @return mixed
[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 getDescription()
37     {
38         return _("Display differences between revisions.");
39     }
40
41     // Establish default values for each of this plugin's arguments.
42     // todo: makes only sense with more args.
43     function getDefaultArguments()
44     {
45         return array('pagename' => '[pagename]',
46             'versions' => false,
47             'version' => false,
48             'previous' => 'major', // author, minor or major
49         );
50     }
51
52     function PageInfoRow($label, $rev, &$request)
53     {
54
55         global $WikiTheme;
56
57         $row = HTML::tr(HTML::td(array('class' => '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     /**
77      * @param WikiDB $dbi
78      * @param string $argstr
79      * @param WikiRequest $request
80      * @param string $basepage
81      * @return mixed
82      */
83     function run($dbi, $argstr, &$request, $basepage)
84     {
85         extract($this->getArgs($argstr, $request));
86         if (is_array($versions)) {
87             // Version selection from pageinfo.php display:
88             rsort($versions);
89             list ($version, $previous) = $versions;
90         }
91
92         // Check if user is allowed to get the Page.
93         if (!mayAccessPage('view', $pagename)) {
94             return $this->error(sprintf(_("Illegal access to page %s: no read access"),
95                 $pagename));
96         }
97
98         // abort if page doesn't exist
99         $page = $request->getPage($pagename);
100         $current = $page->getCurrentRevision();
101         if ($current->getVersion() < 1) {
102             $html = HTML(HTML::p(fmt("Page ā€œ%sā€ does not exist.",
103                 WikiLink($pagename, 'unknown'))));
104             return $html; //early return
105         }
106
107         if ($version) {
108             if (!($new = $page->getRevision($version)))
109                 NoSuchRevision($request, $page, $version);
110             $new_version = fmt("version %d", $version);
111         } else {
112             $new = $current;
113             $new_version = _("current version");
114         }
115
116         if (preg_match('/^\d+$/', $previous)) {
117             if (!($old = $page->getRevision($previous)))
118                 NoSuchRevision($request, $page, $previous);
119             $old_version = fmt("version %d", $previous);
120             $others = array('major', 'minor', 'author');
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                     $old = $page->getRevisionBefore($new);
134                     $old_version = _("previous revision");
135                     $others = array('major', 'author');
136                     break;
137                 case 'major':
138                 default:
139                     $old = $new;
140                     while ($old && $old->get('is_minor_edit'))
141                         $old = $page->getRevisionBefore($old);
142                     if ($old)
143                         $old = $page->getRevisionBefore($old);
144                     $old_version = _("predecessor to the previous major change");
145                     $others = array('minor', 'author');
146                     break;
147             }
148         }
149
150         $new_link = WikiLink($new, '', $new_version);
151         $old_link = $old ? WikiLink($old, '', $old_version) : $old_version;
152         $page_link = WikiLink($page);
153
154         $html = HTML(HTML::p(fmt("Differences between %s and %s of %s.",
155             $new_link, $old_link, $page_link)));
156
157         $otherdiffs = HTML::p(_("Other diffs:"));
158         $label = array('major' => _("Previous Major Revision"),
159             'minor' => _("Previous Revision"),
160             'author' => _("Previous Author"));
161         foreach ($others as $other) {
162             $args = array('pagename' => $pagename, 'previous' => $other);
163             if ($version)
164                 $args['version'] = $version;
165             if (count($otherdiffs->getContent()) > 1)
166                 $otherdiffs->pushContent(", ");
167             else
168                 $otherdiffs->pushContent(" ");
169             $otherdiffs->pushContent(Button($args, $label[$other]));
170         }
171         $html->pushContent($otherdiffs);
172
173         if ($old and $old->getVersion() == 0)
174             $old = false;
175
176         $html->pushContent(HTML::Table($this->PageInfoRow(_("Newer page:"), $new,
177                 $request),
178             $this->PageInfoRow(_("Older page:"), $old,
179                 $request)));
180
181         if ($new && $old) {
182             $diff = new Diff($old->getContent(), $new->getContent());
183
184             if ($diff->isEmpty()) {
185                 $html->pushContent(HTML::hr(),
186                     HTML::p(_("Content of versions "), $old->getVersion(),
187                         _(" and "), $new->getVersion(), _(" is identical.")));
188                 // If two consecutive versions have the same content, it is because the page was
189                 // renamed, or metadata changed: ACL, owner, markup.
190                 // We give the reason by printing the summary.
191                 if (($new->getVersion() - $old->getVersion()) == 1) {
192                     $html->pushContent(HTML::p(_("Version "), $new->getVersion(),
193                         _(" was created because: "), $new->get('summary')));
194                 }
195             } else {
196                 $fmt = new HtmlUnifiedDiffFormatter;
197                 $html->pushContent($fmt->format($diff));
198             }
199         }
200
201         return $html;
202     }
203 }
204
205 // Local Variables:
206 // mode: php
207 // tab-width: 8
208 // c-basic-offset: 4
209 // c-hanging-comment-ender-p: nil
210 // indent-tabs-mode: nil
211 // End: