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