aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--admin/statistics/index.php25
-rw-r--r--engine/lib/admin.php4
-rw-r--r--engine/lib/statistics.php40
-rw-r--r--languages/en.php282
-rw-r--r--views/default/admin/main_opt/statistics.php17
-rw-r--r--views/default/admin/statistics.php54
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