aboutsummaryrefslogtreecommitdiff
path: root/engine/lib
diff options
context:
space:
mode:
Diffstat (limited to 'engine/lib')
-rw-r--r--engine/lib/actions.php22
-rw-r--r--engine/lib/admin.php70
-rw-r--r--engine/lib/database.php38
-rw-r--r--engine/lib/deprecated-1.8.php436
-rw-r--r--engine/lib/elgglib.php14
-rw-r--r--engine/lib/extender.php8
-rw-r--r--engine/lib/group.php5
-rw-r--r--engine/lib/output.php2
-rw-r--r--engine/lib/pagehandler.php14
-rw-r--r--engine/lib/plugins.php41
-rw-r--r--engine/lib/river.php206
-rw-r--r--engine/lib/sessions.php9
-rw-r--r--engine/lib/upgrades/2011052801.php45
-rw-r--r--engine/lib/upgrades/2011061200-1.8b1-sites_need_a_site_guid-6d9dcbf46c0826cc.php30
-rw-r--r--engine/lib/users.php117
15 files changed, 770 insertions, 287 deletions
diff --git a/engine/lib/actions.php b/engine/lib/actions.php
index 47e4dd4a4..ff598916f 100644
--- a/engine/lib/actions.php
+++ b/engine/lib/actions.php
@@ -152,6 +152,7 @@ function action($action, $forwarder = "") {
* @param string $filename Optionally, the filename where this action is located. If not specified,
* will assume the action is in elgg/actions/<action>.php
* @param string $access Who is allowed to execute this action: admin, public, or logged_in.
+ * (default: logged_in)
*
* @see action()
* @see http://docs.elgg.org/Actions
@@ -411,6 +412,16 @@ function elgg_is_xhr() {
*/
function ajax_forward_hook($hook, $type, $reason, $params) {
if (elgg_is_xhr()) {
+ // always pass the full structure to avoid boilerplate JS code.
+ $params = array(
+ 'output' => '',
+ 'status' => 0,
+ 'system_messages' => array(
+ 'error' => array(),
+ 'success' => array()
+ )
+ );
+
//grab any data echo'd in the action
$output = ob_get_clean();
@@ -423,12 +434,15 @@ function ajax_forward_hook($hook, $type, $reason, $params) {
}
//Grab any system messages so we can inject them via ajax too
- $params['system_messages'] = system_messages(NULL, "");
+ $system_messages = system_messages(NULL, "");
+
+ if (isset($system_messages['success'])) {
+ $params['system_messages']['success'] = $system_messages['success'];
+ }
- if (isset($params['system_messages']['error'])) {
+ if (isset($system_messages['error'])) {
+ $params['system_messages']['error'] = $system_messages['error'];
$params['status'] = -1;
- } else {
- $params['status'] = 0;
}
header("Content-type: application/json");
diff --git a/engine/lib/admin.php b/engine/lib/admin.php
index 06418c44f..3bfb69102 100644
--- a/engine/lib/admin.php
+++ b/engine/lib/admin.php
@@ -183,7 +183,7 @@ function elgg_admin_notice_exists($id) {
function elgg_register_admin_menu_item($section, $menu_id, $parent_id = NULL, $priority = 100) {
// make sure parent is registered
- if ($parent_id && !elgg_is_menu_item_registered($menu_id, $parent_id)) {
+ if ($parent_id && !elgg_is_menu_item_registered('page', $parent_id)) {
elgg_register_admin_menu_item($section, $parent_id);
}
@@ -211,7 +211,7 @@ function elgg_register_admin_menu_item($section, $menu_id, $parent_id = NULL, $p
}
/**
- * Initialise the admin backend.
+ * Initialize the admin backend.
*
* @return void
*/
@@ -262,11 +262,18 @@ function admin_init() {
// configure
// plugins
- elgg_register_admin_menu_item('configure', 'plugins', null, 10);
- elgg_register_admin_menu_item('configure', 'simple', 'plugins', 10);
- elgg_register_admin_menu_item('configure', 'advanced', 'plugins', 20);
+ elgg_register_menu_item('page', array(
+ 'name' => 'plugins',
+ 'href' => 'admin/plugins',
+ 'text' => elgg_echo('admin:plugins'),
+ 'context' => 'admin',
+ 'priority' => 75,
+ 'section' => 'configure'
+ ));
// settings
+ elgg_register_admin_menu_item('configure', 'appearance', null, 50);
+ elgg_register_admin_menu_item('configure', 'settings', null, 100);
elgg_register_admin_menu_item('configure', 'basic', 'settings', 10);
elgg_register_admin_menu_item('configure', 'advanced', 'settings', 20);
elgg_register_admin_menu_item('configure', 'menu_items', 'appearance', 30);
@@ -277,6 +284,11 @@ function admin_init() {
// plugin settings are added in elgg_admin_add_plugin_settings_menu() via the admin page handler
// for performance reasons.
+ // we want plugin settings menu items to be sorted alphabetical
+ if (elgg_in_context('admin')) {
+ elgg_register_plugin_hook_handler('prepare', 'menu:page', 'elgg_admin_sort_page_menu');
+ }
+
if (elgg_is_admin_logged_in()) {
elgg_register_menu_item('topbar', array(
'name' => 'administration',
@@ -314,6 +326,7 @@ function admin_init() {
*
* @return void
* @access private
+ * @since 1.8.0
*/
function elgg_admin_add_plugin_settings_menu() {
@@ -325,11 +338,13 @@ function elgg_admin_add_plugin_settings_menu() {
foreach ($active_plugins as $plugin) {
$plugin_id = $plugin->getID();
- if (elgg_view_exists("settings/$plugin_id/edit")) {
+ $settings_view_old = 'settings/' . $plugin_id . '/edit';
+ $settings_view_new = 'plugins/' . $plugin_id . '/settings';
+ if (elgg_view_exists($settings_view_new) || elgg_view_exists($settings_view_old)) {
elgg_register_menu_item('page', array(
'name' => $plugin_id,
'href' => "admin/plugin_settings/$plugin_id",
- 'text' => $plugin->manifest->getName(),
+ 'text' => $plugin->getManifest()->getName(),
'parent_name' => 'settings',
'context' => 'admin',
'section' => 'configure',
@@ -339,6 +354,33 @@ function elgg_admin_add_plugin_settings_menu() {
}
/**
+ * Sort the plugin settings menu items
+ *
+ * @param string $hook
+ * @param string $type
+ * @param array $return
+ * @param array $params
+ *
+ * @return void
+ * @since 1.8.0
+ */
+function elgg_admin_sort_page_menu($hook, $type, $return, $params) {
+ $configure_items = $return['configure'];
+ foreach ($configure_items as $menu_item) {
+ if ($menu_item->getName() == 'settings') {
+ $settings = $menu_item;
+ }
+ }
+
+ // keep the basic and advanced settings at the top
+ $children = $settings->getChildren();
+ $site_settings = array_splice($children, 0, 2);
+ usort($children, array('ElggMenuBuilder', 'compareByText'));
+ array_splice($children, 0, 0, $site_settings);
+ $settings->setChildren($children);
+}
+
+/**
* Handles any set up required for administration pages
*
* @return void
@@ -413,8 +455,8 @@ function admin_settings_page_handler($page) {
$vars = array('page' => $page);
// special page for plugin settings since we create the form for them
- if ($page[0] == 'plugin_settings' && isset($page[1])
- && elgg_view_exists("settings/{$page[1]}/edit")) {
+ if ($page[0] == 'plugin_settings' && isset($page[1]) &&
+ (elgg_view_exists("settings/{$page[1]}/edit") || elgg_view_exists("plugins/{$page[1]}/settings"))) {
$view = 'admin/plugin_settings';
$plugin = elgg_get_plugin_from_id($page[1]);
@@ -516,9 +558,11 @@ function admin_markdown_page_handler($pages) {
$filename = elgg_extract(1, $pages);
$error = false;
-
if (!$plugin) {
$error = elgg_echo('admin:plugins:markdown:unknown_plugin');
+ $body = elgg_view_layout('admin', array('content' => $error, 'title' => $error));
+ echo elgg_view_page($title, $body, 'admin');
+ return true;
}
$text_files = $plugin->getAvailableTextFiles();
@@ -541,11 +585,13 @@ function admin_markdown_page_handler($pages) {
return true;
}
- $title = $plugin->manifest->getName() . ": $filename";
+ $title = $plugin->getManifest()->getName() . ": $filename";
$text = Markdown($file_contents);
$body = elgg_view_layout('admin', array(
- 'content' => $text,
+ // setting classes here because there's no way to pass classes
+ // to the layout
+ 'content' => '<div class="elgg-markdown">' . $text . '</div>',
'title' => $title
));
diff --git a/engine/lib/database.php b/engine/lib/database.php
index 6b1b494b9..7747eb0d5 100644
--- a/engine/lib/database.php
+++ b/engine/lib/database.php
@@ -250,8 +250,6 @@ function explain_query($query, $link) {
function execute_query($query, $dblink) {
global $CONFIG, $dbcalls;
- // remove newlines so logs are easier to read
- $query = preg_replace("/[\r\n]/", "", $query);
if ($query == NULL) {
throw new DatabaseException(elgg_echo('DatabaseException:InvalidQuery'));
}
@@ -362,7 +360,7 @@ function get_data_row($query, $callback = "") {
/**
* Handles returning data from a query, running it through a callback function,
- * and caching the results.
+ * and caching the results. This is for R queries (from CRUD).
*
* @access private
*
@@ -377,6 +375,8 @@ function get_data_row($query, $callback = "") {
function elgg_query_runner($query, $callback = null, $single = false) {
global $CONFIG, $DB_QUERY_CACHE;
+ $query = elgg_format_query($query);
+
// since we want to cache results of running the callback, we need to
// need to namespace the query with the callback, and single result request.
$hash = (string)$callback . (string)$single . $query;
@@ -386,7 +386,7 @@ function elgg_query_runner($query, $callback = null, $single = false) {
$cached_query = $DB_QUERY_CACHE[$hash];
if ($cached_query !== FALSE) {
- elgg_log("$query results returned from cache (hash: $hash)");
+ elgg_log("DB query $query results returned from cache (hash: $hash)", 'NOTICE');
return $cached_query;
}
}
@@ -415,13 +415,13 @@ function elgg_query_runner($query, $callback = null, $single = false) {
}
if (empty($return)) {
- elgg_log("DB query \"$query\" returned no results.");
+ elgg_log("DB query $query returned no results.", 'NOTICE');
}
// Cache result
if ($DB_QUERY_CACHE) {
$DB_QUERY_CACHE[$hash] = $return;
- elgg_log("$query results cached (hash: $hash)");
+ elgg_log("DB query $query results cached (hash: $hash)", 'NOTICE');
}
return $return;
@@ -440,6 +440,9 @@ function elgg_query_runner($query, $callback = null, $single = false) {
function insert_data($query) {
global $CONFIG, $DB_QUERY_CACHE;
+ $query = elgg_format_query($query);
+ elgg_log("DB query $query", 'NOTICE');
+
$dblink = get_db_link('write');
// Invalidate query cache
@@ -447,7 +450,7 @@ function insert_data($query) {
$DB_QUERY_CACHE->clear();
}
- elgg_log("Query cache invalidated");
+ elgg_log("Query cache invalidated", 'NOTICE');
if (execute_query("$query", $dblink)) {
return mysql_insert_id($dblink);
@@ -468,12 +471,15 @@ function insert_data($query) {
function update_data($query) {
global $CONFIG, $DB_QUERY_CACHE;
+ $query = elgg_format_query($query);
+ elgg_log("DB query $query", 'NOTICE');
+
$dblink = get_db_link('write');
// Invalidate query cache
if ($DB_QUERY_CACHE) {
$DB_QUERY_CACHE->clear();
- elgg_log("Query cache invalidated");
+ elgg_log("Query cache invalidated", 'NOTICE');
}
if (execute_query("$query", $dblink)) {
@@ -495,12 +501,15 @@ function update_data($query) {
function delete_data($query) {
global $CONFIG, $DB_QUERY_CACHE;
+ $query = elgg_format_query($query);
+ elgg_log("DB query $query", 'NOTICE');
+
$dblink = get_db_link('write');
// Invalidate query cache
if ($DB_QUERY_CACHE) {
$DB_QUERY_CACHE->clear();
- elgg_log("Query cache invalidated");
+ elgg_log("Query cache invalidated", 'NOTICE');
}
if (execute_query("$query", $dblink)) {
@@ -635,6 +644,17 @@ function run_sql_script($scriptlocation) {
}
/**
+ * Format a query string for logging
+ *
+ * @param string $query Query string
+ * @return string
+ */
+function elgg_format_query($query) {
+ // remove newlines and extra spaces so logs are easier to read
+ return preg_replace('/\s\s+/', ' ', $query);
+}
+
+/**
* Sanitise a string for database use, but with the option of escaping extra characters.
*
* @param string $string The string to sanitise
diff --git a/engine/lib/deprecated-1.8.php b/engine/lib/deprecated-1.8.php
index bb52881cd..d92257a09 100644
--- a/engine/lib/deprecated-1.8.php
+++ b/engine/lib/deprecated-1.8.php
@@ -1,7 +1,83 @@
<?php
/**
- * @return str
+ * ***************************************************************************
+ * NOTE: If this is ever removed from Elgg, sites lose the ability to upgrade
+ * from 1.7.x and earlier to the latest version of Elgg without upgrading to
+ * 1.8 first.
+ * ***************************************************************************
+ *
+ * Upgrade the database schema in an ordered sequence.
+ *
+ * Executes all upgrade files in elgg/engine/schema/upgrades/ in sequential order.
+ * Upgrade files must be in the standard Elgg release format of YYYYMMDDII.sql
+ * where II is an incrementor starting from 01.
+ *
+ * Files that are < $version will be ignored.
+ *
+ * @warning Plugin authors should not call this function directly.
+ *
+ * @param int $version The version you are upgrading from in the format YYYYMMDDII.
+ * @param string $fromdir Optional directory to load upgrades from. default: engine/schema/upgrades/
+ * @param bool $quiet If true, suppress all error messages. Only use for the upgrade from <=1.6.
+ *
+ * @return bool
+ * @see upgrade.php
+ * @see version.php
+ * @deprecated 1.8 Use PHP upgrades for sql changes.
+ */
+function db_upgrade($version, $fromdir = "", $quiet = FALSE) {
+ global $CONFIG;
+
+ elgg_deprecated_notice('db_upgrade() is deprecated by using PHP upgrades.', 1.8);
+
+ $version = (int) $version;
+
+ if (!$fromdir) {
+ $fromdir = $CONFIG->path . 'engine/schema/upgrades/';
+ }
+
+ if ($handle = opendir($fromdir)) {
+ $sqlupgrades = array();
+
+ while ($sqlfile = readdir($handle)) {
+ if (!is_dir($fromdir . $sqlfile)) {
+ if (preg_match('/^([0-9]{10})\.(sql)$/', $sqlfile, $matches)) {
+ $sql_version = (int) $matches[1];
+ if ($sql_version > $version) {
+ $sqlupgrades[] = $sqlfile;
+ }
+ }
+ }
+ }
+
+ asort($sqlupgrades);
+
+ if (sizeof($sqlupgrades) > 0) {
+ foreach ($sqlupgrades as $sqlfile) {
+
+ // hide all errors.
+ if ($quiet) {
+ try {
+ run_sql_script($fromdir . $sqlfile);
+ } catch (DatabaseException $e) {
+ error_log($e->getmessage());
+ }
+ } else {
+ run_sql_script($fromdir . $sqlfile);
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * Lists entities from an access collection
+ *
* @deprecated 1.8 Use elgg_list_entities_from_access_id()
+ *
+ * @return str
*/
function list_entities_from_access_id($access_id, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $listtypetoggle = true, $pagination = true) {
@@ -14,7 +90,14 @@ function list_entities_from_access_id($access_id, $entity_type = "", $entity_sub
}
/**
+ * Registers a particular action in memory
+ *
* @deprecated 1.8 Use {@link elgg_register_action()} instead
+ *
+ * @param string $action The name of the action (eg "register", "account/settings/save")
+ * @param boolean $public Can this action be accessed by people not logged into the system?
+ * @param string $filename Optionally, the filename where this action is located
+ * @param boolean $admin_only Whether this action is only available to admin users.
*/
function register_action($action, $public = false, $filename = "", $admin_only = false) {
elgg_deprecated_notice("register_action() was deprecated by elgg_register_action()", 1.8);
@@ -35,6 +118,8 @@ function register_action($action, $public = false, $filename = "", $admin_only =
* This function extends the view "admin/main" with the provided view.
* This view should provide a description and either a control or a link to.
*
+ * @deprecated 1.8 Extend admin views manually
+ *
* Usage:
* - To add a control to the main admin panel then extend admin/main
* - To add a control to a new page create a page which renders a view admin/subpage
@@ -48,8 +133,6 @@ function register_action($action, $public = false, $filename = "", $admin_only =
* @param string $view The view to extend, by default this is 'admin/main'.
* @param int $priority Optional priority to govern the appearance in the list.
*
- * @deprecated 1.8 Extend admin views manually
- *
* @return void
*/
function extend_elgg_admin_page($new_admin_view, $view = 'admin/main', $priority = 500) {
@@ -115,7 +198,7 @@ function get_entities_from_annotations_calculate_x($sum = "sum", $entity_type =
$options['limit'] = $limit;
$options['offset'] = $offset;
- $options['order_by'] = "calculation $orderdir";
+ $options['order_by'] = "annotation_calculation $orderdir";
$options['count'] = $count;
@@ -125,6 +208,12 @@ function get_entities_from_annotations_calculate_x($sum = "sum", $entity_type =
/**
* Returns entities ordered by the sum of an annotation
*
+ * @warning This is function uses sum instead of count. THIS IS SLOW. See #3366.
+ * This should be used when you have annotations with different values and you
+ * want a list of entities ordered by the sum of all of those values.
+ * If you want a list of entities ordered by the number of annotations on each entity,
+ * use __get_entities_from_annotations_calculate_x() and pass 'count' as the first param.
+ *
* @deprecated 1.8 Use elgg_get_entities_from_annotation_calculation()
*
* @param string $entity_type Type of Entity
@@ -179,7 +268,7 @@ function get_entities_from_annotation_count($entity_type = "", $entity_subtype =
$options['limit'] = $limit;
$options['offset'] = $offset;
- $options['order_by'] = "calculation $orderdir";
+ $options['order_by'] = "annotation_calculation $orderdir";
$options['count'] = $count;
@@ -241,7 +330,7 @@ function list_entities_from_annotation_count($entity_type = "", $entity_subtype
$options['limit'] = $limit;
- $options['order_by'] = "calculation $orderdir";
+ $options['order_by'] = "annotation_calculation $orderdir";
return elgg_get_entities_from_annotation_calculation($options);
}
@@ -249,6 +338,8 @@ function list_entities_from_annotation_count($entity_type = "", $entity_subtype
/**
* Adds an entry in $CONFIG[$register_name][$subregister_name].
*
+ * @deprecated 1.8 Use the new menu system.
+ *
* This is only used for the site-wide menu. See {@link add_menu()}.
*
* @param string $register_name The name of the top-level register
@@ -257,7 +348,6 @@ function list_entities_from_annotation_count($entity_type = "", $entity_subtype
* @param array $children_array Optionally, an array of children
*
* @return true|false Depending on success
- * @deprecated 1.8
*/
function add_to_register($register_name, $subregister_name, $subregister_value, $children_array = array()) {
elgg_deprecated_notice("add_to_register() has been deprecated", 1.8);
@@ -290,6 +380,8 @@ function add_to_register($register_name, $subregister_name, $subregister_value,
/**
* Removes a register entry from $CONFIG[register_name][subregister_name]
*
+ * @deprecated 1.8 Use the new menu system.
+ *
* This is used to by {@link remove_menu()} to remove site-wide menu items.
*
* @param string $register_name The name of the top-level register
@@ -297,7 +389,6 @@ function add_to_register($register_name, $subregister_name, $subregister_value,
*
* @return true|false Depending on success
* @since 1.7.0
- * @deprecated 1.8
*/
function remove_from_register($register_name, $subregister_name) {
elgg_deprecated_notice("remove_from_register() has been deprecated", 1.8);
@@ -326,10 +417,11 @@ function remove_from_register($register_name, $subregister_name) {
/**
* If it exists, returns a particular register as an array
*
+ * @deprecated 1.8 Use the new menu system
+ *
* @param string $register_name The name of the register
*
* @return array|false Depending on success
- * @deprecated 1.8
*/
function get_register($register_name) {
elgg_deprecated_notice("get_register() has been deprecated", 1.8);
@@ -363,6 +455,8 @@ function get_register($register_name) {
* Deprecated events core function. Code divided between elgg_register_event_handler()
* and trigger_elgg_event().
*
+ * @deprecated 1.8 Use explicit register/trigger event functions
+ *
* @param string $event The type of event (eg 'init', 'update', 'delete')
* @param string $object_type The type of object (eg 'system', 'blog', 'user')
* @param string $function The name of the function that will handle the event
@@ -371,7 +465,6 @@ function get_register($register_name) {
* @param mixed $object Optionally, the object the event is being performed on (eg a user)
*
* @return true|false Depending on success
- * @deprecated 1.8 Use explicit register/trigger event functions
*/
function events($event = "", $object_type = "", $function = "", $priority = 500, $call = false, $object = null) {
@@ -386,7 +479,14 @@ function events($event = "", $object_type = "", $function = "", $priority = 500,
}
/**
+ * Alias function for events, that registers a function to a particular kind of event
+ *
* @deprecated 1.8 Use elgg_register_event_handler() instead
+ *
+ * @param string $event The event type
+ * @param string $object_type The object type
+ * @param string $function The function name
+ * @return true|false Depending on success
*/
function register_elgg_event_handler($event, $object_type, $callback, $priority = 500) {
elgg_deprecated_notice("register_elgg_event_handler() was deprecated by elgg_register_event_handler()", 1.8);
@@ -394,7 +494,14 @@ function register_elgg_event_handler($event, $object_type, $callback, $priority
}
/**
+ * Unregisters a function to a particular kind of event
+ *
* @deprecated 1.8 Use elgg_unregister_event_handler instead
+ *
+ * @param string $event The event type
+ * @param string $object_type The object type
+ * @param string $function The function name
+ * @since 1.7.0
*/
function unregister_elgg_event_handler($event, $object_type, $callback) {
elgg_deprecated_notice('unregister_elgg_event_handler => elgg_unregister_event_handler', 1.8);
@@ -402,7 +509,14 @@ function unregister_elgg_event_handler($event, $object_type, $callback) {
}
/**
+ * Alias function for events, that triggers a particular kind of event
+ *
* @deprecated 1.8 Use elgg_trigger_event() instead
+ *
+ * @param string $event The event type
+ * @param string $object_type The object type
+ * @param string $function The function name
+ * @return true|false Depending on success
*/
function trigger_elgg_event($event, $object_type, $object = null) {
elgg_deprecated_notice('trigger_elgg_event() was deprecated by elgg_trigger_event()', 1.8);
@@ -410,7 +524,29 @@ function trigger_elgg_event($event, $object_type, $object = null) {
}
/**
+ * Register a function to a plugin hook for a particular entity type, with a given priority.
+ *
* @deprecated 1.8 Use elgg_register_plugin_hook_handler() instead
+ *
+ * eg if you want the function "export_user" to be called when the hook "export" for "user" entities
+ * is run, use:
+ *
+ * register_plugin_hook("export", "user", "export_user");
+ *
+ * "all" is a valid value for both $hook and $entity_type. "none" is a valid value for $entity_type.
+ *
+ * The export_user function would then be defined as:
+ *
+ * function export_user($hook, $entity_type, $returnvalue, $params);
+ *
+ * Where $returnvalue is the return value returned by the last function returned by the hook, and
+ * $params is an array containing a set of parameters (or nothing).
+ *
+ * @param string $hook The name of the hook
+ * @param string $entity_type The name of the type of entity (eg "user", "object" etc)
+ * @param string $function The name of a valid function to be run
+ * @param string $priority The priority - 0 is first, 1000 last, default is 500
+ * @return true|false Depending on success
*/
function register_plugin_hook($hook, $type, $callback, $priority = 500) {
elgg_deprecated_notice("register_plugin_hook() was deprecated by elgg_register_plugin_hook_handler()", 1.8);
@@ -418,7 +554,14 @@ function register_plugin_hook($hook, $type, $callback, $priority = 500) {
}
/**
+ * Unregister a function to a plugin hook for a particular entity type
+ *
* @deprecated 1.8 Use elgg_unregister_plugin_hook_handler() instead
+ *
+ * @param string $hook The name of the hook
+ * @param string $entity_type The name of the type of entity (eg "user", "object" etc)
+ * @param string $function The name of a valid function to be run
+ * @since 1.7.0
*/
function unregister_plugin_hook($hook, $entity_type, $callback) {
elgg_deprecated_notice("unregister_plugin_hook() was deprecated by elgg_unregister_plugin_hook_handler()", 1.8);
@@ -426,7 +569,20 @@ function unregister_plugin_hook($hook, $entity_type, $callback) {
}
/**
+ * Triggers a plugin hook, with various parameters as an array. For example, to provide
+ * a 'foo' hook that concerns an entity of type 'bar', with a parameter called 'param1'
+ * with value 'value1', that by default returns true, you'd call:
+ *
* @deprecated 1.8 Use elgg_trigger_plugin_hook() instead
+ *
+ * trigger_plugin_hook('foo', 'bar', array('param1' => 'value1'), true);
+ *
+ * @see register_plugin_hook
+ * @param string $hook The name of the hook to trigger
+ * @param string $entity_type The name of the entity type to trigger it for (or "all", or "none")
+ * @param array $params Any parameters. It's good practice to name the keys, i.e. by using array('name' => 'value', 'name2' => 'value2')
+ * @param mixed $returnvalue An initial return value
+ * @return mixed|null The cumulative return value for the plugin hook functions
*/
function trigger_plugin_hook($hook, $type, $params = null, $returnvalue = null) {
elgg_deprecated_notice("trigger_plugin_hook() was deprecated by elgg_trigger_plugin_hook()", 1.8);
@@ -1667,7 +1823,7 @@ function get_installed_plugins($status = 'all') {
if ($include) {
$installed_plugins[$plugin->getID()] = array(
'active' => $plugin->isActive(),
- 'manifest' => $plugin->manifest->getManifest()
+ 'manifest' => $plugin->getManifest()->getManifest()
);
}
}
@@ -2844,6 +3000,13 @@ $priority = 500) {
}
/**
+ * Returns a representation of a full 'page' (which might be an HTML page,
+ * RSS file, etc, depending on the current viewtype)
+ *
+ * @param string $title
+ * @param string $body
+ * @return string
+ *
* @deprecated 1.8 Use elgg_view_page()
*/
function page_draw($title, $body, $sidebar = "") {
@@ -3504,14 +3667,18 @@ $asc = false, $fullview = true, $listtypetoggle = false, $pagination = true, $or
$options['limit'] = $limit;
- $options['order_by'] = "calculation $orderdir";
+ $options['order_by'] = "annotation_calculation $orderdir";
return elgg_get_entities_from_annotation_calculation($options);
}
/**
- * @deprecated 1.8
- * @see elgg_set_view_location()
+ * Set an alternative base location for a view (as opposed to the default of $CONFIG->viewpath)
+ *
+ * @param string $view The name of the view
+ * @param string $location The base location path
+ *
+ * @deprecated 1.8 Use elgg_set_view_location()
*/
function set_view_location($view, $location, $viewtype = '') {
elgg_deprecated_notice("set_view_location() was deprecated by elgg_set_view_location()", 1.8);
@@ -3519,8 +3686,14 @@ function set_view_location($view, $location, $viewtype = '') {
}
/**
- * @deprecated 1.8
- * @see elgg_register_entity_url_handler()
+ * Sets the URL handler for a particular entity type and subtype
+ *
+ * @param string $function_name The function to register
+ * @param string $entity_type The entity type
+ * @param string $entity_subtype The entity subtype
+ * @return true|false Depending on success
+ *
+ * @deprecated 1.8 Use elgg_register_entity_url_handler()
*/
function register_entity_url_handler($function_name, $entity_type = "all", $entity_subtype = "all") {
elgg_deprecated_notice("register_entity_url_handler() was deprecated by elgg_register_entity_url_handler()", 1.8);
@@ -3807,6 +3980,27 @@ function clear_annotations_by_owner($owner_guid) {
}
/**
+ * Registers a page handler for a particular identifier
+ *
+ * For example, you can register a function called 'blog_page_handler' for handler type 'blog'
+ * Now for all URLs of type http://yoururl/pg/blog/*, the blog_page_handler() function will be called.
+ * The part of the URL marked with * above will be exploded on '/' characters and passed as an
+ * array to that function.
+ * For example, the URL http://yoururl/blog/username/friends/ would result in the call:
+ * blog_page_handler(array('username','friends'), blog);
+ *
+ * Page handler functions should return true or the default page handler will be called.
+ *
+ * A request to register a page handler with the same identifier as previously registered
+ * handler will replace the previous one.
+ *
+ * The context is set to the page handler identifier before the registered
+ * page handler function is called. For the above example, the context is set to 'blog'.
+ *
+ * @param string $handler The page type to handle
+ * @param string $function Your function name
+ * @return true|false Depending on success
+ *
* @deprecated 1.8 Use {@link elgg_register_page_handler()}
*/
function register_page_handler($handler, $function){
@@ -3815,6 +4009,13 @@ function register_page_handler($handler, $function){
}
/**
+ * Unregister a page handler for an identifier
+ *
+ * Note: to replace a page handler, call register_page_handler()
+ *
+ * @param string $handler The page type identifier
+ * @since 1.7.2
+ *
* @deprecated 1.8 Use {@link elgg_unregister_page_handler()}
*/
function unregister_page_handler($handler) {
@@ -3823,6 +4024,11 @@ function unregister_page_handler($handler) {
}
/**
+ * Register an annotation url handler.
+ *
+ * @param string $function_name The function.
+ * @param string $extender_name The name, default 'all'.
+ *
* @deprecated 1.8 Use {@link elgg_register_annotation_url_handler()}
*/
function register_annotation_url_handler($function, $extender_name) {
@@ -3831,6 +4037,15 @@ function register_annotation_url_handler($function, $extender_name) {
}
/**
+ * Sets the URL handler for a particular extender type and name.
+ * It is recommended that you do not call this directly, instead use one of the wrapper functions in the
+ * subtype files.
+ *
+ * @param string $function_name The function to register
+ * @param string $extender_type Extender type
+ * @param string $extender_name The name of the extender
+ * @return true|false Depending on success
+ *
* @deprecated 1.8 Use {@link elgg_register_extender_url_handler()}
*/
function register_extender_url_handler($function, $type = "all", $name = "all") {
@@ -3839,6 +4054,14 @@ function register_extender_url_handler($function, $type = "all", $name = "all")
}
/**
+ * Registers and entity type and subtype to return in search and other places.
+ * A description in the elgg_echo languages file of the form item:type:subtype
+ * is also expected.
+ *
+ * @param string $type The type of entity (object, site, user, group)
+ * @param string $subtype The subtype to register (may be blank)
+ * @return true|false Depending on success
+ *
* @deprecated 1.8 Use {@link elgg_register_entity_type()}
*/
function register_entity_type($type, $subtype = null) {
@@ -3847,6 +4070,11 @@ function register_entity_type($type, $subtype = null) {
}
/**
+ * Register a metadata url handler.
+ *
+ * @param string $function_name The function.
+ * @param string $extender_name The name, default 'all'.
+ *
* @deprecated 1.8 Use {@link elgg_register_metadata_url_handler()}
*/
function register_metadata_url_handler($function, $extender_name = "all") {
@@ -3854,7 +4082,12 @@ function register_metadata_url_handler($function, $extender_name = "all") {
}
/**
+ * Sets the URL handler for a particular relationship type
*
+ * @param string $function_name The function to register
+ * @param string $relationship_type The relationship type.
+ * @return true|false Depending on success
+ *
* @deprecated 1.8 Use {@link elgg_register_relationship_url_handler()}
*/
function register_relationship_url_handler($function_name, $relationship_type = "all") {
@@ -3863,6 +4096,15 @@ function register_relationship_url_handler($function_name, $relationship_type =
}
/**
+ * Registers a view to be simply cached
+ *
+ * Views cached in this manner must take no parameters and be login agnostic -
+ * that is to say, they look the same no matter who is logged in (or logged out).
+ *
+ * CSS and the basic jS views are automatically cached like this.
+ *
+ * @param string $viewname View name
+ *
* @deprecated 1.8 Use {@link elgg_register_simplecache_view()}
*/
function elgg_view_register_simplecache($viewname) {
@@ -3871,6 +4113,11 @@ function elgg_view_register_simplecache($viewname) {
}
/**
+ * Regenerates the simple cache.
+ *
+ * @param string $viewtype Optional viewtype to regenerate
+ * @see elgg_view_register_simplecache()
+ *
* @deprecated 1.8 Use {@link elgg_regenerate_simplecache()}
*/
function elgg_view_regenerate_simplecache($viewtype = NULL) {
@@ -3879,6 +4126,10 @@ function elgg_view_regenerate_simplecache($viewtype = NULL) {
}
/**
+ * Enables the simple cache.
+ *
+ * @see elgg_view_register_simplecache()
+ *
* @deprecated 1.8 Use {@link elgg_enable_simplecache()}
*/
function elgg_view_enable_simplecache() {
@@ -3887,6 +4138,10 @@ function elgg_view_enable_simplecache() {
}
/**
+ * Disables the simple cache.
+ *
+ * @see elgg_view_register_simplecache()
+ *
* @deprecated 1.8 Use {@link elgg_disable_simplecache()}
*/
function elgg_view_disable_simplecache() {
@@ -3912,6 +4167,22 @@ function is_installed() {
}
/**
+ * Attempt to authenticate.
+ * This function will process all registered PAM handlers or stop when the first
+ * handler fails. A handler fails by either returning false or throwing an
+ * exception. The advantage of throwing an exception is that it returns a message
+ * through the global $_PAM_HANDLERS_MSG which can be used in communication with
+ * a user. The order that handlers are processed is determined by the order that
+ * they were registered.
+ *
+ * If $credentials are provided the PAM handler should authenticate using the
+ * provided credentials, if not then credentials should be prompted for or
+ * otherwise retrieved (eg from the HTTP header or $_SESSION).
+ *
+ * @param mixed $credentials Mixed PAM handler specific credentials (e.g. username, password)
+ * @param string $policy - the policy type, default is "user"
+ * @return bool true if authenticated, false if not.
+ *
* @deprecated 1.8 See {@link ElggPAM}
*/
function pam_authenticate($credentials = NULL, $policy = "user") {
@@ -4375,6 +4646,11 @@ function using_widgets() {
}
/**
+ * Displays a particular widget
+ *
+ * @param ElggObject $widget The widget to display
+ * @return string The HTML for the widget, including JavaScript wrapper
+ *
* @deprecated 1.8
*/
function display_widget(ElggObject $widget) {
@@ -4382,92 +4658,76 @@ function display_widget(ElggObject $widget) {
return elgg_view_entity($widget);
}
-
/**
- * ***************************************************************************
- * NOTE: If this is ever removed from Elgg, sites lose the ability to upgrade
- * from 1.7.x and earlier to the latest version of Elgg without upgrading to
- * 1.8 first.
- * ***************************************************************************
- *
- * Upgrade the database schema in an ordered sequence.
- *
- * Executes all upgrade files in elgg/engine/schema/upgrades/ in sequential order.
- * Upgrade files must be in the standard Elgg release format of YYYYMMDDII.sql
- * where II is an incrementor starting from 01.
- *
- * Files that are < $version will be ignored.
- *
- * @warning Plugin authors should not call this function directly.
- *
- * @param int $version The version you are upgrading from in the format YYYYMMDDII.
- * @param string $fromdir Optional directory to load upgrades from. default: engine/schema/upgrades/
- * @param bool $quiet If true, suppress all error messages. Only use for the upgrade from <=1.6.
+ * Count the number of comments attached to an entity
*
- * @return bool
- * @see upgrade.php
- * @see version.php
- * @deprecated 1.8 Use PHP upgrades for sql changes.
+ * @param ElggEntity $entity
+ * @return int Number of comments
*/
-function db_upgrade($version, $fromdir = "", $quiet = FALSE) {
- global $CONFIG;
-
- elgg_deprecated_notice('db_upgrade() is deprecated by using PHP upgrades.', 1.8);
-
- $version = (int) $version;
+function elgg_count_comments($entity) {
+ elgg_deprecated_notice('elgg_count_comments() is deprecated by ElggEntity->countComments()', 1.8);
- if (!$fromdir) {
- $fromdir = $CONFIG->path . 'engine/schema/upgrades/';
+ if ($entity instanceof ElggEntity) {
+ return $entity->countComments();
}
- if ($handle = opendir($fromdir)) {
- $sqlupgrades = array();
-
- while ($sqlfile = readdir($handle)) {
- if (!is_dir($fromdir . $sqlfile)) {
- if (preg_match('/^([0-9]{10})\.(sql)$/', $sqlfile, $matches)) {
- $sql_version = (int) $matches[1];
- if ($sql_version > $version) {
- $sqlupgrades[] = $sqlfile;
- }
- }
- }
- }
+ return 0;
+}
- asort($sqlupgrades);
+/**
+ * Removes all items relating to a particular acting entity from the river
+ *
+ * @param int $subject_guid The GUID of the entity
+ *
+ * @return bool Depending on success
+ * @deprecated 1.8 Use elgg_delete_river()
+ */
+function remove_from_river_by_subject($subject_guid) {
+ elgg_deprecated_notice("remove_from_river_by_subject() deprecated by elgg_delete_river()", 1.8);
- if (sizeof($sqlupgrades) > 0) {
- foreach ($sqlupgrades as $sqlfile) {
+ return elgg_delete_river(array('subject_guid' => $subject_guid));
+}
- // hide all errors.
- if ($quiet) {
- try {
- run_sql_script($fromdir . $sqlfile);
- } catch (DatabaseException $e) {
- error_log($e->getmessage());
- }
- } else {
- run_sql_script($fromdir . $sqlfile);
- }
- }
- }
- }
+/**
+ * Removes all items relating to a particular entity being acted upon from the river
+ *
+ * @param int $object_guid The GUID of the entity
+ *
+ * @return bool Depending on success
+ * @deprecated 1.8 Use elgg_delete_river()
+ */
+function remove_from_river_by_object($object_guid) {
+ elgg_deprecated_notice("remove_from_river_by_object() deprecated by elgg_delete_river()", 1.8);
- return TRUE;
+ return elgg_delete_river(array('object_guid' => $object_guid));
}
/**
- * Count the number of comments attached to an entity
+ * Removes all items relating to a particular annotation being acted upon from the river
*
- * @param ElggEntity $entity
- * @return int Number of comments
+ * @param int $annotation_id The ID of the annotation
+ *
+ * @return bool Depending on success
+ * @since 1.7.0
+ * @deprecated 1.8 Use elgg_delete_river()
*/
-function elgg_count_comments($entity) {
- elgg_deprecated_notice('elgg_count_comments() is deprecated by ElggEntity->countComments()', 1.8);
+function remove_from_river_by_annotation($annotation_id) {
+ elgg_deprecated_notice("remove_from_river_by_annotation() deprecated by elgg_delete_river()", 1.8);
- if ($entity instanceof ElggEntity) {
- return $entity->countComments();
- }
+ return elgg_delete_river(array('annotation_id' => $annotation_id));
+}
- return 0;
-} \ No newline at end of file
+/**
+ * Removes a single river entry
+ *
+ * @param int $id The ID of the river entry
+ *
+ * @return bool Depending on success
+ * @since 1.7.2
+ * @deprecated 1.8 Use elgg_delete_river()
+ */
+function remove_from_river_by_id($id) {
+ elgg_deprecated_notice("remove_from_river_by_id() deprecated by elgg_delete_river()", 1.8);
+
+ return elgg_delete_river(array('id' => $id));
+}
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index e67f8b627..df78515f2 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -33,21 +33,15 @@ function _elgg_autoload($class) {
*
* @param string $dir The dir to look in
*
- * @return true
+ * @return void
* @since 1.8.0
*/
function elgg_register_classes($dir) {
$classes = elgg_get_file_list($dir, array(), array(), array('.php'));
- if (!$classes) {
- return false;
- }
-
foreach ($classes as $class) {
elgg_register_class(basename($class, '.php'), $class);
}
-
- return true;
}
/**
@@ -1795,8 +1789,9 @@ function elgg_cacheable_view_page_handler($page, $type) {
// translates to the url /js/calendars/jquery.fullcalendar.min.<ts>.js
// and the view js/calendars/jquery.fullcalendar.min
// we ignore the last two dots for the ts and the ext.
+ // Additionally, the timestamp is optional.
$page = implode('/', $page);
- $regex = '|(.+)\.([^\.]+)\.([^.]+)$|';
+ $regex = '|(.+?)\.([\d]+\.)?\w+$|';
preg_match($regex, $page, $matches);
$view = $matches[1];
$return = elgg_view("$type/$view");
@@ -2008,8 +2003,9 @@ function elgg_init() {
elgg_register_menu_item('topbar', array(
'name' => 'elgg_logo',
'href' => 'http://www.elgg.org/',
- 'text' => "<img src=\"$logo_url\" alt=\"Elgg logo\" />",
+ 'text' => "<img src=\"$logo_url\" alt=\"Elgg logo\" width=\"38\" height=\"20\" />",
'priority' => 1,
+ 'link_class' => 'elgg-topbar-logo',
));
// Sets a blacklist of words in the current language.
diff --git a/engine/lib/extender.php b/engine/lib/extender.php
index a017c9eec..50b05579b 100644
--- a/engine/lib/extender.php
+++ b/engine/lib/extender.php
@@ -132,7 +132,7 @@ function can_edit_extender($extender_id, $type, $user_guid = 0) {
$user = elgg_get_logged_in_user_entity();
}
- $functionname = "get_{$type}";
+ $functionname = "elgg_get_{$type}_from_id";
if (is_callable($functionname)) {
$extender = $functionname($extender_id);
} else {
@@ -161,13 +161,13 @@ function can_edit_extender($extender_id, $type, $user_guid = 0) {
/**
* Sets the URL handler for a particular extender type and name.
* It is recommended that you do not call this directly, instead use
- * one of the wrapper functions in the subtype files.
+ * one of the wrapper functions such as elgg_register_annotation_url_handler().
*
* @param string $function_name The function to register
- * @param string $extender_type Extender type
+ * @param string $extender_type Extender type ('annotation', 'metadata')
* @param string $extender_name The name of the extender
*
- * @return true|false Depending on success
+ * @return bool
*/
function elgg_register_extender_url_handler($extender_type, $extender_name, $function_name) {
diff --git a/engine/lib/group.php b/engine/lib/group.php
index d78274961..755482b00 100644
--- a/engine/lib/group.php
+++ b/engine/lib/group.php
@@ -276,8 +276,9 @@ function group_gatekeeper($forward = true) {
if ($forward && $allowed == false) {
register_error(elgg_echo('membershiprequired'));
- forward($url, 'member');
- exit;
+ if (!forward($url, 'member')) {
+ throw new SecurityException(elgg_echo('SecurityException:UnexpectedOutputInGatekeeper'));
+ }
}
return $allowed;
diff --git a/engine/lib/output.php b/engine/lib/output.php
index 3f35a1576..04c737062 100644
--- a/engine/lib/output.php
+++ b/engine/lib/output.php
@@ -170,7 +170,7 @@ function elgg_format_attributes(array $attrs) {
}
// ignore $vars['entity'] => ElggEntity stuff
- if (is_not_null($val) && (is_array($val) || !is_object($val))) {
+ if ($val !== NULL && $val !== false && (is_array($val) || !is_object($val))) {
// allow $vars['class'] => array('one', 'two');
// @todo what about $vars['style']? Needs to be semi-colon separated...
diff --git a/engine/lib/pagehandler.php b/engine/lib/pagehandler.php
index e598d6821..31d73b18c 100644
--- a/engine/lib/pagehandler.php
+++ b/engine/lib/pagehandler.php
@@ -27,6 +27,20 @@ function page_handler($handler, $page) {
array_pop($page);
}
+ // return false to stop processing the request (because you handled it)
+ // return a new $params array if you want to route the request differently
+ $params = array(
+ 'handler' => $handler,
+ 'segments' => $page,
+ );
+ $params = elgg_trigger_plugin_hook('route', $handler, NULL, $params);
+ if ($params === false) {
+ return true;
+ }
+
+ $handler = $params['handler'];
+ $page = $params['segments'];
+
if (!isset($CONFIG->pagehandler) || empty($handler)) {
$result = false;
} else if (isset($CONFIG->pagehandler[$handler]) && is_callable($CONFIG->pagehandler[$handler])) {
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index 0947b7a8e..88217b782 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -266,9 +266,9 @@ function elgg_is_active_plugin($plugin_id, $site_guid = null) {
/**
* Loads all active plugins in the order specified in the tool admin panel.
*
- * @note This is called on every page load and includes additional checking that plugins
- * are fit to be loaded. If a plugin is active and problematic, it will be disabled
- * and a visible error emitted.
+ * @note This is called on every page load. If a plugin is active and problematic, it
+ * will be disabled and a visible error emitted. This does not check the deps system because
+ * that was too slow.
*
* @return bool
*/
@@ -307,17 +307,6 @@ function elgg_load_plugins() {
$plugins = elgg_get_plugins('active');
if ($plugins) {
foreach ($plugins as $plugin) {
- // check if plugin can be started and try to start it.
- // if anything is bad, disable it and emit a message.
- if (!$plugin->isValid()) {
- $plugin->deactivate();
- $msg = elgg_echo('PluginException:MisconfiguredPlugin', array($plugin->getID(), $plugin->guid));
- register_error($msg);
- $return = false;
-
- continue;
- }
-
try {
$plugin->start($start_flags);
} catch (Exception $e) {
@@ -345,11 +334,10 @@ function elgg_load_plugins() {
* Returns an ordered list of plugins
*
* @param string $status The status of the plugins. active, inactive, or all.
- * @param bool $include_bad Include physically deleted and invalid plugins?
* @param mixed $site_guid Optional site guid
* @return array
*/
-function elgg_get_plugins($status = 'active', $include_bad = false, $site_guid = NULL) {
+function elgg_get_plugins($status = 'active', $site_guid = null) {
$db_prefix = get_config('dbprefix');
$priority = elgg_namespace_plugin_private_setting('internal', 'priority');
@@ -388,22 +376,9 @@ function elgg_get_plugins($status = 'active', $include_bad = false, $site_guid =
break;
}
- if ($include_bad) {
- $old_ia = elgg_set_ignore_access(true);
- }
-
+ $old_ia = elgg_set_ignore_access(true);
$plugins = elgg_get_entities_from_relationship($options);
-
- if ($include_bad) {
- elgg_set_ignore_access($old_ia);
- } else {
- // remove bad plugins
- foreach ($plugins as $i => $plugin) {
- if (!$plugin->isValid()) {
- unset ($plugins[$i]);
- }
- }
- }
+ elgg_set_ignore_access($old_ia);
return $plugins;
}
@@ -422,7 +397,7 @@ function elgg_get_plugins($status = 'active', $include_bad = false, $site_guid =
function elgg_set_plugin_priorities(array $order) {
$name = elgg_namespace_plugin_private_setting('internal', 'priority');
- $plugins = elgg_get_plugins('any', true);
+ $plugins = elgg_get_plugins('any');
if (!$plugins) {
return false;
}
@@ -573,7 +548,7 @@ function elgg_get_plugins_provides($type = null, $name = null) {
$provides = array();
foreach ($active_plugins as $plugin) {
- if ($plugin_provides = $plugin->manifest->getProvides()) {
+ if ($plugin_provides = $plugin->getManifest()->getProvides()) {
foreach ($plugin_provides as $provided) {
$provides[$provided['type']][$provided['name']] = array(
'version' => $provided['version'],
diff --git a/engine/lib/river.php b/engine/lib/river.php
index 80f285e50..36dde7f05 100644
--- a/engine/lib/river.php
+++ b/engine/lib/river.php
@@ -18,12 +18,14 @@
* @param int $posted The UNIX epoch timestamp of the river item (default: now)
* @param int $annotation_id The annotation ID associated with this river entry
*
- * @return bool Depending on success
+ * @return int/bool River ID or false on failure
*/
function add_to_river($view, $action_type, $subject_guid, $object_guid, $access_id = "",
$posted = 0, $annotation_id = 0) {
- // use default viewtype for when called from REST api
+ global $CONFIG;
+
+ // use default viewtype for when called from web services api
if (!elgg_view_exists($view, 'default')) {
return false;
}
@@ -60,7 +62,7 @@ $posted = 0, $annotation_id = 0) {
);
// return false to stop insert
- $params = elgg_trigger_plugin_hook('add', 'river', null, $params);
+ $params = elgg_trigger_plugin_hook('creating', 'river', null, $params);
if ($params == false) {
// inserting did not fail - it was just prevented
return true;
@@ -68,11 +70,8 @@ $posted = 0, $annotation_id = 0) {
extract($params);
- // Load config
- global $CONFIG;
-
// Attempt to save river item; return success status
- $insert_data = insert_data("insert into {$CONFIG->dbprefix}river " .
+ $id = insert_data("insert into {$CONFIG->dbprefix}river " .
" set type = '$type', " .
" subtype = '$subtype', " .
" action_type = '$action_type', " .
@@ -83,89 +82,130 @@ $posted = 0, $annotation_id = 0) {
" annotation_id = $annotation_id, " .
" posted = $posted");
- //update the entities which had the action carried out on it
- if ($insert_data) {
+ // update the entities which had the action carried out on it
+ // @todo shouldn't this be down elsewhere? Like when an annotation is saved?
+ if ($id) {
update_entity_last_action($object_guid, $posted);
- return $insert_data;
+
+ $river_items = elgg_get_river(array('id' => $id));
+ if ($river_items) {
+ elgg_trigger_event('created', 'river', $river_items[0]);
+ }
+ return $id;
+ } else {
+ return false;
}
}
/**
- * Removes all items relating to a particular acting entity from the river
+ * Delete river items
*
- * @param int $subject_guid The GUID of the entity
+ * @warning not checking access (should we?)
*
- * @return bool Depending on success
+ * @param array $options
+ * ids => INT|ARR River item id(s)
+ * subject_guids => INT|ARR Subject guid(s)
+ * object_guids => INT|ARR Object guid(s)
+ * annotation_ids => INT|ARR The identifier of the annotation(s)
+ * action_types => STR|ARR The river action type(s) identifier
+ * views => STR|ARR River view(s)
+ *
+ * types => STR|ARR Entity type string(s)
+ * subtypes => STR|ARR Entity subtype string(s)
+ * type_subtype_pairs => ARR Array of type => subtype pairs where subtype
+ * can be an array of subtype strings
+ *
+ * posted_time_lower => INT The lower bound on the time posted
+ * posted_time_upper => INT The upper bound on the time posted
+ *
+ * @return bool
+ * @since 1.8.0
*/
-function remove_from_river_by_subject($subject_guid) {
- // Sanitise
- $subject_guid = (int) $subject_guid;
-
- // Load config
+function elgg_delete_river(array $options = array()) {
global $CONFIG;
- // Remove
- return delete_data("delete from {$CONFIG->dbprefix}river where subject_guid = {$subject_guid}");
-}
+ $defaults = array(
+ 'ids' => ELGG_ENTITIES_ANY_VALUE,
-/**
- * Removes all items relating to a particular entity being acted upon from the river
- *
- * @param int $object_guid The GUID of the entity
- *
- * @return bool Depending on success
- */
-function remove_from_river_by_object($object_guid) {
- // Sanitise
- $object_guid = (int) $object_guid;
+ 'subject_guids' => ELGG_ENTITIES_ANY_VALUE,
+ 'object_guids' => ELGG_ENTITIES_ANY_VALUE,
+ 'annotation_ids' => ELGG_ENTITIES_ANY_VALUE,
- // Load config
- global $CONFIG;
+ 'views' => ELGG_ENTITIES_ANY_VALUE,
+ 'action_types' => ELGG_ENTITIES_ANY_VALUE,
- // Remove
- return delete_data("delete from {$CONFIG->dbprefix}river where object_guid = {$object_guid}");
-}
+ 'types' => ELGG_ENTITIES_ANY_VALUE,
+ 'subtypes' => ELGG_ENTITIES_ANY_VALUE,
+ 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE,
-/**
- * Removes all items relating to a particular annotation being acted upon from the river
- *
- * @param int $annotation_id The ID of the annotation
- *
- * @return bool Depending on success
- * @since 1.7.0
- */
-function remove_from_river_by_annotation($annotation_id) {
- // Sanitise
- $annotation_id = (int) $annotation_id;
+ 'posted_time_lower' => ELGG_ENTITIES_ANY_VALUE,
+ 'posted_time_upper' => ELGG_ENTITIES_ANY_VALUE,
- // Load config
- global $CONFIG;
+ 'wheres' => array(),
+ 'joins' => array(),
- // Remove
- return delete_data("delete from {$CONFIG->dbprefix}river where annotation_id = {$annotation_id}");
-}
+ );
-/**
- * Removes a single river entry
- *
- * @param int $id The ID of the river entry
- *
- * @return bool Depending on success
- * @since 1.7.2
- */
-function remove_from_river_by_id($id) {
- global $CONFIG;
+ $options = array_merge($defaults, $options);
- // Sanitise
- $id = (int) $id;
+ $singulars = array('id', 'subject_guid', 'object_guid', 'annotation_id', 'action_type', 'view', 'type', 'subtype');
+ $options = elgg_normalise_plural_options_array($options, $singulars);
+
+ $wheres = $options['wheres'];
+
+ $wheres[] = elgg_get_guid_based_where_sql('rv.id', $options['ids']);
+ $wheres[] = elgg_get_guid_based_where_sql('rv.subject_guid', $options['subject_guids']);
+ $wheres[] = elgg_get_guid_based_where_sql('rv.object_guid', $options['object_guids']);
+ $wheres[] = elgg_get_guid_based_where_sql('rv.annotation_id', $options['annotation_ids']);
+ $wheres[] = elgg_river_get_action_where_sql($options['action_types']);
+ $wheres[] = elgg_river_get_view_where_sql($options['views']);
+ $wheres[] = elgg_get_river_type_subtype_where_sql('rv', $options['types'],
+ $options['subtypes'], $options['type_subtype_pairs']);
+
+ if ($options['posted_time_lower'] && is_int($options['posted_time_lower'])) {
+ $wheres[] = "rv.posted >= {$options['posted_time_lower']}";
+ }
+
+ if ($options['posted_time_upper'] && is_int($options['posted_time_upper'])) {
+ $wheres[] = "rv.posted <= {$options['posted_time_upper']}";
+ }
+
+ // remove identical where clauses
+ $wheres = array_unique($wheres);
+
+ // see if any functions failed
+ // remove empty strings on successful functions
+ foreach ($wheres as $i => $where) {
+ if ($where === FALSE) {
+ return FALSE;
+ } elseif (empty($where)) {
+ unset($wheres[$i]);
+ }
+ }
+
+ $query = "DELETE rv.* FROM {$CONFIG->dbprefix}river rv ";
+
+ // add joins
+ foreach ($joins as $j) {
+ $query .= " $j ";
+ }
- return delete_data("delete from {$CONFIG->dbprefix}river where id = {$id}");
+ // add wheres
+ $query .= ' WHERE ';
+
+ foreach ($wheres as $w) {
+ $query .= " $w AND ";
+ }
+ $query .= "1=1";
+
+ return delete_data($query);
}
/**
* Get river items
*
* @param array $options
+ * ids => INT|ARR River item id(s)
* subject_guids => INT|ARR Subject guid(s)
* object_guids => INT|ARR Object guid(s)
* annotation_ids => INT|ARR The identifier of the annotation(s)
@@ -195,6 +235,8 @@ function elgg_get_river(array $options = array()) {
global $CONFIG;
$defaults = array(
+ 'ids' => ELGG_ENTITIES_ANY_VALUE,
+
'subject_guids' => ELGG_ENTITIES_ANY_VALUE,
'object_guids' => ELGG_ENTITIES_ANY_VALUE,
'annotation_ids' => ELGG_ENTITIES_ANY_VALUE,
@@ -224,11 +266,12 @@ function elgg_get_river(array $options = array()) {
$options = array_merge($defaults, $options);
- $singulars = array('subject_guid', 'object_guid', 'annotation_id', 'action_type', 'type', 'subtype');
+ $singulars = array('id', 'subject_guid', 'object_guid', 'annotation_id', 'action_type', 'type', 'subtype');
$options = elgg_normalise_plural_options_array($options, $singulars);
$wheres = $options['wheres'];
+ $wheres[] = elgg_get_guid_based_where_sql('rv.id', $options['ids']);
$wheres[] = elgg_get_guid_based_where_sql('rv.subject_guid', $options['subject_guids']);
$wheres[] = elgg_get_guid_based_where_sql('rv.object_guid', $options['object_guids']);
$wheres[] = elgg_get_guid_based_where_sql('rv.annotation_id', $options['annotation_ids']);
@@ -471,7 +514,7 @@ function elgg_river_get_action_where_sql($types) {
if (!is_array($types)) {
$types = sanitise_string($types);
- return "'(rv.action_type = '$types')";
+ return "(rv.action_type = '$types')";
}
// sanitize types array
@@ -485,6 +528,35 @@ function elgg_river_get_action_where_sql($types) {
}
/**
+ * Get the where clause based on river view strings
+ *
+ * @param array $types Array of view strings
+ *
+ * @return string
+ * @since 1.8.0
+ * @access private
+ */
+function elgg_river_get_view_where_sql($views) {
+ if (!$views) {
+ return '';
+ }
+
+ if (!is_array($views)) {
+ $views = sanitise_string($views);
+ return "(rv.view = '$views')";
+ }
+
+ // sanitize views array
+ $views_sanitized = array();
+ foreach ($views as $view) {
+ $views_sanitized[] = sanitise_string($view);
+ }
+
+ $view_str = implode("','", $views_sanitized);
+ return "(rv.view IN ('$view_str'))";
+}
+
+/**
* Sets the access ID on river items for a particular object
*
* @param int $object_guid The GUID of the entity
diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php
index ae42956a9..407bb69c5 100644
--- a/engine/lib/sessions.php
+++ b/engine/lib/sessions.php
@@ -472,7 +472,10 @@ function gatekeeper() {
if (!elgg_is_logged_in()) {
$_SESSION['last_forward_from'] = current_page_url();
register_error(elgg_echo('loggedinrequired'));
- forward('', 'login');
+
+ if (!forward('', 'login')) {
+ throw new SecurityException(elgg_echo('SecurityException:UnexpectedOutputInGatekeeper'));
+ }
}
}
@@ -487,7 +490,9 @@ function admin_gatekeeper() {
if (!elgg_is_admin_logged_in()) {
$_SESSION['last_forward_from'] = current_page_url();
register_error(elgg_echo('adminrequired'));
- forward('', 'admin');
+ if (!forward('', 'admin')) {
+ throw new SecurityException(elgg_echo('SecurityException:UnexpectedOutputInGatekeeper'));
+ }
}
}
diff --git a/engine/lib/upgrades/2011052801.php b/engine/lib/upgrades/2011052801.php
new file mode 100644
index 000000000..8084bc06c
--- /dev/null
+++ b/engine/lib/upgrades/2011052801.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Make sure all users have the relationship member_of_site
+ */
+global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE, $CONFIG;
+$db_prefix = get_config('dbprefix');
+
+$limit = 100;
+
+$q = "SELECT e.* FROM {$db_prefix}entities e
+ WHERE e.type = 'user' AND e.guid NOT IN (
+ SELECT guid_one FROM {$db_prefix}entity_relationships
+ WHERE guid_two = 1 AND relationship = 'member_of_site'
+ )
+ LIMIT $limit";
+
+$users = get_data($q);
+
+while ($users) {
+ $DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array();
+
+ // do manually to not trigger any events because these aren't new users.
+ foreach ($users as $user) {
+ $rel_q = "INSERT INTO {$db_prefix}entity_relationships VALUES (
+ '',
+ '$user->guid',
+ 'member_of_site',
+ '$user->site_guid',
+ '$user->time_created'
+ )";
+
+ insert_data($rel_q);
+ }
+
+ // every time we run this query we've just reduced the rows it returns by $limit
+ // so don't pass an offset.
+ $q = "SELECT e.* FROM {$db_prefix}entities e
+ WHERE e.type = 'user' AND e.guid NOT IN (
+ SELECT guid_one FROM {$db_prefix}entity_relationships
+ WHERE guid_two = 1 AND relationship = 'member_of_site'
+ )
+ LIMIT $limit";
+
+ $users = get_data($q);
+} \ No newline at end of file
diff --git a/engine/lib/upgrades/2011061200-1.8b1-sites_need_a_site_guid-6d9dcbf46c0826cc.php b/engine/lib/upgrades/2011061200-1.8b1-sites_need_a_site_guid-6d9dcbf46c0826cc.php
new file mode 100644
index 000000000..4fc59ac41
--- /dev/null
+++ b/engine/lib/upgrades/2011061200-1.8b1-sites_need_a_site_guid-6d9dcbf46c0826cc.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Elgg 1.8b1 upgrade 2011061200
+ * sites_need_a_site_guid
+ *
+ * Sites did not have a site guid. This causes problems with getting
+ * metadata on site objects since we default to the current site.
+ */
+
+global $CONFIG;
+
+$ia = elgg_set_ignore_access(true);
+$access_status = access_get_show_hidden_status();
+access_show_hidden_entities(true);
+
+$options = array(
+ 'type' => 'site',
+ 'site_guid' => 0,
+);
+$batch = new ElggBatch('elgg_get_entities', $options);
+
+foreach ($batch as $entity) {
+ if (!$entity->site_guid) {
+ update_data("UPDATE {$CONFIG->dbprefix}entities SET site_guid=$entity->guid
+ WHERE guid=$entity->guid");
+ }
+}
+
+access_show_hidden_entities($access_status);
+elgg_set_ignore_access($ia);
diff --git a/engine/lib/users.php b/engine/lib/users.php
index dcec36ba5..59bfa1259 100644
--- a/engine/lib/users.php
+++ b/engine/lib/users.php
@@ -748,40 +748,6 @@ function execute_new_password_request($user_guid, $conf_code) {
}
/**
- * Handles pages for password reset requests.
- *
- * @param array $page Pages array
- *
- * @return void
- */
-function elgg_user_resetpassword_page_handler($page) {
-
- $user_guid = get_input('u');
- $code = get_input('c');
-
- $user = get_entity($user_guid);
-
- // don't check code here to avoid automated attacks
- if (!$user instanceof ElggUser) {
- register_error(elgg_echo('user:passwordreset:unknown_user'));
- forward();
- }
-
- $params = array(
- 'guid' => $user_guid,
- 'code' => $code,
- );
- $form = elgg_view_form('user/passwordreset', array(), $params);
-
- $title = elgg_echo('resetpassword');
- $content = elgg_view_title(elgg_echo('resetpassword')) . $form;
-
- $body = elgg_view_layout('one_column', array('content' => $content));
-
- echo elgg_view_page($title, $body);
-}
-
-/**
* Simple function that will generate a random clear text password
* suitable for feeding into generate_user_password().
*
@@ -1074,7 +1040,7 @@ function collections_submenu_items() {
*/
function friends_page_handler($page_elements) {
if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) {
- set_page_owner($user->getGUID());
+ elgg_set_page_owner_guid($user->getGUID());
}
if (elgg_get_logged_in_user_guid() == elgg_get_page_owner_guid()) {
collections_submenu_items();
@@ -1129,26 +1095,27 @@ function collections_page_handler($page_elements) {
}
/**
- * Page handler for dashboard
+ * Page handler for account related pages
*
- * @param array $page_elements Page elements
+ * @param array $page_elements Page elements
+ * @param string $handler The handler string
*
* @return void
*/
-function dashboard_page_handler($page_elements) {
- require_once(dirname(dirname(dirname(__FILE__))) . "/pages/dashboard.php");
-}
-
-
-/**
- * Page handler for registration
- *
- * @param array $page_elements Page elements
- *
- * @return void
- */
-function registration_page_handler($page_elements) {
- require_once(dirname(dirname(dirname(__FILE__))) . "/pages/account/register.php");
+function elgg_user_account_page_handler($page_elements, $handler) {
+
+ $base_dir = elgg_get_root_path() . 'pages/account';
+ switch ($handler) {
+ case 'forgotpassword':
+ require_once("$base_dir/forgotten_password.php");
+ break;
+ case 'resetpassword':
+ require_once("$base_dir/reset_password.php");
+ break;
+ case 'register':
+ require_once("$base_dir/register.php");
+ break;
+ }
}
/**
@@ -1309,6 +1276,41 @@ function elgg_user_hover_menu($hook, $type, $return, $params) {
return $return;
}
+function elgg_users_setup_entity_menu($hook, $type, $return, $params) {
+ if (elgg_in_context('widgets')) {
+ return $return;
+ }
+
+ $entity = $params['entity'];
+ if (!elgg_instanceof($entity, 'user')) {
+ return $return;
+ }
+
+ if ($entity->isBanned()) {
+ $banned = elgg_echo('banned');
+ $options = array(
+ 'name' => 'banned',
+ 'text' => "<span>$banned</span>",
+ 'href' => false,
+ 'priority' => 0,
+ );
+ $return = array(ElggMenuItem::factory($options));
+ } else {
+ $return = array();
+ if (isset($entity->location)) {
+ $options = array(
+ 'name' => 'location',
+ 'text' => "<span>$entity->location</span>",
+ 'href' => false,
+ 'priority' => 150,
+ );
+ $return[] = ElggMenuItem::factory($options);
+ }
+ }
+
+ return $return;
+}
+
/**
* This function loads a set of default fields into the profile, then triggers a hook letting other plugins to edit
* add and delete fields.
@@ -1322,7 +1324,7 @@ function elgg_profile_fields_setup() {
$profile_defaults = array (
'description' => 'longtext',
'briefdescription' => 'text',
- 'location' => 'tags',
+ 'location' => 'location',
'interests' => 'tags',
'skills' => 'tags',
'contactemail' => 'email',
@@ -1356,7 +1358,7 @@ function elgg_profile_fields_setup() {
// register any tag metadata names
foreach ($CONFIG->profile_fields as $name => $type) {
- if ($type == 'tags') {
+ if ($type == 'tags' || $type == 'location' || $type == 'tag') {
elgg_register_tag_metadata_name($name);
// register a tag name translation
add_translation(get_current_language(), array("tag_names:$name" => elgg_echo("profile:$name")));
@@ -1451,6 +1453,7 @@ function users_pagesetup() {
'href' => $user->getURL(),
'text' => "<img src=\"$icon_url\" alt=\"$user->name\" title=\"$title\" class=\"$class\" />",
'priority' => 100,
+ 'link_class' => 'elgg-topbar-avatar',
));
elgg_register_menu_item('topbar', array(
@@ -1490,9 +1493,9 @@ function users_init() {
elgg_register_page_handler('friends', 'friends_page_handler');
elgg_register_page_handler('friendsof', 'friends_of_page_handler');
- elgg_register_page_handler('dashboard', 'dashboard_page_handler');
- elgg_register_page_handler('register', 'registration_page_handler');
- elgg_register_page_handler('resetpassword', 'elgg_user_resetpassword_page_handler');
+ elgg_register_page_handler('register', 'elgg_user_account_page_handler');
+ elgg_register_page_handler('forgotpassword', 'elgg_user_account_page_handler');
+ elgg_register_page_handler('resetpassword', 'elgg_user_account_page_handler');
elgg_register_page_handler('login', 'elgg_user_login_page_handler');
elgg_register_page_handler('avatar', 'elgg_avatar_page_handler');
elgg_register_page_handler('profile', 'elgg_profile_page_handler');
@@ -1529,6 +1532,8 @@ function users_init() {
// Register the user type
elgg_register_entity_type('user', '');
+ elgg_register_plugin_hook_handler('register', 'menu:entity', 'elgg_users_setup_entity_menu', 501);
+
elgg_register_event_handler('create', 'user', 'user_create_hook_add_site_relationship');
}