diff -r 000000000000 -r 902822492a68 plugins/SpecialAdmin.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/SpecialAdmin.php Wed Jun 13 16:03:00 2007 -0400 @@ -0,0 +1,2722 @@ +attachHook('base_classes_initted', ' + global $paths; + $paths->add_page(Array( + \'name\'=>\'Administration\', + \'urlname\'=>\'Administration\', + \'namespace\'=>\'Special\', + \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', + )); + + $paths->add_page(Array( + \'name\'=>\'Manage the Sidebar\', + \'urlname\'=>\'EditSidebar\', + \'namespace\'=>\'Special\', + \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', + )); + '); + +// function names are IMPORTANT!!! The name pattern is: page__ + +function page_Admin_Home() { + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + + // Basic information + echo RenderMan::render( +'== Welcome to Runt, the Enano administration panel. == + +Thank you for choosing Enano as your CMS. This screen allows you to see some information about your website, plus some details about how your site is doing statistically. + +Using the links on the left you can control every aspect of your website\'s look and feel, plus you can manage users, work with pages, and install plugins to make your Enano installation even better.'); + + // Check for the installer scripts + if(file_exists(ENANO_ROOT.'/install.php') || file_exists(ENANO_ROOT.'/schema.sql')) + { + echo '
NOTE: It appears that your install.php and/or schema.sql files still exist. It is HIGHLY RECOMMENDED that you delete or rename these files, to prevent getting your server hacked.
'; + } + + // Inactive users + $q = $db->sql_query('SELECT * FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\';'); + if($q) + if($db->numrows() > 0) + { + $n = $db->numrows(); + if($n == 1) $s = $n . ' user is'; + else $s = $n . ' users are'; + echo '
It appears that '.$s.' awaiting account activation. You can activate those accounts by going to the User Manager.
'; + } + $db->free_result(); + // Stats + if(getConfig('log_hits') == '1') + { + $stats = stats_top_pages(10); + $c = 0; + $cls = 'row2'; + echo '

Most requested pages

'; + foreach($stats as $page => $count) + { + if(isset($paths->pages[$page])) + { + echo ''; + $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; + echo ''; + echo ''; + } + } + echo '
PageHits
'.$paths->pages[$page]['name'].''.$count.'
'; + } + + // Security log + echo '

Security log

'; + echo '
'; + $cls = 'row2'; + echo ''; + if(isset($_GET['fulllog'])) + { + $l = 'SELECT action,date_string,author,edit_summary,time_id,page_text FROM '.table_prefix.'logs WHERE log_type=\'security\' ORDER BY time_id DESC, action ASC;'; + } + else + { + $l = 'SELECT action,date_string,author,edit_summary,time_id,page_text FROM '.table_prefix.'logs WHERE log_type=\'security\' ORDER BY time_id DESC, action ASC LIMIT 5'; + } + $q = $db->sql_query($l); + while($r = $db->fetchrow()) + { + if($cls == 'row2') $cls = 'row1'; + else $cls = 'row2'; + echo ''; + } + $db->free_result(); + echo '
TypeDateUsernameIP Address
'; + switch($r['action']) { + case "admin_auth_good": echo 'Successful elevated authentication'; if ( !empty($r['page_text']) ) { $level = $session->userlevel_to_string( intval($r['page_text']) ); echo "
Authentication level: $level"; } break; + case "admin_auth_bad": echo 'Failed administration logon'; break; + case "activ_good": echo 'Successful account activation'; break; + case "auth_good": echo 'Successful regular user logon'; break; + case "activ_bad": echo 'Failed account activation'; break; + case "auth_bad": echo 'Failed regular user logon'; break; + case "sql_inject": echo 'SQL injection attempt
Offending query: ' . htmlspecialchars($r['page_text']) . '
'; break; + case "db_backup": echo 'Database backup created
Tables: ' . $r['page_text'] . ''; break; + case "install_enano": echo "Installed Enano version {$r['page_text']}"; break; + } + echo '
'.date('d M Y h:i a', $r['time_id']).''.$r['author'].''.$r['edit_summary'].'
'; + if(!isset($_GET['fulllog'])) echo '

Full security log

'; + +} + +function page_Admin_GeneralConfig() { + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + if(isset($_POST['submit'])) { + + // Global site options + setConfig('site_name', $_POST['site_name']); + setConfig('site_desc', $_POST['site_desc']); + setConfig('main_page', str_replace(' ', '_', $_POST['main_page'])); + setConfig('copyright_notice', $_POST['copyright']); + setConfig('contact_email', $_POST['contact_email']); + + // Wiki mode + if(isset($_POST['wikimode'])) setConfig('wiki_mode', '1'); + else setConfig('wiki_mode', '0'); + if(isset($_POST['wiki_mode_require_login'])) setConfig('wiki_mode_require_login', '1'); + else setConfig('wiki_mode_require_login', '0'); + if(isset($_POST['editmsg'])) setConfig('wiki_edit_notice', '1'); + else setConfig('wiki_edit_notice', '0'); + setConfig('wiki_edit_notice_text', $_POST['editmsg_text']); + + // Stats + if(isset($_POST['log_hits'])) setConfig('log_hits', '1'); + else setConfig('log_hits', '0'); + + // Disablement + if(isset($_POST['site_disabled'])) { setConfig('site_disabled', '1'); setConfig('site_disabled_notice', $_POST['site_disabled_notice']); } + else setConfig('site_disabled', '0'); + + // Account activation + setConfig('account_activation', $_POST['account_activation']); + + // W3C compliance buttons + if(isset($_POST['w3c-vh32'])) setConfig("w3c_vh32", "1"); + else setConfig("w3c_vh32", "0"); + if(isset($_POST['w3c-vh40'])) setConfig("w3c_vh40", "1"); + else setConfig("w3c_vh40", "0"); + if(isset($_POST['w3c-vh401'])) setConfig("w3c_vh401", "1"); + else setConfig("w3c_vh401", "0"); + if(isset($_POST['w3c-vxhtml10'])) setConfig("w3c_vxhtml10", "1"); + else setConfig("w3c_vxhtml10", "0"); + if(isset($_POST['w3c-vxhtml11'])) setConfig("w3c_vxhtml11", "1"); + else setConfig("w3c_vxhtml11", "0"); + if(isset($_POST['w3c-vcss'])) setConfig("w3c_vcss", "1"); + else setConfig("w3c_vcss", "0"); + + // SourceForge.net logo + if(isset($_POST['showsf'])) setConfig('sflogo_enabled', '1'); + else setConfig('sflogo_enabled', '0'); + setConfig('sflogo_groupid', $_POST['sfgroup']); + setConfig('sflogo_type', $_POST['sflogo']); + + // Comment options + if(isset($_POST['comment-approval'])) setConfig('approve_comments', '1'); + else setConfig('approve_comments', '0'); + if(isset($_POST['enable-comments'])) setConfig('enable_comments', '1'); + else setConfig('enable_comments', '0'); + setConfig('comments_need_login', $_POST['comments_need_login']); + + // Powered by link + if ( isset($_POST['enano_powered_link']) ) setConfig('powered_btn', '1'); + else setConfig('powered_btn', '0'); + + if(isset($_POST['dbdbutton'])) setConfig('dbd_button', '1'); + else setConfig('dbd_button', '0'); + + if($_POST['emailmethod'] == 'phpmail') setConfig('smtp_enabled', '0'); + else setConfig('smtp_enabled', '1'); + + setConfig('smtp_server', $_POST['smtp_host']); + setConfig('smtp_user', $_POST['smtp_user']); + if($_POST['smtp_pass'] != 'XXXXXXXXXXXX') setConfig('smtp_password', $_POST['smtp_pass']); + + echo '
Your changes to the site configuration have been saved.

'; + + } + echo('
'); + ?> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Global site options
These options control the entire site.
Site name:
Site description:
Main page: pagename_field('main_page', str_replace('_', ' ', getConfig('main_page'))); ?>
Copyright notice shown on pages:
Hint: If you're using Windows, you can make a "©" symbol by holding ALT and pressing 0169 on the numeric keypad.
Contact e-mail
All e-mail sent from this site will appear to have come from the address shown here.
Wiki mode
+ Enano can also act as a wiki, meaning anyone can edit and create pages. To enable Wiki Mode, check the box to the right.

+ In Wiki Mode, certain HTML tags such as <script> and <object> are disabled, and all PHP code is disabled, except if the person editing the page is an administrator.

+ Also, Enano keeps complete page history, which makes restoring vandalized pages easy. You can also protect pages so that they cannot be edited. +
+ /> +
+ Edit page notice
+ When Wiki Mode is enabled, anyone can edit pages. Check the box below and enter a message to display it whenever the page editor is opened. +
+ /> +
+ +
Statistics and hit counting
Enano has the ability to show statistics for every page on the site. This allows you to keep very close track of who is visiting your site, and from where.

Unfortunately, some users don't like being logged. For this reason, you should state clearly what is logged (usually the username or IP address, current time, page name, and referer URL) in your privacy policy. If your site is primarily geared towards children, and you are a United States citizen, you are required to have a privacy policy stating exactly what is being logged under the terms of the Childrens' Online Privacy Protection Act.

This excludes special and administration pages.
Comment system
/>
/>
Guest comment posting allowed + +
Promote Enano
+ If you think Enano is nice, or if you want to show your support for the Enano team, you can do so by placing a link to the Enano + homepage in your Links sidebar block. You absolutely don't have to do this, and you won't get degraded support if you don't. Because + Enano is still relatively new in the CMS world, it needs all the attention it can get - and you can easily help to spread the word + using this link. + + +
Disable all site access
Disabling the site allows you to work on the site without letting non-administrators see or use it.
+
+ Message to show to users:
+ +
+
User account activation
+ If you would like to require users to confirm their e-mail addresses by way of account activation, you can enable this behavior here. If this option is set to "None", users will be able to register and use this site without confirming their e-mail addresses. If this option is set to "User", users will automatically be sent e-mails upon registration with a link to activate their accounts. And lastly, if this option is set to "Admin", users' accounts will not be active until an administrator activates the account.

+ You may also disable registration completely if needed.

+ Note: because of abuse by project administrators, sending account activation e-mails will not work on SourceForge.net servers. +
Account activation: + Disable registration
'; + echo ''; + echo ''; + echo ''; + ?> +
E-mail sent from the site
E-mail sending method:
Try using the built-in e-mail method first. If that doesn't work, you will need to enter valid SMTP information here.

+
SMTP hostname:
This option only applies to the external SMTP mode.
SMTP credentials:
This option only applies to the external SMTP mode.
Username:
+ Password:
SourceForge.net logo
+ All projects hosted by SourceForge.net are required to display an official SourceForge.net logo on their pages. If you want + to display a SourceForge.net logo on the sidebar, check the box below, enter your group ID, and select an image type. +
Display the SourceForge.net logo on the right sidebar />
Group ID:
Logo style: + +
W3C compliance logos
Enano generates (by default) Valid XHTML 1.1 code, plus valid CSS. If you want to show this off, check the appropriate boxes below.
id="w3c-vh32" name="w3c-vh32" />
id="w3c-vh40" name="w3c-vh40" />
id="w3c-vh401" name="w3c-vh401" />
id="w3c-vxhtml10" name="w3c-vxhtml10" />
id="w3c-vxhtml11" name="w3c-vxhtml11" />
id="w3c-vcss" name="w3c-vcss" />
Defective By Design Anti-DRM button
The Enano project is strongly against Digital Restrictions Management. DRM removes the freedoms that every consumer should have: to freely copy and use digital media items they legally purchased to their own devices. Showing your opposition to DRM is as easy as checking the box below to place a link to DefectiveByDesign.org on your sidebar.
/>
+
+
+ auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + if(isset($_POST['save'])) + { + if(isset($_POST['enable_uploads'])) setConfig('enable_uploads', '1'); else setConfig('enable_uploads', '0'); + if(isset($_POST['enable_imagemagick'])) setConfig('enable_imagemagick', '1'); else setConfig('enable_imagemagick', '0'); + if(isset($_POST['cache_thumbs'])) setConfig('cache_thumbs', '1'); else setConfig('cache_thumbs', '0'); + if(isset($_POST['file_history'])) setConfig('file_history', '1'); else setConfig('file_history', '0'); + if(file_exists($_POST['imagemagick_path'])) setConfig('imagemagick_path', $_POST['imagemagick_path']); + else echo 'Warning: the file "'.$_POST['imagemagick_path'].'" was not found, and the ImageMagick file path was not updated.'; + $max_upload = floor((float)$_POST['max_file_size'] * (int)$_POST['fs_units']); + setConfig('max_file_size', $max_upload.''); + } + echo '
'; + ?> +

File upload configuration

+

Enano supports the ability to upload files to your website and store the files in the database. This enables you to embed images + and such into pages without manually writing the HTML. However, the upload feature can sometimes pose a risk to your site, as viruses + and executable files can sometimes be uploaded.

+

+

Maximum file size:

+

You can allow Enano to generate thumbnails of images automatically. This feature requires ImageMagick to work properly. If your server + does not have ImageMagick on it, Enano will simply make your users' browsers scale the images. In most cases this is fine, but if you + are uploading large (>100KB) images and embedding them inside of pages, you should try to enable ImageMagick because transferring these + large images many times can cost you quite a lot of bandwidth.

+


+ Path to ImageMagick:
+ On Linux and Unix servers, the most likely options here are /usr/bin/convert and /usr/local/bin/convert. If you server runs Windows, then + ImageMagick is most likely to be C:\Windows\Convert.exe or C:\Windows\System32\Convert.exe. +

+

If you use ImageMagick to scale images, your server will be very busy constantly scaling images if your website is busy, and your site + may experience slowdowns. You can dramatically speed up this scaling process if you use a directory to cache thumbnail images.

+

Please note: the cache/ directory on your server must be writable by the server. While this is not usually a problem on + Windows servers, most Linux/Unix servers will require you to CHMOD the cache/ directory to 777. See your FTP client's user guide for + more information on how to do this.At present, it seems that the cache directory + is not writable. The checkbox below has been disabled to maintain the stability of Enano.'; ?>

+

+

Lastly, you can choose whether file history will be saved. If this option is turned on, you will be able to roll back any malicious + changes made to uploaded files, but this requires a significant amount of database storage. You should probably leave this option + enabled unless you have less than 250MB of MySQL database space.

+

+
+

+ '; +} + +function page_Admin_PluginManager() { + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + + if(isset($_GET['action'])) { + switch($_GET['action']) { + case "enable": + setConfig('plugin_'.$_GET['plugin'], '1'); + break; + case "disable": + if($_GET['plugin']!='admin.php') setConfig('plugin_'.$_GET['plugin'], '0'); + else echo('

Error disabling plugin

The administration panel plugin cannot be disabled.

'); + break; + } + } + $dir = './plugins/'; + $plugin_list = Array(); + $system = Array(); + if (is_dir($dir)) { + if ($dh = opendir($dir)) { + while (($file = readdir($dh)) !== false) { + if(preg_match('#^(.*?)\.php$#is', $file) && $file != 'index.php') + { + if ( in_array($file, $plugins->system_plugins) ) + { + $thelist =& $system; + continue; + } + else + { + $thelist =& $plugin_list; + } + $f = file_get_contents($dir . $file); + $f = explode("\n", $f); + $f = array_slice($f, 2, 7); + $f[0] = substr($f[0], 13, strlen($f[0])); + $f[1] = substr($f[1], 12, strlen($f[1])); + $f[2] = substr($f[2], 13, strlen($f[2])); + $f[3] = substr($f[3], 8, strlen($f[3])); + $f[4] = substr($f[4], 9, strlen($f[4])); + $f[5] = substr($f[5], 12, strlen($f[5])); + $thelist[$file] = Array(); + $thelist[$file]['name'] = $f[0]; + $thelist[$file]['uri'] = $f[1]; + $thelist[$file]['desc'] = $f[2]; + $thelist[$file]['auth'] = $f[3]; + $thelist[$file]['vers'] = $f[4]; + $thelist[$file]['aweb'] = $f[5]; + } + } + closedir($dh); + } + } + echo('
+ '); + $plugin_files = array_keys($plugin_list); + $cls = 'row2'; + for ( $i = 0; $i < sizeof($plugin_files); $i++ ) + { + $cls = ( $cls == 'row2' ) ? 'row3' : 'row2'; + echo ' + + + + + + '; + } + echo '
Plugin filenamePlugin nameDescriptionAuthorVersion
'.$plugin_files[$i].''.$plugin_list[$plugin_files[$i]]['name'].''.$plugin_list[$plugin_files[$i]]['desc'].''.$plugin_list[$plugin_files[$i]]['auth'].''.$plugin_list[$plugin_files[$i]]['vers'].''; + if ( getConfig('plugin_'.$plugin_files[$i]) == '1' ) + { + echo 'Disable'; + } + else + { + echo 'Enable'; + } + echo '
'; +} + +function page_Admin_UploadAllowedMimeTypes() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + global $mime_types, $mimetype_exps, $mimetype_extlist; + if(isset($_POST['save'])) + { + $bits = ''; + $keys = array_keys($mime_types); + foreach($keys as $i => $k) + { + if(isset($_POST['ext_'.$k])) $bits .= '1'; + else $bits .= '0'; + } + $bits = compress_bitfield($bits); + setConfig('allowed_mime_types', $bits); + echo '
Your changes have been saved.
'; + } + $allowed = fetch_allowed_extensions(); + ?> +

Allowed file types

+

Using the form below, you can decide which file types are allowed to be uploaded to this site.

+ nslist['Special'].'Administration', (( isset($_GET['sqldbg'])) ? 'sqldbg&' : '') .'module='.$paths->cpage['module']).'" method="post">'; + $c = -1; + $t = -1; + $cl = 'row1'; + echo "\n".'
'."\n".' '."\n".' '."\n "; + foreach($mime_types as $e => $m) + { + $c++; + $t++; + if($c == 3) + { + $c = 0; + $cl = ( $cl == 'row1' ) ? 'row2' : 'row1'; + echo ''."\n".' '."\n "; + } + $seed = "extchkbx_{$e}_".md5(microtime() . mt_rand()); + $chk = (!empty($allowed[$e])) ? ' checked="checked"' : ''; + echo " \n "; + } + while($c < 2) + { + $c++; + echo " \n "; + } + echo ''; + echo ''."\n".'
\n \n
'."\n".'
'; + echo '
'; + ?> + auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + ?> +

Editing and managing the Enano sidebar

+

The Enano sidebar is a versatile tool when scripted correctly. You don't have to be a programmer to enjoy the features the Sidebar + provides; however, editing the sidebar requires a small bit of programming knowledge and an understanding of Enano's system message + markup language. +

+

The Enano system markup language is somewhat similar to HTML, in that it uses tags (<example>like this</example>) for the + main syntax. However, Enano uses curly brackets ({ and }) as opposed to less-than and greater-than signs (< and >).

+

Programming the Enano sidebar requires the use of two tags: {slider} and {if}. The {slider} tag is used to create a new heading + on the sidebar, and all text enclosed in that tag will be collapsed when the heading is clicked. To specify the text on the heading, + use an equals sign (=) after the "slider" text. Then insert any links (they should be wiki-formatted) to internal Enano pages and + external sites.

+

So here is what the language for the default sidebar's "Navigation" heading looks like:

+
{slider=Navigation}
+  [[Main Page|Home]]
+  [[Enano:Sidebar|Edit the sidebar]]
+{/slider}
+

Pretty simple, huh? Good, now we're going to learn another common aspect of Enano programming: conditionals. The {if} tag allows you + to decide whether a portion of the sidebar will be displayed based on a template variable. Currently the only available conditions are + "user_logged_in" and "auth_admin", but more will be added soon. To use a conditional, enter {if conditional_name}, and then the + wiki-formatted text that you want to be under that condition, and then close the tag with {/if}. In the same way, you can reverse the + effect with {!if}. With {!if}, the closing tag is still {/if}, so keep that in mind. An {else} tag will be supported soon.

+

Now it's time for some real fun: variables. All template variables can be accessed from the sidebar. A variable is simply the + variable name, prefixed by a dollar sign ($). Some of the most common variables are $USERNAME, $SITE_NAME, $SITE_DESC, and $PAGE_NAME. + The sidebar also has some special variables that it uses for some of its links. The logout link can be added with $LOGOUT_LINK, and + the "change theme" button can be added with $STYLE_LINK.

+

So here is the Enano markup for the portion of the sidebar that contains the user tools:

+
{slider=$USERNAME}
+  [[User:$USERNAME|User page]]
+  [[Special:Contributions?user=$USERNAME|My Contributions]]
+  {if user_logged_in}
+    [[Special:Preferences|Preferences]]
+    $THEME_LINK
+  {/if}
+  {if auth_admin}
+    [[Special:Administration|Administration]]
+  {/if}
+  {if user_logged_in}
+    $LOGOUT_LINK
+  {/if}
+  {!if user_logged_in}
+    Create an account
+    Log in
+  {/if}
+{/slider}
+ auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + if(isset($_POST['go'])) { + // We need the user ID before we can do anything + $q = $db->sql_query('SELECT user_id,username,email,real_name,style,user_level FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_POST['username']) . '\''); + if(!$q) die('Error selecting user ID: '.mysql_error()); + if($db->numrows() < 1) { echo('User does not exist, please enter another username.'); return; } + $r = $db->fetchrow(); + $db->free_result(); + if(isset($_POST['save'])) + { + $_POST['level'] = intval($_POST['level']); + + $new_level = $_POST['level']; + $old_level = intval($r['user_level']); + + $re = $session->update_user((int)$r['user_id'], $_POST['new_username'], false, $_POST['new_pass'], $_POST['email'], $_POST['real_name'], false, $_POST['level']); + + if($re == 'success') + { + + if ( $new_level != $old_level ) + { + $user_id = intval($r['user_id']); + // We need to update group memberships + if ( $old_level == USER_LEVEL_ADMIN ) + { + $session->remove_user_from_group($user_id, GROUP_ID_ADMIN); + } + else if ( $old_level == USER_LEVEL_MOD ) + { + $session->remove_user_from_group($user_id, GROUP_ID_MOD); + } + + if ( $new_level == USER_LEVEL_ADMIN ) + { + $session->add_user_to_group($user_id, GROUP_ID_ADMIN, false); + } + else if ( $new_level == USER_LEVEL_MOD ) + { + $session->add_user_to_group($user_id, GROUP_ID_MOD, false); + } + } + + echo('
Your changes have been saved.
'); + } + else + { + echo('
Error saving changes: '.implode('
', $re).'
'); + } + $q = $db->sql_query('SELECT user_id,username,email,real_name,style,user_level FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['username']).'\''); + if ( !$q ) + { + die('Error selecting user ID: '.mysql_error()); + } + if($db->numrows($q) < 1) + { + die('User does not exist, please enter another username.'); + } + $r = mysql_fetch_object($q); + $db->free_result(); + } + elseif(isset($_POST['deleteme']) && isset($_POST['delete_conf'])) + { + $q = $db->sql_query('DELETE FROM users WHERE user_id='.$r['user_id'].';'); + if($q) + { + echo '
The user account "'.$r['username'].'" was deleted.
'; + } + else + { + echo '
The user account "'.$r['username'].'" could not be deleted due to a database error.

'.$db->get_error().'
'; + } + } + else + { + echo(' +

Edit User Info

+
+ + + + + + + +
Username:
New Password:
E-mail:
Real Name:
User level:
Delete user: +
+
+
+ '); + } + } elseif(isset($_POST['clearsessions'])) { + // Get the current session information so the user doesn't get logged out + $aes = new AESCrypt(); + $sk = md5($session->sid_super); + $qb = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.$sk.'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_ADMIN); + if(!$qb) die('Error selecting session key info block B: '.$db->get_error()); + if($db->numrows($qb) < 1) die('Error: cannot read admin session info block B, aborting table clear process'); + $qa = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.md5($session->sid).'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_MEMBER); + if(!$qa) die('Error selecting session key info block A: '.$db->get_error()); + if($db->numrows($qa) < 1) die('Error: cannot read user session info block A, aborting table clear process'); + $ra = mysql_fetch_object($qa); + $rb = mysql_fetch_object($qb); + $db->free_result($qa); + $db->free_result($qb); + $db->sql_query('DELETE FROM '.table_prefix.'session_keys;'); + $db->sql_query('INSERT INTO '.table_prefix.'session_keys( session_key,salt,user_id,auth_level,source_ip,time ) VALUES( \''.$ra->session_key.'\', \''.$ra->salt.'\', \''.$session->user_id.'\', \''.$ra->auth_level.'\', \''.$ra->source_ip.'\', '.$ra->time.' ),( \''.$rb->session_key.'\', \''.$rb->salt.'\', \''.$session->user_id.'\', \''.$rb->auth_level.'\', \''.$rb->source_ip.'\', '.$rb->time.' )'); + echo(' +
The session key table has been cleared. Your database should be a little bit smaller now.
+ '); + } + echo(' +

User Management

+
+

Username: '.$template->username_field('username').'

+

Clear session keys table

+

It\'s a good idea to clean out your session keys table every once in a while, since this helps to reduce database size. During this process you will be logged off and (hopefully) logged back on automatically. The side effects of this include all users except you being logged off.

+

+
+ '); + if(isset($_GET['action']) && isset($_GET['user'])) + { + switch($_GET['action']) + { + case "activate": + $e = $db->sql_query('SELECT activation_key FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_GET['user']) . '\''); + if($e) + { + $row = $db->fetchrow(); + $db->free_result(); + if($session->activate_account($_GET['user'], $row['activation_key'])) { echo '
The user account "'.$_GET['user'].'" has been activated.
'; $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid'])); } + else echo '
The user account "'.$_GET['user'].'" has NOT been activated, possibly because the account is already active.
'; + } else echo '
Error activating account: '.mysql_error().'
'; + break; + case "sendemail": + if($session->send_activation_mail($_GET['user'])) { echo '
The user "'.$_GET['user'].'" has been sent an e-mail with an activation link.
'; $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid'])); } + else echo '
The user account "'.$_GET['user'].'" has not been activated, probably because of a bad SMTP configuration.
'; + break; + case "deny": + $e = $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' AND edit_summary=\'' . $db->escape($_GET['user']) . '\';'); + if(!$e) echo '
Error during row deletion: '.mysql_error().'
'; + else echo '
All activation requests for the user "'.$_GET['user'].'" have been deleted.
'; + break; + } + } + $q = $db->sql_query('SELECT log_type, action, time_id, date_string, author, edit_summary FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' ORDER BY time_id DESC;'); + if($q) + { + if($db->numrows() > 0) + { + $n = $db->numrows(); + if($n == 1) $s = $n . ' user is'; + else $s = $n . ' users are'; + echo '

'.$s . ' awaiting account activation

'; + echo '
+ + '; + $cls = 'row2'; + while($row = $db->fetchrow()) + { + if($cls == 'row2') $cls = 'row1'; + else $cls = 'row2'; + echo ''; + } + echo '
Date of requestRequested byRequested forActions
'.date('F d, Y h:i a', $row['time_id']).''.$row['author'].''.$row['edit_summary'].'Activate nowSend activation e-mailDeny request
'; + } + $db->free_result(); + } +} + +function page_Admin_GroupManager() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + if(isset($_POST['do_create_stage1'])) + { + if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name'])) + { + echo '

The group name you chose is invalid.

'; + return; + } + echo '
'; + echo '
+ + + + + + + + + +
Creating group: '.$_POST['create_group_name'].'
Group moderator' . $template->username_field('group_mod') . '
Group status +
+
+
+ +
+ + +
+
'; + echo '
'; + return; + } + elseif(isset($_POST['do_create_stage2'])) + { + if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name'])) + { + echo '

The group name you chose is invalid.

'; + return; + } + if(!in_array(intval($_POST['group_status']), Array(GROUP_CLOSED, GROUP_OPEN, GROUP_HIDDEN, GROUP_REQUEST))) + { + echo '

Hacking attempt

'; + return; + } + $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';'); + if(!$e) + { + echo $db->get_error(); + return; + } + if($db->numrows() > 0) + { + echo '

The group name you entered already exists.

'; + return; + } + $db->free_result(); + $q = $db->sql_query('INSERT INTO '.table_prefix.'groups(group_name,group_type) VALUES( \''.$db->escape($_POST['create_group_name']).'\', ' . intval($_POST['group_status']) . ' )'); + if(!$q) + { + echo $db->get_error(); + return; + } + $e = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['group_mod']).'\';'); + if(!$e) + { + echo $db->get_error(); + return; + } + if($db->numrows() < 1) + { + echo '

The username you entered could not be found.

'; + return; + } + $row = $db->fetchrow(); + $id = $row['user_id']; + $db->free_result(); + $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';'); + if(!$e) + { + echo $db->get_error(); + return; + } + if($db->numrows() < 1) + { + echo '

The group ID could not be looked up.

'; + return; + } + $row = $db->fetchrow(); + $gid = $row['group_id']; + $db->free_result(); + $e = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.$gid.', '.$id.', 1);'); + if(!$e) + { + echo $db->get_error(); + return; + } + echo "
+ Information
+ The group {$_POST['create_group_name']} has been created successfully. +
"; + } + if(isset($_POST['do_edit']) || isset($_POST['edit_do'])) + { + // Fetch the group name + $q = $db->sql_query('SELECT group_name,system_group FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + if($db->numrows() < 1) + { + echo '

Error: couldn\'t look up group name

'; + } + $row = $db->fetchrow(); + $name = $row['group_name']; + $db->free_result(); + if(isset($_POST['edit_do'])) + { + if(isset($_POST['edit_do']['del_group'])) + { + if ( $row['system_group'] == 1 ) + { + echo '
The group "' . $name . '" could not be deleted because it is a system group required for site functionality.
'; + } + else + { + $q = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + $q = $db->sql_query('DELETE FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + echo '
The group "'.$name.'" has been deleted. Return to the group manager.
'; + return; + } + } + if(isset($_POST['edit_do']['save_name'])) + { + if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['group_name'])) + { + echo '

The group name you chose is invalid.

'; + return; + } + $q = $db->sql_query('UPDATE '.table_prefix.'groups SET group_name=\''.$db->escape($_POST['group_name']).'\' + WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + else + { + echo '
+ The group name has been updated. +
'; + } + $name = $_POST['group_name']; + + } + $q = $db->sql_query('SELECT member_id FROM '.table_prefix.'group_members + WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + if($db->numrows() > 0) + { + while($row = $db->fetchrow($q)) + { + if(isset($_POST['edit_do']['del_' . $row['member_id']])) + { + $e = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE member_id='.$row['member_id']); + if(!$e) + { + echo $db->get_error(); + return; + } + } + } + } + $db->free_result(); + if(isset($_POST['edit_do']['add_member'])) + { + $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['edit_add_username']).'\';'); + if(!$q) + { + echo $db->get_error(); + return; + } + if($db->numrows() > 0) + { + $row = $db->fetchrow(); + $user_id = $row['user_id']; + $is_mod = ( isset( $_POST['add_mod'] ) ) ? '1' : '0'; + $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.intval($_POST['group_edit_id']).','.$user_id.','.$is_mod.');'); + if(!$q) + { + echo $db->get_error(); + return; + } + else + { + echo '
+ The user "'.$_POST['edit_add_username'].'" has been added to this usergroup. +
'; + } + } + else + echo '
The user "'.$_POST['edit_add_username'].'" could not be added.
This username does not exist.
'; + } + } + $sg_disabled = ( $row['system_group'] == 1 ) ? ' value="Can\'t delete system group" disabled="disabled" style="color: #FF9773" ' : ' value="Delete this group" style="color: #FF3713" '; + echo '
'; + echo '
+ + + + + + + + +
Edit group name
+ Group name: +
+ + +
+
+ '; + echo '
'; + echo '
'; + echo '
+ + '; + $q = $db->sql_query('SELECT m.member_id,m.is_mod,u.username FROM '.table_prefix.'group_members AS m + LEFT JOIN '.table_prefix.'users AS u + ON u.user_id=m.user_id + WHERE m.group_id='.intval($_POST['group_edit_id']).' + ORDER BY m.is_mod DESC, u.username ASC;'); + if(!$q) + { + echo $db->get_error(); + return; + } + if($db->numrows() < 1) + { + echo ''; + } + else + { + $cls = 'row2'; + while($row = $db->fetchrow()) + { + $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; + $mod = ( $row['is_mod'] == 1 ) ? 'Mod' : ''; + echo ' + + + + '; + } + } + $db->free_result(); + echo '
Edit group members
This group has no members.
+ ' . $row['username'] . ' + + '.$mod.' + + +
+
+ '; + echo '
'; + echo '
'; + echo '
+ + + + + + + + + + + + + +
Add a new member
+ Username: ' . $template->username_field('edit_add_username') . ' +
+ (can add and delete other members) +
+ +
+
+ '; + echo '
'; + return; + } + echo '

Manage Usergroups

'; + echo '
'; + $q = $db->sql_query('SELECT group_id,group_name FROM '.table_prefix.'groups ORDER BY group_name ASC;'); + if(!$q) + { + echo $db->get_error(); + } + else + { + echo '
+ + + + '; + echo ''; + echo ' +
Edit an existing group
+
+

'; + } + echo '
'; + echo '
+ + + + '; + echo ''; + echo ' +
Create a new group
Group name:
+
'; + echo '
'; +} + +function page_Admin_PageManager() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + + echo '

Page management

'; + + if(isset($_POST['search']) || isset($_POST['select']) || ( isset($_GET['source']) && $_GET['source'] == 'ajax' )) { + // The object of the game: using only the text a user entered, guess the page ID and namespace. *sigh* I HATE writing search algorithms... + $source = ( isset($_GET['source']) ) ? $_GET['source'] : false; + if ( $source == 'ajax' ) + { + $_POST['search'] = true; + $_POST['page_url'] = $_GET['page_id']; + } + if(isset($_POST['search'])) $pid = $_POST['page_url']; + elseif(isset($_POST['select'])) $pid = $_POST['page_force_url']; + else { echo 'Internal error selecting page search terms'; return false; } + // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary + $k = array_keys($paths->nslist); + for($i=0;$inslist);$i++) + { + $ln = strlen($paths->nslist[$k[$i]]); + if(substr($pid, 0, $ln) == $paths->nslist[$k[$i]]) + { + $ns = $k[$i]; + $page_id = substr($pid, $ln, strlen($pid)); + } + } + // The namespace is in $ns and the page name or ID (we don't know which yet) is in $page_id + // Now, iterate through $paths->pages searching for a page with this name or ID + for($i=0;$ipages)/2;$i++) + { + if(!isset($final_pid)) + { + if ($paths->pages[$i]['urlname_nons'] == str_replace(' ', '_', $page_id)) $final_pid = str_replace(' ', '_', $page_id); + elseif($paths->pages[$i]['name'] == $page_id) $final_pid = $paths->pages[$i]['urlname_nons']; + elseif(strtolower($paths->pages[$i]['urlname_nons']) == strtolower(str_replace(' ', '_', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons']; + elseif(strtolower($paths->pages[$i]['name']) == strtolower(str_replace('_', ' ', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons']; + if(isset($final_pid)) { $_POST['name'] = $paths->pages[$i]['name']; $_POST['urlname'] = $paths->pages[$i]['urlname_nons']; } + } + } + if(!isset($final_pid)) { echo 'The page you searched for cannot be found. Back'; return false; } + $_POST['namespace'] = $ns; + $_POST['old_namespace'] = $ns; + $_POST['page_id'] = $final_pid; + $_POST['old_page_id'] = $final_pid; + if(!isset($paths->pages[$paths->nslist[$_POST['namespace']].$_POST['urlname']])) { echo 'The page you searched for cannot be found. Back'; return false; } + } + + if(isset($_POST['page_id']) && isset($_POST['namespace']) && !isset($_POST['cancel'])) + { + $cpage = $paths->pages[$paths->nslist[$_POST['namespace']].$_POST['old_page_id']]; + if(isset($_POST['submit'])) + { + // Create a list of things to update + $page_info = Array( + 'name'=>$_POST['name'], + 'urlname'=>$_POST['page_id'], + 'namespace'=>$_POST['namespace'], + 'special'=>isset($_POST['special']) ? '1' : '0', + 'visible'=>isset($_POST['visible']) ? '1' : '0', + 'comments_on'=>isset($_POST['comments_on']) ? '1' : '0', + 'protected'=>isset($_POST['protected']) ? '1' : '0' + ); + // Build the query + $q = 'UPDATE '.table_prefix.'pages SET '; + $k = array_keys($page_info); + foreach($k as $c) + { + $q .= $c.'=\''.$db->escape($page_info[$c]).'\','; + } + $q = substr($q, 0, strlen($q)-1); + // Build the WHERE statements + $q .= ' WHERE '; + $k = array_keys($cpage); + foreach($k as $c) + { + if($c != 'urlname_nons' && $c != 'urlname' && $c != 'really_protected') $q .= $c.'=\''.$cpage[$c].'\' AND '; + elseif($c == 'urlname') $q .= $c.'=\''.$cpage['urlname_nons'].'\' AND '; + } + $q = substr($q, 0, strlen($q)-5) . ';'; + // Send the completed query to MySQL + $e = $db->sql_query($q); + if(!$e) $db->_die('The page data could not be updated.'); + // Update any additional tables + $q = Array( + 'UPDATE '.table_prefix.'categories SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', + 'UPDATE '.table_prefix.'comments SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', + 'UPDATE '.table_prefix.'logs SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', + 'UPDATE '.table_prefix.'page_text SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', + ); + foreach($q as $cq) + { + $e = $db->sql_query($cq); + if(!$e) $db->_die('Some of the additional tables containing page information could not be updated.'); + } + // Update $cpage + $cpage = $page_info; + $cpage['urlname_nons'] = $cpage['urlname']; + $cpage['urlname'] = $paths->nslist[$cpage['namespace']].$cpage['urlname']; + $_POST['old_page_id'] = $page_info['urlname']; + $_POST['old_namespace'] = $page_info['namespace']; + echo '
Your changes have been saved.
'; + } elseif(isset($_POST['delete'])) { + $q = Array( + 'DELETE FROM '.table_prefix.'categories WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', + 'DELETE FROM '.table_prefix.'comments WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', + 'DELETE FROM '.table_prefix.'logs WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', + 'DELETE FROM '.table_prefix.'page_text WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', + ); + foreach($q as $cq) + { + $e = $db->sql_query($cq); + if(!$e) $db->_die('Some of the additional tables containing page information could not be updated.'); + } + + if(!$db->sql_query( + 'DELETE FROM '.table_prefix.'pages WHERE urlname="'.$db->escape($_POST['old_page_id']).'" AND namespace="'.$db->escape($_POST['old_namespace']).'";' + )) $db->_die('The page could not be deleted.'); + echo '
This page has been deleted.

Return to Page manager
Admin home

'; + return; + } + echo '
'; + ?> +

Modify page:

+ + + + + + + + + + + +
Namespace:
Page title:
Page URL string:
No spaces, and don't enter the namespace prefix (e.g. User:).
Changing this value is usually not a good idea, especially for templates and project pages.
name="comments_on" type="checkbox" id="cmt" />
name="special" type="checkbox" id="spc" />
This option enables you to use your own HTML headers and other code. It is recommended that only advanced users enable this feature. As with other Enano pages, you may use PHP code in your pages, meaning you can use Enano's API on the page.
name="visible" type="checkbox" id="vis" />
Unchecking this checkbox prevents the page for being indexed for searching. The index is rebuilt each time a page is saved, and you can force an index rebuild by going to the page nslist['Special']; ?>SearchRebuild.
name="protected" type="checkbox" id="prt" />
This option only has an effect when Wiki Mode is enabled.

+ + +
+ '; + } else { + echo '

Please select a page

'; + echo ''; + ?> +

Search for page title (remember prefixes like User: and File:) pagename_field('page_url'); ?>

+

Select page title from a list:

+ '; + + } +} + +function page_Admin_PageEditor() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + + echo '

Edit page content

'; + + if(isset($_POST['search']) || isset($_POST['select'])) { + // The object of the game: using only the text a user entered, guess the page ID and namespace. *sigh* I HATE writing search algorithms... + if(isset($_POST['search'])) $pid = $_POST['page_url']; + elseif(isset($_POST['select'])) $pid = $_POST['page_force_url']; + else { echo 'Internal error selecting page search terms'; return false; } + // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary + $k = array_keys($paths->nslist); + for($i=0;$inslist);$i++) + { + $ln = strlen($paths->nslist[$k[$i]]); + if(substr($pid, 0, $ln) == $paths->nslist[$k[$i]]) + { + $ns = $k[$i]; + $page_id = substr($pid, $ln, strlen($pid)); + } + } + // The namespace is in $ns and the page name or ID (we don't know which yet) is in $page_id + // Now, iterate through $paths->pages searching for a page with this name or ID + for($i=0;$ipages)/2;$i++) + { + if(!isset($final_pid)) + { + if ($paths->pages[$i]['urlname_nons'] == str_replace(' ', '_', $page_id)) $final_pid = str_replace(' ', '_', $page_id); + elseif($paths->pages[$i]['name'] == $page_id) $final_pid = $paths->pages[$i]['urlname_nons']; + elseif(strtolower($paths->pages[$i]['urlname_nons']) == strtolower(str_replace(' ', '_', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons']; + elseif(strtolower($paths->pages[$i]['name']) == strtolower(str_replace('_', ' ', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons']; + if(isset($final_pid)) { $_POST['name'] = $paths->pages[$i]['name']; $_POST['urlname'] = $paths->pages[$i]['urlname_nons']; } + } + } + if(!isset($final_pid)) { echo 'The page you searched for cannot be found. Back'; return false; } + $_POST['namespace'] = $ns; + $_POST['page_id'] = $final_pid; + if(!isset($paths->pages[$paths->nslist[$_POST['namespace']].$_POST['urlname']])) { echo 'The page you searched for cannot be found. Back'; return false; } + } + + if(isset($_POST['page_id']) && !isset($_POST['cancel'])) + { + echo ''; + if(!isset($_POST['content']) || isset($_POST['revert'])) $content = RenderMan::getPage($_POST['page_id'], $_POST['namespace'], 0, false, false, false, false); + else $content = $_POST['content']; + if(isset($_POST['save'])) + { + $data = $content; + $id = md5( microtime() . mt_rand() ); + + $minor = isset($_POST['minor']) ? 'true' : 'false'; + $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').'\', \'' . $db->escape($_POST['page_id']) . '\', \'' . $db->escape($_POST['namespace']) . '\', \''.$data.'\', \''.$id.'\', \''.$session->username.'\', \''.$db->escape(htmlspecialchars($_POST['summary'])).'\', '.$minor.');'; + if(!$db->sql_query($q)) $db->_die('The history (log) entry could not be inserted into the logs table.'); + + $query = 'UPDATE '.table_prefix.'page_text SET page_text=\''.$db->escape($data).'\',char_tag=\''.$id.'\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'' . $db->escape($_POST['namespace']) . '\';'; + $e = $db->sql_query($query); + if(!$e) echo '
The page data could not be saved. MySQL said: '.mysql_error().'

Query:
'.$query.'
'; + else echo '
Your page has been saved. View page...
'; + } elseif(isset($_POST['preview'])) { + echo '

Preview

Reminder: This is only a preview; your changes to this page have not yet been saved.

'.RenderMan::render($content).'
'; + } + ?> +

+
+ Edit summary:
+ +

+

+ + +        +

+ '; + } else { + echo '

Please select a page

'; + echo ''; + ?> +

Search for page title (remember prefixes like User: and File:) pagename_field('page_url'); ?>

+

Select page title from a list:

+ '; + } +} + +function page_Admin_ThemeManager() +{ + + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + + // Get the list of styles in the themes/ dir + $h = opendir('./themes'); + $l = Array(); + if(!$h) die('Error opening directory "./themes" for reading.'); + while(false !== ($n = readdir($h))) { + if($n != '.' && $n != '..' && is_dir('./themes/'.$n)) + $l[] = $n; + } + closedir($h); + echo(' +

Theme Management

+

Install, uninstall, and manage Enano themes.

+ '); + if(isset($_POST['disenable'])) { + $q = 'SELECT enabled FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\''; + $s = $db->sql_query($q); + if(!$s) die('Error selecting enabled/disabled state value: '.mysql_error().'
SQL:
'.$q); + $r = $db->fetchrow_num($s); + $db->free_result(); + if($r[0] == 1) $e = 0; + else $e = 1; + $s=true; + if($e==0) + { + $c = $db->sql_query('SELECT * FROM '.table_prefix.'themes WHERE enabled=1'); + if(!$c) $db->_die('The backup check for having at least on theme enabled failed.'); + if($db->numrows() <= 1) { echo '
You cannot disable the last remaining theme.
'; $s=false; } + } + $db->free_result(); + if($s) { + $q = 'UPDATE '.table_prefix.'themes SET enabled='.$e.' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\''; + $a = $db->sql_query($q); + if(!$a) die('Error updating enabled/disabled state value: '.mysql_error().'
SQL:
'.$q); + else echo('
The theme "'.$_POST['theme_id'].'" has been '. ( ( $e == '1' ) ? 'enabled' : 'disabled' ).'.
'); + } + } + elseif(isset($_POST['edit'])) { + + $dir = './themes/'.$_POST['theme_id'].'/css/'; + $list = Array(); + // Open a known directory, and proceed to read its contents + if (is_dir($dir)) { + if ($dh = opendir($dir)) { + while (($file = readdir($dh)) !== false) { + if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') { + $list[$file] = capitalize_first_letter(substr($file, 0, strlen($file)-4)); + } + } + closedir($dh); + } + } + $lk = array_keys($list); + + $q = 'SELECT theme_name,default_style FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\''; + $s = $db->sql_query($q); + if(!$s) die('Error selecting name value: '.mysql_error().'
SQL:
'.$q); + $r = $db->fetchrow_num($s); + $db->free_result(); + echo(''); + echo('
+ Theme name displayed to users:

+ Default stylesheet:

+ +
'); + echo(''); + } + elseif(isset($_POST['editsave'])) { + $q = 'UPDATE '.table_prefix.'themes SET theme_name=\'' . $db->escape($_POST['name']) . '\',default_style=\''.$db->escape($_POST['defaultcss']).'\' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\''; + $s = $db->sql_query($q); + if(!$s) die('Error updating name value: '.mysql_error().'
SQL:
'.$q); + else echo('
Theme data updated.
'); + } + elseif(isset($_POST['up'])) { + // If there is only one theme or if the selected theme is already at the top, do nothing + $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;'; + $s = $db->sql_query($q); + if(!$s) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); + $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\''; + $sn = $db->sql_query($q); + if(!$sn) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); + $r = $db->fetchrow_num($sn); + if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == 1 /* ...and check if this theme is already at the top */ ) { echo('
This theme is already at the top of the list, or there is only one theme installed.
'); } else { + // Get the order IDs of the selected theme and the theme before it + $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\''; + $s = $db->sql_query($q); + if(!$s) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); + $r = $db->fetchrow_num($s); + $r = $r[0]; + $rb = $r - 1; + // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;) + $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.''; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); + $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); + $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0'; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); + echo('
Theme moved up.
'); + } + $db->free_result($s); + $db->free_result($sn); + } + elseif(isset($_POST['down'])) { + // If there is only one theme or if the selected theme is already at the top, do nothing + $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;'; + $s = $db->sql_query($q); + if(!$s) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); + $r = $db->fetchrow_num($s); + if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == $db->numrows($s) /* ...and check if this theme is already at the bottom */ ) { echo('
This theme is already at the bottom of the list, or there is only one theme installed.
'); } else { + // Get the order IDs of the selected theme and the theme before it + $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\''; + $s = $db->sql_query($q); + if(!$s) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); + $r = $db->fetchrow_num($s); + $r = $r[0]; + $rb = $r + 1; + // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;) + $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.''; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); + $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); + $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0'; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); + echo('
Theme moved down.
'); + } + } + else if(isset($_POST['uninstall'])) + { + $q = 'SELECT * FROM '.table_prefix.'themes;'; + $s = $db->sql_query($q); + if ( !$s ) + { + die('Error getting theme count: '.mysql_error().'
SQL:
'.$q); + } + $n = $db->numrows($s); + $db->free_result(); + + if ( $_POST['theme_id'] == 'oxygen' ) + { + echo '
The Oxygen theme is used by Enano for installation, upgrades, and error messages, and cannot be uninstalled.
'; + } + else + { + if($n < 2) + { + echo '
The theme could not be uninstalled because it is the only theme left.
'; + } + else + { + $q = 'DELETE FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\' LIMIT 1;'; + $s = $db->sql_query($q); + if ( !$s ) + { + die('Error deleting theme data: '.mysql_error().'
SQL:
'.$q); + } + else + { + echo('
Theme uninstalled.
'); + } + } + } + } + elseif(isset($_POST['install'])) { + $q = 'SELECT * FROM '.table_prefix.'themes;'; + $s = $db->sql_query($q); + if(!$s) die('Error getting theme count: '.mysql_error().'
SQL:
'.$q); + $n = $db->numrows($s); + $n++; + $theme_id = $_POST['theme_id']; + $theme = Array(); + include('./themes/'.$theme_id.'/theme.cfg'); + $q = 'INSERT INTO '.table_prefix.'themes(theme_id,theme_name,theme_order,enabled) VALUES(\''.$theme['theme_id'].'\', \''.$theme['theme_name'].'\', '.$n.', 1)'; + $s = $db->sql_query($q); + if(!$s) die('Error inserting theme data: '.mysql_error().'
SQL:
'.$q); + else echo('
Theme "'.$theme['theme_name'].'" installed.
'); + } + echo(' +

Currently installed themes

+
+

+ +

+
+

Install a new theme

+ '); + $theme = Array(); + $obb = ''; + for($i=0;$isql_query($q); + if(!$s) die('Error selecting list of currently installed themes: '.mysql_error().'
Attempted SQL:
'.$q); + if($db->numrows($s) < 1) { + $obb .= ''; + } + $db->free_result(); + } + } + if($obb != '') { + echo('

'); + echo(''); + echo(' + +

'); + } else echo('

All themes are currently installed.

'); +} + +function page_Admin_BanControl() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + if(isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['id']) && $_GET['id'] != '') + { + $e = $db->sql_query('DELETE FROM '.table_prefix.'banlist WHERE ban_id=' . $db->escape($_GET['id']) . ''); + if(!$e) $db->_die('The ban list entry was not deleted.'); + } + if(isset($_POST['create'])) + { + $q = 'INSERT INTO '.table_prefix.'banlist(ban_type,ban_value,reason,is_regex) VALUES( ' . $db->escape($_POST['type']) . ', \'' . $db->escape($_POST['value']) . '\', \''.$db->escape($_POST['reason']).'\''; + if(isset($_POST['regex'])) $q .= ', 1'; + else $q .= ', 0'; + $q .= ');'; + $e = $db->sql_query($q); + if(!$e) $db->_die('The banlist could not be updated.'); + } + $q = $db->sql_query('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;'); + if(!$q) $db->_die('The banlist data could not be selected.'); + echo ''; + echo ''; + if($db->numrows() < 1) echo ''; + while($r = $db->fetchrow()) + { + if($r['ban_type']==BAN_IP) $t = 'IP address'; + elseif($r['ban_type']==BAN_USER) $t = 'Username'; + elseif($r['ban_type']==BAN_EMAIL) $t = 'E-mail address'; + if($r['is_regex']) $g = 'Yes'; else $g = 'No'; + echo ''; + } + $db->free_result(); + echo '
TypeValueRegular Expression
No ban rules yet.
'.$t.''.$r['ban_value'].''.$g.'Delete
'; + echo '

Create new ban rule

'; + echo '
'; + ?> + Type:
+ Rule:
+ Reason to show to the banned user:
+ (advanced users only)
+ + '; +} + +function page_Admin_MassEmail() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + global $enano_config; + if ( isset($_POST['do_send']) ) + { + $use_smtp = getConfig('smtp_enabled') == '1'; + + // + // Let's do some checking to make sure that mass mail functions + // are working in win32 versions of php. (copied from phpBB) + // + if ( preg_match('/[c-z]:\\\.*/i', getenv('PATH')) && !$use_smtp) + { + $ini_val = ( @phpversion() >= '4.0.0' ) ? 'ini_get' : 'get_cfg_var'; + + // We are running on windows, force delivery to use our smtp functions + // since php's are broken by default + $use_smtp = true; + $enano_config['smtp_server'] = @$ini_val('SMTP'); + } + + $mail = new emailer( !empty($use_smtp) ); + + // Validate subject/message body + $subject = stripslashes(trim($_POST['subject'])); + $message = stripslashes(trim($_POST['message'])); + + if ( empty($subject) ) + $errors[] = 'Please enter a subject.'; + if ( empty($message) ) + $errors[] = 'Please enter a message.'; + + // Get list of members + if ( !empty($_POST['userlist']) ) + { + $userlist = str_replace(', ', ',', $_POST['userlist']); + $userlist = explode(',', $userlist); + foreach ( $userlist as $k => $u ) + { + if ( $u == $session->username ) + { + // Message is automatically sent to the sender + unset($userlist[$k]); + } + else + { + $userlist[$k] = $db->escape($u); + } + } + $userlist = 'WHERE username=\'' . implode('\' OR username=\'', $userlist) . '\''; + + $q = $db->sql_query('SELECT email FROM '.table_prefix.'users ' . $userlist . ';'); + if ( !$q ) + $db->_die(); + + if ( $row = $db->fetchrow() ) + { + do { + $mail->cc($row['email']); + } while ( $row = $db->fetchrow() ); + } + + $db->free_result(); + + } + else + { + // Sending to a usergroup + + $group_id = intval($_POST['group_id']); + if ( $group_id < 1 ) + { + $errors[] = 'Invalid group ID'; + } + else + { + $q = $db->sql_query('SELECT u.email FROM '.table_prefix.'group_members AS g + LEFT JOIN '.table_prefix.'users AS u + ON (u.user_id=g.user_id) + WHERE g.group_id=' . $group_id . ';'); + if ( !$q ) + $db->_die(); + + if ( $row = $db->fetchrow() ) + { + do { + $mail->cc($row['email']); + } while ( $row = $db->fetchrow() ); + } + + $db->free_result(); + } + } + + if ( sizeof($errors) < 1 ) + { + + $mail->from(getConfig('contact_email')); + $mail->replyto(getConfig('contact_email')); + $mail->set_subject($subject); + $mail->email_address(getConfig('contact_email')); + + // Copied/modified from phpBB + $email_headers = 'X-AntiAbuse: Website server name - ' . $_SERVER['SERVER_NAME'] . "\n"; + $email_headers .= 'X-AntiAbuse: User_id - ' . $session->user_id . "\n"; + $email_headers .= 'X-AntiAbuse: Username - ' . $session->username . "\n"; + $email_headers .= 'X-AntiAbuse: User IP - ' . $_SERVER['REMOTE_ADDR'] . "\n"; + + $mail->extra_headers($email_headers); + + $tpl = 'The following message was mass-mailed by {SENDER}, one of the administrators from {SITE_NAME}. If this message contains spam or any comments which you find abusive or offensive, please contact the administration team at: + +{CONTACT_EMAIL} + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{MESSAGE} +'; + + $mail->use_template($tpl); + + $mail->assign_vars(array( + 'SENDER' => $session->username, + 'SITE_NAME' => getConfig('site_name'), + 'CONTACT_EMAIL' => getConfig('contact_email'), + 'MESSAGE' => $message + )); + + //echo '
'.print_r($mail,true).'
'; + + // All done + $mail->send(); + $mail->reset(); + + echo '
Your message has been sent.
'; + + } + else + { + echo '
Could not send message for the following reason(s):
  • ' . implode('
  • ', $errors) . '
'; + } + + } + echo ''; + ?> +
+ + + + + + + + + + + + + + + + + + + + + + + +
Send mass e-mail
+ Send message to:
+ + By default, this message will be sent to the group selected here. You may instead send the message to a specific + list of users by entering them in the second row, with usernames separated by a single comma (no space). + +
+ +
+ Usernames: +
+ Subject: + + +
+ Message: + + +
+
+ Please be warned: it may take a LONG time to send this message. Please do not stop the script until the process is finished. +
+
+ '; +} + +function page_Admin_DBBackup() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + global $system_table_list; + if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes') + { + + if(defined('SQL_BACKUP_CRYPT')) + // Try to increase our time limit + @set_time_limit(300); // five minutes + // Do the actual export + $aesext = ( defined('SQL_BACKUP_CRYPT') ) ? '.tea' : ''; + $filename = 'enano_backup_' . date('dmy') . '.sql' . $aesext; + ob_start(); + header('Content-disposition: attachment, filename="'.$filename.'";'); + header('Content-type: application/transact-sql'); + // Spew some headers + $headdate = date('F d, Y \a\t h:i a'); + echo <<
username} + +HEADER; + // build the table list + $base = ( isset($_POST['do_system_tables']) ) ? $system_table_list : Array(); + $add = ( isset($_POST['additional_tables'])) ? $_POST['additional_tables'] : Array(); + $tables = array_merge($base, $add); + + // Log it! + $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'db_backup\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($session->username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', \'' . $db->escape(implode(', ', $tables)) . '\')'); + if ( !$e ) + $db->_die(); + + foreach($tables as $i => $t) + { + if(!preg_match('#^([a-z0-9_]+)$#i', $t)) + die('Hacking attempt'); + // if($t == table_prefix.'files' && isset($_POST['do_data'])) + // unset($tables[$i]); + } + foreach($tables as $t) + { + // Sorry folks - this script CAN'T backup enano_files, enano_search_index, and enano_search_cache due to the sheer size of the tables. + // If encryption is enabled the log data will be excluded too. + echo export_table( + $t, + isset($_POST['do_struct']), + ( isset($_POST['do_data']) /* && $t != table_prefix.'files' && $t != table_prefix.'search_index' && $t != table_prefix.'search_cache' && ( !defined('SQL_BACKUP_CRYPT') || ( defined('SQL_BACKUP_CRYPT') && $t != table_prefix.'logs' ) ) */ ), + false + ) . "\n"; + } + $data = ob_get_contents(); + ob_end_clean(); + if(defined('SQL_BACKUP_CRYPT')) + { + // Free some memory, we don't need this stuff any more + $db->close(); + unset($paths, $db, $template, $plugins); + $tea = new TEACrypt(); + $data = $tea->encrypt($data, $session->private_key); + } + header('Content-length: '.strlen($data)); + echo $data; + exit; + } + else + { + // Show the UI + echo ''; + ?> +

This page allows you to back up your Enano database should something go miserably wrong.

+

+

Additional tables to export:

+

+

+


+ +

+

+ '; + } +} + +function page_Admin_AdminLogout() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + return; + } + + $session->logout(USER_LEVEL_ADMIN); + echo '

You have now been logged out of the administration panel.

You will continue to be logged into the website, but you will need to re-authenticate before you can access the administration panel again.

Return to the Main Page.

'; +} + +function page_Special_Administration() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + + if($session->auth_level < USER_LEVEL_ADMIN) { + redirect(makeUrlNS('Special', 'Login/'.$paths->page, 'level='.USER_LEVEL_ADMIN), 'Not authorized', 'You need an authorization level of '.USER_LEVEL_ADMIN.' to use this page, your auth level is: ' . $session->auth_level, 0); + exit; + } + else + { + $template->load_theme('admin', 'default'); + $template->init_vars(); + if( !isset( $_GET['noheaders'] ) ) + { + $template->header(); + } + echo 'Administer your Enano website.'; + ?> + + + + + + +
+
+ +
+
+
+ nslist); + for ( $i = 0; $i < sizeof($paths->nslist); $i++ ) + { + $ln = strlen( $paths->nslist[ $k[ $i ] ] ); + if ( substr($_GET['module'], 0, $ln) == $paths->nslist[$k[$i]] ) + { + $ns = $k[$i]; + $nm = substr($_GET['module'], $ln, strlen($_GET['module'])); + } + } + $fname = 'page_'.$ns.'_'.$nm; + $s = strpos($fname, '?noheaders'); + if($s) $fname = substr($fname, 0, $s); + $paths->cpage['module'] = $_GET['module']; + if ( function_exists($fname) && $_GET['module'] != $paths->nslist['Special'] . 'Administration' ) + { + eval($fname.'();'); + } + } + else + { + echo '
Please wait while the administration panel loads. You need to be using a recent browser with AJAX support in order to use Runt.
'; + } + ?> +
+
+ + footer(); + } +} + +function page_Special_EditSidebar() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + + if($session->auth_level < USER_LEVEL_ADMIN) + { + redirect(makeUrlNS('Special', 'Login/'.$paths->page, 'level='.USER_LEVEL_ADMIN), '', '', false); + exit; + } + else + { + + $template->add_header(''); + $template->add_header(''); + $template->add_header(''); + $template->add_header(''); + + // Knock the sidebars dead to keep javascript in plugins from interfering + $template->tpl_strings['SIDEBAR_LEFT'] = ''; + $template->tpl_strings['SIDEBAR_RIGHT'] = ''; + + $template->load_theme('oxygen', 'bleu'); + $template->init_vars(); + + $template->header(); + + if(isset($_POST['save'])) + { + // Write the new block order to the database + // The only way to do this is with tons of queries (one per block + one select query at the start to count everything) but afaik its safe... + // Anyone know a better way to do this? + $q = $db->sql_query('SELECT item_order,item_id,sidebar_id FROM '.table_prefix.'sidebar ORDER BY sidebar_id ASC, item_order ASC;'); + if ( !$q ) + { + $db->_die('The sidebar order data could not be selected.'); + } + $orders = Array(); + while($row = $db->fetchrow()) + { + $orders[] = Array( + count($orders), + $row['item_id'], + $row['sidebar_id'], + ); + } + $db->free_result(); + + // We now have an array with each sidebar ID in its respective order. Explode the order string in $_POST['order_(left|right)'] and use it to build a set of queries. + $ol = explode(',', $_POST['order_left']); + $odr = explode(',', $_POST['order_right']); + $om = array_merge($ol, $odr); + unset($ol, $odr); + $queries = Array(); + foreach($orders as $k => $v) + { + $queries[] = 'UPDATE '.table_prefix.'sidebar SET item_order='.$om[$k].' WHERE item_id='.$v[1].';'; + } + foreach($queries as $sql) + { + $q = $db->sql_query($sql); + if(!$q) + { + $t = $db->get_error(); + echo $t; + $template->footer(); + exit; + } + } + echo '
The sidebar order information was updated successfully.
'; + } + elseif(isset($_POST['create'])) + { + switch((int)$_POST['type']) + { + case BLOCK_WIKIFORMAT: + $content = $_POST['wikiformat_content']; + break; + case BLOCK_TEMPLATEFORMAT: + $content = $_POST['templateformat_content']; + break; + case BLOCK_HTML: + $content = $_POST['html_content']; + break; + case BLOCK_PHP: + $content = $_POST['php_content']; + break; + case BLOCK_PLUGIN: + $content = $_POST['plugin_id']; + break; + } + // Get the value of item_order + + $q = $db->sql_query('SELECT * FROM '.table_prefix.'sidebar WHERE sidebar_id='.$db->escape($_POST['sidebar_id']).';'); + if(!$q) $db->_die('The order number could not be selected'); + $io = $db->numrows(); + + $db->free_result(); + + $q = 'INSERT INTO '.table_prefix.'sidebar(block_name, block_type, sidebar_id, block_content, item_order) VALUES ( \''.$db->escape($_POST['title']).'\', \''.$db->escape($_POST['type']).'\', \''.$db->escape($_POST['sidebar_id']).'\', \''.$db->escape($content).'\', '.$io.' );'; + $result = $db->sql_query($q); + if(!$result) + { + echo $db->get_error(); + $template->footer(); + exit; + } + + echo '
The item was added.
'; + + } + + if(isset($_GET['action']) && isset($_GET['id'])) + { + if(preg_match('#^([0-9]*)$#', $_GET['id'])) + { + } else { + echo '
Error with action: $_GET["id"] was not an integer, aborting to prevent SQL injection
'; + } + switch($_GET['action']) + { + case 'new': + ?> + + + + +

+ What type of block should this be? +

+

+ +

+ +

+ + Block title:
+ Which sidebar: + +

+ +
+

+ Wikitext: +

+

+ +

+
+ +
+

+ Template code: +

+

+ +

+
+ +
+

+ HTML to place inside the sidebar: +

+

+ +

+
+ +
+

+ WARNING: If you don't know what you're doing, or if you are not fluent in PHP, stop now and choose a different block type. You will brick your Enano installation if you are not careful here. + ALWAYS remember to write secure code! The Enano team is not responsible if someone drops all your tables because of an SQL injection vulnerability in your sidebar code. You are probably better off using the template-formatted block type. +

+

+ + It is especially important to note that this code is NOT checked for errors! If there is a syntax error in your code here, it will prevent any pages from loading AT ALL. So you need to use an external PHP editor (like jEdit) to check your syntax before you hit save. + You have been warned. +

+

+ Also, you should avoid using output buffering functions (ob_[start|end|get_contents|clean]) here, because Enano uses those to track output from this script. +

+

+ The standard <?php and ?> tags work here. Don't use an initial "<?php" or it will cause a parse error. +

+

+ PHP code: +

+

+ +

+
+ +
+

+ Plugin: +

+

+ +

+
+ +

+ +   + + +

+ + + + + + footer(); + return; + break; + case 'move': + if( !isset($_GET['side']) || ( isset($_GET['side']) && !preg_match('#^([0-9]+)$#', $_GET['side']) ) ) + { + echo '
$_GET[\'side\'] contained an SQL injection attempt
'; + break; + } + $query = $db->sql_query('UPDATE '.table_prefix.'sidebar SET sidebar_id=' . $db->escape($_GET['side']) . ' WHERE item_id=' . $db->escape($_GET['id']) . ';'); + if(!$query) + { + echo $db->get_error(); + $template->footer(); + exit; + } + echo '
Item moved.
'; + break; + case 'delete': + $query = $db->sql_query('DELETE FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';'); // Already checked for injection attempts ;-) + if(!$query) + { + echo $db->get_error(); + $template->footer(); + exit; + } + if(isset($_GET['ajax'])) + { + ob_end_clean(); + die('GOOD'); + } + echo '
Item deleted.
'; + break; + case 'disenable'; + $q = $db->sql_query('SELECT item_enabled FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';'); + if(!$q) + { + echo $db->get_error(); + $template->footer(); + exit; + } + $r = $db->fetchrow(); + $db->free_result(); + $e = ( $r['item_enabled'] == 1 ) ? '0' : '1'; + $q = $db->sql_query('UPDATE '.table_prefix.'sidebar SET item_enabled='.$e.' WHERE item_id=' . $db->escape($_GET['id']) . ';'); + if(!$q) + { + echo $db->get_error(); + $template->footer(); + exit; + } + if(isset($_GET['ajax'])) + { + ob_end_clean(); + die('GOOD'); + } + break; + case 'getsource': + $q = $db->sql_query('SELECT block_content,block_type FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';'); + if(!$q) + { + echo $db->get_error(); + $template->footer(); + exit; + } + ob_end_clean(); + $r = $db->fetchrow(); + $db->free_result(); + if($r['block_type'] == BLOCK_PLUGIN) die('HOUSTON_WE_HAVE_A_PLUGIN'); + die($r['block_content']); + break; + case 'save': + $q = $db->sql_query('UPDATE '.table_prefix.'sidebar SET block_content=\''.$db->escape(rawurldecode($_POST['content'])).'\' WHERE item_id=' . $db->escape($_GET['id']) . ';'); + if(!$q) + { + echo 'var status=unescape(\''.hexencode($db->get_error()).'\');'; + exit; + } + $q = $db->sql_query('SELECT block_type,block_content FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';'); + if(!$q) + { + echo 'var status=unescape(\''.hexencode($db->get_error()).'\');'; + exit; + } + $row = $db->fetchrow(); + $db->free_result(); + switch($row['block_type']) + { + case BLOCK_WIKIFORMAT: + default: + $c = RenderMan::render($row['block_content']); + break; + case BLOCK_TEMPLATEFORMAT: + $c = $template->tplWikiFormat($row['block_content'], false, 'sidebar-editor.tpl'); + $c = preg_replace('#(.*?)#is', '\\2', $c); + break; + case BLOCK_HTML: + $c = $row['block_content']; + $c = preg_replace('#(.*?)#is', '\\2', $c); + break; + case BLOCK_PHP: + ob_start(); + eval($row['block_content']); + $c = ob_get_contents(); + ob_end_clean(); + $c = preg_replace('#(.*?)#is', '\\2', $c); + break; + case BLOCK_PLUGIN: + $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : 'Can\'t find plugin block'; + break; + } + die('var status = \'GOOD\'; var content = unescape(\''.hexencode($c).'\');'); + break; + } + } + + $q = $db->sql_query('SELECT item_id,sidebar_id,item_enabled,block_name,block_type,block_content FROM '.table_prefix.'sidebar ORDER BY sidebar_id ASC, item_order ASC;'); + if(!$q) $db->_die('The sidebar text data could not be selected.'); + + $vars = $template->extract_vars('sidebar-editor.tpl'); + + $parser = $template->makeParserText($vars['sidebar_button']); + $parser->assign_vars(Array( + 'HREF'=>'#', + 'FLAGS'=>'onclick="return false;"', + 'TEXT'=>'Change theme' + )); + $template->tpl_strings['THEME_LINK'] = $parser->run(); + $parser->assign_vars(Array( + 'TEXT'=>'Log out', + )); + $template->tpl_strings['LOGOUT_LINK'] = $parser->run(); + + $n1 = Array(); + $n2 = Array(); + $n =& $n1; + + echo '
'; + //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_top']); + + // Time for the loop + // what this loop does is fetch the row data, then send it out to the appropriate parser for formatting, + // then puts the result into $c, which is then sent to the template compiler for insertion into the TPL code. + while($row = $db->fetchrow()) + { + if(isset($current_side)) + { + if($current_side != $row['sidebar_id']) + { + // Time to switch! + //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_bottom']); + echo '
'; + //echo '
'; + //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_top']); + $n =& $n2; + } + } + $n[] = count($n); + $current_side = $row['sidebar_id']; + switch($row['block_type']) + { + case BLOCK_WIKIFORMAT: + default: + $parser = $template->makeParserText($vars['sidebar_section']); + $c = RenderMan::render($row['block_content']); + break; + case BLOCK_TEMPLATEFORMAT: + $parser = $template->makeParserText($vars['sidebar_section']); + $c = $template->tplWikiFormat($row['block_content'], false, 'sidebar-editor.tpl'); + $c = preg_replace('#(.*?)#is', '\\2', $c); + break; + case BLOCK_HTML: + $parser = $template->makeParserText($vars['sidebar_section_raw']); + $c = $row['block_content']; + $c = preg_replace('#(.*?)#is', '\\2', $c); + break; + case BLOCK_PHP: + $parser = $template->makeParserText($vars['sidebar_section_raw']); + ob_start(); + eval($row['block_content']); + $c = ob_get_contents(); + ob_end_clean(); + $c = preg_replace('#(.*?)#is', '\\2', $c); + break; + case BLOCK_PLUGIN: + $parser = $template->makeParserText($vars['sidebar_section_raw']); + $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : 'Can\'t find plugin block'; + break; + } + $t = $template->tplWikiFormat($row['block_name']); + if($row['item_enabled'] == 0) $t .= ' (disabled)'; + else $t .= ' '; + $side = ( $row['sidebar_id'] == SIDEBAR_LEFT ) ? SIDEBAR_RIGHT : SIDEBAR_LEFT; + $tb = 'Enable/disable this block + Edit this block + Delete this block + Move this block'; + $as = ''; + $ae = '  '.$tb; + $parser->assign_vars(Array('CONTENT'=>$c,'TITLE'=>$t,'ADMIN_START'=>$as,'ADMIN_END'=>$ae)); + echo $parser->run(); + unset($parser); + + } + $db->free_result(); + //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_bottom']); + echo '
'; + echo '
'; + $order = implode(',', $n1); + echo ""; + $order = implode(',', $n2); + echo ""; + echo ' + +
+ '; + } + + $template->footer(); +} + +?> \ No newline at end of file