|
1 <?php |
|
2 /* |
|
3 * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between |
|
4 * Version 1.0 (Banshee) |
|
5 * Copyright (C) 2006-2007 Dan Fuhry |
|
6 * pageutils.php - a class that handles raw page manipulations, used mostly by AJAX requests or their old-fashioned form-based counterparts |
|
7 * |
|
8 * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License |
|
9 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
|
10 * |
|
11 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
|
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
|
13 */ |
|
14 |
|
15 class PageUtils { |
|
16 |
|
17 /** |
|
18 * List possible username completions |
|
19 * @param $name the name to check for |
|
20 * @return array |
|
21 */ |
|
22 |
|
23 function checkusername($name) |
|
24 { |
|
25 global $db, $session, $paths, $template, $plugins; // Common objects |
|
26 $q = $db->sql_query('SELECT username FROM '.table_prefix.'users WHERE username=\''.$db->escape(rawurldecode($name)).'\''); |
|
27 if(!$q) die(mysql_error()); |
|
28 if($db->numrows() < 1) { $db->free_result(); return('good'); } |
|
29 else { $db->free_result(); return('bad'); } |
|
30 } |
|
31 |
|
32 /** |
|
33 * Get the wiki formatting source for a page |
|
34 * @param $page the full page id (Namespace:Pagename) |
|
35 * @return string |
|
36 * @todo (DONE) Make it require a password (just for security purposes) |
|
37 */ |
|
38 |
|
39 function getsource($page, $password = false) |
|
40 { |
|
41 global $db, $session, $paths, $template, $plugins; // Common objects |
|
42 if(!isset($paths->pages[$page])) |
|
43 { |
|
44 return ''; |
|
45 } |
|
46 |
|
47 if(strlen($paths->pages[$page]['password']) == 40) |
|
48 { |
|
49 if(!$password || ( $password != $paths->pages[$page]['password'])) |
|
50 { |
|
51 return 'invalid_password'; |
|
52 } |
|
53 } |
|
54 |
|
55 if(!$session->get_permissions('view_source')) // Dependencies handle this for us - this also checks for read privileges |
|
56 return 'access_denied'; |
|
57 $pid = RenderMan::strToPageID($page); |
|
58 if($pid[1] == 'Special' || $pid[1] == 'Admin') |
|
59 { |
|
60 die('This type of page ('.$paths->nslist[$pid[1]].') cannot be edited because the page source code is not stored in the database.'); |
|
61 } |
|
62 |
|
63 $e = $db->sql_query('SELECT page_text,char_tag FROM '.table_prefix.'page_text WHERE page_id=\''.$pid[0].'\' AND namespace=\''.$pid[1].'\''); |
|
64 if ( !$e ) |
|
65 { |
|
66 $db->_die('The page text could not be selected.'); |
|
67 } |
|
68 if( $db->numrows() < 1 ) |
|
69 { |
|
70 return ''; //$db->_die('There were no rows in the text table that matched the page text query.'); |
|
71 } |
|
72 |
|
73 $r = $db->fetchrow(); |
|
74 $db->free_result(); |
|
75 $message = $r['page_text']; |
|
76 |
|
77 return htmlspecialchars($message); |
|
78 } |
|
79 |
|
80 /** |
|
81 * Basically a frontend to RenderMan::getPage(), with the ability to send valid data for nonexistent pages |
|
82 * @param $page the full page id (Namespace:Pagename) |
|
83 * @param $send_headers true if the theme headers should be sent (still dependent on current page settings), false otherwise |
|
84 * @return string |
|
85 */ |
|
86 |
|
87 function getpage($page, $send_headers = false, $hist_id = false) |
|
88 { |
|
89 die('PageUtils->getpage is deprecated.'); |
|
90 global $db, $session, $paths, $template, $plugins; // Common objects |
|
91 ob_start(); |
|
92 $pid = RenderMan::strToPageID($page); |
|
93 //die('<pre>'.print_r($pid, true).'</pre>'); |
|
94 if(isset($paths->pages[$page]['password']) && strlen($paths->pages[$page]['password']) == 40) |
|
95 { |
|
96 password_prompt($page); |
|
97 } |
|
98 if(isset($paths->pages[$page])) |
|
99 { |
|
100 doStats($pid[0], $pid[1]); |
|
101 } |
|
102 if($paths->custom_page || $pid[1] == 'Special') |
|
103 { |
|
104 // If we don't have access to the page, get out and quick! |
|
105 if(!$session->get_permissions('read') && $pid[0] != 'Login' && $pid[0] != 'Register') |
|
106 { |
|
107 $template->tpl_strings['PAGE_NAME'] = 'Access denied'; |
|
108 |
|
109 if ( $send_headers ) |
|
110 { |
|
111 $template->header(); |
|
112 } |
|
113 |
|
114 echo '<div class="error-box"><b>Access to this page is denied.</b><br />This may be because you are not logged in or you have not met certain criteria for viewing this page.</div>'; |
|
115 |
|
116 if ( $send_headers ) |
|
117 { |
|
118 $template->footer(); |
|
119 } |
|
120 |
|
121 $r = ob_get_contents(); |
|
122 ob_end_clean(); |
|
123 return $r; |
|
124 } |
|
125 |
|
126 $fname = 'page_'.$pid[1].'_'.$paths->pages[$page]['urlname_nons']; |
|
127 @call_user_func($fname); |
|
128 |
|
129 } |
|
130 else if ( $pid[1] == 'Admin' ) |
|
131 { |
|
132 // If we don't have access to the page, get out and quick! |
|
133 if(!$session->get_permissions('read')) |
|
134 { |
|
135 $template->tpl_strings['PAGE_NAME'] = 'Access denied'; |
|
136 if ( $send_headers ) |
|
137 { |
|
138 $template->header(); |
|
139 } |
|
140 echo '<div class="error-box"><b>Access to this page is denied.</b><br />This may be because you are not logged in or you have not met certain criteria for viewing this page.</div>'; |
|
141 if ( $send_headers ) |
|
142 { |
|
143 $template->footer(); |
|
144 } |
|
145 $r = ob_get_contents(); |
|
146 ob_end_clean(); |
|
147 return $r; |
|
148 } |
|
149 |
|
150 $fname = 'page_'.$pid[1].'_'.$pid[0]; |
|
151 if ( !function_exists($fname) ) |
|
152 { |
|
153 $title = 'Page backend not found'; |
|
154 $message = "The administration page you are looking for was properly registered using the page API, but the backend function |
|
155 (<tt>$fname</tt>) was not found. If this is a plugin page, then this is almost certainly a bug with the plugin."; |
|
156 if ( $send_headers ) |
|
157 { |
|
158 die_friendly($title, "<p>$message</p>"); |
|
159 } |
|
160 else |
|
161 { |
|
162 echo "<h2>$title</h2>\n<p>$message</p>"; |
|
163 } |
|
164 } |
|
165 @call_user_func($fname); |
|
166 } |
|
167 else if ( !isset( $paths->pages[$page] ) ) |
|
168 { |
|
169 ob_start(); |
|
170 $code = $plugins->setHook('page_not_found'); |
|
171 foreach ( $code as $cmd ) |
|
172 { |
|
173 eval($cmd); |
|
174 } |
|
175 $text = ob_get_contents(); |
|
176 if ( $text != '' ) |
|
177 { |
|
178 ob_end_clean(); |
|
179 return $text; |
|
180 } |
|
181 $template->header(); |
|
182 if($m = $paths->sysmsg('Page_not_found')) |
|
183 { |
|
184 eval('?>'.RenderMan::render($m)); |
|
185 } |
|
186 else |
|
187 { |
|
188 header('HTTP/1.1 404 Not Found'); |
|
189 echo '<h3>There is no page with this title yet.</h3> |
|
190 <p>You have requested a page that doesn\'t exist yet.'; |
|
191 if($session->get_permissions('create_page')) echo ' You can <a href="'.makeUrl($paths->page, 'do=edit', true).'" onclick="ajaxEditor(); return false;">create this page</a>, or return to the <a href="'.makeUrl(getConfig('main_page')).'">homepage</a>.'; |
|
192 else echo ' Return to the <a href="'.makeUrl(getConfig('main_page')).'">homepage</a>.</p>'; |
|
193 if($session->get_permissions('history_rollback')) { |
|
194 $e = $db->sql_query('SELECT * FROM '.table_prefix.'logs WHERE action=\'delete\' AND page_id=\''.$paths->cpage['urlname_nons'].'\' AND namespace=\''.$pid[1].'\' ORDER BY time_id DESC;'); |
|
195 if(!$e) $db->_die('The deletion log could not be selected.'); |
|
196 if($db->numrows() > 0) { |
|
197 $r = $db->fetchrow(); |
|
198 echo '<p>This page also appears to have some log entries in the database - it seems that it was deleted on '.$r['date_string'].'. You can probably <a href="'.makeUrl($paths->page, 'do=rollback&id='.$r['time_id']).'" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">roll back</a> the deletion.</p>'; |
|
199 } |
|
200 $db->free_result(); |
|
201 } |
|
202 echo '<p> |
|
203 HTTP Error: 404 Not Found |
|
204 </p>'; |
|
205 } |
|
206 $template->footer(); |
|
207 } |
|
208 else |
|
209 { |
|
210 |
|
211 // If we don't have access to the page, get out and quick! |
|
212 if(!$session->get_permissions('read')) |
|
213 { |
|
214 $template->tpl_strings['PAGE_NAME'] = 'Access denied'; |
|
215 if($send_headers) $template->header(); |
|
216 echo '<div class="error-box"><b>Access to this page is denied.</b><br />This may be because you are not logged in or you have not met certain criteria for viewing this page.</div>'; |
|
217 if($send_headers) $template->footer(); |
|
218 $r = ob_get_contents(); |
|
219 ob_end_clean(); |
|
220 return $r; |
|
221 } |
|
222 |
|
223 ob_start(); |
|
224 $code = $plugins->setHook('page_custom_handler'); |
|
225 foreach ( $code as $cmd ) |
|
226 { |
|
227 eval($cmd); |
|
228 } |
|
229 $text = ob_get_contents(); |
|
230 if ( $text != '' ) |
|
231 { |
|
232 ob_end_clean(); |
|
233 return $text; |
|
234 } |
|
235 |
|
236 if($hist_id) { |
|
237 $e = $db->sql_query('SELECT page_text,date_string,char_tag FROM '.table_prefix.'logs WHERE page_id=\''.$paths->pages[$page]['urlname_nons'].'\' AND namespace=\''.$pid[1].'\' AND log_type=\'page\' AND action=\'edit\' AND time_id='.$db->escape($hist_id).''); |
|
238 if($db->numrows() < 1) |
|
239 { |
|
240 $db->_die('There were no rows in the text table that matched the page text query.'); |
|
241 } |
|
242 $r = $db->fetchrow(); |
|
243 $db->free_result(); |
|
244 $message = '<div class="info-box" style="margin-left: 0; margin-top: 5px;"><b>Notice:</b><br />The page you are viewing was archived on '.$r['date_string'].'.<br /><a href="'.makeUrl($page).'" onclick="ajaxReset(); return false;">View current version</a> | <a href="'.makeUrl($page, 'do=rollback&id='.$hist_id).'" onclick="ajaxRollback(\''.$hist_id.'\')">Restore this version</a></div><br />'.RenderMan::render($r['page_text']); |
|
245 |
|
246 if( !$paths->pages[$page]['special'] ) |
|
247 { |
|
248 if($send_headers) |
|
249 { |
|
250 $template->header(); |
|
251 } |
|
252 display_page_headers(); |
|
253 } |
|
254 |
|
255 eval('?>'.$message); |
|
256 |
|
257 if( !$paths->pages[$page]['special'] ) |
|
258 { |
|
259 display_page_footers(); |
|
260 if($send_headers) |
|
261 { |
|
262 $template->footer(); |
|
263 } |
|
264 } |
|
265 |
|
266 } else { |
|
267 if(!$paths->pages[$page]['special']) |
|
268 { |
|
269 $message = RenderMan::getPage($paths->pages[$page]['urlname_nons'], $pid[1]); |
|
270 } |
|
271 else |
|
272 { |
|
273 $message = RenderMan::getPage($paths->pages[$page]['urlname_nons'], $pid[1], 0, false, false, false, false); |
|
274 } |
|
275 // This line is used to debug wikiformatted code |
|
276 // die('<pre>'.htmlspecialchars($message).'</pre>'); |
|
277 |
|
278 if( !$paths->pages[$page]['special'] ) |
|
279 { |
|
280 if($send_headers) |
|
281 { |
|
282 $template->header(); |
|
283 } |
|
284 display_page_headers(); |
|
285 } |
|
286 |
|
287 // This is it, this is what all of Enano has been working up to... |
|
288 |
|
289 eval('?>'.$message); |
|
290 |
|
291 if( !$paths->pages[$page]['special'] ) |
|
292 { |
|
293 display_page_footers(); |
|
294 if($send_headers) |
|
295 { |
|
296 $template->footer(); |
|
297 } |
|
298 } |
|
299 } |
|
300 } |
|
301 $ret = ob_get_contents(); |
|
302 ob_end_clean(); |
|
303 return $ret; |
|
304 } |
|
305 |
|
306 /** |
|
307 * Writes page data to the database, after verifying permissions and running the XSS filter |
|
308 * @param $page_id the page ID |
|
309 * @param $namespace the namespace |
|
310 * @param $message the text to save |
|
311 * @return string |
|
312 */ |
|
313 |
|
314 function savepage($page_id, $namespace, $message, $summary = 'No edit summary given', $minor = false) |
|
315 { |
|
316 global $db, $session, $paths, $template, $plugins; // Common objects |
|
317 $uid = sha1(microtime()); |
|
318 $pname = $paths->nslist[$namespace] . $page_id; |
|
319 |
|
320 if(!$session->get_permissions('edit_page')) |
|
321 return 'Access to edit pages is denied.'; |
|
322 |
|
323 if(!isset($paths->pages[$pname])) |
|
324 { |
|
325 if(!PageUtils::createPage($page_id, $namespace)) |
|
326 return 'The page did not exist, and I was not able to create it. Permissions problem?'; |
|
327 } |
|
328 |
|
329 $prot = ( ( $paths->pages[$pname]['protected'] == 2 && $session->user_logged_in && $session->reg_time + 60*60*24*4 < time() ) || $paths->pages[$pname]['protected'] == 1) ? true : false; |
|
330 $wiki = ( ( $paths->pages[$pname]['wiki_mode'] == 2 && getConfig('wiki_mode') == '1') || $paths->pages[$pname]['wiki_mode'] == 1) ? true : false; |
|
331 if(($prot || !$wiki) && $session->user_level < USER_LEVEL_ADMIN ) return('You are not authorized to edit this page.'); |
|
332 |
|
333 // Strip potentially harmful tags and PHP from the message, if we are in wiki mode and the user is not an administrator |
|
334 $message = RenderMan::preprocess_text($message, false, false); |
|
335 |
|
336 $msg=$db->escape($message); |
|
337 |
|
338 $minor = $minor ? 'true' : 'false'; |
|
339 $q='INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.date('d M Y h:i a').'\', \''.$paths->cpage['urlname_nons'].'\', \''.$paths->namespace.'\', \''.$msg.'\', \''.$uid.'\', \''.$session->username.'\', \''.$db->escape(htmlspecialchars($summary)).'\', '.$minor.');'; |
|
340 if(!$db->sql_query($q)) $db->_die('The history (log) entry could not be inserted into the logs table.'); |
|
341 |
|
342 $q = 'UPDATE '.table_prefix.'page_text SET page_text=\''.$msg.'\',char_tag=\''.$uid.'\' WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'; |
|
343 $e = $db->sql_query($q); |
|
344 if(!$e) $db->_die('Enano was unable to save the page contents. Your changes have been lost <tt>:\'(</tt>.'); |
|
345 |
|
346 $paths->rebuild_page_index($page_id, $namespace); |
|
347 |
|
348 return 'good'; |
|
349 } |
|
350 |
|
351 /** |
|
352 * Creates a page, both in memory and in the database. |
|
353 * @param string $page_id |
|
354 * @param string $namespace |
|
355 * @return bool true on success, false on failure |
|
356 */ |
|
357 |
|
358 function createPage($page_id, $namespace, $name = false, $visible = 1) |
|
359 { |
|
360 global $db, $session, $paths, $template, $plugins; // Common objects |
|
361 if(in_array($namespace, Array('Special', 'Admin'))) |
|
362 { |
|
363 // echo '<b>Notice:</b> PageUtils::createPage: You can\'t create a special page in the database<br />'; |
|
364 return false; // Can't create a special page |
|
365 } |
|
366 |
|
367 if(!isset($paths->nslist[$namespace])) |
|
368 { |
|
369 // echo '<b>Notice:</b> PageUtils::createPage: Couldn\'t look up the namespace<br />'; |
|
370 return false; // Couldn't look up namespace |
|
371 } |
|
372 |
|
373 $pname = $paths->nslist[$namespace] . $page_id; |
|
374 if(isset($paths->pages[$pname])) |
|
375 { |
|
376 // echo '<b>Notice:</b> PageUtils::createPage: Page already exists<br />'; |
|
377 return false; // Page already exists |
|
378 } |
|
379 |
|
380 if(!$session->get_permissions('create_page')) |
|
381 { |
|
382 // echo '<b>Notice:</b> PageUtils::createPage: Not authorized to create pages<br />'; |
|
383 return false; // Access denied |
|
384 } |
|
385 |
|
386 if($session->user_level < USER_LEVEL_ADMIN && $namespace == 'System') |
|
387 { |
|
388 // echo '<b>Notice:</b> PageUtils::createPage: Not authorized to create system messages<br />'; |
|
389 return false; // Not authorized to create system messages |
|
390 } |
|
391 |
|
392 if ( !$name ) |
|
393 $name = str_replace('_', ' ', $page_id); |
|
394 $page = str_replace(' ', '_', $page_id); |
|
395 $regex = '#^([A-z0-9 _\-\.\/\!\@\(\)]*)$#is'; |
|
396 if(!preg_match($regex, $page)) |
|
397 { |
|
398 //echo '<b>Notice:</b> PageUtils::createPage: Name contains invalid characters<br />'; |
|
399 return false; // Name contains invalid characters |
|
400 } |
|
401 |
|
402 $prot = ( $namespace == 'System' ) ? 1 : 0; |
|
403 |
|
404 $paths->add_page(Array( |
|
405 'name'=>$name, |
|
406 'urlname'=>$page, |
|
407 'namespace'=>$namespace, |
|
408 'special'=>0,'visible'=>1,'comments_on'=>0,'protected'=>$prot,'delvotes'=>0,'delvote_ips'=>'','wiki_mode'=>2, |
|
409 )); |
|
410 |
|
411 $qa = $db->sql_query('INSERT INTO '.table_prefix.'pages(name,urlname,namespace,visible,protected) VALUES(\''.$db->escape($name).'\', \''.$db->escape($page).'\', \''.$namespace.'\', '. ( $visible ? '1' : '0' ) .', '.$prot.');'); |
|
412 $qb = $db->sql_query('INSERT INTO '.table_prefix.'page_text(page_id,namespace) VALUES(\''.$db->escape($page).'\', \''.$namespace.'\');'); |
|
413 $qc = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'create\', \''.$session->username.'\', \''.$db->escape($page).'\', \''.$namespace.'\');'); |
|
414 |
|
415 if($qa && $qb && $qc) |
|
416 return true; |
|
417 else |
|
418 { |
|
419 echo $db->get_error(); |
|
420 return false; |
|
421 } |
|
422 } |
|
423 |
|
424 /** |
|
425 * Sets the protection level on a page. |
|
426 * @param $page_id string the page ID |
|
427 * @param $namespace string the namespace |
|
428 * @param $level int level of protection - 0 is off, 1 is full, 2 is semi |
|
429 * @param $reason string why the page is being (un)protected |
|
430 * @return string - "good" on success, in all other cases, an error string (on query failure, calls $db->_die() ) |
|
431 */ |
|
432 function protect($page_id, $namespace, $level, $reason) |
|
433 { |
|
434 global $db, $session, $paths, $template, $plugins; // Common objects |
|
435 |
|
436 $pname = $paths->nslist[$namespace] . $page_id; |
|
437 $wiki = ( ( $paths->pages[$pname]['wiki_mode'] == 2 && getConfig('wiki_mode') == '1') || $paths->pages[$pname]['wiki_mode'] == 1) ? true : false; |
|
438 $prot = ( ( $paths->pages[$pname]['protected'] == 2 && $session->user_logged_in && $session->reg_time + 60*60*24*4 < time() ) || $paths->pages[$pname]['protected'] == 1) ? true : false; |
|
439 |
|
440 if(!$session->get_permissions('protect')) return('Insufficient access rights'); |
|
441 if(!$wiki) return('Page protection only has an effect when Wiki Mode is enabled.'); |
|
442 if(!preg_match('#^([0-9]+){1}$#', (string)$level)) return('Invalid $level parameter.'); |
|
443 |
|
444 if($reason!='NO_REASON') { |
|
445 switch($level) |
|
446 { |
|
447 case 0: |
|
448 $q = 'INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'unprot\', \''.$session->username.'\', \''.$page_id.'\', \''.$namespace.'\', \''.$db->escape(htmlspecialchars($reason)).'\');'; |
|
449 break; |
|
450 case 1: |
|
451 $q = 'INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'prot\', \''.$session->username.'\', \''.$page_id.'\', \''.$namespace.'\', \''.$db->escape(htmlspecialchars($reason)).'\');'; |
|
452 break; |
|
453 case 2: |
|
454 $q = 'INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'semiprot\', \''.$session->username.'\', \''.$page_id.'\', \''.$namespace.'\', \''.$db->escape(htmlspecialchars($reason)).'\');'; |
|
455 break; |
|
456 default: |
|
457 return 'PageUtils::protect(): Invalid value for $level'; |
|
458 break; |
|
459 } |
|
460 if(!$db->sql_query($q)) $db->_die('The log entry for the page protection could not be inserted.'); |
|
461 } |
|
462 |
|
463 $q = $db->sql_query('UPDATE '.table_prefix.'pages SET protected='.$_POST['level'].' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
464 if(!$q) $db->_die('The pages table was not updated.'); |
|
465 |
|
466 return('good'); |
|
467 } |
|
468 |
|
469 /** |
|
470 * Generates an HTML table with history information in it. |
|
471 * @param $page_id the page ID |
|
472 * @param $namespace the namespace |
|
473 * @return string |
|
474 */ |
|
475 |
|
476 function histlist($page_id, $namespace) |
|
477 { |
|
478 global $db, $session, $paths, $template, $plugins; // Common objects |
|
479 |
|
480 if(!$session->get_permissions('history_view')) |
|
481 return 'Access denied'; |
|
482 |
|
483 ob_start(); |
|
484 |
|
485 $pname = $paths->nslist[$namespace] . $page_id; |
|
486 $wiki = ( ( $paths->pages[$pname]['wiki_mode'] == 2 && getConfig('wiki_mode') == '1') || $paths->pages[$pname]['wiki_mode'] == 1) ? true : false; |
|
487 $prot = ( ( $paths->pages[$pname]['protected'] == 2 && $session->user_logged_in && $session->reg_time + 60*60*24*4 < time() ) || $paths->pages[$pname]['protected'] == 1) ? true : false; |
|
488 |
|
489 $q = 'SELECT time_id,date_string,page_id,namespace,author,edit_summary,minor_edit FROM '.table_prefix.'logs WHERE log_type=\'page\' AND action=\'edit\' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' ORDER BY time_id DESC;'; |
|
490 if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.'); |
|
491 echo 'History of edits and actions<h3>Edits:</h3>'; |
|
492 $numrows = $db->numrows(); |
|
493 if($numrows < 1) echo 'No history entries in this category.'; |
|
494 else |
|
495 { |
|
496 |
|
497 echo '<form action="'.makeUrlNS($namespace, $page_id, 'do=diff').'" onsubmit="ajaxHistDiff(); return false;" method="get"> |
|
498 <input type="submit" value="Compare selected revisions" /> |
|
499 <br /><span> </span> |
|
500 <div class="tblholder"> |
|
501 <table border="0" width="100%" cellspacing="1" cellpadding="4"> |
|
502 <tr> |
|
503 <th colspan="2">Diff</th> |
|
504 <th>Date/time</th> |
|
505 <th>User</th> |
|
506 <th>Edit summary</th> |
|
507 <th>Minor</th> |
|
508 <th colspan="3">Actions</th> |
|
509 </tr>'."\n"."\n"; |
|
510 $cls = 'row2'; |
|
511 $ticker = 0; |
|
512 |
|
513 while($r = $db->fetchrow()) { |
|
514 |
|
515 $ticker++; |
|
516 |
|
517 if($cls == 'row2') $cls = 'row1'; |
|
518 else $cls = 'row2'; |
|
519 |
|
520 echo '<tr>'."\n"; |
|
521 |
|
522 // Diff selection |
|
523 if($ticker == 1) |
|
524 { |
|
525 $s1 = ''; |
|
526 $s2 = 'checked="checked" '; |
|
527 } |
|
528 elseif($ticker == 2) |
|
529 { |
|
530 $s1 = 'checked="checked" '; |
|
531 $s2 = ''; |
|
532 } |
|
533 else |
|
534 { |
|
535 $s1 = ''; |
|
536 $s2 = ''; |
|
537 } |
|
538 if($ticker > 1) echo '<td class="'.$cls.'" style="padding: 0;"><input '.$s1.'name="diff1" type="radio" value="'.$r['time_id'].'" id="diff1_'.$r['time_id'].'" class="clsDiff1Radio" onclick="selectDiff1Button(this);" /></td>'."\n"; else echo '<td class="'.$cls.'"></td>'; |
|
539 if($ticker < $numrows) echo '<td class="'.$cls.'" style="padding: 0;"><input '.$s2.'name="diff2" type="radio" value="'.$r['time_id'].'" id="diff2_'.$r['time_id'].'" class="clsDiff2Radio" onclick="selectDiff2Button(this);" /></td>'."\n"; else echo '<td class="'.$cls.'"></td>'; |
|
540 |
|
541 // Date and time |
|
542 echo '<td class="'.$cls.'">'.$r['date_string'].'</td class="'.$cls.'">'."\n"; |
|
543 |
|
544 // User |
|
545 if($session->get_permissions('mod_misc') && preg_match('#^([0-9]*){1,3}\.([0-9]*){1,3}\.([0-9]*){1,3}\.([0-9]*){1,3}$#', $r['author'])) $rc = ' style="cursor: pointer;" title="Click cell background for reverse DNS info" onclick="ajaxReverseDNS(this, \''.$r['author'].'\');"'; |
|
546 else $rc = ''; |
|
547 echo '<td class="'.$cls.'"'.$rc.'><a href="'.makeUrlNS('User', $r['author']).'" '; |
|
548 if(!isPage($paths->nslist['User'] . $r['author'])) echo 'class="wikilink-nonexistent"'; |
|
549 echo '>'.$r['author'].'</a></td class="'.$cls.'">'."\n"; |
|
550 |
|
551 // Edit summary |
|
552 echo '<td class="'.$cls.'">'.$r['edit_summary'].'</td>'."\n"; |
|
553 |
|
554 // Minor edit |
|
555 echo '<td class="'.$cls.'" style="text-align: center;">'. (( $r['minor_edit'] ) ? 'M' : '' ) .'</td>'."\n"; |
|
556 |
|
557 // Actions! |
|
558 echo '<td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS($namespace, $page_id, 'oldid='.$r['time_id']).'" onclick="ajaxHistView(\''.$r['time_id'].'\'); return false;">View revision</a></td>'."\n"; |
|
559 echo '<td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrl($paths->nslist['Special'].'Contributions/'.$r['author']).'">View user contribs</a></td>'."\n"; |
|
560 echo '<td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS($namespace, $page_id, 'do=rollback&id='.$r['time_id']).'" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">Revert to this revision</a></td>'."\n"; |
|
561 |
|
562 echo '</tr>'."\n"."\n"; |
|
563 |
|
564 } |
|
565 echo '</table> |
|
566 </div> |
|
567 <br /> |
|
568 <input type="hidden" name="do" value="diff" /> |
|
569 <input type="submit" value="Compare selected revisions" /> |
|
570 </form> |
|
571 <script type="text/javascript">buildDiffList();</script>'; |
|
572 } |
|
573 $db->free_result(); |
|
574 echo '<h3>Other changes:</h3>'; |
|
575 $q = 'SELECT time_id,action,date_string,page_id,namespace,author,edit_summary,minor_edit FROM '.table_prefix.'logs WHERE log_type=\'page\' AND action!=\'edit\' AND page_id=\''.$paths->cpage['urlname_nons'].'\' AND namespace=\''.$paths->namespace.'\' ORDER BY time_id DESC;'; |
|
576 if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.'); |
|
577 if($db->numrows() < 1) echo 'No history entries in this category.'; |
|
578 else { |
|
579 |
|
580 echo '<div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4"><tr><th>Date/time</th><th>User</th><th>Minor</th><th>Action taken</th><th>Extra info</th><th colspan="2"></th></tr>'; |
|
581 $cls = 'row2'; |
|
582 while($r = $db->fetchrow()) { |
|
583 |
|
584 if($cls == 'row2') $cls = 'row1'; |
|
585 else $cls = 'row2'; |
|
586 |
|
587 echo '<tr>'; |
|
588 |
|
589 // Date and time |
|
590 echo '<td class="'.$cls.'">'.$r['date_string'].'</td class="'.$cls.'">'; |
|
591 |
|
592 // User |
|
593 echo '<td class="'.$cls.'"><a href="'.makeUrlNS('User', $r['author']).'" '; |
|
594 if(!isPage($paths->nslist['User'] . $r['author'])) echo 'class="wikilink-nonexistent"'; |
|
595 echo '>'.$r['author'].'</a></td class="'.$cls.'">'; |
|
596 |
|
597 |
|
598 // Minor edit |
|
599 echo '<td class="'.$cls.'" style="text-align: center;">'. (( $r['minor_edit'] ) ? 'M' : '' ) .'</td>'; |
|
600 |
|
601 // Action taken |
|
602 echo '<td class="'.$cls.'">'; |
|
603 if ($r['action']=='prot') echo 'Protected page</td><td class="'.$cls.'">Reason: '.$r['edit_summary']; |
|
604 elseif($r['action']=='unprot') echo 'Unprotected page</td><td class="'.$cls.'">Reason: '.$r['edit_summary']; |
|
605 elseif($r['action']=='semiprot') echo 'Semi-protected page</td><td class="'.$cls.'">Reason: '.$r['edit_summary']; |
|
606 elseif($r['action']=='rename') echo 'Renamed page</td><td class="'.$cls.'">Old title: '.$r['edit_summary']; |
|
607 elseif($r['action']=='create') echo 'Created page</td><td class="'.$cls.'">'; |
|
608 elseif($r['action']=='delete') echo 'Deleted page</td><td class="'.$cls.'">'; |
|
609 elseif($r['action']=='reupload') echo 'Uploaded new file version</td><td class="'.$cls.'">Reason: '.$r['edit_summary']; |
|
610 echo '</td>'; |
|
611 |
|
612 // Actions! |
|
613 echo '<td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrl($paths->nslist['Special'].'Contributions/'.$r['author']).'">View user contribs</a></td>'; |
|
614 echo '<td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS($namespace, $page_id, 'do=rollback&id='.$r['time_id']).'" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">Revert action</a></td>'; |
|
615 |
|
616 //echo '(<a href="#" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">rollback</a>) <i>'.$r['date_string'].'</i> '.$r['author'].' (<a href="'.makeUrl($paths->nslist['User'].$r['author']).'">Userpage</a>, <a href="'.makeUrl($paths->nslist['Special'].'Contributions/'.$r['author']).'">Contrib</a>): '; |
|
617 |
|
618 if($r['minor_edit']) echo '<b> - minor edit</b>'; |
|
619 echo '<br />'; |
|
620 |
|
621 echo '</tr>'; |
|
622 } |
|
623 echo '</table></div>'; |
|
624 } |
|
625 $db->free_result(); |
|
626 $ret = ob_get_contents(); |
|
627 ob_end_clean(); |
|
628 return $ret; |
|
629 } |
|
630 |
|
631 /** |
|
632 * Rolls back a logged action |
|
633 * @param $id the time ID, a.k.a. the primary key in the logs table |
|
634 * @return string |
|
635 */ |
|
636 |
|
637 function rollback($id) |
|
638 { |
|
639 global $db, $session, $paths, $template, $plugins; // Common objects |
|
640 if(!$session->get_permissions('history_rollback')) return('You are not authorized to perform rollbacks.'); |
|
641 if(!preg_match('#^([0-9]+)$#', (string)$id)) return('The value "id" on the query string must be an integer.'); |
|
642 $e = $db->sql_query('SELECT log_type,action,date_string,page_id,namespace,page_text,char_tag,author,edit_summary FROM '.table_prefix.'logs WHERE time_id='.$id.';'); |
|
643 if(!$e) $db->_die('The rollback data could not be selected.'); |
|
644 $rb = $db->fetchrow(); |
|
645 $db->free_result(); |
|
646 switch($rb['log_type']) { |
|
647 case "page": |
|
648 switch($rb['action']) { |
|
649 case "edit": |
|
650 $t = $db->escape($rb['page_text']); |
|
651 $e = $db->sql_query('UPDATE '.table_prefix.'page_text SET page_text=\''.$t.'\',char_tag=\''.$rb['char_tag'].'\' WHERE page_id=\''.$rb['page_id'].'\' AND namespace=\''.$rb['namespace'].'\''); |
|
652 if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); |
|
653 else return('The page "'.$paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been rolled back to the state it was in on '.$rb['date_string'].'.'); |
|
654 break; |
|
655 case "rename": |
|
656 $t = $db->escape($rb['edit_summary']); |
|
657 $e = $db->sql_query('UPDATE '.table_prefix.'pages SET name=\''.$t.'\' WHERE urlname=\''.$rb['page_id'].'\' AND namespace=\''.$rb['namespace'].'\''); |
|
658 if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); |
|
659 else return('The page "'.$paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been rolled back to the name it had ("'.$rb['edit_summary'].'") before '.$rb['date_string'].'.'); |
|
660 break; |
|
661 case "prot": |
|
662 $e = $db->sql_query('UPDATE '.table_prefix.'pages SET protected=0 WHERE urlname=\''.$rb['page_id'].'\' AND namespace=\''.$rb['namespace'].'\''); |
|
663 if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); |
|
664 else return('The page "'.$paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been unprotected according to the log created at '.$rb['date_string'].'.'); |
|
665 break; |
|
666 case "semiprot": |
|
667 $e = $db->sql_query('UPDATE '.table_prefix.'pages SET protected=0 WHERE urlname=\''.$rb['page_id'].'\' AND namespace=\''.$rb['namespace'].'\''); |
|
668 if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); |
|
669 else return('The page "'.$paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been unprotected according to the log created at '.$rb['date_string'].'.'); |
|
670 break; |
|
671 case "unprot": |
|
672 $e = $db->sql_query('UPDATE '.table_prefix.'pages SET protected=1 WHERE urlname=\''.$rb['page_id'].'\' AND namespace=\''.$rb['namespace'].'\''); |
|
673 if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); |
|
674 else return('The page "'.$paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been protected according to the log created at '.$rb['date_string'].'.'); |
|
675 break; |
|
676 case "delete": |
|
677 if(!$session->get_permissions('history_rollback_extra')) return('Administrative privileges are required for page undeletion.'); |
|
678 if(isset($paths->pages[$paths->cpage['urlname']])) return('You cannot raise a dead page that is alive.'); |
|
679 $name = str_replace('_', ' ', $rb['page_id']); |
|
680 $e = $db->sql_query('INSERT INTO '.table_prefix.'pages(name,urlname,namespace) VALUES( \''.$name.'\', \''.$rb['page_id'].'\',\''.$rb['namespace'].'\' )');if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); |
|
681 $e = $db->sql_query('SELECT page_text,char_tag FROM '.table_prefix.'logs WHERE page_id=\''.$rb['page_id'].'\' AND namespace=\''.$rb['namespace'].'\' AND log_type=\'page\' AND action=\'edit\' ORDER BY time_id DESC;'); if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); |
|
682 $r = $db->fetchrow(); |
|
683 $e = $db->sql_query('INSERT INTO '.table_prefix.'page_text(page_id,namespace,page_text,char_tag) VALUES(\''.$rb['page_id'].'\',\''.$rb['namespace'].'\',\''.$db->escape($r['page_text']).'\',\''.$r['char_tag'].'\')'); if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); |
|
684 return('The page "'.$name.'" has been undeleted according to the log created at '.$rb['date_string'].'.'); |
|
685 break; |
|
686 case "reupload": |
|
687 if(!$session->get_permissions('history_rollbacks_extra')) return('Administrative privileges are required for file rollbacks.'); |
|
688 $newtime = time(); |
|
689 $newdate = date('d M Y h:i a'); |
|
690 if(!$db->sql_query('UPDATE '.table_prefix.'logs SET time_id='.$newtime.',date_string=\''.$newdate.'\' WHERE time_id='.$id)) return('Error during query: '.mysql_error()); |
|
691 if(!$db->sql_query('UPDATE '.table_prefix.'files SET time_id='.$newtime.' WHERE time_id='.$id)) return('Error during query: '.mysql_error()); |
|
692 return('The file has been rolled back to the version uploaded on '.date('d M Y h:i a', (int)$id).'.'); |
|
693 break; |
|
694 default: |
|
695 return('Rollback of the action "'.$rb['action'].'" is not yet supported.'); |
|
696 break; |
|
697 } |
|
698 break; |
|
699 case "security": |
|
700 case "login": |
|
701 return('A '.$rb['log_type'].'-related log entry cannot be rolled back.'); |
|
702 break; |
|
703 default: |
|
704 return('Unknown log entry type: "'.$rb['log_type'].'"'); |
|
705 } |
|
706 } |
|
707 |
|
708 /** |
|
709 * Posts a comment. |
|
710 * @param $page_id the page ID |
|
711 * @param $namespace the namespace |
|
712 * @param $name the name of the person posting, defaults to current username/IP |
|
713 * @param $subject the subject line of the comment |
|
714 * @param $text the comment text |
|
715 * @return string javascript code |
|
716 */ |
|
717 |
|
718 function addcomment($page_id, $namespace, $name, $subject, $text, $captcha_code = false, $captcha_id = false) |
|
719 { |
|
720 global $db, $session, $paths, $template, $plugins; // Common objects |
|
721 $_ob = ''; |
|
722 if(!$session->get_permissions('post_comments')) |
|
723 return 'Access denied'; |
|
724 if(getConfig('comments_need_login') == '2' && !$session->user_logged_in) _die('Access denied to post comments: you need to be logged in first.'); |
|
725 if(getConfig('comments_need_login') == '1' && !$session->user_logged_in) |
|
726 { |
|
727 if(!$captcha_code || !$captcha_id) _die('BUG: PageUtils::addcomment: no CAPTCHA data passed to method'); |
|
728 $result = $session->get_captcha($captcha_id); |
|
729 if($captcha_code != $result) _die('The confirmation code you entered was incorrect.'); |
|
730 } |
|
731 $text = RenderMan::preprocess_text($text); |
|
732 $name = $session->user_logged_in ? RenderMan::preprocess_text($session->username) : RenderMan::preprocess_text($name); |
|
733 $subj = RenderMan::preprocess_text($subject); |
|
734 if(getConfig('approve_comments')=='1') $appr = '0'; else $appr = '1'; |
|
735 $q = 'INSERT INTO '.table_prefix.'comments(page_id,namespace,subject,comment_data,name,user_id,approved,time) VALUES(\''.$page_id.'\',\''.$namespace.'\',\''.$subj.'\',\''.$text.'\',\''.$name.'\','.$session->user_id.','.$appr.','.time().')'; |
|
736 $e = $db->sql_query($q); |
|
737 if(!$e) die('alert(unescape(\''.rawurlencode('Error inserting comment data: '.mysql_error().'\n\nQuery:\n'.$q).'\'))'); |
|
738 else $_ob .= '<div class="info-box">Your comment has been posted.</div>'; |
|
739 return PageUtils::comments($page_id, $namespace, false, Array(), $_ob); |
|
740 } |
|
741 |
|
742 /** |
|
743 * Generates partly-compiled HTML/Javascript code to be eval'ed by the user's browser to display comments |
|
744 * @param $page_id the page ID |
|
745 * @param $namespace the namespace |
|
746 * @param $action administrative action to perform, default is false |
|
747 * @param $flags additional info for $action, shouldn't be used except when deleting/approving comments, etc. |
|
748 * @param $_ob text to prepend to output, used by PageUtils::addcomment |
|
749 * @return array |
|
750 * @access private |
|
751 */ |
|
752 |
|
753 function comments_raw($page_id, $namespace, $action = false, $flags = Array(), $_ob = '') |
|
754 { |
|
755 global $db, $session, $paths, $template, $plugins; // Common objects |
|
756 |
|
757 $pname = $paths->nslist[$namespace] . $page_id; |
|
758 |
|
759 ob_start(); |
|
760 |
|
761 if($action && $session->get_permissions('mod_comments')) // Nip hacking attempts in the bud |
|
762 { |
|
763 switch($action) { |
|
764 case "delete": |
|
765 if(isset($flags['id'])) |
|
766 { |
|
767 $q = 'DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND comment_id='.intval($flags['id']).' LIMIT 1;'; |
|
768 } else { |
|
769 $n = $db->escape($flags['name']); |
|
770 $s = $db->escape($flags['subj']); |
|
771 $t = $db->escape($flags['text']); |
|
772 $q = 'DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND name=\''.$n.'\' AND subject=\''.$s.'\' AND comment_data=\''.$t.'\' LIMIT 1;'; |
|
773 } |
|
774 $e=$db->sql_query($q); |
|
775 if(!$e) die('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n'.$q).'\'));'); |
|
776 break; |
|
777 case "approve": |
|
778 if(isset($flags['id'])) |
|
779 { |
|
780 $where = 'comment_id='.intval($flags['id']); |
|
781 } else { |
|
782 $n = $db->escape($flags['name']); |
|
783 $s = $db->escape($flags['subj']); |
|
784 $t = $db->escape($flags['text']); |
|
785 $where = 'name=\''.$n.'\' AND subject=\''.$s.'\' AND comment_data=\''.$t.'\''; |
|
786 } |
|
787 $q = 'SELECT approved FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND '.$where.' LIMIT 1;'; |
|
788 $e = $db->sql_query($q); |
|
789 if(!$e) die('alert(unesape(\''.rawurlencode('Error selecting approval status: '.mysql_error().'\n\nQuery:\n'.$q).'\'));'); |
|
790 $r = $db->fetchrow(); |
|
791 $db->free_result(); |
|
792 $a = ( $r['approved'] ) ? '0' : '1'; |
|
793 $q = 'UPDATE '.table_prefix.'comments SET approved='.$a.' WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND '.$where.';'; |
|
794 $e=$db->sql_query($q); |
|
795 if(!$e) die('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n'.$q).'\'));'); |
|
796 if($a=='1') $v = 'Unapprove'; |
|
797 else $v = 'Approve'; |
|
798 echo 'document.getElementById("mdgApproveLink'.$_GET['id'].'").innerHTML="'.$v.'";'; |
|
799 break; |
|
800 } |
|
801 } |
|
802 |
|
803 if(!defined('ENANO_TEMPLATE_LOADED')) |
|
804 { |
|
805 $template->load_theme($session->theme, $session->style); |
|
806 } |
|
807 |
|
808 $tpl = $template->makeParser('comment.tpl'); |
|
809 |
|
810 $e = $db->sql_query('SELECT * FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND approved=0;'); |
|
811 if(!$e) $db->_die('The comment text data could not be selected.'); |
|
812 $num_unapp = $db->numrows(); |
|
813 $db->free_result(); |
|
814 $e = $db->sql_query('SELECT * FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND approved=1;'); |
|
815 if(!$e) $db->_die('The comment text data could not be selected.'); |
|
816 $num_app = $db->numrows(); |
|
817 $db->free_result(); |
|
818 $lq = $db->sql_query('SELECT c.comment_id,c.subject,c.name,c.comment_data,c.approved,c.time,c.user_id,u.user_level,u.signature |
|
819 FROM '.table_prefix.'comments AS c |
|
820 LEFT JOIN '.table_prefix.'users AS u |
|
821 ON c.user_id=u.user_id |
|
822 WHERE page_id=\''.$page_id.'\' |
|
823 AND namespace=\''.$namespace.'\' ORDER BY c.time ASC;'); |
|
824 if(!$lq) _die('The comment text data could not be selected. '.mysql_error()); |
|
825 $_ob .= '<h3>Article Comments</h3>'; |
|
826 $n = ( $session->get_permissions('mod_comments')) ? $db->numrows() : $num_app; |
|
827 if($n==1) $s = 'is '.$n.' comment'; else $s = 'are '.$n.' comments'; |
|
828 if($n < 1) |
|
829 { |
|
830 $_ob .= '<p>There are currently no comments on this '.strtolower($namespace).''; |
|
831 if($namespace != 'Article') $_ob .= ' page'; |
|
832 $_ob .= '.</p>'; |
|
833 } else $_ob .= '<p>There '.$s.' on this article.</p>'; |
|
834 if($session->get_permissions('mod_comments') && $num_unapp > 0) $_ob .= ' <span style="color: #D84308">'.$num_unapp.' of those are unapproved.</span>'; |
|
835 elseif(!$session->get_permissions('mod_comments') && $num_unapp > 0) { $u = ($num_unapp == 1) ? "is $num_unapp comment" : "are $num_unapp comments"; $_ob .= ' However, there ' . $u . ' awating approval.'; } |
|
836 $list = 'list = { '; |
|
837 // _die(htmlspecialchars($ttext)); |
|
838 $i = -1; |
|
839 while($row = $db->fetchrow($lq)) |
|
840 { |
|
841 $i++; |
|
842 $strings = Array(); |
|
843 $bool = Array(); |
|
844 if($session->get_permissions('mod_comments') || $row['approved']) { |
|
845 $list .= $i . ' : { \'comment\' : unescape(\''.rawurlencode($row['comment_data']).'\'), \'name\' : unescape(\''.rawurlencode($row['name']).'\'), \'subject\' : unescape(\''.rawurlencode($row['subject']).'\'), }, '; |
|
846 |
|
847 // Comment ID (used in the Javascript apps) |
|
848 $strings['ID'] = (string)$i; |
|
849 |
|
850 // Determine the name, and whether to link to the user page or not |
|
851 $name = ''; |
|
852 if($row['user_id'] > 0) $name .= '<a href="'.makeUrlNS('User', str_replace(' ', '_', $row['name'])).'">'; |
|
853 $name .= $row['name']; |
|
854 if($row['user_id'] > 0) $name .= '</a>'; |
|
855 $strings['NAME'] = $name; unset($name); |
|
856 |
|
857 // Subject |
|
858 $s = $row['subject']; |
|
859 if(!$row['approved']) $s .= ' <span style="color: #D84308">(Unapproved)</span>'; |
|
860 $strings['SUBJECT'] = $s; |
|
861 |
|
862 // Date and time |
|
863 $strings['DATETIME'] = date('F d, Y h:i a', $row['time']); |
|
864 |
|
865 // User level |
|
866 switch($row['user_level']) |
|
867 { |
|
868 default: |
|
869 case USER_LEVEL_GUEST: |
|
870 $l = 'Guest'; |
|
871 break; |
|
872 case USER_LEVEL_MEMBER: |
|
873 $l = 'Member'; |
|
874 break; |
|
875 case USER_LEVEL_MOD: |
|
876 $l = 'Moderator'; |
|
877 break; |
|
878 case USER_LEVEL_ADMIN: |
|
879 $l = 'Administrator'; |
|
880 break; |
|
881 } |
|
882 $strings['USER_LEVEL'] = $l; unset($l); |
|
883 |
|
884 // The actual comment data |
|
885 $strings['DATA'] = RenderMan::render($row['comment_data']); |
|
886 |
|
887 if($session->get_permissions('edit_comments')) |
|
888 { |
|
889 // Edit link |
|
890 $strings['EDIT_LINK'] = '<a href="'.makeUrlNS($namespace, $page_id, 'do=comments&sub=editcomment&id='.$row['comment_id']).'" onclick="editComment(\''.$i.'\'); return false;" id="editbtn_'.$i.'">edit</a>'; |
|
891 |
|
892 // Delete link |
|
893 $strings['DELETE_LINK'] = '<a href="'.makeUrlNS($namespace, $page_id, 'do=comments&sub=deletecomment&id='.$row['comment_id']).'" onclick="ajaxDeleteComment(\''.$i.'\'); return false;">delete</a>'; |
|
894 } |
|
895 else |
|
896 { |
|
897 // Edit link |
|
898 $strings['EDIT_LINK'] = ''; |
|
899 |
|
900 // Delete link |
|
901 $strings['DELETE_LINK'] = ''; |
|
902 } |
|
903 |
|
904 // Send PM link |
|
905 $strings['SEND_PM_LINK'] = ( $session->user_logged_in && $row['user_id'] > 0 ) ? '<a href="'.makeUrlNS('Special', 'PrivateMessages/Compose/To/'.$row['name']).'">Send private message</a><br />' : ''; |
|
906 |
|
907 // Add Buddy link |
|
908 $strings['ADD_BUDDY_LINK'] = ( $session->user_logged_in && $row['user_id'] > 0 ) ? '<a href="'.makeUrlNS('Special', 'PrivateMessages/FriendList/Add/'.$row['name']).'">Add to buddy list</a>' : ''; |
|
909 |
|
910 // Mod links |
|
911 $applink = ''; |
|
912 $applink .= '<a href="'.makeUrlNS($namespace, $page_id, 'do=comments&sub=admin&action=approve&id='.$row['comment_id']).'" onclick="ajaxCommentAdmin(\'approve\', \''.$i.'\'); return false;" id="mdgApproveLink'.$i.'">'; |
|
913 if($row['approved']) $applink .= 'Unapprove'; |
|
914 else $applink .= 'Approve'; |
|
915 $applink .= '</a>'; |
|
916 $strings['MOD_APPROVE_LINK'] = $applink; unset($applink); |
|
917 $strings['MOD_DELETE_LINK'] = '<a href="'.makeUrlNS($namespace, $page_id, 'do=comments&sub=admin&action=delete&id='.$row['comment_id']).'" onclick="ajaxCommentAdmin(\'delete\', \''.$i.'\'); return false;">Delete</a>'; |
|
918 |
|
919 // Signature |
|
920 $strings['SIGNATURE'] = ''; |
|
921 if($row['signature'] != '') $strings['SIGNATURE'] = RenderMan::render($row['signature']); |
|
922 |
|
923 $bool['auth_mod'] = ($session->get_permissions('mod_comments')) ? true : false; |
|
924 $bool['can_edit'] = ( ( $session->user_logged_in && $row['name'] == $session->username && $session->get_permissions('edit_comments') ) || $session->get_permissions('mod_comments') ) ? true : false; |
|
925 $bool['signature'] = ( $strings['SIGNATURE'] == '' ) ? false : true; |
|
926 |
|
927 // Done processing and compiling, now let's cook it into HTML |
|
928 $tpl->assign_vars($strings); |
|
929 $tpl->assign_bool($bool); |
|
930 $_ob .= $tpl->run(); |
|
931 } |
|
932 } |
|
933 if(getConfig('comments_need_login') != '2' || $session->user_logged_in) |
|
934 { |
|
935 if(!$session->get_permissions('post_comments')) |
|
936 { |
|
937 $_ob .= '<h3>Got something to say?</h3><p>Access to post comments on this page is denied.</p>'; |
|
938 } |
|
939 else |
|
940 { |
|
941 $_ob .= '<h3>Got something to say?</h3>If you have comments or suggestions on this article, you can shout it out here.'; |
|
942 if(getConfig('approve_comments')=='1') $_ob .= ' Before your comment will be visible to the public, a moderator will have to approve it.'; |
|
943 if(getConfig('comments_need_login') == '1' && !$session->user_logged_in) $_ob .= ' Because you are not logged in, you will need to enter a visual confirmation before your comment will be posted.'; |
|
944 $sn = $session->user_logged_in ? $session->username . '<input name="name" id="mdgScreenName" type="hidden" value="'.$session->username.'" />' : '<input name="name" id="mdgScreenName" type="text" size="35" />'; |
|
945 $_ob .= ' <a href="#" id="mdgCommentFormLink" style="display: none;" onclick="document.getElementById(\'mdgCommentForm\').style.display=\'block\';this.style.display=\'none\';return false;">Leave a comment...</a> |
|
946 <div id="mdgCommentForm"> |
|
947 <h3>Comment form</h3> |
|
948 <form action="'.makeUrlNS($namespace, $page_id, 'do=comments&sub=postcomment').'" method="post" style="margin-left: 1em"> |
|
949 <table border="0"> |
|
950 <tr><td>Your name or screen name:</td><td>'.$sn.'</td></tr> |
|
951 <tr><td>Comment subject:</td><td><input name="subj" id="mdgSubject" type="text" size="35" /></td></tr>'; |
|
952 if(getConfig('comments_need_login') == '1' && !$session->user_logged_in) |
|
953 { |
|
954 $session->kill_captcha(); |
|
955 $captcha = $session->make_captcha(); |
|
956 $_ob .= '<tr><td>Visual confirmation:<br /><small>Please enter the code you see on the right.</small></td><td><img src="'.makeUrlNS('Special', 'Captcha/'.$captcha).'" alt="Visual confirmation" style="cursor: pointer;" onclick="this.src = \''.makeUrlNS("Special", "Captcha/".$captcha).'/\'+Math.floor(Math.random() * 100000);" /><input name="captcha_id" id="mdgCaptchaID" type="hidden" value="'.$captcha.'" /><br />Code: <input name="captcha_input" id="mdgCaptchaInput" type="text" size="10" /><br /><small><script type="text/javascript">document.write("If you can\'t read the code, click on the image to generate a new one.");</script><noscript>If you can\'t read the code, please refresh this page to generate a new one.</noscript></small></td></tr>'; |
|
957 } |
|
958 $_ob .= ' |
|
959 <tr><td valign="top">Comment text:<br />(most HTML will be stripped)</td><td><textarea name="text" id="mdgCommentArea" rows="10" cols="40"></textarea></td></tr> |
|
960 <tr><td colspan="2" style="text-align: center;"><input type="submit" value="Submit Comment" /></td></tr> |
|
961 </table> |
|
962 </form> |
|
963 </div>'; |
|
964 } |
|
965 } else { |
|
966 $_ob .= '<h3>Got something to say?</h3><p>You need to be logged in to post comments. <a href="'.makeUrlNS('Special', 'Login/'.$pname.'%2523comments').'">Log in</a></p>'; |
|
967 } |
|
968 $list .= '};'; |
|
969 echo 'document.getElementById(\'ajaxEditContainer\').innerHTML = unescape(\''. rawurlencode($_ob) .'\'); |
|
970 ' . $list; |
|
971 echo 'Fat.fade_all(); document.getElementById(\'mdgCommentForm\').style.display = \'none\'; document.getElementById(\'mdgCommentFormLink\').style.display="inline";'; |
|
972 |
|
973 $ret = ob_get_contents(); |
|
974 ob_end_clean(); |
|
975 return Array($ret, $_ob); |
|
976 |
|
977 } |
|
978 |
|
979 /** |
|
980 * Generates ready-to-execute Javascript code to be eval'ed by the user's browser to display comments |
|
981 * @param $page_id the page ID |
|
982 * @param $namespace the namespace |
|
983 * @param $action administrative action to perform, default is false |
|
984 * @param $flags additional info for $action, shouldn't be used except when deleting/approving comments, etc. |
|
985 * @param $_ob text to prepend to output, used by PageUtils::addcomment |
|
986 * @return string |
|
987 */ |
|
988 |
|
989 function comments($page_id, $namespace, $action = false, $id = -1, $_ob = '') |
|
990 { |
|
991 global $db, $session, $paths, $template, $plugins; // Common objects |
|
992 $r = PageUtils::comments_raw($page_id, $namespace, $action, $id, $_ob); |
|
993 return $r[0]; |
|
994 } |
|
995 |
|
996 /** |
|
997 * Generates HTML code for comments - used in browser compatibility mode |
|
998 * @param $page_id the page ID |
|
999 * @param $namespace the namespace |
|
1000 * @param $action administrative action to perform, default is false |
|
1001 * @param $flags additional info for $action, shouldn't be used except when deleting/approving comments, etc. |
|
1002 * @param $_ob text to prepend to output, used by PageUtils::addcomment |
|
1003 * @return string |
|
1004 */ |
|
1005 |
|
1006 function comments_html($page_id, $namespace, $action = false, $id = -1, $_ob = '') |
|
1007 { |
|
1008 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1009 $r = PageUtils::comments_raw($page_id, $namespace, $action, $id, $_ob); |
|
1010 return $r[1]; |
|
1011 } |
|
1012 |
|
1013 /** |
|
1014 * Updates comment data. |
|
1015 * @param $page_id the page ID |
|
1016 * @param $namespace the namespace |
|
1017 * @param $subject new subject |
|
1018 * @param $text new text |
|
1019 * @param $old_subject the old subject, unprocessed and identical to the value in the DB |
|
1020 * @param $old_text the old text, unprocessed and identical to the value in the DB |
|
1021 * @param $id the javascript list ID, used internally by the client-side app |
|
1022 * @return string |
|
1023 */ |
|
1024 |
|
1025 function savecomment($page_id, $namespace, $subject, $text, $old_subject, $old_text, $id = -1) |
|
1026 { |
|
1027 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1028 if(!$session->get_permissions('edit_comments')) |
|
1029 return 'result="BAD";error="Access denied"'; |
|
1030 // Avoid SQL injection |
|
1031 $old_text = $db->escape($old_text); |
|
1032 $old_subject = $db->escape($old_subject); |
|
1033 // Safety check - username/login |
|
1034 if(!$session->get_permissions('mod_comments')) // allow mods to edit comments |
|
1035 { |
|
1036 if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.<br /><br />Please log in and try again.'); |
|
1037 $q = 'SELECT c.name FROM '.table_prefix.'comments c, '.table_prefix.'users u WHERE comment_data=\''.$old_text.'\' AND subject=\''.$old_subject.'\' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND u.user_id=c.user_id;'; |
|
1038 $s = $db->sql_query($q); |
|
1039 if(!$s) _die('SQL error during safety check: '.mysql_error().'<br /><br />Attempted SQL:<br /><pre>'.htmlspecialchars($q).'</pre>'); |
|
1040 $r = $db->fetchrow($s); |
|
1041 $db->free_result(); |
|
1042 if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); |
|
1043 } |
|
1044 $s = RenderMan::preprocess_text($subject); |
|
1045 $t = RenderMan::preprocess_text($text); |
|
1046 $sql = 'UPDATE '.table_prefix.'comments SET subject=\''.$s.'\',comment_data=\''.$t.'\' WHERE comment_data=\''.$old_text.'\' AND subject=\''.$old_subject.'\' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''; |
|
1047 $result = $db->sql_query($sql); |
|
1048 if($result) |
|
1049 { |
|
1050 return 'result="GOOD"; |
|
1051 list['.$id.'][\'subject\'] = unescape(\''.str_replace('%5Cn', '%0A', rawurlencode(str_replace('{{EnAnO:Newline}}', '\\n', stripslashes(str_replace('\\n', '{{EnAnO:Newline}}', $s))))).'\'); |
|
1052 list['.$id.'][\'comment\'] = unescape(\''.str_replace('%5Cn', '%0A', rawurlencode(str_replace('{{EnAnO:Newline}}', '\\n', stripslashes(str_replace('\\n', '{{EnAnO:Newline}}', $t))))).'\'); id = '.$id.'; |
|
1053 s = unescape(\''.rawurlencode($s).'\'); |
|
1054 t = unescape(\''.str_replace('%5Cn', '<br \\/>', rawurlencode(RenderMan::render(str_replace('{{EnAnO:Newline}}', "\n", stripslashes(str_replace('\\n', '{{EnAnO:Newline}}', $t)))))).'\');'; |
|
1055 } |
|
1056 else |
|
1057 { |
|
1058 return 'result="BAD"; error=unescape("'.rawurlencode('Enano encountered a problem whilst saving the comment. |
|
1059 Performed SQL: |
|
1060 '.$sql.' |
|
1061 |
|
1062 Error returned by MySQL: '.mysql_error()).'");'; |
|
1063 } |
|
1064 } |
|
1065 |
|
1066 /** |
|
1067 * Updates comment data using the comment_id column instead of the old, messy way |
|
1068 * @param $page_id the page ID |
|
1069 * @param $namespace the namespace |
|
1070 * @param $subject new subject |
|
1071 * @param $text new text |
|
1072 * @param $id the comment ID (primary key in enano_comments table) |
|
1073 * @return string |
|
1074 */ |
|
1075 |
|
1076 function savecomment_neater($page_id, $namespace, $subject, $text, $id) |
|
1077 { |
|
1078 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1079 if(!is_int($id)) die('PageUtils::savecomment: $id is not an integer, aborting for safety'); |
|
1080 if(!$session->get_permissions('edit_comments')) |
|
1081 return 'Access denied'; |
|
1082 // Safety check - username/login |
|
1083 if(!$session->get_permissions('mod_comments')) // allow mods to edit comments |
|
1084 { |
|
1085 if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.<br /><br />Please log in and try again.'); |
|
1086 $q = 'SELECT c.name FROM '.table_prefix.'comments c, '.table_prefix.'users u WHERE comment_id='.$id.' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND u.user_id=c.user_id;'; |
|
1087 $s = $db->sql_query($q); |
|
1088 if(!$s) _die('SQL error during safety check: '.mysql_error().'<br /><br />Attempted SQL:<br /><pre>'.htmlspecialchars($q).'</pre>'); |
|
1089 $r = $db->fetchrow($s); |
|
1090 if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); |
|
1091 $db->free_result(); |
|
1092 } |
|
1093 $s = RenderMan::preprocess_text($subject); |
|
1094 $t = RenderMan::preprocess_text($text); |
|
1095 $sql = 'UPDATE '.table_prefix.'comments SET subject=\''.$s.'\',comment_data=\''.$t.'\' WHERE comment_id='.$id.' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''; |
|
1096 $result = $db->sql_query($sql); |
|
1097 if($result) |
|
1098 return 'good'; |
|
1099 else return 'Enano encountered a problem whilst saving the comment. |
|
1100 Performed SQL: |
|
1101 '.$sql.' |
|
1102 |
|
1103 Error returned by MySQL: '.mysql_error(); |
|
1104 } |
|
1105 |
|
1106 /** |
|
1107 * Deletes a comment. |
|
1108 * @param $page_id the page ID |
|
1109 * @param $namespace the namespace |
|
1110 * @param $name the name the user posted under |
|
1111 * @param $subj the subject of the comment to be deleted |
|
1112 * @param $text the text of the comment to be deleted |
|
1113 * @param $id the javascript list ID, used internally by the client-side app |
|
1114 * @return string |
|
1115 */ |
|
1116 |
|
1117 function deletecomment($page_id, $namespace, $name, $subj, $text, $id) |
|
1118 { |
|
1119 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1120 |
|
1121 if(!$session->get_permissions('edit_comments')) |
|
1122 return 'alert("Access to delete/edit comments is denied");'; |
|
1123 |
|
1124 if(!preg_match('#^([0-9]+)$#', (string)$id)) die('$_GET[id] is improperly formed.'); |
|
1125 $n = $db->escape($name); |
|
1126 $s = $db->escape($subj); |
|
1127 $t = $db->escape($text); |
|
1128 |
|
1129 // Safety check - username/login |
|
1130 if(!$session->get_permissions('mod_comments')) // allows mods to delete comments |
|
1131 { |
|
1132 if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.<br /><br />Please log in and try again.'); |
|
1133 $q = 'SELECT c.name FROM '.table_prefix.'comments c, '.table_prefix.'users u WHERE comment_data=\''.$t.'\' AND subject=\''.$s.'\' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND u.user_id=c.user_id;'; |
|
1134 $s = $db->sql_query($q); |
|
1135 if(!$s) _die('SQL error during safety check: '.mysql_error().'<br /><br />Attempted SQL:<br /><pre>'.htmlspecialchars($q).'</pre>'); |
|
1136 $r = $db->fetchrow($s); |
|
1137 if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); |
|
1138 $db->free_result(); |
|
1139 } |
|
1140 $q = 'DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND name=\''.$n.'\' AND subject=\''.$s.'\' AND comment_data=\''.$t.'\' LIMIT 1;'; |
|
1141 $e=$db->sql_query($q); |
|
1142 if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n'.$q).'\'));'); |
|
1143 return('good'); |
|
1144 } |
|
1145 |
|
1146 /** |
|
1147 * Deletes a comment in a cleaner fashion. |
|
1148 * @param $page_id the page ID |
|
1149 * @param $namespace the namespace |
|
1150 * @param $id the comment ID (primary key) |
|
1151 * @return string |
|
1152 */ |
|
1153 |
|
1154 function deletecomment_neater($page_id, $namespace, $id) |
|
1155 { |
|
1156 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1157 |
|
1158 if(!preg_match('#^([0-9]+)$#', (string)$id)) die('$_GET[id] is improperly formed.'); |
|
1159 |
|
1160 if(!$session->get_permissions('edit_comments')) |
|
1161 return 'alert("Access to delete/edit comments is denied");'; |
|
1162 |
|
1163 // Safety check - username/login |
|
1164 if(!$session->get_permissions('mod_comments')) // allows mods to delete comments |
|
1165 { |
|
1166 if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.<br /><br />Please log in and try again.'); |
|
1167 $q = 'SELECT c.name FROM '.table_prefix.'comments c, '.table_prefix.'users u WHERE comment_id='.$id.' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND u.user_id=c.user_id;'; |
|
1168 $s = $db->sql_query($q); |
|
1169 if(!$s) _die('SQL error during safety check: '.mysql_error().'<br /><br />Attempted SQL:<br /><pre>'.htmlspecialchars($q).'</pre>'); |
|
1170 $r = $db->fetchrow($s); |
|
1171 if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); |
|
1172 $db->free_result(); |
|
1173 } |
|
1174 $q = 'DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND comment_id='.$id.' LIMIT 1;'; |
|
1175 $e=$db->sql_query($q); |
|
1176 if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n'.$q).'\'));'); |
|
1177 return('good'); |
|
1178 } |
|
1179 |
|
1180 /** |
|
1181 * Renames a page. |
|
1182 * @param $page_id the page ID |
|
1183 * @param $namespace the namespace |
|
1184 * @param $name the new name for the page |
|
1185 * @return string error string or success message |
|
1186 */ |
|
1187 |
|
1188 function rename($page_id, $namespace, $name) |
|
1189 { |
|
1190 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1191 |
|
1192 $pname = $paths->nslist[$namespace] . $page_id; |
|
1193 |
|
1194 $prot = ( ( $paths->pages[$pname]['protected'] == 2 && $session->user_logged_in && $session->reg_time + 60*60*24*4 < time() ) || $paths->pages[$pname]['protected'] == 1) ? true : false; |
|
1195 $wiki = ( ( $paths->pages[$pname]['wiki_mode'] == 2 && getConfig('wiki_mode') == '1') || $paths->pages[$pname]['wiki_mode'] == 1) ? true : false; |
|
1196 |
|
1197 if( empty($name)) die('Name is too short'); |
|
1198 if( ( $session->get_permissions('rename') && ( ( $prot && $session->get_permissions('even_when_protected') ) || !$prot ) ) && ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' )) { |
|
1199 $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'rename\', \''.$paths->cpage['urlname_nons'].'\', \''.$paths->namespace.'\', \''.$session->username.'\', \''.$paths->cpage['name'].'\')'); |
|
1200 if(!$e) $db->_die('The page title could not be updated.'); |
|
1201 $e = $db->sql_query('UPDATE '.table_prefix.'pages SET name=\''.$db->escape($name).'\' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
1202 if(!$e) $db->_die('The page title could not be updated.'); |
|
1203 else return('The page "'.$paths->pages[$pname]['name'].'" has been renamed to "'.$name.'". You are encouraged to leave a comment explaining your action. |
|
1204 |
|
1205 You will see the change take effect the next time you reload this page.'); |
|
1206 } else { |
|
1207 return('Access is denied.'); |
|
1208 } |
|
1209 } |
|
1210 |
|
1211 /** |
|
1212 * Flushes (clears) the action logs for a given page |
|
1213 * @param $page_id the page ID |
|
1214 * @param $namespace the namespace |
|
1215 * @return string error/success string |
|
1216 */ |
|
1217 |
|
1218 function flushlogs($page_id, $namespace) |
|
1219 { |
|
1220 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1221 if(!$session->get_permissions('clear_logs')) die('Administrative privileges are required to flush logs, you loser.'); |
|
1222 $e = $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
1223 if(!$e) $db->_die('The log entries could not be deleted.'); |
|
1224 $e = $db->sql_query('SELECT page_text,char_tag FROM '.table_prefix.'page_text WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
1225 if(!$e) $db->_die('The current page text could not be selected; as a result, creating the backup of the page failed. Please make a backup copy of the page by clicking Edit this page and then clicking Save Changes.'); |
|
1226 $row = $db->fetchrow(); |
|
1227 $db->free_result(); |
|
1228 $q='INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.date('d M Y h:i a').'\', \''.$page_id.'\', \''.$namespace.'\', \''.$db->escape($row['page_text']).'\', \''.$row['char_tag'].'\', \''.$session->username.'\', \''."Automatic backup created when logs were purged".'\', '.'false'.');'; |
|
1229 if(!$db->sql_query($q)) $db->_die('The history (log) entry could not be inserted into the logs table.'); |
|
1230 return('The logs for this page have been cleared. A backup of this page has been added to the logs table so that this page can be restored in case of vandalism or spam later.'); |
|
1231 } |
|
1232 |
|
1233 /** |
|
1234 * Deletes a page. |
|
1235 * @param $page_id the condemned page ID |
|
1236 * @param $namespace the condemned namespace |
|
1237 * @return string |
|
1238 */ |
|
1239 |
|
1240 function deletepage($page_id, $namespace) |
|
1241 { |
|
1242 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1243 $perms = $session->fetch_page_acl($page_id, $namespace); |
|
1244 if(!$perms->get_permissions('delete_page')) die('Administrative privileges are required to delete pages, you loser.'); |
|
1245 $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'delete\', \''.$page_id.'\', \''.$namespace.'\', \''.$session->username.'\')'); |
|
1246 if(!$e) $db->_die('The page log entry could not be inserted.'); |
|
1247 $e = $db->sql_query('DELETE FROM '.table_prefix.'categories WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''); |
|
1248 if(!$e) $db->_die('The page categorization entries could not be deleted.'); |
|
1249 $e = $db->sql_query('DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''); |
|
1250 if(!$e) $db->_die('The page comments could not be deleted.'); |
|
1251 $e = $db->sql_query('DELETE FROM '.table_prefix.'page_text WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''); |
|
1252 if(!$e) $db->_die('The page text entry could not be deleted.'); |
|
1253 $e = $db->sql_query('DELETE FROM '.table_prefix.'pages WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\''); |
|
1254 if(!$e) $db->_die('The page entry could not be deleted.'); |
|
1255 $e = $db->sql_query('DELETE FROM '.table_prefix.'files WHERE page_id=\''.$page_id.'\''); |
|
1256 if(!$e) $db->_die('The file entry could not be deleted.'); |
|
1257 return('This page has been deleted. Note that there is still a log of edits and actions in the database, and anyone with admin rights can raise this page from the dead unless the log is cleared. If the deleted file is an image, there may still be cached thumbnails of it in the cache/ directory, which is inaccessible to users.'); |
|
1258 } |
|
1259 |
|
1260 /** |
|
1261 * Increments the deletion votes for a page by 1, and adds the current username/IP to the list of users that have voted for the page to prevent dual-voting |
|
1262 * @param $page_id the page ID |
|
1263 * @param $namespace the namespace |
|
1264 * @return string |
|
1265 */ |
|
1266 |
|
1267 function delvote($page_id, $namespace) |
|
1268 { |
|
1269 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1270 if(!$session->get_permissions('vote_delete')) |
|
1271 return 'Access denied'; |
|
1272 $pname = $paths->nslist[$namespace] . $page_id; |
|
1273 $cv = $paths->pages[$pname]['delvotes']; |
|
1274 $ips = $paths->pages[$pname]['delvote_ips']; |
|
1275 $ips = explode('|', $ips); |
|
1276 if(in_array($_SERVER['REMOTE_ADDR'], $ips)) return('It appears that you have already voted to have this page deleted.'); |
|
1277 if($session->user_logged_in) |
|
1278 if(in_array($session->username, $ips)) |
|
1279 return('It appears that you have already voted to have this page deleted.'); |
|
1280 $ips[] = $_SERVER['REMOTE_ADDR']; |
|
1281 if($session->user_logged_in) $ips[] = $session->username; |
|
1282 $ips = implode('|', $ips); |
|
1283 $ips = substr($ips, 1, strlen($ips)); |
|
1284 $cv++; |
|
1285 $q = 'UPDATE '.table_prefix.'pages SET delvotes='.$cv.',delvote_ips=\''.$ips.'\' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\''; |
|
1286 $w = $db->sql_query($q); |
|
1287 if(!$w) return("Error updating pages table: ".mysql_error()."\n\nAttemped SQL:\n".$q); |
|
1288 return('Your vote to have this page deleted has been cast.'."\nYou are encouraged to leave a comment explaining the reason for your vote."); |
|
1289 } |
|
1290 |
|
1291 /** |
|
1292 * Resets the number of votes against a page to 0. |
|
1293 * @param $page_id the page ID |
|
1294 * @param $namespace the namespace |
|
1295 * @return string |
|
1296 */ |
|
1297 |
|
1298 function resetdelvotes($page_id, $namespace) |
|
1299 { |
|
1300 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1301 if(!$session->get_permissions('vote_reset')) die('You need moderator rights in order to do this, stinkin\' hacker.'); |
|
1302 $q = 'UPDATE '.table_prefix.'pages SET delvotes=0,delvote_ips=\'\' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\''; |
|
1303 $e = $db->sql_query($q); |
|
1304 if(!$e) $db->_die('The number of delete votes was not reset.'); |
|
1305 else return('The number of votes for having this page deleted has been reset to zero.'); |
|
1306 } |
|
1307 |
|
1308 /** |
|
1309 * Gets a list of styles for a given theme name. |
|
1310 * @param $id the name of the directory for the theme |
|
1311 * @return string Javascript code |
|
1312 */ |
|
1313 |
|
1314 function getstyles() |
|
1315 { |
|
1316 $dir = './themes/'.$_GET['id'].'/css/'; |
|
1317 $list = Array(); |
|
1318 // Open a known directory, and proceed to read its contents |
|
1319 if (is_dir($dir)) { |
|
1320 if ($dh = opendir($dir)) { |
|
1321 while (($file = readdir($dh)) !== false) { |
|
1322 if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') { // _printable.css should be included with every theme |
|
1323 // it should be a copy of the original style, but |
|
1324 // mostly black and white |
|
1325 // Note to self: document this |
|
1326 $list[] = substr($file, 0, strlen($file)-4); |
|
1327 } |
|
1328 } |
|
1329 closedir($dh); |
|
1330 } |
|
1331 } else return($dir.' is not a dir'); |
|
1332 $l = 'var list = new Array();'; |
|
1333 $i = -1; |
|
1334 foreach($list as $li) { |
|
1335 $i++; |
|
1336 $l .= "list[$i] = '$li';"; |
|
1337 } |
|
1338 return $l; |
|
1339 } |
|
1340 |
|
1341 /** |
|
1342 * Assembles a Javascript app with category information |
|
1343 * @param $page_id the page ID |
|
1344 * @param $namespace the namespace |
|
1345 * @return string Javascript code |
|
1346 */ |
|
1347 |
|
1348 function catedit($page_id, $namespace) |
|
1349 { |
|
1350 $d = PageUtils::catedit_raw($page_id, $namespace); |
|
1351 return $d[0] . ' /* BEGIN CONTENT */ document.getElementById("ajaxEditContainer").innerHTML = unescape(\''.rawurlencode($d[1]).'\');'; |
|
1352 } |
|
1353 |
|
1354 /** |
|
1355 * Does the actual HTML/javascript generation for cat editing, but returns an array |
|
1356 * @access private |
|
1357 */ |
|
1358 |
|
1359 function catedit_raw($page_id, $namespace) |
|
1360 { |
|
1361 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1362 ob_start(); |
|
1363 $_ob = ''; |
|
1364 $e = $db->sql_query('SELECT category_id FROM '.table_prefix.'categories WHERE page_id=\''.$paths->cpage['urlname_nons'].'\' AND namespace=\''.$paths->namespace.'\''); |
|
1365 if(!$e) jsdie('Error selecting category information for current page: '.mysql_error()); |
|
1366 $cat_current = Array(); |
|
1367 while($r = $db->fetchrow()) |
|
1368 { |
|
1369 $cat_current[] = $r; |
|
1370 } |
|
1371 $db->free_result(); |
|
1372 $cat_all = Array(); |
|
1373 for($i=0;$i<sizeof($paths->pages)/2;$i++) |
|
1374 { |
|
1375 if($paths->pages[$i]['namespace']=='Category') $cat_all[] = $paths->pages[$i]; |
|
1376 } |
|
1377 |
|
1378 // Make $cat_all an associative array, like $paths->pages |
|
1379 $sz = sizeof($cat_all); |
|
1380 for($i=0;$i<$sz;$i++) |
|
1381 { |
|
1382 $cat_all[$cat_all[$i]['urlname_nons']] = $cat_all[$i]; |
|
1383 } |
|
1384 // Now, the "zipper" function - join the list of categories with the list of cats that this page is a part of |
|
1385 $cat_info = $cat_all; |
|
1386 for($i=0;$i<sizeof($cat_current);$i++) |
|
1387 { |
|
1388 $un = $cat_current[$i]['category_id']; |
|
1389 $cat_info[$un]['member'] = true; |
|
1390 } |
|
1391 // Now copy the information we just set into the numerically named keys |
|
1392 for($i=0;$i<sizeof($cat_info)/2;$i++) |
|
1393 { |
|
1394 $un = $cat_info[$i]['urlname_nons']; |
|
1395 $cat_info[$i] = $cat_info[$un]; |
|
1396 } |
|
1397 |
|
1398 echo 'catlist = new Array();'; // Initialize the client-side category list |
|
1399 $_ob .= '<h3>Select which categories this page should be included in.</h3> |
|
1400 <form name="mdgCatForm" action="'.makeUrlNS($namespace, $page_id, 'do=catedit').'" method="post">'; |
|
1401 if ( sizeof($cat_info) < 1 ) |
|
1402 { |
|
1403 $_ob .= '<p>There are no categories on this site yet.</p>'; |
|
1404 } |
|
1405 for ( $i = 0; $i < sizeof($cat_info) / 2; $i++ ) |
|
1406 { |
|
1407 // Protection code added 1/3/07 |
|
1408 // Updated 3/4/07 |
|
1409 $is_prot = false; |
|
1410 $perms = $session->fetch_page_acl($cat_info[$i]['urlname_nons'], 'Category'); |
|
1411 if ( !$session->get_permissions('edit_cat') || !$perms->get_permissions('edit_cat') || |
|
1412 ( $cat_info[$i]['really_protected'] && !$perms->get_permissions('even_when_protected') ) ) |
|
1413 $is_prot = true; |
|
1414 $prot = ( $is_prot ) ? ' disabled="disabled" ' : ''; |
|
1415 $prottext = ( $is_prot ) ? ' <img alt="(protected)" width="16" height="16" src="'.scriptPath.'/images/lock16.png" />' : ''; |
|
1416 echo 'catlist['.$i.'] = \''.$cat_info[$i]['urlname_nons'].'\';'; |
|
1417 $_ob .= '<span class="catCheck"><input '.$prot.' name="'.$cat_info[$i]['urlname_nons'].'" id="mdgCat_'.$cat_info[$i]['urlname_nons'].'" type="checkbox"'; |
|
1418 if(isset($cat_info[$i]['member'])) $_ob .= ' checked="checked"'; |
|
1419 $_ob .= '/> <label for="mdgCat_'.$cat_info[$i]['urlname_nons'].'">'.$cat_info[$i]['name'].$prottext.'</label></span><br />'; |
|
1420 } |
|
1421 |
|
1422 $disabled = ( sizeof($cat_info) < 1 ) ? 'disabled="disabled"' : ''; |
|
1423 |
|
1424 $_ob .= '<div style="border-top: 1px solid #CCC; padding-top: 5px; margin-top: 10px;"><input name="__enanoSaveButton" ' . $disabled . ' style="font-weight: bold;" type="submit" onclick="ajaxCatSave(); return false;" value="Save changes" /> <input name="__enanoCatCancel" type="submit" onclick="ajaxReset(); return false;" value="Cancel" /></div></form>'; |
|
1425 |
|
1426 $cont = ob_get_contents(); |
|
1427 ob_end_clean(); |
|
1428 return Array($cont, $_ob); |
|
1429 } |
|
1430 |
|
1431 /** |
|
1432 * Saves category information |
|
1433 * WARNING: If $which_cats is empty, all the category information for the selected page will be nuked! |
|
1434 * @param $page_id string the page ID |
|
1435 * @param $namespace string the namespace |
|
1436 * @param $which_cats array associative array of categories to put the page in |
|
1437 * @return string "GOOD" on success, error string on failure |
|
1438 */ |
|
1439 |
|
1440 function catsave($page_id, $namespace, $which_cats) |
|
1441 { |
|
1442 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1443 if(!$session->get_permissions('edit_cat')) return('Insufficient privileges to change category information'); |
|
1444 |
|
1445 $page_perms = $session->fetch_page_acl($page_id, $namespace); |
|
1446 $page_data =& $paths->pages[$paths->nslist[$namespace].$page_id]; |
|
1447 |
|
1448 $cat_all = Array(); |
|
1449 for($i=0;$i<sizeof($paths->pages)/2;$i++) |
|
1450 { |
|
1451 if($paths->pages[$i]['namespace']=='Category') $cat_all[] = $paths->pages[$i]; |
|
1452 } |
|
1453 |
|
1454 // Make $cat_all an associative array, like $paths->pages |
|
1455 $sz = sizeof($cat_all); |
|
1456 for($i=0;$i<$sz;$i++) |
|
1457 { |
|
1458 $cat_all[$cat_all[$i]['urlname_nons']] = $cat_all[$i]; |
|
1459 } |
|
1460 |
|
1461 $rowlist = Array(); |
|
1462 |
|
1463 for($i=0;$i<sizeof($cat_all)/2;$i++) |
|
1464 { |
|
1465 $auth = true; |
|
1466 $perms = $session->fetch_page_acl($cat_all[$i]['urlname_nons'], 'Category'); |
|
1467 if ( !$session->get_permissions('edit_cat') || !$perms->get_permissions('edit_cat') || |
|
1468 ( $cat_all[$i]['really_protected'] && !$perms->get_permissions('even_when_protected') ) || |
|
1469 ( !$page_perms->get_permissions('even_when_protected') && $page_data['protected'] == '1' ) ) |
|
1470 $auth = false; |
|
1471 if(!$auth) |
|
1472 { |
|
1473 // Find out if the page is currently in the category |
|
1474 $q = $db->sql_query('SELECT * FROM '.table_prefix.'categories WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
1475 if(!$q) |
|
1476 return 'MySQL error: '.$db->get_error(); |
|
1477 if($db->numrows() > 0) |
|
1478 { |
|
1479 $auth = true; |
|
1480 $which_cats[$cat_all[$i]['urlname_nons']] = true; // Force the category to stay in its current state |
|
1481 } |
|
1482 $db->free_result(); |
|
1483 } |
|
1484 if(isset($which_cats[$cat_all[$i]['urlname_nons']]) && $which_cats[$cat_all[$i]['urlname_nons']] == true /* for clarity ;-) */ && $auth ) $rowlist[] = '(\''.$page_id.'\', \''.$namespace.'\', \''.$cat_all[$i]['urlname_nons'].'\')'; |
|
1485 } |
|
1486 if(sizeof($rowlist) > 0) |
|
1487 { |
|
1488 $val = implode(',', $rowlist); |
|
1489 $q = 'INSERT INTO '.table_prefix.'categories(page_id,namespace,category_id) VALUES' . $val . ';'; |
|
1490 $e = $db->sql_query('DELETE FROM '.table_prefix.'categories WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
1491 if(!$e) $db->_die('The old category data could not be deleted.'); |
|
1492 $e = $db->sql_query($q); |
|
1493 if(!$e) $db->_die('The new category data could not be inserted.'); |
|
1494 return('GOOD'); |
|
1495 } |
|
1496 else |
|
1497 { |
|
1498 $e = $db->sql_query('DELETE FROM '.table_prefix.'categories WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
1499 if(!$e) $db->_die('The old category data could not be deleted.'); |
|
1500 return('GOOD'); |
|
1501 } |
|
1502 } |
|
1503 |
|
1504 /** |
|
1505 * Sets the wiki mode level for a page. |
|
1506 * @param $page_id string the page ID |
|
1507 * @param $namespace string the namespace |
|
1508 * @param $level int 0 for off, 1 for on, 2 for use global setting |
|
1509 * @return string "GOOD" on success, error string on failure |
|
1510 */ |
|
1511 |
|
1512 function setwikimode($page_id, $namespace, $level) |
|
1513 { |
|
1514 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1515 if(!$session->get_permissions('set_wiki_mode')) return('Insufficient access rights'); |
|
1516 if(!isset($level) || (isset($level) && !preg_match('#^([0-2]){1}$#', (string)$level))) return('Invalid mode string'); |
|
1517 $q = $db->sql_query('UPDATE '.table_prefix.'pages SET wiki_mode='.$level.' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
1518 if(!$q) return('Error during update query: '.mysql_error()."\n\nSQL Backtrace:\n".$db->sql_backtrace()); |
|
1519 return('GOOD'); |
|
1520 } |
|
1521 |
|
1522 /** |
|
1523 * Sets the access password for a page. |
|
1524 * @param $page_id string the page ID |
|
1525 * @param $namespace string the namespace |
|
1526 * @param $pass string the SHA1 hash of the password - if the password doesn't match the regex ^([0-9a-f]*){40,40}$ it will be sha1'ed |
|
1527 * @return string |
|
1528 */ |
|
1529 |
|
1530 function setpass($page_id, $namespace, $pass) |
|
1531 { |
|
1532 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1533 // Determine permissions |
|
1534 if($paths->pages[$paths->nslist[$namespace].$page_id]['password'] != '') |
|
1535 $a = $session->get_permissions('password_reset'); |
|
1536 else |
|
1537 $a = $session->get_permissions('password_set'); |
|
1538 if(!$a) |
|
1539 return 'Access is denied'; |
|
1540 if(!isset($pass)) return('Password was not set on URL'); |
|
1541 $p = $pass; |
|
1542 if(!preg_match('#([0-9a-f]){40,40}#', $p)) $p = sha1($p); |
|
1543 if($p=='da39a3ee5e6b4b0d3255bfef95601890afd80709') $p = ''; |
|
1544 $e = $db->sql_query('UPDATE '.table_prefix.'pages SET password=\''.$p.'\' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); |
|
1545 if(!$e) die('PageUtils::setpass(): Error during update query: '.mysql_error()."\n\nSQL Backtrace:\n".$db->sql_backtrace()); |
|
1546 if($p=='') return('The password for this page has been disabled.'); |
|
1547 else return('The password for this page has been set.'); |
|
1548 } |
|
1549 |
|
1550 /** |
|
1551 * Generates some preview HTML |
|
1552 * @param $text string the wikitext to use |
|
1553 * @return string |
|
1554 */ |
|
1555 |
|
1556 function genPreview($text) |
|
1557 { |
|
1558 return '<div class="info-box"><b>Reminder:</b> This is only a preview - your changes to this page have not yet been saved.</div><div style="background-color: #F8F8F8; padding: 10px; border: 1px dashed #406080; max-height: 250px; overflow: auto; margin: 1em 0 1em 1em;">'.RenderMan::render(RenderMan::preprocess_text($text, false, false)).'</div>'; |
|
1559 } |
|
1560 |
|
1561 /** |
|
1562 * Makes a scrollable box |
|
1563 * @param string $text the inner HTML |
|
1564 * @param int $height Optional - the maximum height. Defaults to 250. |
|
1565 * @return string |
|
1566 */ |
|
1567 |
|
1568 function scrollBox($text, $height = 250) |
|
1569 { |
|
1570 return '<div style="background-color: #F8F8F8; padding: 10px; border: 1px dashed #406080; max-height: '.(string)intval($height).'px; overflow: auto; margin: 1em 0 1em 1em;">'.$text.'</div>'; |
|
1571 } |
|
1572 |
|
1573 /** |
|
1574 * Generates a diff summary between two page revisions. |
|
1575 * @param $page_id the page ID |
|
1576 * @param $namespace the namespace |
|
1577 * @param $id1 the time ID of the first revision |
|
1578 * @param $id2 the time ID of the second revision |
|
1579 * @return string XHTML-formatted diff |
|
1580 */ |
|
1581 |
|
1582 function pagediff($page_id, $namespace, $id1, $id2) |
|
1583 { |
|
1584 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1585 if(!$session->get_permissions('history_view')) |
|
1586 return 'Access denied'; |
|
1587 if(!preg_match('#^([0-9]+)$#', (string)$id1) || |
|
1588 !preg_match('#^([0-9]+)$#', (string)$id2 )) return 'SQL injection attempt'; |
|
1589 // OK we made it through security |
|
1590 // Safest way to make sure we don't end up with the revisions in wrong columns is to make 2 queries |
|
1591 if(!$q1 = $db->sql_query('SELECT page_text,char_tag,author,edit_summary FROM '.table_prefix.'logs WHERE time_id='.$id1.' AND log_type=\'page\' AND action=\'edit\' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';')) return 'MySQL error: '.mysql_error(); |
|
1592 if(!$q2 = $db->sql_query('SELECT page_text,char_tag,author,edit_summary FROM '.table_prefix.'logs WHERE time_id='.$id2.' AND log_type=\'page\' AND action=\'edit\' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';')) return 'MySQL error: '.mysql_error(); |
|
1593 $row1 = $db->fetchrow($q1); |
|
1594 $db->free_result($q1); |
|
1595 $row2 = $db->fetchrow($q2); |
|
1596 $db->free_result($q2); |
|
1597 if(sizeof($row1) < 1 || sizeof($row2) < 2) return 'Couldn\'t find any rows that matched the query. The time ID probably doesn\'t exist in the logs table.'; |
|
1598 $text1 = $row1['page_text']; |
|
1599 $text2 = $row2['page_text']; |
|
1600 $time1 = date('F d, Y h:i a', $id1); |
|
1601 $time2 = date('F d, Y h:i a', $id2); |
|
1602 $_ob = " |
|
1603 <p>Comparing revisions: {$time1} → {$time2}</p> |
|
1604 "; |
|
1605 // Free some memory |
|
1606 unset($row1, $row2, $q1, $q2); |
|
1607 |
|
1608 $_ob .= RenderMan::diff($text1, $text2); |
|
1609 return $_ob; |
|
1610 } |
|
1611 |
|
1612 /** |
|
1613 * Gets ACL information about the selected page for target type X and target ID Y. |
|
1614 * @param string $page_id The page ID |
|
1615 * @param string $namespace The namespace |
|
1616 * @param array $parms What to select. This is an array purely for JSON compatibility. It should be an associative array with keys target_type and target_id. |
|
1617 * @return array |
|
1618 */ |
|
1619 |
|
1620 function acl_editor($parms = Array()) |
|
1621 { |
|
1622 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1623 if(!$session->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN) |
|
1624 return 'Access is denied.'; |
|
1625 $parms['page_id'] = ( isset($parms['page_id']) ) ? $parms['page_id'] : false; |
|
1626 $parms['namespace'] = ( isset($parms['namespace']) ) ? $parms['namespace'] : false; |
|
1627 $page_id =& $parms['page_id']; |
|
1628 $namespace =& $parms['namespace']; |
|
1629 $page_where_clause = ( empty($page_id) || empty($namespace) ) ? 'AND a.page_id IS NULL AND a.namespace IS NULL' : 'AND a.page_id=\''.$db->escape($page_id).'\' AND a.namespace=\''.$db->escape($namespace).'\''; |
|
1630 $page_where_clause_lite = ( empty($page_id) || empty($namespace) ) ? 'AND page_id IS NULL AND namespace IS NULL' : 'AND page_id=\''.$db->escape($page_id).'\' AND namespace=\''.$db->escape($namespace).'\''; |
|
1631 //die(print_r($page_id,true)); |
|
1632 $template->load_theme(); |
|
1633 // $perms_obj = $session->fetch_page_acl($page_id, $namespace); |
|
1634 $perms_obj =& $session; |
|
1635 $return = Array(); |
|
1636 if ( !file_exists(ENANO_ROOT . '/themes/' . $session->theme . '/acledit.tpl') ) |
|
1637 { |
|
1638 return Array( |
|
1639 'mode' => 'error', |
|
1640 'error' => 'It seems that (a) the file acledit.tpl is missing from these theme, and (b) the JSON response is working.', |
|
1641 ); |
|
1642 } |
|
1643 $return['template'] = $template->extract_vars('acledit.tpl'); |
|
1644 $return['page_id'] = $page_id; |
|
1645 $return['namespace'] = $namespace; |
|
1646 if(isset($parms['mode'])) |
|
1647 { |
|
1648 switch($parms['mode']) |
|
1649 { |
|
1650 case 'listgroups': |
|
1651 $return['groups'] = Array(); |
|
1652 $q = $db->sql_query('SELECT group_id,group_name FROM '.table_prefix.'groups ORDER BY group_name ASC;'); |
|
1653 while($row = $db->fetchrow()) |
|
1654 { |
|
1655 $return['groups'][] = Array( |
|
1656 'id' => $row['group_id'], |
|
1657 'name' => $row['group_name'], |
|
1658 ); |
|
1659 } |
|
1660 $db->free_result(); |
|
1661 break; |
|
1662 case 'seltarget': |
|
1663 $return['mode'] = 'seltarget'; |
|
1664 $return['acl_types'] = $perms_obj->acl_types; |
|
1665 $return['acl_deps'] = $perms_obj->acl_deps; |
|
1666 $return['acl_descs'] = $perms_obj->acl_descs; |
|
1667 $return['target_type'] = $parms['target_type']; |
|
1668 $return['target_id'] = $parms['target_id']; |
|
1669 switch($parms['target_type']) |
|
1670 { |
|
1671 case ACL_TYPE_USER: |
|
1672 $q = $db->sql_query('SELECT a.rules,u.user_id FROM '.table_prefix.'users AS u |
|
1673 LEFT JOIN '.table_prefix.'acl AS a |
|
1674 ON a.target_id=u.user_id |
|
1675 WHERE a.target_type='.ACL_TYPE_USER.' |
|
1676 AND u.username=\''.$db->escape($parms['target_id']).'\' |
|
1677 '.$page_where_clause.';'); |
|
1678 if(!$q) |
|
1679 return(Array('mode'=>'error','error'=>mysql_error())); |
|
1680 if($db->numrows() < 1) |
|
1681 { |
|
1682 $return['type'] = 'new'; |
|
1683 $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($parms['target_id']).'\';'); |
|
1684 if(!$q) |
|
1685 return(Array('mode'=>'error','error'=>mysql_error())); |
|
1686 if($db->numrows() < 1) |
|
1687 return Array('mode'=>'error','error'=>'The username you entered was not found.'); |
|
1688 $row = $db->fetchrow(); |
|
1689 $return['target_name'] = $return['target_id']; |
|
1690 $return['target_id'] = intval($row['user_id']); |
|
1691 $return['current_perms'] = $session->acl_types; |
|
1692 } |
|
1693 else |
|
1694 { |
|
1695 $return['type'] = 'edit'; |
|
1696 $row = $db->fetchrow(); |
|
1697 $return['target_name'] = $return['target_id']; |
|
1698 $return['target_id'] = intval($row['user_id']); |
|
1699 $return['current_perms'] = $session->acl_merge($perms_obj->acl_types, $session->string_to_perm($row['rules'])); |
|
1700 } |
|
1701 $db->free_result(); |
|
1702 // Eliminate types that don't apply to this namespace |
|
1703 if ( $namespace ) |
|
1704 { |
|
1705 foreach ( $return['current_perms'] AS $i => $perm ) |
|
1706 { |
|
1707 if ( ( $page_id != null && $namespace != null ) && ( !in_array ( $namespace, $session->acl_scope[$i] ) && !in_array('All', $session->acl_scope[$i]) ) ) |
|
1708 { |
|
1709 // echo "// SCOPE CONTROL: eliminating: $i\n"; |
|
1710 unset($return['current_perms'][$i]); |
|
1711 unset($return['acl_types'][$i]); |
|
1712 unset($return['acl_descs'][$i]); |
|
1713 unset($return['acl_deps'][$i]); |
|
1714 } |
|
1715 } |
|
1716 } |
|
1717 break; |
|
1718 case ACL_TYPE_GROUP: |
|
1719 $q = $db->sql_query('SELECT a.rules,g.group_name,g.group_id FROM '.table_prefix.'groups AS g |
|
1720 LEFT JOIN '.table_prefix.'acl AS a |
|
1721 ON a.target_id=g.group_id |
|
1722 WHERE a.target_type='.ACL_TYPE_GROUP.' |
|
1723 AND g.group_id=\''.intval($parms['target_id']).'\' |
|
1724 '.$page_where_clause.';'); |
|
1725 if(!$q) |
|
1726 return(Array('mode'=>'error','error'=>mysql_error())); |
|
1727 if($db->numrows() < 1) |
|
1728 { |
|
1729 $return['type'] = 'new'; |
|
1730 $q = $db->sql_query('SELECT group_id,group_name FROM '.table_prefix.'groups WHERE group_id=\''.intval($parms['target_id']).'\';'); |
|
1731 if(!$q) |
|
1732 return(Array('mode'=>'error','error'=>mysql_error())); |
|
1733 if($db->numrows() < 1) |
|
1734 return Array('mode'=>'error','error'=>'The group ID you submitted is not valid.'); |
|
1735 $row = $db->fetchrow(); |
|
1736 $return['target_name'] = $row['group_name']; |
|
1737 $return['target_id'] = intval($row['group_id']); |
|
1738 $return['current_perms'] = $session->acl_types; |
|
1739 } |
|
1740 else |
|
1741 { |
|
1742 $return['type'] = 'edit'; |
|
1743 $row = $db->fetchrow(); |
|
1744 $return['target_name'] = $row['group_name']; |
|
1745 $return['target_id'] = intval($row['group_id']); |
|
1746 $return['current_perms'] = $session->acl_merge($session->acl_types, $session->string_to_perm($row['rules'])); |
|
1747 } |
|
1748 $db->free_result(); |
|
1749 // Eliminate types that don't apply to this namespace |
|
1750 if ( $namespace ) |
|
1751 { |
|
1752 foreach ( $return['current_perms'] AS $i => $perm ) |
|
1753 { |
|
1754 if ( ( $page_id != false && $namespace != false ) && ( !in_array ( $namespace, $session->acl_scope[$i] ) && !in_array('All', $session->acl_scope[$i]) ) ) |
|
1755 { |
|
1756 // echo "// SCOPE CONTROL: eliminating: $i\n"; //; ".print_r($namespace,true).":".print_r($page_id,true)."\n"; |
|
1757 unset($return['current_perms'][$i]); |
|
1758 unset($return['acl_types'][$i]); |
|
1759 unset($return['acl_descs'][$i]); |
|
1760 unset($return['acl_deps'][$i]); |
|
1761 } |
|
1762 } |
|
1763 } |
|
1764 //return Array('mode'=>'debug','text'=>print_r($return, true)); |
|
1765 break; |
|
1766 default: |
|
1767 return Array('mode'=>'error','error','Invalid ACL type ID'); |
|
1768 break; |
|
1769 } |
|
1770 return $return; |
|
1771 break; |
|
1772 case 'save_new': |
|
1773 case 'save_edit': |
|
1774 $q = $db->sql_query('DELETE FROM '.table_prefix.'acl WHERE target_type='.intval($parms['target_type']).' AND target_id='.intval($parms['target_id']).' |
|
1775 '.$page_where_clause_lite.';'); |
|
1776 if(!$q) |
|
1777 return Array('mode'=>'error','error'=>mysql_error()); |
|
1778 $rules = $session->perm_to_string($parms['perms']); |
|
1779 if ( sizeof ( $rules ) < 1 ) |
|
1780 { |
|
1781 return array( |
|
1782 'mode' => 'error', |
|
1783 'error' => 'Supplied rule list has a length of zero' |
|
1784 ); |
|
1785 } |
|
1786 $q = ($page_id && $namespace) ? 'INSERT INTO '.table_prefix.'acl ( target_type, target_id, page_id, namespace, rules ) |
|
1787 VALUES( '.intval($parms['target_type']).', '.intval($parms['target_id']).', \''.$db->escape($page_id).'\', \''.$db->escape($namespace).'\', \''.$db->escape($rules).'\' )' : |
|
1788 'INSERT INTO '.table_prefix.'acl ( target_type, target_id, rules ) |
|
1789 VALUES( '.intval($parms['target_type']).', '.intval($parms['target_id']).', \''.$db->escape($rules).'\' )'; |
|
1790 if(!$db->sql_query($q)) return Array('mode'=>'error','error'=>mysql_error()); |
|
1791 return Array( |
|
1792 'mode' => 'success', |
|
1793 'target_type' => $parms['target_type'], |
|
1794 'target_id' => $parms['target_id'], |
|
1795 'target_name' => $parms['target_name'], |
|
1796 'page_id' => $page_id, |
|
1797 'namespace' => $namespace, |
|
1798 ); |
|
1799 break; |
|
1800 case 'delete': |
|
1801 $q = $db->sql_query('DELETE FROM '.table_prefix.'acl WHERE target_type='.intval($parms['target_type']).' AND target_id='.intval($parms['target_id']).' |
|
1802 '.$page_where_clause_lite.';'); |
|
1803 if(!$q) |
|
1804 return Array('mode'=>'error','error'=>mysql_error()); |
|
1805 return Array( |
|
1806 'mode' => 'delete', |
|
1807 'target_type' => $parms['target_type'], |
|
1808 'target_id' => $parms['target_id'], |
|
1809 'target_name' => $parms['target_name'], |
|
1810 'page_id' => $page_id, |
|
1811 'namespace' => $namespace, |
|
1812 ); |
|
1813 break; |
|
1814 default: |
|
1815 return Array('mode'=>'error','error'=>'Hacking attempt'); |
|
1816 break; |
|
1817 } |
|
1818 } |
|
1819 return $return; |
|
1820 } |
|
1821 |
|
1822 /** |
|
1823 * Same as PageUtils::acl_editor(), but the parms are a JSON string instead of an array. This also returns a JSON string. |
|
1824 * @param string $parms Same as PageUtils::acl_editor/$parms, but should be a valid JSON string. |
|
1825 * @return string |
|
1826 */ |
|
1827 |
|
1828 function acl_json($parms = '{ }') |
|
1829 { |
|
1830 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1831 $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); |
|
1832 $parms = $json->decode($parms); |
|
1833 $ret = PageUtils::acl_editor($parms); |
|
1834 $ret = $json->encode($ret); |
|
1835 return $ret; |
|
1836 } |
|
1837 |
|
1838 /** |
|
1839 * A non-Javascript frontend for the ACL API. |
|
1840 * @param array The request data, if any, this should be in the format required by PageUtils::acl_editor() |
|
1841 */ |
|
1842 |
|
1843 function aclmanager($parms) |
|
1844 { |
|
1845 global $db, $session, $paths, $template, $plugins; // Common objects |
|
1846 ob_start(); |
|
1847 // Convenience |
|
1848 $formstart = '<form |
|
1849 action="' . makeUrl($paths->page, 'do=aclmanager', true) . '" |
|
1850 method="post" enctype="multipart/form-data" |
|
1851 onsubmit="if(!submitAuthorized) return false;" |
|
1852 >'; |
|
1853 $formend = '</form>'; |
|
1854 $parms = PageUtils::acl_preprocess($parms); |
|
1855 $response = PageUtils::acl_editor($parms); |
|
1856 $response = PageUtils::acl_postprocess($response); |
|
1857 |
|
1858 //die('<pre>' . htmlspecialchars(print_r($response, true)) . '</pre>'); |
|
1859 |
|
1860 switch($response['mode']) |
|
1861 { |
|
1862 case 'debug': |
|
1863 echo '<pre>' . htmlspecialchars($response['text']) . '</pre>'; |
|
1864 break; |
|
1865 case 'stage1': |
|
1866 echo '<h3>Manage page access</h3> |
|
1867 <p>Please select who should be affected by this access rule.</p>'; |
|
1868 echo $formstart; |
|
1869 echo '<p><label><input type="radio" name="data[target_type]" value="' . ACL_TYPE_GROUP . '" checked="checked" /> A usergroup</label></p> |
|
1870 <p><select name="data[target_id_grp]">'; |
|
1871 foreach ( $response['groups'] as $group ) |
|
1872 { |
|
1873 echo '<option value="' . $group['id'] . '">' . $group['name'] . '</option>'; |
|
1874 } |
|
1875 echo '</select></p> |
|
1876 <p><label><input type="radio" name="data[target_type]" value="' . ACL_TYPE_USER . '" /> A specific user</label></p> |
|
1877 <p>' . $template->username_field('data[target_id_user]') . '</p> |
|
1878 <p>What should this access rule control?</p> |
|
1879 <p><label><input name="data[scope]" value="only_this" type="radio" checked="checked" /> Only this page</p> |
|
1880 <p><label><input name="data[scope]" value="entire_site" type="radio" /> The entire site</p> |
|
1881 <div style="margin: 0 auto 0 0; text-align: right;"> |
|
1882 <input name="data[mode]" value="seltarget" type="hidden" /> |
|
1883 <input type="hidden" name="data[page_id]" value="' . $paths->cpage['urlname_nons'] . '" /> |
|
1884 <input type="hidden" name="data[namespace]" value="' . $paths->namespace . '" /> |
|
1885 <input type="submit" value="Next >" /> |
|
1886 </div>'; |
|
1887 echo $formend; |
|
1888 break; |
|
1889 case 'success': |
|
1890 echo '<div class="info-box"> |
|
1891 <b>Permissions updated</b><br /> |
|
1892 The permissions for ' . $response['target_name'] . ' on this page have been updated successfully.<br /> |
|
1893 ' . $formstart . ' |
|
1894 <input type="hidden" name="data[mode]" value="seltarget" /> |
|
1895 <input type="hidden" name="data[target_type]" value="' . $response['target_type'] . '" /> |
|
1896 <input type="hidden" name="data[target_id_user]" value="' . ( ( intval($response['target_type']) == ACL_TYPE_USER ) ? $response['target_name'] : $response['target_id'] ) .'" /> |
|
1897 <input type="hidden" name="data[target_id_grp]" value="' . ( ( intval($response['target_type']) == ACL_TYPE_USER ) ? $response['target_name'] : $response['target_id'] ) .'" /> |
|
1898 <input type="hidden" name="data[scope]" value="' . ( ( $response['page_id'] ) ? 'only_this' : 'entire_site' ) . '" /> |
|
1899 <input type="hidden" name="data[page_id]" value="' . ( ( $response['page_id'] ) ? $response['page_id'] : 'false' ) . '" /> |
|
1900 <input type="hidden" name="data[namespace]" value="' . ( ( $response['namespace'] ) ? $response['namespace'] : 'false' ) . '" /> |
|
1901 <input type="submit" value="Return to ACL editor" /> <input type="submit" name="data[act_go_stage1]" value="Return to user/scope selection" /> |
|
1902 ' . $formend . ' |
|
1903 </div>'; |
|
1904 break; |
|
1905 case 'delete': |
|
1906 echo '<div class="info-box"> |
|
1907 <b>Rule deleted</b><br /> |
|
1908 The selected access rule has been successfully deleted.<br /> |
|
1909 ' . $formstart . ' |
|
1910 <input type="hidden" name="data[mode]" value="seltarget" /> |
|
1911 <input type="hidden" name="data[target_type]" value="' . $response['target_type'] . '" /> |
|
1912 <input type="hidden" name="data[target_id_user]" value="' . ( ( intval($response['target_type']) == ACL_TYPE_USER ) ? $response['target_name'] : $response['target_id'] ) .'" /> |
|
1913 <input type="hidden" name="data[target_id_grp]" value="' . ( ( intval($response['target_type']) == ACL_TYPE_USER ) ? $response['target_name'] : $response['target_id'] ) .'" /> |
|
1914 <input type="hidden" name="data[scope]" value="' . ( ( $response['page_id'] ) ? 'only_this' : 'entire_site' ) . '" /> |
|
1915 <input type="hidden" name="data[page_id]" value="' . ( ( $response['page_id'] ) ? $response['page_id'] : 'false' ) . '" /> |
|
1916 <input type="hidden" name="data[namespace]" value="' . ( ( $response['namespace'] ) ? $response['namespace'] : 'false' ) . '" /> |
|
1917 <input type="submit" value="Return to ACL editor" /> <input type="submit" name="data[act_go_stage1]" value="Return to user/scope selection" /> |
|
1918 ' . $formend . ' |
|
1919 </div>'; |
|
1920 break; |
|
1921 case 'seltarget': |
|
1922 if ( $response['type'] == 'edit' ) |
|
1923 { |
|
1924 echo '<h3>Editing permissions</h3>'; |
|
1925 } |
|
1926 else |
|
1927 { |
|
1928 echo '<h3>Create new rule</h3>'; |
|
1929 } |
|
1930 $type = ( $response['target_type'] == ACL_TYPE_GROUP ) ? 'group' : 'user'; |
|
1931 $scope = ( $response['page_id'] ) ? 'this page' : 'this entire site'; |
|
1932 echo 'This panel allows you to edit what the '.$type.' "'.$response['target_name'].'" can do on <b>'.$scope.'</b>. Unless you set a permission to "Deny", these permissions may be overridden by other rules.'; |
|
1933 echo $formstart; |
|
1934 $parser = $template->makeParserText( $response['template']['acl_field_begin'] ); |
|
1935 echo $parser->run(); |
|
1936 $parser = $template->makeParserText( $response['template']['acl_field_item'] ); |
|
1937 $cls = 'row2'; |
|
1938 foreach ( $response['acl_types'] as $acl_type => $value ) |
|
1939 { |
|
1940 $vars = Array( |
|
1941 'FIELD_DENY_CHECKED' => '', |
|
1942 'FIELD_DISALLOW_CHECKED' => '', |
|
1943 'FIELD_WIKIMODE_CHECKED' => '', |
|
1944 'FIELD_ALLOW_CHECKED' => '', |
|
1945 ); |
|
1946 $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; |
|
1947 $vars['ROW_CLASS'] = $cls; |
|
1948 |
|
1949 switch ( $response['current_perms'][$acl_type] ) |
|
1950 { |
|
1951 case AUTH_ALLOW: |
|
1952 $vars['FIELD_ALLOW_CHECKED'] = 'checked="checked"'; |
|
1953 break; |
|
1954 case AUTH_WIKIMODE: |
|
1955 $vars['FIELD_WIKIMODE_CHECKED'] = 'checked="checked"'; |
|
1956 break; |
|
1957 case AUTH_DISALLOW: |
|
1958 default: |
|
1959 $vars['FIELD_DISALLOW_CHECKED'] = 'checked="checked"'; |
|
1960 break; |
|
1961 case AUTH_DENY: |
|
1962 $vars['FIELD_DENY_CHECKED'] = 'checked="checked"'; |
|
1963 break; |
|
1964 } |
|
1965 $vars['FIELD_NAME'] = 'data[perms][' . $acl_type . ']'; |
|
1966 $vars['FIELD_DESC'] = $response['acl_descs'][$acl_type]; |
|
1967 $parser->assign_vars($vars); |
|
1968 echo $parser->run(); |
|
1969 } |
|
1970 $parser = $template->makeParserText( $response['template']['acl_field_end'] ); |
|
1971 echo $parser->run(); |
|
1972 echo '<div style="margin: 10px auto 0 0; text-align: right;"> |
|
1973 <input name="data[mode]" value="save_' . $response['type'] . '" type="hidden" /> |
|
1974 <input type="hidden" name="data[page_id]" value="' . (( $response['page_id'] ) ? $response['page_id'] : 'false') . '" /> |
|
1975 <input type="hidden" name="data[namespace]" value="' . (( $response['namespace'] ) ? $response['namespace'] : 'false') . '" /> |
|
1976 <input type="hidden" name="data[target_type]" value="' . $response['target_type'] . '" /> |
|
1977 <input type="hidden" name="data[target_id]" value="' . $response['target_id'] . '" /> |
|
1978 <input type="hidden" name="data[target_name]" value="' . $response['target_name'] . '" /> |
|
1979 <input type="submit" value="Save changes" /> <input type="submit" name="data[act_delete_rule]" value="Delete rule" style="color: #AA0000;" onclick="return confirm(\'Do you really want to delete this ACL rule?\');" /> |
|
1980 </div>'; |
|
1981 echo $formend; |
|
1982 break; |
|
1983 case 'error': |
|
1984 ob_end_clean(); |
|
1985 die_friendly('Error occurred', '<p>Error returned by permissions API:</p><pre>' . htmlspecialchars($response['error']) . '</pre>'); |
|
1986 break; |
|
1987 } |
|
1988 $ret = ob_get_contents(); |
|
1989 ob_end_clean(); |
|
1990 echo |
|
1991 $template->getHeader() . |
|
1992 $ret . |
|
1993 $template->getFooter(); |
|
1994 } |
|
1995 |
|
1996 /** |
|
1997 * Preprocessor to turn the form-submitted data from the ACL editor into something the backend can handle |
|
1998 * @param array The posted data |
|
1999 * @return array |
|
2000 * @access private |
|
2001 */ |
|
2002 |
|
2003 function acl_preprocess($parms) |
|
2004 { |
|
2005 if ( !isset($parms['mode']) ) |
|
2006 // Nothing to do |
|
2007 return $parms; |
|
2008 switch ( $parms['mode'] ) |
|
2009 { |
|
2010 case 'seltarget': |
|
2011 |
|
2012 // Who's affected? |
|
2013 $parms['target_type'] = intval( $parms['target_type'] ); |
|
2014 $parms['target_id'] = ( $parms['target_type'] == ACL_TYPE_GROUP ) ? $parms['target_id_grp'] : $parms['target_id_user']; |
|
2015 |
|
2016 case 'save_edit': |
|
2017 case 'save_new': |
|
2018 if ( isset($parms['act_delete_rule']) ) |
|
2019 { |
|
2020 $parms['mode'] = 'delete'; |
|
2021 } |
|
2022 |
|
2023 // Scope (just this page or entire site?) |
|
2024 if ( $parms['scope'] == 'entire_site' || ( $parms['page_id'] == 'false' && $parms['namespace'] == 'false' ) ) |
|
2025 { |
|
2026 $parms['page_id'] = false; |
|
2027 $parms['namespace'] = false; |
|
2028 } |
|
2029 |
|
2030 break; |
|
2031 } |
|
2032 |
|
2033 if ( isset($parms['act_go_stage1']) ) |
|
2034 { |
|
2035 $parms = array( |
|
2036 'mode' => 'listgroups' |
|
2037 ); |
|
2038 } |
|
2039 |
|
2040 return $parms; |
|
2041 } |
|
2042 |
|
2043 function acl_postprocess($response) |
|
2044 { |
|
2045 if(!isset($response['mode'])) |
|
2046 { |
|
2047 if ( isset($response['groups']) ) |
|
2048 $response['mode'] = 'stage1'; |
|
2049 else |
|
2050 $response = Array( |
|
2051 'mode' => 'error', |
|
2052 'error' => 'Invalid action passed by API backend.', |
|
2053 ); |
|
2054 } |
|
2055 return $response; |
|
2056 } |
|
2057 |
|
2058 } |
|
2059 |
|
2060 ?> |