diff options
-rw-r--r-- | admin/statistics/index.php | 25 | ||||
-rw-r--r-- | engine/lib/admin.php | 4 | ||||
-rw-r--r-- | engine/lib/statistics.php | 40 | ||||
-rw-r--r-- | languages/en.php | 282 | ||||
-rw-r--r-- | views/default/admin/main_opt/statistics.php | 17 | ||||
-rw-r--r-- | views/default/admin/statistics.php | 54 |
6 files changed, 282 insertions, 140 deletions
diff --git a/admin/statistics/index.php b/admin/statistics/index.php new file mode 100644 index 000000000..cea6526df --- /dev/null +++ b/admin/statistics/index.php @@ -0,0 +1,25 @@ +<?php + + /** + * Elgg administration statistics index + * This is a special page that displays a number of statistics + * + * @package Elgg + * @subpackage Core + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Marcus Povey + * @copyright Curverider Ltd 2008 + * @link http://elgg.org/ + */ + + // Get the Elgg framework + require_once(dirname(dirname(dirname(__FILE__))) . "/engine/start.php"); + + // Make sure only valid admin users can see this + admin_gatekeeper(); + + + // Display main admin menu + page_draw(elgg_echo("admin:statistics"),elgg_view("admin/statistics")); + +?> diff --git a/engine/lib/admin.php b/engine/lib/admin.php index 10ab87cd7..f1e088eca 100644 --- a/engine/lib/admin.php +++ b/engine/lib/admin.php @@ -42,7 +42,7 @@ global $CONFIG; // Add plugin main menu option (last) - extend_elgg_admin_page('admin/statistics', 'admin/main'); + extend_elgg_admin_page('admin/main_opt/statistics', 'admin/main'); extend_elgg_admin_page('admin/main_opt/site', 'admin/main'); extend_elgg_admin_page('admin/main_opt/user', 'admin/main'); extend_elgg_admin_page('admin/main_opt/plugins', 'admin/main', 999); // Always last @@ -74,4 +74,4 @@ // Register a plugin hook for permissions
register_plugin_hook('permissions_check','all','admin_permissions');
-?>
\ No newline at end of file +?> diff --git a/engine/lib/statistics.php b/engine/lib/statistics.php index ce601e7b4..f5bf23250 100644 --- a/engine/lib/statistics.php +++ b/engine/lib/statistics.php @@ -38,7 +38,8 @@ $query = "SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='{$type->type}'"; if ($type->subtype) $query.= " and subtype={$type->subtype_id}"; - $subtype_cnt = get_data($query); + + $subtype_cnt = get_data_row($query); if ($type->subtype) $entity_stats[$type->type][$type->subtype] = $subtype_cnt->count; @@ -48,4 +49,41 @@ return $entity_stats; } + + /** + * Return the number of users registered in the system. + * + * @return int + */ + function get_number_users() + { + global $CONFIG; + + $result = get_data_row("SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='user'"); + + if ($result) + return $result->count; + + return false; + } + + /** + * Report how many users are currently online + * + * @return int + */ + function get_number_online() + { + // TODO: get logged in users somehow + } + + /** + * Return a list of how many users are currently online. + * + * @param int $limit Number of users to return + */ + function get_online_users($limit = 10) + { + // TODO: Writeme + } ?> diff --git a/languages/en.php b/languages/en.php index f89b20365..82d378de8 100644 --- a/languages/en.php +++ b/languages/en.php @@ -17,116 +17,116 @@ /**
* Errors
*/
- - 'InstallationException:CantCreateSite' => "Unable to create a default ElggSite with credentials Name:%s, Url: %s", +
+ 'InstallationException:CantCreateSite' => "Unable to create a default ElggSite with credentials Name:%s, Url: %s",
'actionundefined' => "The requested action (%s) was not defined in the system.",
'actionloggedout' => "Sorry, you cannot perform this action while logged out.",
- 'notfound' => "The requested resource could not be found, or you do not have access to it.", - - 'SecurityException:Codeblock' => "Denied access to execute privileged code block", - 'DatabaseException:WrongCredentials' => "Elgg couldn't connect to the database using the given credentials %s@%s (pw: %s).", - 'DatabaseException:NoConnect' => "Elgg couldn't select the database %s.", - 'SecurityException:FunctionDenied' => "Access to privileged function '%s' is denied.", - 'DatabaseException:DBSetupIssues' => "There were a number of issues: ", - 'DatabaseException:ScriptNotFound' => "Elgg couldn't find the requested database script at %s.", - - 'IOException:FailedToLoadGUID' => "Failed to load new %s from GUID:%d", - 'InvalidParameterException:NonElggObject' => "Passing a non-ElggObject to an ElggObject constructor!", - 'InvalidParameterException:UnrecognisedValue' => "Unrecognised value passed to constuctor.", - - 'InvalidClassException:NotValidElggStar' => "GUID:%d is not a valid %s", - - 'PluginException:MisconfiguredPlugin' => "%s is a misconfigured plugin.", - - 'InvalidParameterException:NonElggUser' => "Passing a non-ElggUser to an ElggUser constructor!", - - 'InvalidParameterException:NonElggSite' => "Passing a non-ElggSite to an ElggSite constructor!", - - 'IOException:UnableToSaveNew' => "Unable to save new %s", - - 'InvalidParameterException:GUIDNotForExport' => "GUID has not been specified during export, this should never happen.", - 'InvalidParameterException:NonArrayReturnValue' => "Entity serialisation function passed a non-array returnvalue parameter", - - 'ConfigurationException:NoCachePath' => "Cache path set to nothing!", - 'IOException:NotDirectory' => "%s is not a directory.", - - 'IOException:BaseEntitySaveFailed' => "Unable to save new object's base entity information!", - 'InvalidParameterException:UnexpectedODDClass' => "import() passed an unexpected ODD class", - 'InvalidParameterException:EntityTypeNotSet' => "Entity type must be set.", - - 'ClassException:ClassnameNotClass' => "%s is not a %s.", + 'notfound' => "The requested resource could not be found, or you do not have access to it.",
+
+ 'SecurityException:Codeblock' => "Denied access to execute privileged code block",
+ 'DatabaseException:WrongCredentials' => "Elgg couldn't connect to the database using the given credentials %s@%s (pw: %s).",
+ 'DatabaseException:NoConnect' => "Elgg couldn't select the database %s.",
+ 'SecurityException:FunctionDenied' => "Access to privileged function '%s' is denied.",
+ 'DatabaseException:DBSetupIssues' => "There were a number of issues: ",
+ 'DatabaseException:ScriptNotFound' => "Elgg couldn't find the requested database script at %s.",
+
+ 'IOException:FailedToLoadGUID' => "Failed to load new %s from GUID:%d",
+ 'InvalidParameterException:NonElggObject' => "Passing a non-ElggObject to an ElggObject constructor!",
+ 'InvalidParameterException:UnrecognisedValue' => "Unrecognised value passed to constuctor.",
+
+ 'InvalidClassException:NotValidElggStar' => "GUID:%d is not a valid %s",
+
+ 'PluginException:MisconfiguredPlugin' => "%s is a misconfigured plugin.",
+
+ 'InvalidParameterException:NonElggUser' => "Passing a non-ElggUser to an ElggUser constructor!",
+
+ 'InvalidParameterException:NonElggSite' => "Passing a non-ElggSite to an ElggSite constructor!",
+
+ 'IOException:UnableToSaveNew' => "Unable to save new %s",
+
+ 'InvalidParameterException:GUIDNotForExport' => "GUID has not been specified during export, this should never happen.",
+ 'InvalidParameterException:NonArrayReturnValue' => "Entity serialisation function passed a non-array returnvalue parameter",
+
+ 'ConfigurationException:NoCachePath' => "Cache path set to nothing!",
+ 'IOException:NotDirectory' => "%s is not a directory.",
+
+ 'IOException:BaseEntitySaveFailed' => "Unable to save new object's base entity information!",
+ 'InvalidParameterException:UnexpectedODDClass' => "import() passed an unexpected ODD class",
+ 'InvalidParameterException:EntityTypeNotSet' => "Entity type must be set.",
+
+ 'ClassException:ClassnameNotClass' => "%s is not a %s.",
'InstallationException:TypeNotSupported' => "Type %s is not supported. This indicates an error in your installation, most likely caused by an incomplete upgrade.",
- - 'ImportException:ImportFailed' => "Could not import element %d", - 'ImportException:ProblemSaving' => "There was a problem saving %s", - 'ImportException:NoGUID' => "New entity created but has no GUID, this should not happen.", - - 'ImportException:GUIDNotFound' => "Entity '%d' could not be found.", - 'ImportException:ProblemUpdatingMeta' => "There was a problem updating '%s' on entity '%d'", - - 'ExportException:NoSuchEntity' => "No such entity GUID:%d", - - 'ImportException:NoODDElements' => "No OpenDD elements found in import data, import failed.", - 'ImportException:NotAllImported' => "Not all elements were imported.", - - 'InvalidParameterException:UnrecognisedFileMode' => "Unrecognised file mode '%s'", - 'InvalidParameterException:MissingOwner' => "All files must have an owner!", - 'IOException:CouldNotMake' => "Could not make %s", - 'IOException:MissingFileName' => "You must specify a name before opening a file.", - 'ClassNotFoundException:NotFoundNotSavedWithFile' => "Filestore not found or class not saved with file!", - 'NotificationException:NoNotificationMethod' => "No notification method specified.", - 'NotificationException:NoHandlerFound' => "No handler found for '%s' or it was not callable.", - 'NotificationException:ErrorNotifyingGuid' => "There was an error while notifying %d", - 'NotificationException:NoEmailAddress' => "Could not get the email address for GUID:%d", - - 'DatabaseException:WhereSetNonQuery' => "Where set contains non WhereQueryComponent", - 'DatabaseException:SelectFieldsMissing' => "Fields missing on a select style query", - 'DatabaseException:UnspecifiedQueryType' => "Unrecognised or unspecified query type.", - 'DatabaseException:NoTablesSpecified' => "No tables specified for query.", - 'DatabaseException:NoACL' => "No access control was provided on query", - - 'InvalidParameterException:NoEntityFound' => "No entity found, it either doesn't exist or you don't have access to it.", - - - 'InvalidParameterException:IdNotExistForGUID' => "Sorry, '%s' does not exist for guid:%d", - 'InvalidParameterException:CanNotExportType' => "Sorry, I don't know how to export '%s'", - 'InvalidParameterException:NoDataFound' => "Could not find any data.", - 'InvalidParameterException:DoesNotBelong' => "Does not belong to entity.", - 'InvalidParameterException:DoesNotBelongOrRefer' => "Does not belong to entity or refer to entity.", - 'InvalidParameterException:MissingParameter' => "Missing parameter, you need to provide a GUID.", - - 'SecurityException:APIAccessDenied' => "Sorry, API access has been disabled by the administrator.", - 'SecurityException:NoAuthMethods' => "No authentication methods were found that could authenticate this API request.", - 'APIException:ApiResultUnknown' => "API Result is of an unknown type, this should never happen.", - - 'ConfigurationException:NoSiteID' => "No site ID has been specified.", - 'InvalidParameterException:UnrecognisedMethod' => "Unrecognised call method '%s'", - 'APIException:MissingParameterInMethod' => "Missing parameter %s in method %s", - 'APIException:ParameterNotArray' => "%s does not appear to be an array.", - 'APIException:UnrecognisedTypeCast' => "Unrecognised type in cast %s for variable '%s' in method '%s'", - 'APIException:InvalidParameter' => "Invalid parameter found for '%s' in method '%s'.", - 'APIException:FunctionParseError' => "%s(%s) has a parsing error.", - 'APIException:FunctionNoReturn' => "%s(%s) returned no value.", - 'SecurityException:AuthTokenExpired' => "Authentication token either missing, invalid or expired.", - 'CallException:InvalidCallMethod' => "%s must be called using '%s'", - 'APIException:MethodCallNotImplemented' => "Method call '%s' has not been implemented.", - 'APIException:AlgorithmNotSupported' => "Algorithm '%s' is not supported or has been disabled.", - 'ConfigurationException:CacheDirNotSet' => "Cache directory 'cache_path' not set.", - 'APIException:NotGetOrPost' => "Request method must be GET or POST", - 'APIException:MissingAPIKey' => "Missing X-Elgg-apikey HTTP header", - 'APIException:MissingHmac' => "Missing X-Elgg-hmac header", - 'APIException:MissingHmacAlgo' => "Missing X-Elgg-hmac-algo header", - 'APIException:MissingTime' => "Missing X-Elgg-time header", - 'APIException:TemporalDrift' => "X-Elgg-time is too far in the past or future", - 'APIException:NoQueryString' => "No data on the query string", - 'APIException:MissingPOSTHash' => "Missing X-Elgg-posthash header", - 'APIException:MissingPOSTAlgo' => "Missing X-Elgg-posthash_algo header", - 'APIException:MissingContentType' => "Missing content type for post data", - 'SecurityException:InvalidPostHash' => "POST data hash is invalid - Expected %s but got %s.", - 'SecurityException:DupePacket' => "Packet signature already seen.", - 'SecurityException:InvalidAPIKey' => "Invalid or missing API Key.", +
+ 'ImportException:ImportFailed' => "Could not import element %d",
+ 'ImportException:ProblemSaving' => "There was a problem saving %s",
+ 'ImportException:NoGUID' => "New entity created but has no GUID, this should not happen.",
+
+ 'ImportException:GUIDNotFound' => "Entity '%d' could not be found.",
+ 'ImportException:ProblemUpdatingMeta' => "There was a problem updating '%s' on entity '%d'",
+
+ 'ExportException:NoSuchEntity' => "No such entity GUID:%d",
+
+ 'ImportException:NoODDElements' => "No OpenDD elements found in import data, import failed.",
+ 'ImportException:NotAllImported' => "Not all elements were imported.",
+
+ 'InvalidParameterException:UnrecognisedFileMode' => "Unrecognised file mode '%s'",
+ 'InvalidParameterException:MissingOwner' => "All files must have an owner!",
+ 'IOException:CouldNotMake' => "Could not make %s",
+ 'IOException:MissingFileName' => "You must specify a name before opening a file.",
+ 'ClassNotFoundException:NotFoundNotSavedWithFile' => "Filestore not found or class not saved with file!",
+ 'NotificationException:NoNotificationMethod' => "No notification method specified.",
+ 'NotificationException:NoHandlerFound' => "No handler found for '%s' or it was not callable.",
+ 'NotificationException:ErrorNotifyingGuid' => "There was an error while notifying %d",
+ 'NotificationException:NoEmailAddress' => "Could not get the email address for GUID:%d",
+
+ 'DatabaseException:WhereSetNonQuery' => "Where set contains non WhereQueryComponent",
+ 'DatabaseException:SelectFieldsMissing' => "Fields missing on a select style query",
+ 'DatabaseException:UnspecifiedQueryType' => "Unrecognised or unspecified query type.",
+ 'DatabaseException:NoTablesSpecified' => "No tables specified for query.",
+ 'DatabaseException:NoACL' => "No access control was provided on query",
+
+ 'InvalidParameterException:NoEntityFound' => "No entity found, it either doesn't exist or you don't have access to it.",
+
+
+ 'InvalidParameterException:IdNotExistForGUID' => "Sorry, '%s' does not exist for guid:%d",
+ 'InvalidParameterException:CanNotExportType' => "Sorry, I don't know how to export '%s'",
+ 'InvalidParameterException:NoDataFound' => "Could not find any data.",
+ 'InvalidParameterException:DoesNotBelong' => "Does not belong to entity.",
+ 'InvalidParameterException:DoesNotBelongOrRefer' => "Does not belong to entity or refer to entity.",
+ 'InvalidParameterException:MissingParameter' => "Missing parameter, you need to provide a GUID.",
+
+ 'SecurityException:APIAccessDenied' => "Sorry, API access has been disabled by the administrator.",
+ 'SecurityException:NoAuthMethods' => "No authentication methods were found that could authenticate this API request.",
+ 'APIException:ApiResultUnknown' => "API Result is of an unknown type, this should never happen.",
+
+ 'ConfigurationException:NoSiteID' => "No site ID has been specified.",
+ 'InvalidParameterException:UnrecognisedMethod' => "Unrecognised call method '%s'",
+ 'APIException:MissingParameterInMethod' => "Missing parameter %s in method %s",
+ 'APIException:ParameterNotArray' => "%s does not appear to be an array.",
+ 'APIException:UnrecognisedTypeCast' => "Unrecognised type in cast %s for variable '%s' in method '%s'",
+ 'APIException:InvalidParameter' => "Invalid parameter found for '%s' in method '%s'.",
+ 'APIException:FunctionParseError' => "%s(%s) has a parsing error.",
+ 'APIException:FunctionNoReturn' => "%s(%s) returned no value.",
+ 'SecurityException:AuthTokenExpired' => "Authentication token either missing, invalid or expired.",
+ 'CallException:InvalidCallMethod' => "%s must be called using '%s'",
+ 'APIException:MethodCallNotImplemented' => "Method call '%s' has not been implemented.",
+ 'APIException:AlgorithmNotSupported' => "Algorithm '%s' is not supported or has been disabled.",
+ 'ConfigurationException:CacheDirNotSet' => "Cache directory 'cache_path' not set.",
+ 'APIException:NotGetOrPost' => "Request method must be GET or POST",
+ 'APIException:MissingAPIKey' => "Missing X-Elgg-apikey HTTP header",
+ 'APIException:MissingHmac' => "Missing X-Elgg-hmac header",
+ 'APIException:MissingHmacAlgo' => "Missing X-Elgg-hmac-algo header",
+ 'APIException:MissingTime' => "Missing X-Elgg-time header",
+ 'APIException:TemporalDrift' => "X-Elgg-time is too far in the past or future",
+ 'APIException:NoQueryString' => "No data on the query string",
+ 'APIException:MissingPOSTHash' => "Missing X-Elgg-posthash header",
+ 'APIException:MissingPOSTAlgo' => "Missing X-Elgg-posthash_algo header",
+ 'APIException:MissingContentType' => "Missing content type for post data",
+ 'SecurityException:InvalidPostHash' => "POST data hash is invalid - Expected %s but got %s.",
+ 'SecurityException:DupePacket' => "Packet signature already seen.",
+ 'SecurityException:InvalidAPIKey' => "Invalid or missing API Key.",
/**
* User details
@@ -182,12 +182,12 @@ 'friends:of' => "Friends of",
'friends:of:owned' => "People who have made %s a friend",
- - /** - * River - */ - 'river' => "River", - +
+ /**
+ * River
+ */
+ 'river' => "River",
+
/**
* Search
@@ -209,28 +209,38 @@ /**
* Administration
- */ - - 'admin:configuration:success' => "Your settings have been saved.", + */
+
+ 'admin:configuration:success' => "Your settings have been saved.",
'admin:configuration:fail' => "Your settings could not be saved.",
'admin' => "Administration",
- 'admin:description' => "The admin panel allows you to control all aspects of the system, from user management to how plugins behave. Choose an option below to get started.", - - 'admin:user' => "User Administration", - 'admin:user:description' => "This admin panel allows you to control user settings for your site. Choose an option below to get started.", - 'admin:user:opt:linktext' => "Configure users...", - 'admin:user:opt:description' => "Configure users and account information. ", - - 'admin:site' => "Site Administration", - 'admin:site:description' => "This admin panel allows you to control global settings for your site. Choose an option below to get started.", - 'admin:site:opt:linktext' => "Configure site...", - 'admin:site:opt:description' => "Configure the site technical and non-technical settings. ", - - 'admin:plugins' => "Tool Administration", - 'admin:plugins:description' => "This admin panel allows you to control and configure tools installed on your site.", - 'admin:plugins:opt:linktext' => "Configure tools...", - 'admin:plugins:opt:description' => "Configure the tools installed on the site. ", + 'admin:description' => "The admin panel allows you to control all aspects of the system, from user management to how plugins behave. Choose an option below to get started.",
+
+ 'admin:user' => "User Administration",
+ 'admin:user:description' => "This admin panel allows you to control user settings for your site. Choose an option below to get started.",
+ 'admin:user:opt:linktext' => "Configure users...",
+ 'admin:user:opt:description' => "Configure users and account information. ",
+
+ 'admin:site' => "Site Administration",
+ 'admin:site:description' => "This admin panel allows you to control global settings for your site. Choose an option below to get started.",
+ 'admin:site:opt:linktext' => "Configure site...",
+ 'admin:site:opt:description' => "Configure the site technical and non-technical settings. ",
+
+ 'admin:plugins' => "Tool Administration",
+ 'admin:plugins:description' => "This admin panel allows you to control and configure tools installed on your site.",
+ 'admin:plugins:opt:linktext' => "Configure tools...",
+ 'admin:plugins:opt:description' => "Configure the tools installed on the site. ",
+
+ 'admin:statistics' => "Statistics",
+ 'admin:statistics:description' => "This admin panel will allow you to view statistics about your site.",
+ 'admin:statistics:opt:description' => "View statistical information about users and objects on your site.",
+ 'admin:statistics:opt:linktext' => "View statistics...",
+ 'admin:statistics:label:basic' => "Basic site statistics",
+ 'admin:statistics:label:numentities' => "Entities on site",
+ 'admin:statistics:label:numusers' => "Number of users",
+ 'admin:statistics:label:numonline' => "Number of users online",
+ 'admin:statistics:label:onlineusers' => "Most recent %d users online",
/**
@@ -258,11 +268,11 @@ 'deleteconfirm' => "Are you sure you want to delete this item?",
'fileexists' => "A file has already been uploaded. To replace it, select it below:",
- - /** - * Import / export - */ - 'importsuccess' => "Import of data was successful", +
+ /**
+ * Import / export
+ */
+ 'importsuccess' => "Import of data was successful",
/**
* Widgets
@@ -299,4 +309,4 @@ add_translation("en",$english);
-?>
\ No newline at end of file +?>
diff --git a/views/default/admin/main_opt/statistics.php b/views/default/admin/main_opt/statistics.php new file mode 100644 index 000000000..da37decf6 --- /dev/null +++ b/views/default/admin/main_opt/statistics.php @@ -0,0 +1,17 @@ +<?php + /** + * Elgg satistics sub-component on the main menu. + * + * @package Elgg + * @subpackage Core + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Marcus Povey + * @copyright Curverider Ltd 2008 + * @link http://elgg.org/ + */ +?> +<div class="admin-menu-option"> + <h2><?php echo elgg_echo('admin:statistics'); ?> </h2> + <p><?php echo elgg_echo('admin:statistics:opt:description'); ?><br /> + <a href="<?php echo $CONFIG->wwwroot . "admin/statistics/"; ?>"><?php echo elgg_echo('admin:statistics:opt:linktext'); ?></a></p> +</div> diff --git a/views/default/admin/statistics.php b/views/default/admin/statistics.php index ad9356276..d8e2bd276 100644 --- a/views/default/admin/statistics.php +++ b/views/default/admin/statistics.php @@ -12,5 +12,57 @@ global $CONFIG; + echo "<p>" . nl2br(elgg_echo("admin:statistics:description")) . "</p>"; + + + + // Get entity statistics + $entity_stats = get_entity_statistics(); + + // Work out number of users + $users_stats = get_number_users(); + + // users online + $users_online = get_number_online(); + + -?>
\ No newline at end of file +?> +<div id="basic_site_statistics"> + <h2><?php echo elgg_echo('admin:statistics:label:basic'); ?></h2> + <table> + <tr> + <td><b><?php echo elgg_echo('admin:statistics:label:numusers'); ?> :</b></td> + <td><?php echo $users_stats; ?></td> + </tr> + <tr> + <td><b><?php echo elgg_echo('admin:statistics:label:numonline'); ?> :</b></td> + <td><?php echo $users_online; ?></td> + </tr> + </table> + + <h2><?php echo elgg_echo('admin:statistics:label:numentities'); ?></h2> + <table> + <?php + foreach ($entity_stats as $k => $entry) + { + echo "<table>"; + foreach ($entry as $a => $b) + { + if ($a == "__base__") + $a=$k; + else + $a = "$k $a"; + echo <<< END + <tr> + <td><b>$a :</b></td> + <td>$b</td> + </tr> +END; + } + echo "</table>"; + } + ?> + </table> + +</div>
\ No newline at end of file |