source: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/publish/action.php@ 25027

Last change on this file since 25027 was 25027, checked in by jmt12, 12 years ago

Adding the packages directory, and within it a configured version of dokuwiki all ready to run

File size: 11.4 KB
Line 
1<?php
2/**
3 * DokuWiki Plugin publish (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author Jarrod Lowe <[email protected]>
7 * @author Andreas Gohr <[email protected]>
8 */
9
10// TODO:
11// Old Revisions Display X
12// Recent Changes Display X
13// Redirection X
14// List of Unapproved Documents user has permission to approve X
15// Namespace restrictions + admin X
16// Diff Links in banner on Prev Approved X
17// List of Recent Approvals X
18// Subscriptions should show approvals - hard (MAIL_MESSAGE_SEND is the only appropriate hook)
19// Allow submits of docs with no changes for approval, with autocomment X
20// RSS Info -- hard (no hooks in feed.php)
21// Internationalisation (or not) X
22
23// must be run within Dokuwiki
24if(!defined('DOKU_INC')) die();
25
26class action_plugin_publish extends DokuWiki_Action_Plugin {
27 private $hlp;
28
29 function action_plugin_publish(){
30 $this->hlp = plugin_load('helper','publish'); // load helper plugin
31 }
32
33 function register(&$controller) {
34 $controller->register_hook('HTML_EDITFORM_OUTPUT', 'BEFORE', $this, handle_html_editform_output, array());
35 #$controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, debug, array());
36 $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, handle_display_banner, array());
37 $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, handle_io_write, array());
38 $controller->register_hook('HTML_REVISIONSFORM_OUTPUT', 'BEFORE', $this, handle_revisions, array());
39 $controller->register_hook('HTML_RECENTFORM_OUTPUT', 'BEFORE', $this, handle_recent, array());
40 $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, handle_start, array());
41 }
42
43 function handle_html_editform_output(&$event, $param) {
44 global $ID;
45 global $INFO;
46
47 if(!$this->hlp->in_namespace($this->getConf('apr_namespaces'), $ID)) {
48 return;
49 }
50 if($INFO['perm'] < AUTH_DELETE) {
51 return;
52 }
53
54 $html = '<label class="nowrap" for="approved"><input type="checkbox" id="approved" name="approved" value="1" tabindex=3 onclick="{ return approval_checkbox(\'' . $this->getConf('apr_approved_text') . '\'); }"/> <span>' . $this->getLang('apr_do_approve') . '</span></label>';
55 $event->data->insertElement(12,$html); //FIXME hardcoded element position
56 }
57
58 function debug(&$event, $param) {
59 global $ID;
60 ptln('<pre>');
61 ptln(print_r(p_get_metadata($ID), true));
62 ptln(print_r(pageinfo(), true));
63 ptln('</pre>');
64 }
65
66 function handle_io_write(&$event, $param) {
67 # This is the only hook I could find which runs on save,
68 # but late enough to have lastmod set (ACTION_ACT_PREPROCESS
69 # is too early)
70 global $_POST;
71 global $ID;
72 global $ACT;
73 global $USERINFO;
74 global $INFO;
75 if(!$this->hlp->in_namespace($this->getConf('apr_namespaces'), $ID)) { return; }
76 if($INFO['perm'] < AUTH_DELETE) { return true; }
77 if($ACT != 'save') { return true; }
78 if(!$event->data[3]) { return true; } # don't approve the doc being moved to archive
79 if($_POST['approved']) {
80 $data = pageinfo();
81 #$newdata = p_get_metadata($ID, 'approval');
82 $newdata = $data['meta']['approval'];
83 $newdata[$data['lastmod']] = array($data['client'], $_SERVER['REMOTE_USER'], $USERINFO['mail']);
84 p_set_metadata($ID, array('approval' => $newdata), true, true);
85 }
86 return true;
87 }
88
89 function handle_display_banner(&$event, $param) {
90 global $ID;
91 global $REV;
92 global $INFO;
93
94 if(!$this->hlp->in_namespace($this->getConf('apr_namespaces'), $ID)) return;
95 if($event->data != 'show') return true;
96 if(!$INFO['exists']) return true;
97
98 $strings = array();
99 $meta = p_get_metadata($ID);
100 $rev = $REV;
101 if(!$rev) { $rev = $meta['last_change']['date']; }
102 if(!$meta['approval']) { $meta['approval'] = array(); }
103 $allapproved = array_keys($meta['approval']);
104 sort($allapproved);
105 $latest_rev = $meta['last_change']['date'];
106 #$strings[] = '<!-- ' . print_r($meta, true) . '-->';
107
108 $longdate = dformat($rev);
109
110 # Is this document approved?
111 $approver = null;
112 if($meta['approval'][$rev]) {
113 # Approved
114 if(is_array($meta['approval'][$rev])) {
115 $approver = $meta['approval'][$rev][1];
116 if(!$approver) { $approver = $meta['approval'][$rev][2]; }
117 if(!$approver) { $approver = $meta['approval'][$rev][0]; }
118 }else{
119 $approver = $meta['approval'][$rev];
120 }
121 }
122
123 # What is the most recent approved version?
124 $most_recent_approved = null;
125 $id = count($allapproved)-1;
126 if($id >= 0) {
127 if($allapproved[$id] > $rev) {
128 $most_recent_approved = $allapproved[$id];
129 }
130 }
131
132 # Latest, if draft
133 $most_recent_draft = null;
134 #$strings[] = '<!-- lr='.$latest_rev.', r='.$rev.', mra='.$most_recently_approved.', d='.($latest_rev != $rev).','.($latest_rev != $most_recently_approved).' -->';
135 if($latest_rev != $rev && $latest_rev != $most_recent_approved) {
136 $most_recent_draft = $latest_rev;
137 }
138
139 # Approved *before* this one
140 $previous_approved = null;
141 foreach($allapproved as $arev) {
142 if($arev >= $rev) { break; }
143 $previous_approved = $arev;
144 }
145
146 $strings[] = '<div class="approval approved_';
147 if($approver && !$most_recent_approved) { $strings[] = 'yes'; } else { $strings[] = 'no'; }
148 $strings[] = '">';
149
150 # [jmt12] We may not display the message at all
151 $display_message = false;
152
153 if($most_recent_draft) {
154 $strings[] = '<span class="approval_latest_draft">';
155 $strings[] = sprintf($this->getLang('apr_recent_draft'), wl($ID, 'force_rev=1'));
156 $strings[] = $this->difflink($ID, null, $REV) . '</span>';
157 $display_message = true;
158 }
159
160 if($most_recent_approved) {
161 # Approved, but there is a more recent version
162 $userrev = $most_recent_approved;
163 if($userrev == $latest_rev) { $userrev = ''; }
164 $strings[] = '<span class="approval_outdated">';
165 $strings[] = sprintf($this->getLang('apr_outdated'), wl($ID, 'rev=' . $userrev));
166 $strings[] = $this->difflink($ID, $userrev, $REV) . '</span>';
167 $display_message = true;
168 }
169
170 if(!$approver) {
171 # Draft
172 $strings[] = '<span class="approval_draft">';
173 $strings[] = sprintf($this->getLang('apr_draft'),
174 '<span class="approval_date">' . $longdate . '</span>');
175 $strings[] = '</span>';
176 $display_message = true;
177 }
178
179 // [jmt12] Only display this notice to editors
180 if($approver && $INFO['perm'] >= AUTH_EDIT) {
181 # Approved
182 $strings[] = '<span class="approval_approved">';
183 $strings[] = sprintf($this->getLang('apr_approved'),
184 '<span class="approval_date">' . $longdate . '</span>',
185 editorinfo($approver));
186 $strings[] = '</span>';
187 $display_message = true;
188 }
189
190 $strings[] = '</div>';
191
192 // [jmt12] if there is no message content, hide empty div
193 if ($display_message)
194 {
195 ptln(implode($strings));
196 }
197 return true;
198 }
199
200 function handle_revisions(&$event, $param) {
201 global $ID;
202 global $REV;
203 if(!$this->hlp->in_namespace($this->getConf('apr_namespaces'), $ID)) { return; }
204 $meta = p_get_metadata($ID);
205 $latest_rev = $meta['last_change']['date'];
206
207 $member = null;
208 foreach($event->data->_content as $key => $ref) {
209 if($ref['_elem'] == 'opentag' && $ref['_tag'] == 'div' && $ref['class'] == 'li') {
210 $member = $key;
211 }
212
213 if($member && $ref['_elem'] == 'tag' &&
214 $ref['_tag'] == 'input' && $ref['name'] == 'rev2[]'){
215 if($meta['approval'][$ref['value']] ||
216 ($ref['value'] == 'current' && $meta['approval'][$latest_rev])) {
217 $event->data->_content[$member]['class'] = 'li approved_revision';
218 }else{
219 $event->data->_content[$member]['class'] = 'li unapproved_revision';
220 }
221 $member = null;
222 }
223 }
224
225
226 return true;
227 }
228
229 function handle_recent(&$event, $param) {
230 #$meta = p_get_metadata($ID);
231 #$latest_rev = $meta['last_change']['date'];
232
233 $member = null;
234 foreach($event->data->_content as $key => $ref) {
235 if($ref['_elem'] == 'opentag' && $ref['_tag'] == 'div' && $ref['class'] == 'li') {
236 $member = $key;
237 }
238
239 if($member && $ref['_elem'] == 'opentag' &&
240 $ref['_tag'] == 'a' && $ref['class'] == 'diff_link'){
241 $name = $ref['href'];
242 $name = explode('?', $name);
243 $name = explode('&', $name[1]);
244 $usename = null;
245 foreach($name as $n) {
246 $fields = explode('=', $n);
247 if($fields[0] == 'id') {
248 $usename = $fields[1];
249 break;
250 }
251 }
252 if($usename) {
253 if($this->hlp->in_namespace($this->getConf('apr_namespaces'), $usename)) {
254 $meta = p_get_metadata($usename);
255
256 if($meta['approval'][$meta['last_change']['date']]) {
257 $event->data->_content[$member]['class'] = 'li approved_revision';
258 }else{
259 $event->data->_content[$member]['class'] = 'li unapproved_revision';
260 }
261 }
262 }
263 $member = null;
264 }
265 }
266 return true;
267 }
268
269 function difflink($id, $rev1, $rev2) {
270 if($rev1 == $rev2) { return ''; }
271 return '<a href="' . wl($id, 'rev2[]=' . $rev1 . '&rev2[]=' . $rev2 . '&do[diff]=1') .
272 '" class="approved_diff_link">' .
273 '<img src="'.DOKU_BASE.'lib/images/diff.png" class="approved_diff_link" alt="Diff" />' .
274 '</a>';
275 }
276
277 function handle_start(&$event, $param) {
278 # show only
279 global $ACT;
280 if($ACT != 'show') { return; }
281
282 # only apply to latest rev
283 global $REV;
284 if($REV != '') { return; }
285
286 # apply to readers only
287 global $INFO;
288 if($INFO['perm'] != AUTH_READ) { return; }
289
290 # Check for override token
291 global $_GET;
292 if($_GET['force_rev']) { return; }
293
294 # Only apply to appropriate namespaces
295 global $ID;
296 if(!$this->hlp->in_namespace($this->getConf('apr_namespaces'), $ID)) { return; }
297
298 # Find latest rev
299 $meta = p_get_metadata($ID);
300 if($meta['approval'][$meta['last_change']['date']]) { return; } //REV=0 *is* approved
301
302 if(!$meta['approval']) { return; } //no approvals
303
304 # Get list of approvals
305 $all = array_keys($meta['approval']);
306 if(count($all) == 0) { return; } //no approvals
307
308 $REV = $all[count($all)-1];
309 }
310}
311
312
313
Note: See TracBrowser for help on using the repository browser.