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