# HG changeset patch # User Dan # Date 1239839087 14400 # Node ID 91f4da84966f461dedffca3dc91a66b58fc661cc # Parent f808e55fb92aa9222ec612bb70866686c55404e1 New, beautiful, rethought Admin:Home. No, really, you'll like it. diff -r f808e55fb92a -r 91f4da84966f includes/functions.php --- a/includes/functions.php Wed Apr 15 19:37:10 2009 -0400 +++ b/includes/functions.php Wed Apr 15 19:44:47 2009 -0400 @@ -2618,6 +2618,35 @@ } /** + * Converts a number to a human file size. + * @param int File size + * @return string + */ + +function humanize_filesize($size) +{ + global $lang; + + if ( $size > ( 1099511627776 * 0.9 ) ) + { + return number_format($size / 1099511627776, 1) . $lang->get('etc_unit_terabytes_short'); + } + if ( $size > ( 1073741824 * 0.9 ) ) + { + return number_format($size / 1073741824, 1) . $lang->get('etc_unit_gigabytes_short'); + } + if ( $size > ( 1048576 * 0.9 ) ) + { + return number_format($size / 1048576, 1) . $lang->get('etc_unit_megabytes_short'); + } + if ( $size > ( 1024 * 0.9 ) ) + { + return number_format($size / 1024, 1) . $lang->get('etc_unit_kilobytes_short'); + } + return "$size " . $lang->get('etc_unit_bytes'); +} + +/** * Injects a string into another string at the specified position. * @param string The haystack * @param string The needle diff -r f808e55fb92a -r 91f4da84966f includes/paths.php --- a/includes/paths.php Wed Apr 15 19:37:10 2009 -0400 +++ b/includes/paths.php Wed Apr 15 19:44:47 2009 -0400 @@ -427,6 +427,14 @@ function sysmsg($n) { global $db, $session, $paths, $template, $plugins; // Common objects + + // sometimes this gets called during die_semicritical()... + if ( !is_object($db) ) + return false; + + if ( !@$db->_conn ) + return false; + $q = $db->sql_query('SELECT page_text, char_tag FROM '.table_prefix.'page_text WHERE page_id=\''.$db->escape(sanitize_page_id($n)).'\' AND namespace=\'System\''); if( !$q ) { diff -r f808e55fb92a -r 91f4da84966f includes/sessions.php --- a/includes/sessions.php Wed Apr 15 19:37:10 2009 -0400 +++ b/includes/sessions.php Wed Apr 15 19:44:47 2009 -0400 @@ -1424,7 +1424,6 @@ $lang = new Language($language); @setlocale(LC_ALL, $lang->lang_code); - $this->logout(); $a = getConfig('account_activation'); switch($a) { diff -r f808e55fb92a -r 91f4da84966f includes/template.php --- a/includes/template.php Wed Apr 15 19:37:10 2009 -0400 +++ b/includes/template.php Wed Apr 15 19:44:47 2009 -0400 @@ -3170,6 +3170,11 @@ else $this->tpl_strings = $vars; } + + function get_theme_hook() + { + return ''; + } } // class template_nodb diff -r f808e55fb92a -r 91f4da84966f language/english/admin.json --- a/language/english/admin.json Wed Apr 15 19:37:10 2009 -0400 +++ b/language/english/admin.json Wed Apr 15 19:44:47 2009 -0400 @@ -214,17 +214,43 @@ inherit_key_local_user: '%this.acl_inherit_local_user% (most specific)', }, acphome: { - heading_main: 'Welcome to Runt, the Enano administration panel.', - welcome_line1: '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.', - welcome_line2: '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.', + heading_main: 'Welcome to the Administration Dashboard.', + welcome_line1: 'Thanks for choosing Enano as your site\'s CMS! The administration panel gives you control over nearly every aspect of your site. The links to the left allow you to navigate around the panel. Below you will find some statistics on your site and any alerts you might need to attend to.', + + // Stats! + stat_header: 'Site statistics', + stat_enano_version: 'Enano CMS %version% (%releasename%)
View server information and license', + stat_numpages: 'Number of pages:', + stat_edits: 'Number of edits made:', + stat_edits_data: '%edit_count% (average of %per_day% per day)', + stat_comments: 'Number of comments:', + stat_comments_data: '%comment_count% (average of %per_day% per day)', + stat_users: 'Number of users:', + stat_filesize: 'Total size of uploaded files:', + stat_cachesize: 'Total size of cache:', + stat_avatarsize: 'Space occupied by avatars:', + stat_dbsize: 'Database size:', + stat_dbsize_unsupported: 'Unsupported', + stat_installdate: 'Site started:', + stat_lastupdate: 'Last Enano upgrade:', + stat_lastupdate_never: 'Never', + + heading_alerts: 'Active alerts', msg_demo_title: 'Enano is running in demo mode.', msg_demo_body: 'If you borked something up, or if you\'re done testing, you can reset this site. The site is reset automatically once every two hours. When a reset is performed, all custom modifications to the site are lost and replaced with default values.', - msg_install_files: 'NOTE: It appears that the install/ directory still exists in your Enano installation root. Even though sensitive tools try to avoid hacking attempts, it is highly recommended that you remove the entire install directory from your server for security reasons.', + msg_install_files_title: 'Installer files found', + msg_install_files_body: 'Please delete the install/ directory from your Enano installation folder – it contains sensitive tools that might allow your site to be compromised.', heading_updates: 'Check for updates', - msg_updates_info: 'Periodically, new releases of Enano will be made available. Click the button below to check for updates to Enano. During this process, a request will be sent to the Enano CMS server (ktulu.enanocms.org) over HTTP for an XML file containing a list of the latest releases. No information about your Enano installation will be transmitted.', + msg_updates_info: 'The Enano team will on occasion release new versions of Enano. We always recommend that you run the latest available version because many releases contain security patches. Enano checks for updates by looking at an XML file and doesn\'t share any information about your site.', btn_check_updates: 'Check for updates', - msg_inactive_users_one: 'It appears that 1 user is awaiting account activation. You can activate the account by going to the User Manager.', - msg_inactive_users_plural: 'It appears that %num_users% users are awaiting account activation. You can activate those accounts by going to the User Manager.', + heading_inactive_users: 'Users are awaiting activation', + msg_inactive_users_one: '1 user has requested manual account activation. You can activate the account by going to the User Manager.', + msg_inactive_users_plural: '%num_users% users have requested manual account activation. You can activate those accounts by going to the User Manager.', + heading_docs: 'Enano documentation', + msg_docs_info: 'The Enano administrator\'s handbook is maintained as a wiki. It will help you get started with Enano and learn about how we do things differently.', + heading_support: 'Get support', + msg_support_info: 'Stuck? Think you found a bug? Tell us about it! Post a message in the Enano support forums to obtain community support for Enano. You may also be interested in our other support channels.', + heading_top_pages: 'Most requested pages', th_toppages_page: 'Page', th_toppages_hits: 'Hits', diff -r f808e55fb92a -r 91f4da84966f plugins/SpecialAdmin.php --- a/plugins/SpecialAdmin.php Wed Apr 15 19:37:10 2009 -0400 +++ b/plugins/SpecialAdmin.php Wed Apr 15 19:44:47 2009 -0400 @@ -73,6 +73,7 @@ list($pid, $ns) = RenderMan::strToPageID($paths->get_pageid_from_url()); if ( $ns == 'Admin' || ( $pid == 'Administration' && $ns == 'Special' ) ) { + require(ENANO_ROOT . '/plugins/admin/Home.php'); require(ENANO_ROOT . '/plugins/admin/PageManager.php'); require(ENANO_ROOT . '/plugins/admin/PageEditor.php'); require(ENANO_ROOT . '/plugins/admin/PageGroups.php'); @@ -96,139 +97,6 @@ // function names are IMPORTANT!!! The name pattern is: page__ -function page_Admin_Home() { - global $db, $session, $paths, $template, $plugins; // Common objects - global $lang; - if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) - { - $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); - echo '

' . $lang->get('adm_err_not_auth_title') . '

'; - echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; - return; - } - - if ( $paths->getParam(0) == 'updates.xml' ) - { - require_once(ENANO_ROOT . '/includes/http.php'); - $req = new Request_HTTP('ktulu.enanocms.org', '/meta/updates.xml'); - $response = $req->get_response_body(); - header('Content-type: application/xml'); - if ( $req->response_code != HTTP_OK ) - { - // Error in response - echo 'response_code . ' ' . $req->response_string . ' -]]>'; - } - else - { - // Retrieve first update - $first_update = preg_match('//', $response, $match); - if ( !$first_update ) - { - echo ''; - } - else - { - if ( version_compare(enano_version(true), $match[2], '<') ) - { - $response = str_replace_once('', " \n ", $response); - } - echo $response; - } - } - return; - } - - // Basic information - echo '

' . $lang->get('acphome_heading_main') . '

'; - echo '

' . $lang->get('acphome_welcome_line1') . '

'; - echo '

' . $lang->get('acphome_welcome_line2') . '

'; - - // Demo mode - if ( defined('ENANO_DEMO_MODE') ) - { - echo '

' . $lang->get('acphome_msg_demo_title') . '

-

' . $lang->get('acphome_msg_demo_body', array('reset_url' => makeUrlNS('Special', 'DemoReset', false, true))) . '

'; - } - - // Check for the installer scripts - if( file_exists(ENANO_ROOT.'/install/install.php') && !defined('ENANO_DEMO_MODE') ) - { - echo '
- ' . $lang->get('acphome_msg_install_files') . ' -
'; - } - - echo '

' . $lang->get('acphome_heading_updates') . '

'; - echo '

' . $lang->get('acphome_msg_updates_info', array('updates_url' => 'http://ktulu.enanocms.org/meta/updates.xml')) . '

'; - echo '
'; - - // Inactive users - $q = $db->sql_query('SELECT time_id FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\';'); - if ( $q ) - { - if ( $db->numrows() > 0 ) - { - $n = $db->numrows(); - $um_flags = 'href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'UserManager\'); return false;"'; - if ( $n == 1 ) - $s = $lang->get('acphome_msg_inactive_users_one', array('um_flags' => $um_flags)); - else - $s = $lang->get('acphome_msg_inactive_users_plural', array('um_flags' => $um_flags)); - echo '
- ' . $s . ' -
'; - } - } - $db->free_result(); - // Stats - if(getConfig('log_hits') == '1') - { - require_once(ENANO_ROOT . '/includes/stats.php'); - $stats = stats_top_pages(10); - //die('
'.print_r($stats,true).'
'); - $c = 0; - $cls = 'row2'; - echo '

' . $lang->get('acphome_heading_top_pages') . '

-
- - - - - '; - foreach($stats as $data) - { - echo ''; - $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; - echo ''; - echo ''; - } - echo '
' . $lang->get('acphome_th_toppages_page') . '' . $lang->get('acphome_th_toppages_hits') . '
- '.$data['page_title'].''.$data['num_hits'] - . '
-
'; - } - - // Any hooks? - $code = $plugins->setHook('acp_home'); - foreach ( $code as $cmd ) - { - eval($cmd); - } - - // Security log - echo '

' . $lang->get('acphome_heading_seclog') . '

'; - echo '

' . $lang->get('acphome_msg_seclog_info') . '

'; - $seclog = get_security_log(5); - echo $seclog; - - echo '

' . $lang->get('acphome_btn_seclog_full') . '

'; - -} - function page_Admin_GeneralConfig() { global $db, $session, $paths, $template, $plugins; // Common objects global $lang; @@ -390,21 +258,7 @@ setConfig('gravatar_rating', $_POST['gravatar_rating']); } - if ( is_dir(ENANO_ROOT . '/' . $_POST['avatar_directory']) ) - { - if ( preg_match('/^[A-z0-9_-]+(?:\/(?:[A-z0-9_-]+))*\/?$/', $_POST['avatar_directory']) ) - { - setConfig('avatar_directory', $_POST['avatar_directory']); - } - else - { - echo '
' . $lang->get('acpgc_err_avatar_dir_invalid') . '
'; - } - } - else - { - echo '
' . $lang->get('acpgc_err_avatar_dir_not_exist') . '
'; - } + setConfig('avatar_directory', 'files/avatars'); setConfig('userpage_grant_acl', ( isset($_POST['userpage_grant_acl']) ? '1' : '0' )); @@ -1028,16 +882,6 @@ - - - get('acpgc_field_avatar_directory'); ?>
- get('acpgc_field_avatar_directory_hint'); ?> - - - /> - - - diff -r f808e55fb92a -r 91f4da84966f plugins/admin/Home.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/admin/Home.php Wed Apr 15 19:44:47 2009 -0400 @@ -0,0 +1,419 @@ +auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; + return; + } + + if ( $paths->getParam(0) == 'updates.xml' ) + { + return acphome_process_updates(); + } + + // Welcome + echo '

' . $lang->get('acphome_heading_main') . '

'; + echo '

' . $lang->get('acphome_welcome_line1') . '

'; + + // Stats + acphome_show_stats(); + + // + // Alerts + // + + echo '

' . $lang->get('acphome_heading_alerts') . '

'; + + // Demo mode + if ( defined('ENANO_DEMO_MODE') ) + { + echo '
'; + echo '

' . $lang->get('acphome_msg_demo_title') . '

+

' . $lang->get('acphome_msg_demo_body', array('reset_url' => makeUrlNS('Special', 'DemoReset', false, true))) . '

'; + echo '
'; + } + + // Check for the installer scripts + if( file_exists(ENANO_ROOT.'/install/install.php') && !defined('ENANO_DEMO_MODE') ) + { + echo '
+

' . $lang->get('acphome_msg_install_files_title') . '

+

' . $lang->get('acphome_msg_install_files_body') . '

+
'; + } + + // Inactive users + $q = $db->sql_query('SELECT time_id FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\';'); + if ( $q ) + { + if ( $db->numrows() > 0 ) + { + $n = $db->numrows(); + $um_flags = 'href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'UserManager\'); return false;"'; + if ( $n == 1 ) + $s = $lang->get('acphome_msg_inactive_users_one', array('um_flags' => $um_flags)); + else + $s = $lang->get('acphome_msg_inactive_users_plural', array('um_flags' => $um_flags)); + echo '
+

' . $lang->get('acphome_heading_inactive_users') . '

+ ' . $s . ' +
'; + } + } + $db->free_result(); + + // Update checker + echo '
'; + echo '

' . $lang->get('acphome_heading_updates') . '

'; + echo '

' . $lang->get('acphome_msg_updates_info', array('updates_url' => 'http://ktulu.enanocms.org/meta/updates.xml')) . '

'; + echo '
'; + echo '
'; + + // Docs + echo '
'; + echo '

' . $lang->get('acphome_heading_docs') . '

'; + echo '

' . $lang->get('acphome_msg_docs_info') . '

'; + echo '
'; + + // Support + echo '
'; + echo '

' . $lang->get('acphome_heading_support') . '

'; + echo '

' . $lang->get('acphome_msg_support_info') . '

'; + echo '
'; + + echo ''; + + // + // Stats + // + + if(getConfig('log_hits') == '1') + { + require_once(ENANO_ROOT . '/includes/stats.php'); + $stats = stats_top_pages(10); + //die('
'.print_r($stats,true).'
'); + $c = 0; + $cls = 'row2'; + echo '

' . $lang->get('acphome_heading_top_pages') . '

+
+ + + + + '; + foreach($stats as $data) + { + echo ''; + $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; + echo ''; + echo ''; + } + echo '
' . $lang->get('acphome_th_toppages_page') . '' . $lang->get('acphome_th_toppages_hits') . '
+ '.$data['page_title'].''.$data['num_hits'] + . '
+
'; + } + + // Any hooks? + $code = $plugins->setHook('acp_home'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + + // + // Security log + // + + echo '

' . $lang->get('acphome_heading_seclog') . '

'; + echo '

' . $lang->get('acphome_msg_seclog_info') . '

'; + $seclog = get_security_log(5); + echo $seclog; + + echo '

' . $lang->get('acphome_btn_seclog_full') . '

'; + +} + +function acphome_process_updates() +{ + require_once(ENANO_ROOT . '/includes/http.php'); + + $req = new Request_HTTP('ktulu.enanocms.org', '/meta/updates.xml'); + $response = $req->get_response_body(); + header('Content-type: application/xml'); + if ( $req->response_code != HTTP_OK ) + { + // Error in response + echo 'response_code . ' ' . $req->response_string . ' +]]>'; + } + else + { + // Retrieve first update + $first_update = preg_match('//', $response, $match); + if ( !$first_update ) + { + echo ''; + } + else + { + if ( version_compare(enano_version(true), $match[2], '<') ) + { + $response = str_replace_once('', " \n ", $response); + } + echo $response; + } + } + return true; +} + +function acphome_show_stats() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + + // Page count + $q = $db->sql_query('SELECT COUNT(*) FROM ' . table_prefix . "pages"); + if ( !$q ) + $db->_die(); + list($page_count) = $db->fetchrow_num(); + $db->free_result(); + + // Edits per day + $q = $db->sql_query('SELECT ( COUNT(*) - 1 ) AS edit_count, MIN(time_id) AS install_date FROM ' . table_prefix . 'logs WHERE ( log_type = \'page\' AND action = \'edit\' ) OR ( log_type = \'security\' AND action = \'install_enano\' );'); + if ( !$q ) + $db->_die(); + $edit_info = $db->fetchrow(); + $install_date =& $edit_info['install_date']; + $db->free_result(); + + $days_installed = round( (time() / 86400) - ($install_date / 86400) ); + + // Comments + $q = $db->sql_query('SELECT COUNT(*) FROM ' . table_prefix . "comments"); + if ( !$q ) + $db->_die(); + list($comment_count) = $db->fetchrow_num(); + $db->free_result(); + + // Users + $q = $db->sql_query('SELECT ( COUNT(*) - 1 ) FROM ' . table_prefix . "users"); + if ( !$q ) + $db->_die(); + list($user_count) = $db->fetchrow_num(); + $db->free_result(); + + // Cache size + $cache_size = 0; + if ( $dr = @opendir(ENANO_ROOT . '/cache/') ) + { + while ( $dh = @readdir($dr) ) + { + $file = ENANO_ROOT . "/cache/$dh"; + if ( @is_file($file) ) + $cache_size += filesize($file); + } + closedir($dr); + } + $cache_size = humanize_filesize($cache_size); + + // Files directory size + $files_size = 0; + if ( $dr = @opendir(ENANO_ROOT . '/files/') ) + { + while ( $dh = @readdir($dr) ) + { + $file = ENANO_ROOT . "/files/$dh"; + if ( @is_file($file) ) + $files_size += filesize($file); + } + closedir($dr); + } + $files_size = humanize_filesize($files_size); + + // Avatar directory size + $avatar_size = 0; + if ( $dr = @opendir(ENANO_ROOT . '/files/avatars/') ) + { + while ( $dh = @readdir($dr) ) + { + $file = ENANO_ROOT . "/files/avatars/$dh"; + if ( @is_file($file) ) + $avatar_size += filesize($file); + } + closedir($dr); + } + $avatar_size = humanize_filesize($avatar_size); + + // Database size + $db_size = $lang->get('acphome_stat_dbsize_unsupported'); + if ( ENANO_DBLAYER == 'MYSQL' ) + { + $q = $db->sql_query('SHOW TABLE STATUS;'); + if ( $q ) + { + $db_size = 0; + while ( $row = $db->fetchrow() ) + { + if ( preg_match('/^' . table_prefix . '/', $row['Name']) ) + { + $db_size += $row['Data_length'] + $row['Index_length']; + } + } + $db_size = humanize_filesize($db_size); + } + } + else if ( ENANO_DBLAYER == 'PGSQL' ) + { + require(ENANO_ROOT . '/config.php'); + global $dbname, $dbuser, $dbpasswd; + $dbuser = false; + $dbpasswd = false; + + $q = $db->sql_query('SELECT pg_database_size(\'' . $db->escape($dbname) . '\');'); + if ( $q ) + { + list($db_size) = $db->fetchrow_num(); + $db_size = humanize_filesize($db_size); + $db->free_result(); + } + } + + // Install date + $install_date_human = MemberlistFormatter::format_date($install_date); + + // Last upgrade + $q = $db->sql_query('SELECT time_id FROM ' . table_prefix . "logs WHERE log_type = 'security' AND action = 'upgrade_enano' ORDER BY time_id DESC LIMIT 1;"); + if ( !$q ) + $db->_die(); + + if ( $db->numrows() < 1 ) + { + $last_upgrade = $lang->get('acphome_stat_lastupdate_never'); + } + else + { + list($last_upgrade) = $db->fetchrow_num(); + $last_upgrade = MemberlistFormatter::format_date($last_upgrade); + } + $db->free_result(); + + ?> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ get('acphome_stat_header'); ?> +
+ get('acphome_stat_numpages'); ?> + + + + get('acphome_stat_edits'); ?> + + get('acphome_stat_edits_data', array('edit_count' => $edit_info['edit_count'], 'per_day' => number_format($edit_info['edit_count'] / $days_installed, 2))); ?> +
+ get('acphome_stat_comments'); ?> + + get('acphome_stat_comments_data', array('comment_count' => $comment_count, 'per_day' => number_format($comment_count / $days_installed, 2))); ?> + + get('acphome_stat_users'); ?> + + +
+ get('acphome_stat_filesize'); ?> + + + + get('acphome_stat_cachesize'); ?> + + +
+ get('acphome_stat_avatarsize'); ?> + + + + get('acphome_stat_dbsize'); ?> + + +
+ get('acphome_stat_installdate'); ?> + + + + get('acphome_stat_lastupdate'); ?> + + +
+ get('acphome_stat_enano_version', array( + 'version' => enano_version(true), + 'releasename' => enano_codename(), + 'aboutlink' => makeUrlNS('Special', 'About_Enano') + )); ?> +
+
+