aboutsummaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/classes/ElggEntity.php18
-rw-r--r--engine/classes/ElggMenuItem.php4
-rw-r--r--engine/classes/ElggPluginPackage.php6
-rw-r--r--engine/classes/ElggPriorityList.php358
-rw-r--r--engine/classes/ElggSite.php3
-rw-r--r--engine/lib/access.php191
-rw-r--r--engine/lib/actions.php12
-rw-r--r--engine/lib/admin.php10
-rw-r--r--engine/lib/deprecated-1.8.php87
-rw-r--r--engine/lib/elgglib.php113
-rw-r--r--engine/lib/entities.php10
-rw-r--r--engine/lib/navigation.php26
-rw-r--r--engine/lib/plugins.php17
-rw-r--r--engine/lib/river.php2
-rw-r--r--engine/lib/users.php34
-rw-r--r--engine/lib/views.php64
-rw-r--r--engine/start.php2
-rw-r--r--engine/tests/api/access_collections.php269
-rw-r--r--engine/tests/api/helpers.php332
19 files changed, 1311 insertions, 247 deletions
diff --git a/engine/classes/ElggEntity.php b/engine/classes/ElggEntity.php
index 6edc99dd4..2fa0d7b02 100644
--- a/engine/classes/ElggEntity.php
+++ b/engine/classes/ElggEntity.php
@@ -371,13 +371,18 @@ abstract class ElggEntity extends ElggData implements
* Deletes all metadata on this object (metadata.entity_guid = $this->guid).
* If you pass a name, only metadata matching that name will be deleted.
*
- * @warning Calling this with no or empty arguments will clear all metadata on the entity.
+ * @warning Calling this with no $name will clear all metadata on the entity.
*
- * @param null|string $name The metadata name to remove.
+ * @param null|string $name The name of the metadata to remove.
* @return bool
* @since 1.8
*/
public function deleteMetadata($name = null) {
+
+ if (!$this->guid) {
+ return false;
+ }
+
$options = array(
'guid' => $this->guid,
'limit' => 0
@@ -1432,11 +1437,7 @@ abstract class ElggEntity extends ElggData implements
* @return true
*/
public function setLocation($location) {
- $location = sanitise_string($location);
-
- $this->location = $location;
-
- return true;
+ return $this->location = $location;
}
/**
@@ -1449,9 +1450,6 @@ abstract class ElggEntity extends ElggData implements
* @todo Unimplemented
*/
public function setLatLong($lat, $long) {
- $lat = sanitise_string($lat);
- $long = sanitise_string($long);
-
$this->set('geo:lat', $lat);
$this->set('geo:long', $long);
diff --git a/engine/classes/ElggMenuItem.php b/engine/classes/ElggMenuItem.php
index cfdc2f5fa..f7a6b5c65 100644
--- a/engine/classes/ElggMenuItem.php
+++ b/engine/classes/ElggMenuItem.php
@@ -59,7 +59,7 @@ class ElggMenuItem {
/**
* @var string Tooltip
*/
- protected $title = '';
+ protected $title = false;
/**
* @var string The string to display if link is clicked
@@ -552,6 +552,8 @@ class ElggMenuItem {
if ($this->confirm) {
$vars['confirm'] = $this->confirm;
return elgg_view('output/confirmlink', $vars);
+ } else {
+ unset($vars['confirm']);
}
return elgg_view('output/url', $vars);
diff --git a/engine/classes/ElggPluginPackage.php b/engine/classes/ElggPluginPackage.php
index 977b72d76..02b985285 100644
--- a/engine/classes/ElggPluginPackage.php
+++ b/engine/classes/ElggPluginPackage.php
@@ -334,7 +334,11 @@ class ElggPluginPackage {
// first, check if any active plugin conflicts with us.
foreach ($enabled_plugins as $plugin) {
- $temp_conflicts = $plugin->getManifest()->getConflicts();
+ $temp_conflicts = array();
+ $temp_manifest = $plugin->getManifest();
+ if ($temp_manifest instanceof ElggPluginManifest) {
+ $temp_conflicts = $plugin->getManifest()->getConflicts();
+ }
foreach ($temp_conflicts as $conflict) {
if ($conflict['type'] == 'plugin' && $conflict['name'] == $this_id) {
$result = $this->checkDepPlugin($conflict, $enabled_plugins, false);
diff --git a/engine/classes/ElggPriorityList.php b/engine/classes/ElggPriorityList.php
new file mode 100644
index 000000000..aa33831ff
--- /dev/null
+++ b/engine/classes/ElggPriorityList.php
@@ -0,0 +1,358 @@
+<?php
+/**
+ * Iterate over elements in a specific priority.
+ *
+ * $pl = new ElggPriorityList();
+ * $pl->add('Element 0');
+ * $pl->add('Element 10', 10);
+ * $pl->add('Element -10', -10);
+ *
+ * foreach ($pl as $priority => $element) {
+ * var_dump("$priority => $element");
+ * }
+ *
+ * Yields:
+ * -10 => Element -10
+ * 0 => Element 0
+ * 10 => Element 10
+ *
+ * Collisions on priority are handled by inserting the element at or as close to the
+ * requested priority as possible:
+ *
+ * $pl = new ElggPriorityList();
+ * $pl->add('Element 5', 5);
+ * $pl->add('Colliding element 5', 5);
+ * $pl->add('Another colliding element 5', 5);
+ *
+ * foreach ($pl as $priority => $element) {
+ * var_dump("$priority => $element");
+ * }
+ *
+ * Yields:
+ * 5 => 'Element 5',
+ * 6 => 'Colliding element 5',
+ * 7 => 'Another colliding element 5'
+ *
+ * You can do priority lookups by element:
+ *
+ * $pl = new ElggPriorityList();
+ * $pl->add('Element 0');
+ * $pl->add('Element -5', -5);
+ * $pl->add('Element 10', 10);
+ * $pl->add('Element -10', -10);
+ *
+ * $priority = $pl->getPriority('Element -5');
+ *
+ * Or element lookups by priority.
+ * $element = $pl->getElement(-5);
+ *
+ * To remove elements, pass the element.
+ * $pl->remove('Element -10');
+ *
+ * To check if an element exists:
+ * $pl->contains('Element -5');
+ *
+ * To move an element:
+ * $pl->move('Element -5', -3);
+ *
+ * ElggPriorityList only tracks priority. No checking is done in ElggPriorityList for duplicates or
+ * updating. If you need to track this use objects and an external map:
+ *
+ * function elgg_register_something($id, $display_name, $location, $priority = 500) {
+ * // $id => $element.
+ * static $map = array();
+ * static $list;
+ *
+ * if (!$list) {
+ * $list = new ElggPriorityList();
+ * }
+ *
+ * // update if already registered.
+ * if (isset($map[$id])) {
+ * $element = $map[$id];
+ * // move it first because we have to pass the original element.
+ * if (!$list->move($element, $priority)) {
+ * return false;
+ * }
+ * $element->display_name = $display_name;
+ * $element->location = $location;
+ * } else {
+ * $element = new stdClass();
+ * $element->display_name = $display_name;
+ * $element->location = $location;
+ * if (!$list->add($element, $priority)) {
+ * return false;
+ * }
+ * $map[$id] = $element;
+ * }
+ *
+ * return true;
+ * }
+ *
+ * @package Elgg.Core
+ * @subpackage Helpers
+ */
+class ElggPriorityList
+ implements Iterator, Countable {
+
+ /**
+ * The list of elements
+ *
+ * @var array
+ */
+ private $elements = array();
+
+ /**
+ * Create a new priority list.
+ *
+ * @param array $elements An optional array of priorities => element
+ */
+ public function __construct(array $elements = array()) {
+ if ($elements) {
+ foreach ($elements as $priority => $element) {
+ $this->add($element, $priority);
+ }
+ }
+ }
+
+ /**
+ * Adds an element to the list.
+ *
+ * @warning This returns the priority at which the element was added, which can be 0. Use
+ * !== false to check for success.
+ *
+ * @param mixed $element The element to add to the list.
+ * @param mixed $priority Priority to add the element. In priority collisions, the original element
+ * maintains its priority and the new element is to the next available
+ * slot, taking into consideration all previously registered elements.
+ * Negative elements are accepted.
+ * @return int The priority of the added element.
+ */
+ public function add($element, $priority = null, $exact = false) {
+ if ($priority !== null && !is_numeric($priority)) {
+ return false;
+ } else {
+ $priority = $this->getNextPriority($priority);
+ }
+
+ $this->elements[$priority] = $element;
+ $this->sorted = false;
+ return $priority;
+ }
+
+ /**
+ * Removes an element from the list.
+ *
+ * @warning The element must have the same attributes / values. If using $strict, it must have
+ * the same types. array(10) will fail in strict against array('10') (str vs int).
+ *
+ * @param type $element
+ * @return bool
+ */
+ public function remove($element, $strict = false) {
+ $index = array_search($element, $this->elements, $strict);
+ if ($index !== false) {
+ unset($this->elements[$index]);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Move an existing element to a new priority.
+ *
+ * @param mixed $current_priority
+ * @param int $new_priority
+ *
+ * @return int The new priority.
+ */
+ public function move($element, $new_priority, $strict = false) {
+ $new_priority = (int) $new_priority;
+
+ $current_priority = $this->getPriority($element, $strict);
+ if ($current_priority === false) {
+ return false;
+ }
+
+ if ($current_priority == $new_priority) {
+ return true;
+ }
+
+ // move the actual element so strict operations still work
+ $element = $this->getElement($current_priority);
+ unset($this->elements[$current_priority]);
+ return $this->add($element, $new_priority);
+ }
+
+ /**
+ * Returns the elements
+ *
+ * @return array
+ */
+ public function getElements() {
+ $this->sortIfUnsorted();
+ return $this->elements;
+ }
+
+ /**
+ * Sort the elements optionally by a callback function.
+ *
+ * If no user function is provided the elements are sorted by priority registered.
+ *
+ * The callback function should accept the array of elements as the first argument and should
+ * return a sorted array.
+ *
+ * This function can be called multiple times.
+ *
+ * @param type $callback
+ * @return bool
+ */
+ public function sort($callback = null) {
+ if (!$callback) {
+ ksort($this->elements, SORT_NUMERIC);
+ } else {
+ $sorted = call_user_func($callback, $this->elements);
+
+ if (!$sorted) {
+ return false;
+ }
+
+ $this->elements = $sorted;
+ }
+
+ $this->sorted = true;
+ return true;
+ }
+
+ /**
+ * Sort the elements if they haven't been sorted yet.
+ *
+ * @return bool
+ */
+ private function sortIfUnsorted() {
+ if (!$this->sorted) {
+ return $this->sort();
+ }
+ }
+
+ /**
+ * Returns the next priority available.
+ *
+ * @param int $near Make the priority as close to $near as possible.
+ * @return int
+ */
+ public function getNextPriority($near = 0) {
+ $near = (int) $near;
+
+ while (array_key_exists($near, $this->elements)) {
+ $near++;
+ }
+
+ return $near;
+ }
+
+ /**
+ * Returns the priority of an element if it exists in the list.
+ *
+ * @warning This can return 0 if the element's priority is 0.
+ *
+ * @param mixed $element The element to check for.
+ * @param bool $strict Use strict checking?
+ * @return mixed False if the element doesn't exists, the priority if it does.
+ */
+ public function getPriority($element, $strict = false) {
+ return array_search($element, $this->elements, $strict);
+ }
+
+ /**
+ * Returns the element at $priority.
+ *
+ * @param int $priority
+ * @return mixed The element or false on fail.
+ */
+ public function getElement($priority) {
+ return (isset($this->elements[$priority])) ? $this->elements[$priority] : false;
+ }
+
+ /**
+ * Returns if the list contains $element.
+ *
+ * @param mixed $element The element to check.
+ * @param bool $strict Use strict checking?
+ * @return bool
+ */
+ public function contains($element, $strict = false) {
+ return $this->getPriority($element, $strict) !== false;
+ }
+
+
+ /**********************
+ * Interface methods *
+ **********************/
+
+ /**
+ * Iterator
+ */
+
+ /**
+ * PHP Iterator Interface
+ *
+ * @see Iterator::rewind()
+ * @return void
+ */
+ public function rewind() {
+ $this->sortIfUnsorted();
+ return rewind($this->elements);
+ }
+
+ /**
+ * PHP Iterator Interface
+ *
+ * @see Iterator::current()
+ * @return mixed
+ */
+ public function current() {
+ $this->sortIfUnsorted();
+ return current($this->elements);
+ }
+
+ /**
+ * PHP Iterator Interface
+ *
+ * @see Iterator::key()
+ * @return int
+ */
+ public function key() {
+ $this->sortIfUnsorted();
+ return key($this->elements);
+ }
+
+ /**
+ * PHP Iterator Interface
+ *
+ * @see Iterator::next()
+ * @return mixed
+ */
+ public function next() {
+ $this->sortIfUnsorted();
+ return next($this->elements);
+ }
+
+ /**
+ * PHP Iterator Interface
+ *
+ * @see Iterator::valid()
+ * @return bool
+ */
+ public function valid() {
+ $this->sortIfUnsorted();
+ $key = key($this->elements);
+ return ($key !== NULL && $key !== FALSE);
+ }
+
+ // Countable
+ public function count() {
+ return count($this->elements);
+ }
+} \ No newline at end of file
diff --git a/engine/classes/ElggSite.php b/engine/classes/ElggSite.php
index e3b8b8f1a..40bfca060 100644
--- a/engine/classes/ElggSite.php
+++ b/engine/classes/ElggSite.php
@@ -410,8 +410,9 @@ class ElggSite extends ElggEntity {
'register',
'action/register',
'forgotpassword',
- 'action/user/requestnewpassword',
'resetpassword',
+ 'action/user/requestnewpassword',
+ 'action/user/passwordreset',
'upgrade\.php',
'xml-rpc\.php',
'mt/mt-xmlrpc\.cgi',
diff --git a/engine/lib/access.php b/engine/lib/access.php
index cde3d256f..6da747463 100644
--- a/engine/lib/access.php
+++ b/engine/lib/access.php
@@ -410,6 +410,43 @@ function get_write_access_array($user_id = 0, $site_id = 0, $flush = false) {
return $tmp_access_array;
}
+
+/**
+ * Can the user write to the access collection?
+ *
+ * Hook into the access:collections:write, user to change this.
+ *
+ * Respects access control disabling for admin users and {@see elgg_set_ignore_access()}
+ *
+ * @see get_write_access_array()
+ *
+ * @param int $collection_id The collection id
+ * @param mixed $user_guid The user GUID to check for. Defaults to logged in user.
+ * @return bool
+ */
+function can_edit_access_collection($collection_id, $user_guid = null) {
+ if ($user_guid) {
+ $user = get_entity((int) $user_guid);
+ } else {
+ $user = get_loggedin_user();
+ }
+
+ $collection = get_access_collection($collection_id);
+
+ if (!($user instanceof ElggUser) || !$collection) {
+ return false;
+ }
+
+ $write_access = get_write_access_array($user->getGUID(), null, true);
+
+ // don't ignore access when checking users.
+ if ($user_guid) {
+ return array_key_exists($collection_id, $write_access);
+ } else {
+ return elgg_get_ignore_access() || array_key_exists($collection_id, $write_access);
+ }
+}
+
/**
* Creates a new access collection.
*
@@ -483,37 +520,30 @@ function create_access_collection($name, $owner_guid = 0, $site_guid = 0) {
function update_access_collection($collection_id, $members) {
global $CONFIG;
- $collection_id = (int) $collection_id;
- $members = (is_array($members)) ? $members : array();
+ $acl = get_access_collection($collection_id);
- $collections = get_write_access_array();
-
- if (array_key_exists($collection_id, $collections)) {
- $cur_members = get_members_of_access_collection($collection_id, true);
- $cur_members = (is_array($cur_members)) ? $cur_members : array();
+ if (!$acl) {
+ return false;
+ }
+ $members = (is_array($members)) ? $members : array();
- $remove_members = array_diff($cur_members, $members);
- $add_members = array_diff($members, $cur_members);
+ $cur_members = get_members_of_access_collection($collection_id, true);
+ $cur_members = (is_array($cur_members)) ? $cur_members : array();
- $params = array(
- 'collection_id' => $collection_id,
- 'members' => $members,
- 'add_members' => $add_members,
- 'remove_members' => $remove_members
- );
+ $remove_members = array_diff($cur_members, $members);
+ $add_members = array_diff($members, $cur_members);
- foreach ($add_members as $guid) {
- add_user_to_access_collection($guid, $collection_id);
- }
+ $result = true;
- foreach ($remove_members as $guid) {
- remove_user_from_access_collection($guid, $collection_id);
- }
+ foreach ($add_members as $guid) {
+ $result = $result && add_user_to_access_collection($guid, $collection_id);
+ }
- return true;
+ foreach ($remove_members as $guid) {
+ $result = $result && remove_user_from_access_collection($guid, $collection_id);
}
- return false;
+ return $result;
}
/**
@@ -527,27 +557,26 @@ function update_access_collection($collection_id, $members) {
* @see update_access_collection()
*/
function delete_access_collection($collection_id) {
+ global $CONFIG;
+
$collection_id = (int) $collection_id;
- $collections = get_write_access_array(null, null, TRUE);
$params = array('collection_id' => $collection_id);
if (!elgg_trigger_plugin_hook('access:collections:deletecollection', 'collection', $params, true)) {
return false;
}
- if (array_key_exists($collection_id, $collections)) {
- global $CONFIG;
- $query = "delete from {$CONFIG->dbprefix}access_collection_membership"
- . " where access_collection_id = {$collection_id}";
- delete_data($query);
+ // Deleting membership doesn't affect result of deleting ACL.
+ $q = "DELETE FROM {$CONFIG->dbprefix}access_collection_membership
+ WHERE access_collection_id = {$collection_id}";
+ delete_data($q);
- $query = "delete from {$CONFIG->dbprefix}access_collections where id = {$collection_id}";
- delete_data($query);
- return true;
- } else {
- return false;
- }
+ $q = "DELETE FROM {$CONFIG->dbprefix}access_collections
+ WHERE id = {$collection_id}";
+ $result = delete_data($q);
+
+ return $result;
}
/**
@@ -584,45 +613,34 @@ function get_access_collection($collection_id) {
* @see remove_user_from_access_collection()
*/
function add_user_to_access_collection($user_guid, $collection_id) {
+ global $CONFIG;
+
$collection_id = (int) $collection_id;
$user_guid = (int) $user_guid;
- $collections = get_write_access_array();
+ $user = get_user($user_guid);
- if (!($collection = get_access_collection($collection_id))) {
- return false;
- }
+ $collection = get_access_collection($collection_id);
- $user = get_user($user_guid);
- if (!$user) {
+ if (!($user instanceof Elgguser) || !$collection) {
return false;
}
- // to add someone to a collection, the user must be a member of the collection or
- // no one must own it
- if ((array_key_exists($collection_id, $collections) || $collection->owner_guid == 0)) {
- $result = true;
- } else {
- $result = false;
- }
-
$params = array(
'collection_id' => $collection_id,
- 'collection' => $collection,
'user_guid' => $user_guid
);
- $result = elgg_trigger_plugin_hook('access:collections:add_user', 'collection', $params, $result);
+ $result = elgg_trigger_plugin_hook('access:collections:add_user', 'collection', $params, true);
if ($result == false) {
return false;
}
try {
- global $CONFIG;
- $query = "insert into {$CONFIG->dbprefix}access_collection_membership"
- . " set access_collection_id = {$collection_id}, user_guid = {$user_guid}";
- insert_data($query);
+ $q = "INSERT INTO {$CONFIG->dbprefix}access_collection_membership
+ SET access_collection_id = {$collection_id},
+ user_guid = {$user_guid}";
+ insert_data($q);
} catch (DatabaseException $e) {
- // nothing.
return false;
}
@@ -640,34 +658,32 @@ function add_user_to_access_collection($user_guid, $collection_id) {
* @return true|false Depending on success
*/
function remove_user_from_access_collection($user_guid, $collection_id) {
+ global $CONFIG;
+
$collection_id = (int) $collection_id;
$user_guid = (int) $user_guid;
- $collections = get_write_access_array();
- $user = $user = get_user($user_guid);
+ $user = get_user($user_guid);
+
+ $collection = get_access_collection($collection_id);
- if (!($collection = get_access_collection($collection_id))) {
+ if (!($user instanceof Elgguser) || !$collection) {
return false;
}
- if ((array_key_exists($collection_id, $collections) || $collection->owner_guid == 0) && $user) {
- global $CONFIG;
- $params = array(
- 'collection_id' => $collection_id,
- 'user_guid' => $user_guid
- );
-
- if (!elgg_trigger_plugin_hook('access:collections:remove_user', 'collection', $params, true)) {
- return false;
- }
-
- delete_data("delete from {$CONFIG->dbprefix}access_collection_membership "
- . "where access_collection_id = {$collection_id} and user_guid = {$user_guid}");
-
- return true;
+ $params = array(
+ 'collection_id' => $collection_id,
+ 'user_guid' => $user_guid
+ );
+ if (!elgg_trigger_plugin_hook('access:collections:remove_user', 'collection', $params, true)) {
+ return false;
}
- return false;
+ $q = "DELETE FROM {$CONFIG->dbprefix}access_collection_membership
+ WHERE access_collection_id = {$collection_id}
+ AND user_guid = {$user_guid}";
+
+ return delete_data($q);
}
/**
@@ -939,8 +955,18 @@ function access_init() {
* @since 1.7.0
* @elgg_event_handler permissions_check all
*/
-function elgg_override_permissions_hook() {
- $user_guid = elgg_get_logged_in_user_guid();
+function elgg_override_permissions_hook($hook, $type, $value, $params) {
+ $user = elgg_extract('user', $params);
+ if (!$user) {
+ $user = elgg_get_logged_in_user_entity();
+ }
+
+ // don't do this so ignore access still works.
+// if (!$user instanceof ElggUser) {
+// return false;
+// }
+
+ $user_guid = $user->guid;
// check for admin
if ($user_guid && elgg_is_admin_user($user_guid)) {
@@ -956,9 +982,20 @@ function elgg_override_permissions_hook() {
return NULL;
}
+/**
+ * Runs unit tests for the entities object.
+ */
+function access_test($hook, $type, $value, $params) {
+ global $CONFIG;
+ $value[] = $CONFIG->path . 'engine/tests/api/access_collections.php';
+ return $value;
+}
+
// This function will let us know when 'init' has finished
elgg_register_event_handler('init', 'system', 'access_init', 9999);
// For overrided permissions
elgg_register_plugin_hook_handler('permissions_check', 'all', 'elgg_override_permissions_hook');
elgg_register_plugin_hook_handler('container_permissions_check', 'all', 'elgg_override_permissions_hook');
+
+elgg_register_plugin_hook_handler('unit_test', 'system', 'access_test'); \ No newline at end of file
diff --git a/engine/lib/actions.php b/engine/lib/actions.php
index 4ccffd267..99e22e104 100644
--- a/engine/lib/actions.php
+++ b/engine/lib/actions.php
@@ -446,7 +446,17 @@ function ajax_forward_hook($hook, $type, $reason, $params) {
$params['status'] = -1;
}
- header("Content-type: application/json");
+ // Check the requester can accept JSON responses, if not fall back to
+ // returning JSON in a plain-text response. Some libraries request
+ // JSON in an invisible iframe which they then read from the iframe,
+ // however some browsers will not accept the JSON MIME type.
+ if (stripos($_SERVER['HTTP_ACCEPT'], 'application/json') === FALSE) {
+ header("Content-type: text/plain");
+ }
+ else {
+ header("Content-type: application/json");
+ }
+
echo json_encode($params);
exit;
}
diff --git a/engine/lib/admin.php b/engine/lib/admin.php
index c16da9295..93ee43008 100644
--- a/engine/lib/admin.php
+++ b/engine/lib/admin.php
@@ -239,6 +239,9 @@ function admin_init() {
elgg_register_action('profile/fields/reorder', '', 'admin');
elgg_register_simplecache_view('js/admin');
+ $url = elgg_get_simplecache_url('js', 'admin');
+ elgg_register_js('elgg.admin', $url);
+ elgg_register_js('jquery.jeditable', 'vendors/jquery/jquery.jeditable.mini.js');
// administer
// dashboard
@@ -434,11 +437,7 @@ function admin_settings_page_handler($page) {
elgg_set_context('admin');
elgg_unregister_css('elgg');
- $url = elgg_get_simplecache_url('js', 'admin');
- elgg_register_js('elgg.admin', $url);
elgg_load_js('elgg.admin');
-
- elgg_register_js('jquery.jeditable', 'vendors/jquery/jquery.jeditable.mini.js');
elgg_load_js('jquery.jeditable');
// default to dashboard
@@ -548,9 +547,8 @@ function admin_markdown_page_handler($pages) {
elgg_set_context('admin');
elgg_unregister_css('elgg');
- $url = elgg_get_simplecache_url('js', 'admin');
- elgg_register_js('elgg.admin', $url);
elgg_load_js('elgg.admin');
+ elgg_load_js('jquery.jeditable');
elgg_load_library('elgg:markdown');
$plugin_id = elgg_extract(0, $pages);
diff --git a/engine/lib/deprecated-1.8.php b/engine/lib/deprecated-1.8.php
index ff4fa0756..f0f4bd9dc 100644
--- a/engine/lib/deprecated-1.8.php
+++ b/engine/lib/deprecated-1.8.php
@@ -1146,7 +1146,7 @@ function get_entities_from_metadata_groups_multi($group_guid, $meta_array, $enti
* @param bool $navigation Display pagination? Default: true
*
* @return string A viewable list of entities
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_entities_from_location()
*/
function list_entities_in_area($lat, $long, $radius, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $listtypetoggle = false, $navigation = true) {
elgg_deprecated_notice('list_entities_in_area() was deprecated. Use elgg_list_entities_from_location()', 1.8);
@@ -1195,7 +1195,7 @@ function list_entities_in_area($lat, $long, $radius, $type = "", $subtype = "",
* @param bool $navigation Display pagination? Default: true
*
* @return string A viewable list of entities
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_list_entities_from_location()
*/
function list_entities_location($location, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $listtypetoggle = false, $navigation = true) {
elgg_deprecated_notice('list_entities_location() was deprecated. Use elgg_list_entities_from_metadata()', 1.8);
@@ -1220,7 +1220,7 @@ function list_entities_location($location, $type = "", $subtype = "", $owner_gui
* @param int|array $container_guid Container GUID
*
* @return array A list of entities.
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_entities_from_location()
*/
function get_entities_in_area($lat, $long, $radius, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid = NULL) {
elgg_deprecated_notice('get_entities_in_area() was deprecated by elgg_get_entities_from_location()!', 1.8);
@@ -1369,7 +1369,7 @@ function list_entities_from_metadata_multi($meta_array, $entity_type = "", $enti
* Deprecated by elgg_register_menu_item(). Set $menu_name to 'page'.
*
* @see elgg_register_menu_item()
- * @deprecated 1.8
+ * @deprecated 1.8 Use the new menu system
*
* @param string $label The label
* @param string $link The link
@@ -1411,7 +1411,7 @@ function add_submenu_item($label, $link, $group = 'default', $onclick = false, $
/**
* Remove an item from submenu by label
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use the new menu system
* @see elgg_unregister_menu_item()
*
* @param string $label The item label
@@ -1429,7 +1429,7 @@ function remove_submenu_item($label, $group = 'a') {
* Use elgg_view_menu(). Set $menu_name to 'owner_block'.
*
* @see elgg_view_menu()
- * @deprecated 1.8
+ * @deprecated 1.8 Use the new menu system. elgg_view_menu()
*
* @return string
*/
@@ -1465,7 +1465,7 @@ function add_menu($menu_name, $menu_url, $menu_children = array(), $context = ""
* @param string $menu_name The name of the menu item
*
* @return true|false Depending on success
- * @deprecated 1.8
+ * @deprecated 1.8 Use the new menu system
*/
function remove_menu($menu_name) {
elgg_deprecated_notice("remove_menu() deprecated by elgg_unregister_menu_item()", 1.8);
@@ -1478,7 +1478,7 @@ function remove_menu($menu_name) {
* @param string $title The title
*
* @return string The optimised title
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_friendly_title()
*/
function friendly_title($title) {
elgg_deprecated_notice('friendly_title was deprecated by elgg_get_friendly_title', 1.8);
@@ -1491,7 +1491,7 @@ function friendly_title($title) {
* @param int $time A UNIX epoch timestamp
*
* @return string The friendly time
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_view_friendly_time()
*/
function friendly_time($time) {
elgg_deprecated_notice('friendly_time was deprecated by elgg_view_friendly_time', 1.8);
@@ -1501,7 +1501,7 @@ function friendly_time($time) {
/**
* Filters a string into an array of significant words
*
- * @deprecated 1.8
+ * @deprecated 1.8 Don't use this.
*
* @param string $string A string
*
@@ -1539,7 +1539,7 @@ function filter_string($string) {
/**
* Returns true if the word in $input is considered significant
*
- * @deprecated 1.8
+ * @deprecated 1.8 Don't use this.
*
* @param string $input A word
*
@@ -1576,7 +1576,7 @@ function page_owner() {
/**
* Gets the owner entity for the current page.
*
- * @deprecated 1.8 Use elgg_get_page_owner()
+ * @deprecated 1.8 Use elgg_get_page_owner_entity()
* @return ElggEntity|false The current page owner or false if none.
*/
function page_owner_entity() {
@@ -1645,7 +1645,7 @@ function get_context() {
/**
* Returns a list of plugins to load, in the order that they should be loaded.
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_plugin_ids_in_dir() or elgg_get_plugins()
*
* @return array List of plugins
*/
@@ -1676,7 +1676,7 @@ function get_plugin_list() {
* elgg_regenerate_simplecache();
* elgg_filepath_cache_reset();
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_generate_plugin_entities() and elgg_set_plugin_priorities()
*
* @param array $pluginorder Optionally, a list of existing plugins and their orders
*
@@ -1708,7 +1708,7 @@ function regenerate_plugin_list($pluginorder = FALSE) {
*
* i.e., if the last plugin was in /mod/foobar/, get_plugin_name would return foo_bar.
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_calling_plugin_id()
*
* @param boolean $mainfilename If set to true, this will instead determine the
* context from the main script filename called by
@@ -1727,7 +1727,7 @@ function get_plugin_name($mainfilename = false) {
*
* @example plugins/manifest.xml Example 1.8-style manifest file.
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use ElggPlugin->getManifest()
*
* @param string $plugin Plugin name.
* @return array of values
@@ -1750,7 +1750,7 @@ function load_plugin_manifest($plugin) {
* This function checks a plugin manifest 'elgg_version' value against the current install
* returning TRUE if the elgg_version is >= the current install's version.
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use ElggPlugin->canActivate()
*
* @param string $manifest_elgg_version_string The build version (eg 2009010201).
* @return bool
@@ -1773,7 +1773,7 @@ function check_plugin_compatibility($manifest_elgg_version_string) {
/**
* Shorthand function for finding the plugin settings.
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_calling_plugin_entity() or elgg_get_plugin_from_id()
*
* @param string $plugin_id Optional plugin id, if not specified
* then it is detected from where you are calling.
@@ -1792,7 +1792,7 @@ function find_plugin_settings($plugin_id = null) {
/**
* Return an array of installed plugins.
*
- * @deprecated 1.8
+ * @deprecated 1.8 use elgg_get_plugins()
*
* @param string $status any|enabled|disabled
* @return array
@@ -1843,7 +1843,7 @@ function get_installed_plugins($status = 'all') {
* elgg_regenerate_simplecache();
* elgg_filepath_cache_reset();
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use ElggPlugin->activate()
*
* @param string $plugin The plugin name.
* @param int $site_guid The site id, if not specified then this is detected.
@@ -1884,7 +1884,7 @@ function enable_plugin($plugin, $site_guid = null) {
* elgg_regenerate_simplecache();
* elgg_filepath_cache_reset();
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use ElggPlugin->deactivate()
*
* @param string $plugin The plugin name.
* @param int $site_guid The site id, if not specified then this is detected.
@@ -1915,7 +1915,7 @@ function disable_plugin($plugin, $site_guid = 0) {
/**
* Return whether a plugin is enabled or not.
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_is_active_plugin()
*
* @param string $plugin The plugin name.
* @param int $site_guid The site id, if not specified then this is detected.
@@ -1943,7 +1943,7 @@ function is_plugin_enabled($plugin, $site_guid = 0) {
* @param mixed $container_guid The container(s) GUIDs
*
* @return array A list of entities.
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_entities_from_private_settings()
*/
function get_entities_from_private_setting($name = "", $value = "", $type = "", $subtype = "",
$owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0,
@@ -2022,13 +2022,13 @@ $container_guid = null) {
* @param mixed $container_guid Container GUID
*
* @return array A list of entities.
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_entities_from_private_settings()
*/
function get_entities_from_private_setting_multi(array $name, $type = "", $subtype = "",
$owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false,
$site_guid = 0, $container_guid = null) {
- elgg_deprecated_notice('get_entities_from_private_setting_multi() was deprecated by elgg_get_entities_from_private_setting()!', 1.8);
+ elgg_deprecated_notice('get_entities_from_private_setting_multi() was deprecated by elgg_get_entities_from_private_settings()!', 1.8);
$options = array();
@@ -2194,7 +2194,7 @@ $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_
/**
* Displays a human-readable list of entities
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_list_entities_from_relationship_count()
*
* @param string $relationship The relationship eg "friends_of"
* @param bool $inverse_relationship Inverse relationship owners
@@ -2245,7 +2245,7 @@ $listtypetoggle = false, $pagination = true) {
* Gets the number of entities by a the number of entities related to
* them in a particular way also constrained by metadata.
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_entities_from_relationship()
*
* @param string $relationship The relationship eg "friends_of"
* @param int $relationship_guid The guid of the entity to use query
@@ -2337,7 +2337,7 @@ $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_
* @param int $posted_max The maximum time period to look at. Default: none
*
* @return array|false Depending on success
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_river()
*/
function get_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '',
$type = '', $subtype = '', $action_type = '', $limit = 20, $offset = 0, $posted_min = 0,
@@ -2404,7 +2404,7 @@ $posted_max = 0) {
* @param bool $pagination Show pagination?
*
* @return string Human-readable river.
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_list_river()
*/
function elgg_view_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '',
$type = '', $subtype = '', $action_type = '', $limit = 20, $posted_min = 0,
@@ -2433,7 +2433,8 @@ $posted_max = 0, $pagination = true) {
/**
* Construct and execute the query required for the activity stream.
*
- * @deprecated 1.8
+ * @deprecated 1.8 This is outdated and uses the systemlog table instead of the river table.
+ * Don't use it.
*/
function get_activity_stream_data($limit = 10, $offset = 0, $type = "", $subtype = "",
$owner_guid = "", $owner_relationship = "") {
@@ -2668,7 +2669,7 @@ function list_site_members($site_guid, $limit = 10, $fullview = true) {
* @param int $collection_guid Collection GUID
*
* @return mixed
- * @deprecated 1.8
+ * @deprecated 1.8 Don't use this.
*/
function add_site_collection($site_guid, $collection_guid) {
elgg_deprecated_notice("add_site_collection has been deprecated", 1.8);
@@ -2687,7 +2688,7 @@ function add_site_collection($site_guid, $collection_guid) {
* @param int $collection_guid Collection GUID
*
* @return mixed
- * @deprecated 1.8
+ * @deprecated 1.8 Don't use this.
*/
function remove_site_collection($site_guid, $collection_guid) {
elgg_deprecated_notice("remove_site_collection has been deprecated", 1.8);
@@ -2706,7 +2707,7 @@ function remove_site_collection($site_guid, $collection_guid) {
* @param int $offset Offset
*
* @return mixed
- * @deprecated 1.8
+ * @deprecated 1.8 Don't use this.
*/
function get_site_collections($site_guid, $subtype = "", $limit = 10, $offset = 0) {
elgg_deprecated_notice("get_site_collections has been deprecated", 1.8);
@@ -2944,7 +2945,7 @@ $limit = 0, $offset = 0) {
* @param bool $status Validated (true) or false
* @param string $method Optional method to say how a user was validated
* @return bool
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_set_user_validation_status()
*/
function set_user_validation_status($user_guid, $status, $method = '') {
elgg_deprecated_notice("set_user_validation_status() is deprecated", 1.8);
@@ -2957,7 +2958,7 @@ function set_user_validation_status($user_guid, $status, $method = '') {
* This function invalidates any existing validation value.
*
* @param int $user_guid User's GUID
- * @deprecated 1.8
+ * @deprecated 1.8 Hook into the register, user plugin hook and request validation.
*/
function request_user_validation($user_guid) {
elgg_deprecated_notice("request_user_validation() is deprecated.
@@ -3314,7 +3315,7 @@ function clear_all_plugin_settings($plugin_id = "") {
* @param int $entity_owner_guid Owner guid for the entity
*
* @return array
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_annotations()
*/
function get_annotations($entity_guid = 0, $entity_type = "", $entity_subtype = "", $name = "",
$value = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "asc", $timelower = 0,
@@ -3379,7 +3380,7 @@ $timeupper = 0, $entity_owner_guid = 0) {
* @param true|false $asc Display annotations in ascending order. (Default: true)
*
* @return string HTML (etc) version of the annotation list
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_list_annotations()
*/
function list_annotations($entity_guid, $name = "", $limit = 25, $asc = true) {
elgg_deprecated_notice('list_annotations() is deprecated by elgg_list_annotations()', 1.8);
@@ -3412,7 +3413,7 @@ function list_annotations($entity_guid, $name = "", $limit = 25, $asc = true) {
* @param unknown_type $timelower
* @param unknown_type $timeupper
* @param unknown_type $calculation
- * @deprecated 1.8
+ * @internal Don't use this at all.
*/
function elgg_deprecated_annotation_calculation($entity_guid = 0, $entity_type = "", $entity_subtype = "",
$name = "", $value = "", $value_type = "", $owner_guid = 0, $timelower = 0,
@@ -3590,7 +3591,7 @@ $value = "", $value_type = "", $owner_guid = 0) {
* @param int $timeupper Upper time limit
*
* @return int
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_get_annotations() and pass anntoation_calculation => <calculation>
*/
function get_annotations_calculate_x($sum = "avg", $entity_guid, $entity_type = "",
$entity_subtype = "", $name = "", $value = "", $value_type = "", $owner_guid = 0,
@@ -4501,7 +4502,7 @@ function save_widget_info($widget_guid, $params) {
* @param int $owner Owner guid
*
* @return void
- * @deprecated 1.8
+ * @deprecated 1.8 Don't use.
*/
function reorder_widgets_from_panel($panelstring1, $panelstring2, $panelstring3, $context, $owner) {
elgg_deprecated_notice("reorder_widgets_from_panel() is deprecated", 1.8);
@@ -4609,7 +4610,7 @@ function reorder_widgets_from_panel($panelstring1, $panelstring2, $panelstring3,
* @param string $context The context we wish to enable context for
*
* @return void
- * @deprecated 1.8
+ * @deprecated 1.8 Don't use.
*/
function use_widgets($context) {
elgg_deprecated_notice("use_widgets is deprecated", 1.8);
@@ -4632,7 +4633,7 @@ function use_widgets($context) {
* Determines whether or not the current context is using widgets
*
* @return bool Depending on widget status
- * @deprecated 1.8
+ * @deprecated 1.8 Don't use.
*/
function using_widgets() {
elgg_deprecated_notice("using_widgets is deprecated", 1.8);
@@ -4654,7 +4655,7 @@ function using_widgets() {
* @param ElggObject $widget The widget to display
* @return string The HTML for the widget, including JavaScript wrapper
*
- * @deprecated 1.8
+ * @deprecated 1.8 Use elgg_view_entity()
*/
function display_widget(ElggObject $widget) {
elgg_deprecated_notice("display_widget() was been deprecated. Use elgg_view_entity().", 1.8);
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index cb736f418..198ffe60c 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -167,12 +167,12 @@ function forward($location = "", $reason = 'system') {
* @param string $name An identifier for the JavaScript library
* @param string $url URL of the JavaScript file
* @param string $location Page location: head or footer. (default: head)
- * @param int $priority Priority of the CSS file (lower numbers load earlier)
+ * @param int $priority Priority of the JS file (lower numbers load earlier)
*
* @return bool
* @since 1.8.0
*/
-function elgg_register_js($name, $url, $location = 'head', $priority = 500) {
+function elgg_register_js($name, $url, $location = 'head', $priority = null) {
return elgg_register_external_file('js', $name, $url, $location, $priority);
}
@@ -225,7 +225,7 @@ function elgg_get_loaded_js($location = 'head') {
* @return bool
* @since 1.8.0
*/
-function elgg_register_css($name, $url, $priority = 500) {
+function elgg_register_css($name, $url, $priority = null) {
return elgg_register_external_file('css', $name, $url, 'head', $priority);
}
@@ -278,7 +278,7 @@ function elgg_get_loaded_css() {
* @return bool
* @since 1.8.0
*/
-function elgg_register_external_file($type, $name, $url, $location, $priority = 500) {
+function elgg_register_external_file($type, $name, $url, $location, $priority = null) {
global $CONFIG;
if (empty($name) || empty($url)) {
@@ -288,32 +288,36 @@ function elgg_register_external_file($type, $name, $url, $location, $priority =
$url = elgg_format_url($url);
$url = elgg_normalize_url($url);
- if (!isset($CONFIG->externals)) {
- $CONFIG->externals = array();
- }
-
- if (!isset($CONFIG->externals[$type])) {
- $CONFIG->externals[$type] = array();
- }
+ elgg_bootstrap_externals_data_structure($type);
$name = trim(strtolower($name));
-
- if (isset($CONFIG->externals[$type][$name])) {
- // update a registered item
- $item = $CONFIG->externals[$type][$name];
-
+ $priority = max((int)$priority, 0);
+ $item = elgg_extract($name, $CONFIG->externals_map[$type]);
+
+ if ($item) {
+ // updating a registered item
+ // don't update loaded because it could already be set
+ $item->url = $url;
+ $item->location = $location;
+
+ // if loaded before registered, that means it hasn't been added to the list yet
+ if ($CONFIG->externals[$type]->contains($item)) {
+ $priority = $CONFIG->externals[$type]->move($item, $priority);
+ } else {
+ $priority = $CONFIG->externals[$type]->add($item, $priority);
+ }
} else {
$item = new stdClass();
$item->loaded = false;
- }
+ $item->url = $url;
+ $item->location = $location;
- $item->url = $url;
- $item->priority = max((int)$priority, 0);
- $item->location = $location;
+ $priority = $CONFIG->externals[$type]->add($item, $priority);
+ }
- $CONFIG->externals[$type][$name] = $item;
+ $CONFIG->externals_map[$type][$name] = $item;
- return true;
+ return $priority !== false;
}
/**
@@ -328,19 +332,14 @@ function elgg_register_external_file($type, $name, $url, $location, $priority =
function elgg_unregister_external_file($type, $name) {
global $CONFIG;
- if (!isset($CONFIG->externals)) {
- return false;
- }
-
- if (!isset($CONFIG->externals[$type])) {
- return false;
- }
+ elgg_bootstrap_externals_data_structure($type);
$name = trim(strtolower($name));
-
- if (array_key_exists($name, $CONFIG->externals[$type])) {
- unset($CONFIG->externals[$type][$name]);
- return true;
+ $item = elgg_extract($name, $CONFIG->externals_map[$type]);
+
+ if ($item) {
+ unset($CONFIG->externals_map[$type][$name]);
+ return $CONFIG->externals[$type]->remove($item);
}
return false;
@@ -358,27 +357,23 @@ function elgg_unregister_external_file($type, $name) {
function elgg_load_external_file($type, $name) {
global $CONFIG;
- if (!isset($CONFIG->externals)) {
- $CONFIG->externals = array();
- }
-
- if (!isset($CONFIG->externals[$type])) {
- $CONFIG->externals[$type] = array();
- }
+ elgg_bootstrap_externals_data_structure($type);
$name = trim(strtolower($name));
- if (isset($CONFIG->externals[$type][$name])) {
+ $item = elgg_extract($name, $CONFIG->externals_map[$type]);
+
+ if ($item) {
// update a registered item
- $CONFIG->externals[$type][$name]->loaded = true;
+ $item->loaded = true;
} else {
$item = new stdClass();
$item->loaded = true;
$item->url = '';
$item->location = '';
- $item->priority = 500;
- $CONFIG->externals[$type][$name] = $item;
+ $priority = $CONFIG->externals[$type]->add($item);
+ $CONFIG->externals_map[$type][$name] = $item;
}
}
@@ -394,13 +389,12 @@ function elgg_load_external_file($type, $name) {
function elgg_get_loaded_external_files($type, $location) {
global $CONFIG;
- if (isset($CONFIG->externals) && isset($CONFIG->externals[$type])) {
- $items = array_values($CONFIG->externals[$type]);
+ if (isset($CONFIG->externals) && $CONFIG->externals[$type] instanceof ElggPriorityList) {
+ $items = $CONFIG->externals[$type]->getElements();
$callback = "return \$v->loaded == true && \$v->location == '$location';";
$items = array_filter($items, create_function('$v', $callback));
if ($items) {
- usort($items, create_function('$a,$b','return $a->priority >= $b->priority;'));
array_walk($items, create_function('&$v,$k', '$v = $v->url;'));
}
return $items;
@@ -409,6 +403,31 @@ function elgg_get_loaded_external_files($type, $location) {
}
/**
+ * Bootstraps the externals data structure in $CONFIG.
+ *
+ * @param string $type The type of external, js or css.
+ */
+function elgg_bootstrap_externals_data_structure($type) {
+ global $CONFIG;
+
+ if (!isset($CONFIG->externals)) {
+ $CONFIG->externals = array();
+ }
+
+ if (!$CONFIG->externals[$type] instanceof ElggPriorityList) {
+ $CONFIG->externals[$type] = new ElggPriorityList();
+ }
+
+ if (!isset($CONFIG->externals_map)) {
+ $CONFIG->externals_map = array();
+ }
+
+ if (!isset($CONFIG->externals_map[$type])) {
+ $CONFIG->externals_map[$type] = array();
+ }
+}
+
+/**
* Returns a list of files in $directory.
*
* Only returns files. Does not recurse into subdirs.
diff --git a/engine/lib/entities.php b/engine/lib/entities.php
index 10313fc8c..cea8af1da 100644
--- a/engine/lib/entities.php
+++ b/engine/lib/entities.php
@@ -1118,8 +1118,12 @@ function elgg_get_guid_based_where_sql($column, $guids) {
$guids_sanitized = array();
foreach ($guids as $guid) {
- if (($guid != sanitise_int($guid))) {
- return FALSE;
+ if ($guid !== ELGG_ENTITIES_NO_VALUE) {
+ $guid = sanitise_int($guid);
+
+ if (!$guid) {
+ return false;
+ }
}
$guids_sanitized[] = $guid;
}
@@ -1494,6 +1498,7 @@ function delete_entity($guid, $recursive = true) {
$entity_disable_override = access_get_show_hidden_status();
access_show_hidden_entities(true);
+ $ia = elgg_set_ignore_access(true);
$sub_entities = get_data("SELECT * from {$CONFIG->dbprefix}entities
WHERE container_guid=$guid
or owner_guid=$guid
@@ -1506,6 +1511,7 @@ function delete_entity($guid, $recursive = true) {
access_show_hidden_entities($entity_disable_override);
$__RECURSIVE_DELETE_TOKEN = null;
+ elgg_set_ignore_access($ia);
}
// Now delete the entity itself
diff --git a/engine/lib/navigation.php b/engine/lib/navigation.php
index 1305ee3de..cefe40ecf 100644
--- a/engine/lib/navigation.php
+++ b/engine/lib/navigation.php
@@ -373,12 +373,38 @@ function elgg_entity_menu_setup($hook, $type, $return, $params) {
}
/**
+ * Adds a delete link to "generic_comment" annotations
+ */
+function elgg_annotation_menu_setup($hook, $type, $return, $params) {
+ $annotation = $params['annotation'];
+
+ if ($annotation->name == 'generic_comment' && $annotation->canEdit()) {
+ $url = elgg_http_add_url_query_elements('action/comments/delete', array(
+ 'annotation_id' => $annotation->id,
+ ));
+
+ $options = array(
+ 'name' => 'delete',
+ 'href' => $url,
+ 'text' => "<span class=\"elgg-icon elgg-icon-delete\"></span>",
+ 'confirm' => elgg_echo('deleteconfirm'),
+ 'text_encode' => false
+ );
+ $return[] = ElggMenuItem::factory($options);
+ }
+
+ return $return;
+}
+
+
+/**
* Navigation initialization
*/
function elgg_nav_init() {
elgg_register_plugin_hook_handler('prepare', 'menu:site', 'elgg_site_menu_setup');
elgg_register_plugin_hook_handler('register', 'menu:river', 'elgg_river_menu_setup');
elgg_register_plugin_hook_handler('register', 'menu:entity', 'elgg_entity_menu_setup');
+ elgg_register_plugin_hook_handler('register', 'menu:annotation', 'elgg_annotation_menu_setup');
}
elgg_register_event_handler('init', 'system', 'elgg_nav_init');
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index 88217b782..fd85ed9f0 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -548,7 +548,12 @@ function elgg_get_plugins_provides($type = null, $name = null) {
$provides = array();
foreach ($active_plugins as $plugin) {
- if ($plugin_provides = $plugin->getManifest()->getProvides()) {
+ $plugin_provides = array();
+ $manifest = $plugin->getManifest();
+ if ($manifest instanceof ElggPluginManifest) {
+ $plugin_provides = $plugin->getManifest()->getProvides();
+ }
+ if ($plugin_provides) {
foreach ($plugin_provides as $provided) {
$provides[$provided['type']][$provided['name']] = array(
'version' => $provided['version'],
@@ -811,7 +816,7 @@ function elgg_set_plugin_user_setting($name, $value, $user_guid = null, $plugin_
/**
* Unsets a user-specific plugin setting
*
- * @param str $name Name of the plugin setting
+ * @param str $name Name of the setting
* @param int $user_guid Defaults to logged in user
* @param str $plugin_id Defaults to contextual plugin name
*
@@ -834,7 +839,7 @@ function elgg_unset_plugin_user_setting($name, $user_guid = null, $plugin_id = n
/**
* Get a user specific setting for a plugin.
*
- * @param string $name The name.
+ * @param string $name The name of the setting.
* @param int $user_guid Guid of owning user
* @param string $plugin_id Optional plugin name, if not specified
* it is detected from where you are calling.
@@ -858,7 +863,7 @@ function elgg_get_plugin_user_setting($name, $user_guid = null, $plugin_id = nul
/**
* Set a setting for a plugin.
*
- * @param string $name The name - note, can't be "title".
+ * @param string $name The name of the setting - note, can't be "title".
* @param mixed $value The value.
* @param string $plugin_id Optional plugin name, if not specified
* then it is detected from where you are calling from.
@@ -882,7 +887,7 @@ function elgg_set_plugin_setting($name, $value, $plugin_id = null) {
/**
* Get setting for a plugin.
*
- * @param string $name The name.
+ * @param string $name The name of the setting.
* @param string $plugin_id Optional plugin name, if not specified
* then it is detected from where you are calling from.
*
@@ -905,7 +910,7 @@ function elgg_get_plugin_setting($name, $plugin_id = null) {
/**
* Unsets a plugin setting.
*
- * @param string $name The name.
+ * @param string $name The name of the setting.
* @param string $plugin_id Optional plugin name, if not specified
* then it is detected from where you are calling from.
*
diff --git a/engine/lib/river.php b/engine/lib/river.php
index 143ff035f..64ddcfdc1 100644
--- a/engine/lib/river.php
+++ b/engine/lib/river.php
@@ -472,7 +472,7 @@ function elgg_get_river_type_subtype_where_sql($table, $types, $subtypes, $pairs
}
if (is_array($wheres) && count($wheres)) {
- $wheres = array(implode(' AND ', $wheres));
+ $wheres = array(implode(' OR ', $wheres));
}
} else {
// using type/subtype pairs
diff --git a/engine/lib/users.php b/engine/lib/users.php
index 48f10f974..36e137876 100644
--- a/engine/lib/users.php
+++ b/engine/lib/users.php
@@ -1419,11 +1419,14 @@ function elgg_profile_page_handler($page) {
*/
function users_pagesetup() {
- if (elgg_get_page_owner_guid()) {
+ $owner = elgg_get_page_owner_entity();
+ $viewer = elgg_get_logged_in_user_entity();
+
+ if ($owner) {
$params = array(
'name' => 'friends',
'text' => elgg_echo('friends'),
- 'href' => 'friends/' . elgg_get_page_owner_entity()->username,
+ 'href' => 'friends/' . $owner->username,
'contexts' => array('friends')
);
elgg_register_menu_item('page', $params);
@@ -1431,43 +1434,43 @@ function users_pagesetup() {
$params = array(
'name' => 'friends:of',
'text' => elgg_echo('friends:of'),
- 'href' => 'friendsof/' . elgg_get_page_owner_entity()->username,
+ 'href' => 'friendsof/' . $owner->username,
'contexts' => array('friends')
);
elgg_register_menu_item('page', $params);
- }
-
- // topbar
- $user = elgg_get_logged_in_user_entity();
- if ($user) {
+
elgg_register_menu_item('page', array(
'name' => 'edit_avatar',
- 'href' => "avatar/edit/{$user->username}",
+ 'href' => "avatar/edit/{$owner->username}",
'text' => elgg_echo('avatar:edit'),
'contexts' => array('profile_edit'),
));
elgg_register_menu_item('page', array(
'name' => 'edit_profile',
- 'href' => "profile/{$user->username}/edit",
+ 'href' => "profile/{$owner->username}/edit",
'text' => elgg_echo('profile:edit'),
'contexts' => array('profile_edit'),
));
+ }
- $icon_url = $user->getIconURL('topbar');
+ // topbar
+ if ($viewer) {
+
+ $icon_url = $viewer->getIconURL('topbar');
$class = 'elgg-border-plain elgg-transition';
$title = elgg_echo('profile');
elgg_register_menu_item('topbar', array(
'name' => 'profile',
- 'href' => $user->getURL(),
- 'text' => "<img src=\"$icon_url\" alt=\"$user->name\" title=\"$title\" class=\"$class\" />",
+ 'href' => $viewer->getURL(),
+ 'text' => "<img src=\"$icon_url\" alt=\"$viewer->name\" title=\"$title\" class=\"$class\" />",
'priority' => 100,
'link_class' => 'elgg-topbar-avatar',
));
elgg_register_menu_item('topbar', array(
'name' => 'friends',
- 'href' => "friends/{$user->username}",
+ 'href' => "friends/{$viewer->username}",
'text' => elgg_view_icon('users'),
'title' => elgg_echo('friends'),
'priority' => 300,
@@ -1475,7 +1478,7 @@ function users_pagesetup() {
elgg_register_menu_item('topbar', array(
'name' => 'usersettings',
- 'href' => "settings/user/{$user->username}",
+ 'href' => "settings/user/{$viewer->username}",
'text' => elgg_view_icon('settings') . elgg_echo('settings'),
'priority' => 500,
'section' => 'alt',
@@ -1489,7 +1492,6 @@ function users_pagesetup() {
'priority' => 1000,
'section' => 'alt',
));
-
}
}
diff --git a/engine/lib/views.php b/engine/lib/views.php
index 04f4b7c2a..0646851f0 100644
--- a/engine/lib/views.php
+++ b/engine/lib/views.php
@@ -369,8 +369,8 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
// Trigger the pagesetup event
if (!isset($CONFIG->pagesetupdone)) {
- elgg_trigger_event('pagesetup', 'system');
$CONFIG->pagesetupdone = true;
+ elgg_trigger_event('pagesetup', 'system');
}
if (!is_array($usercache)) {
@@ -617,13 +617,12 @@ function elgg_view_page($title, $body, $page_shell = 'default', $vars = array())
$vars['title'] = $title;
$vars['body'] = $body;
$vars['sysmessages'] = $messages;
+
+ $vars = elgg_trigger_plugin_hook('output:before', 'page', null, $vars);
// check for deprecated view
if ($page_shell == 'default' && elgg_view_exists('pageshells/pageshell')) {
elgg_deprecated_notice("pageshells/pageshell is deprecated by page/$page_shell", 1.8);
- global $CONFIG;
-
- $vars['config'] = $CONFIG;
$output = elgg_view('pageshells/pageshell', $vars);
} else {
$output = elgg_view("page/$page_shell", $vars);
@@ -681,15 +680,19 @@ function elgg_view_layout($layout_name, $vars = array()) {
$param_array = $vars;
}
+ $params = elgg_trigger_plugin_hook('output:before', 'layout', null, $param_array);
+
// check deprecated location
if (elgg_view_exists("canvas/layouts/$layout_name")) {
elgg_deprecated_notice("canvas/layouts/$layout_name is deprecated by page/layouts/$layout_name", 1.8);
- return elgg_view("canvas/layouts/$layout_name", $param_array);
+ $output = elgg_view("canvas/layouts/$layout_name", $params);
} elseif (elgg_view_exists("page/layouts/$layout_name")) {
- return elgg_view("page/layouts/$layout_name", $param_array);
+ $output = elgg_view("page/layouts/$layout_name", $params);
} else {
- return elgg_view("page/layouts/default", $param_array);
+ $output = elgg_view("page/layouts/default", $params);
}
+
+ return elgg_trigger_plugin_hook('output:after', 'layout', $params, $output);
}
/**
@@ -1224,6 +1227,9 @@ function elgg_view_river_item($item, array $vars = array()) {
* sets the action by default to "action/$action". Automatically wraps the forms/$action
* view with a <form> tag and inserts the anti-csrf security tokens.
*
+ * @tip This automatically appends elgg-form-action-name to the form's class. It replaces any
+ * slashes with dashes (blog/save becomes elgg-form-blog-save)
+ *
* @example
* <code>echo elgg_view_form('login');</code>
*
@@ -1253,9 +1259,18 @@ function elgg_view_form($action, $form_vars = array(), $body_vars = array()) {
$defaults = array(
'action' => $CONFIG->wwwroot . "action/$action",
- 'body' => elgg_view("forms/$action", $body_vars),
+ 'body' => elgg_view("forms/$action", $body_vars)
);
+ $form_class = 'elgg-form-' . preg_replace('/[^a-z0-9]/i', '-', $action);
+
+ // append elgg-form class to any class options set
+ if (isset($form_vars['class'])) {
+ $form_vars['class'] = $form_vars['class'] . " $form_class";
+ } else {
+ $form_vars['class'] = $form_class;
+ }
+
return elgg_view('input/form', array_merge($defaults, $form_vars));
}
@@ -1480,21 +1495,6 @@ function autoregister_views($view_base, $folder, $base_location_path, $viewtype)
}
/**
- * Add the core Elgg head elements that could be cached
- *
- * @return void
- */
-function elgg_views_register_core_head_elements() {
- $url = elgg_get_simplecache_url('js', 'elgg');
- elgg_register_js('elgg', $url, 'head', 10);
- elgg_load_js('elgg');
-
- $url = elgg_get_simplecache_url('css', 'elgg');
- elgg_register_css('elgg', $url, 10);
- elgg_load_css('elgg');
-}
-
-/**
* Add the rss link to the extras when if needed
*
* @return void
@@ -1548,21 +1548,29 @@ function elgg_views_boot() {
elgg_register_simplecache_view('css/ie6');
elgg_register_simplecache_view('js/elgg');
- elgg_register_js('jquery', '/vendors/jquery/jquery-1.6.1.min.js', 'head', 1);
- elgg_register_js('jquery-ui', '/vendors/jquery/jquery-ui-1.8.14.min.js', 'head', 2);
+ elgg_register_js('jquery', '/vendors/jquery/jquery-1.6.2.min.js', 'head');
+ elgg_register_js('jquery-ui', '/vendors/jquery/jquery-ui-1.8.16.min.js', 'head');
elgg_register_js('jquery.form', '/vendors/jquery/jquery.form.js');
+
+ $elgg_js_url = elgg_get_simplecache_url('js', 'elgg');
+ elgg_register_js('elgg', $elgg_js_url, 'head');
+
elgg_load_js('jquery');
elgg_load_js('jquery-ui');
elgg_load_js('jquery.form');
+ elgg_load_js('elgg');
elgg_register_simplecache_view('js/lightbox');
$lightbox_js_url = elgg_get_simplecache_url('js', 'lightbox');
elgg_register_js('lightbox', $lightbox_js_url);
- $lightbox_css_url = 'vendors/jquery/fancybox/jquery.fancybox-1.3.4.css';
+ $lightbox_css_url = elgg_get_simplecache_url('css', 'lightbox');
elgg_register_css('lightbox', $lightbox_css_url);
- elgg_register_event_handler('ready', 'system', 'elgg_views_register_core_head_elements');
- elgg_register_event_handler('pagesetup', 'system', 'elgg_views_add_rss_link');
+ $elgg_css_url = elgg_get_simplecache_url('css', 'elgg');
+ elgg_register_css('elgg', $elgg_css_url, 1);
+ elgg_load_css('elgg');
+
+ elgg_register_plugin_hook_handler('output:before', 'layout', 'elgg_views_add_rss_link');
// discover the built-in view types
// @todo the cache is loaded in load_plugins() but we need to know view_types earlier
diff --git a/engine/start.php b/engine/start.php
index 713d94cc6..132c060b4 100644
--- a/engine/start.php
+++ b/engine/start.php
@@ -144,7 +144,9 @@ if (!defined('UPGRADING')) {
$lastcached = datalist_get("simplecache_lastcached_$viewtype");
if ($lastupdate == 0 || $lastcached < $lastupdate) {
elgg_regenerate_simplecache($viewtype);
+ $lastcached = datalist_get("simplecache_lastcached_$viewtype");
}
+ $CONFIG->lastcache = $lastcached;
}
// System loaded and ready
diff --git a/engine/tests/api/access_collections.php b/engine/tests/api/access_collections.php
new file mode 100644
index 000000000..1e61c45bb
--- /dev/null
+++ b/engine/tests/api/access_collections.php
@@ -0,0 +1,269 @@
+<?php
+/**
+ * Access Collections tests
+ *
+ * @package Elgg
+ * @subpackage Test
+ */
+class ElggCoreAccessCollectionsTest extends ElggCoreUnitTest {
+
+ /**
+ * Called before each test object.
+ */
+ public function __construct() {
+ parent::__construct();
+
+ $this->dbPrefix = get_config("dbprefix");
+
+ $user = new ElggUser();
+ $user->username = 'test_user_' . rand();
+ $user->email = 'fake_email@fake.com' . rand();
+ $user->name = 'fake user';
+ $user->access_id = ACCESS_PUBLIC;
+ $user->salt = generate_random_cleartext_password();
+ $user->password = generate_user_password($user, rand());
+ $user->owner_guid = 0;
+ $user->container_guid = 0;
+ $user->save();
+
+ $this->user = $user;
+ }
+
+ /**
+ * Called before each test method.
+ */
+ public function setUp() {
+
+ }
+
+ /**
+ * Called after each test method.
+ */
+ public function tearDown() {
+ // do not allow SimpleTest to interpret Elgg notices as exceptions
+ $this->swallowErrors();
+ }
+
+ /**
+ * Called after each test object.
+ */
+ public function __destruct() {
+ // all __destruct() code should go above here
+ $this->user->delete();
+ parent::__destruct();
+ }
+
+ public function testCreateGetDeleteACL() {
+ global $DB_QUERY_CACHE;
+
+ $acl_name = 'test access collection';
+ $acl_id = create_access_collection($acl_name);
+
+ $this->assertTrue(is_int($acl_id));
+
+ $q = "SELECT * FROM {$this->dbPrefix}access_collections WHERE id = $acl_id";
+ $acl = get_data_row($q);
+
+ $this->assertEqual($acl->id, $acl_id);
+
+ if ($acl) {
+ $DB_QUERY_CACHE = array();
+
+ $this->assertEqual($acl->name, $acl_name);
+
+ $result = delete_access_collection($acl_id);
+ $this->assertTrue($result);
+
+ $q = "SELECT * FROM {$this->dbPrefix}access_collections WHERE id = $acl_id";
+ $data = get_data($q);
+ $this->assertFalse($data);
+ }
+ }
+
+ public function testAddRemoveUserToACL() {
+ $acl_id = create_access_collection('test acl');
+
+ $result = add_user_to_access_collection($this->user->guid, $acl_id);
+ $this->assertTrue($result);
+
+ if ($result) {
+ $result = remove_user_from_access_collection($this->user->guid, $acl_id);
+ $this->assertTrue($result);
+ }
+
+ delete_access_collection($acl_id);
+ }
+
+ public function testUpdateACL() {
+ // another fake user to test with
+ $user = new ElggUser();
+ $user->username = 'test_user_' . rand();
+ $user->email = 'fake_email@fake.com' . rand();
+ $user->name = 'fake user';
+ $user->access_id = ACCESS_PUBLIC;
+ $user->salt = generate_random_cleartext_password();
+ $user->password = generate_user_password($user, rand());
+ $user->owner_guid = 0;
+ $user->container_guid = 0;
+ $user->save();
+
+ $acl_id = create_access_collection('test acl');
+
+ $member_lists = array(
+ // adding
+ array(
+ $this->user->guid,
+ $user->guid
+ ),
+ // removing one, keeping one.
+ array(
+ $user->guid
+ ),
+ // removing one, adding one
+ array(
+ $this->user->guid,
+ ),
+ // removing all.
+ array()
+ );
+
+ foreach ($member_lists as $members) {
+ $result = update_access_collection($acl_id, $members);
+ $this->assertTrue($result);
+
+ if ($result) {
+ $q = "SELECT * FROM {$this->dbPrefix}access_collection_membership
+ WHERE access_collection_id = $acl_id";
+ $data = get_data($q);
+
+ if (count($members) == 0) {
+ $this->assertFalse($data);
+ } else {
+ $this->assertEqual(count($members), count($data));
+ }
+ foreach ($data as $row) {
+ $this->assertTrue(in_array($row->user_guid, $members));
+ }
+ }
+ }
+
+ delete_access_collection($acl_id);
+ $user->delete();
+ }
+
+ public function testCanEditACL() {
+ $acl_id = create_access_collection('test acl', $this->user->guid);
+
+ // should be true since it's the owner
+ $result = can_edit_access_collection($acl_id, $this->user->guid);
+ $this->assertTrue($result);
+
+ // should be true since IA is on.
+ $ia = elgg_set_ignore_access(true);
+ $result = can_edit_access_collection($acl_id);
+ $this->assertTrue($result);
+ elgg_set_ignore_access($ia);
+
+ // should be false since IA is off
+ $ia = elgg_set_ignore_access(false);
+ $result = can_edit_access_collection($acl_id);
+ $this->assertFalse($result);
+ elgg_set_ignore_access($ia);
+
+ delete_access_collection($acl_id);
+ }
+
+ public function testCanEditACLHook() {
+ // if only we supported closures!
+ global $acl_test_info;
+
+ $acl_id = create_access_collection('test acl');
+
+ $acl_test_info = array(
+ 'acl_id' => $acl_id,
+ 'user' => $this->user
+ );
+
+ function test_acl_access_hook($hook, $type, $value, $params) {
+ global $acl_test_info;
+ if ($params['user_id'] == $acl_test_info['user']->guid) {
+ $acl = get_access_collection($acl_test_info['acl_id']);
+ $value[$acl->id] = $acl->name;
+ }
+
+ return $value;
+ }
+
+ register_plugin_hook('access:collections:write', 'all', 'test_acl_access_hook');
+
+ // enable security since we usually run as admin
+ $ia = elgg_set_ignore_access(false);
+ $result = can_edit_access_collection($acl_id, $this->user->guid);
+ $this->assertTrue($result);
+ $ia = elgg_set_ignore_access($ia);
+
+ unregister_plugin_hook('access:collections:write', 'all', 'test_acl_access_hook');
+ }
+
+ // groups interface
+ // only runs if the groups plugin is enabled because implementation is split between
+ // core and the plugin.
+ public function testCreateDeleteGroupACL() {
+ if (!is_plugin_enabled('groups')) {
+ return;
+ }
+
+ $group = new ElggGroup();
+ $group->name = 'Test group';
+ $group->save();
+ $acl = get_access_collection($group->group_acl);
+
+ // ACLs are owned by groups
+ $this->assertEqual($acl->owner_guid, $group->guid);
+
+ // removing group and acl
+ $this->assertTrue($group->delete());
+
+ $acl = get_access_collection($group->group_acl);
+ $this->assertFalse($acl);
+
+ $group->delete();
+ }
+
+ public function testJoinLeaveGroupACL() {
+ if (!is_plugin_enabled('groups')) {
+ return;
+ }
+
+ $group = new ElggGroup();
+ $group->name = 'Test group';
+ $group->save();
+
+ $result = $group->join($this->user);
+ $this->assertTrue($result);
+
+ // disable security since we run as admin
+ $ia = elgg_set_ignore_access(false);
+
+ // need to set the page owner to emulate being in a group context.
+ // this is kinda hacky.
+ elgg_set_page_owner_guid($group->getGUID());
+
+ if ($result) {
+ $can_edit = can_edit_access_collection($group->group_acl, $this->user->guid);
+ $this->assertTrue($can_edit);
+ }
+
+ $result = $group->leave($this->user);
+ $this->assertTrue($result);
+
+ if ($result) {
+ $can_edit = can_edit_access_collection($group->group_acl, $this->user->guid);
+ $this->assertFalse($can_edit);
+ }
+
+ elgg_set_ignore_access($ia);
+
+ $group->delete();
+ }
+}
diff --git a/engine/tests/api/helpers.php b/engine/tests/api/helpers.php
index 461627547..ee2e64cfe 100644
--- a/engine/tests/api/helpers.php
+++ b/engine/tests/api/helpers.php
@@ -31,6 +31,7 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
global $CONFIG;
unset($CONFIG->externals);
+ unset($CONFIG->externals_map);
}
/**
@@ -106,7 +107,16 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
// specify name
$result = elgg_register_js('key', 'http://test1.com', 'footer');
$this->assertTrue($result);
- $this->assertIdentical('http://test1.com', $CONFIG->externals['js']['key']->url);
+ $this->assertTrue(isset($CONFIG->externals_map['js']['key']));
+
+ $item = $CONFIG->externals_map['js']['key'];
+ $this->assertTrue($CONFIG->externals['js']->contains($item));
+
+ $priority = $CONFIG->externals['js']->getPriority($item);
+ $this->assertTrue($priority !== false);
+
+ $item = $CONFIG->externals['js']->getElement($priority);
+ $this->assertIdentical('http://test1.com', $item->url);
// send a bad url
$result = @elgg_register_js('bad');
@@ -118,11 +128,20 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
*/
public function testElggRegisterCSS() {
global $CONFIG;
-
+
// specify name
$result = elgg_register_css('key', 'http://test1.com');
$this->assertTrue($result);
- $this->assertIdentical('http://test1.com', $CONFIG->externals['css']['key']->url);
+ $this->assertTrue(isset($CONFIG->externals_map['css']['key']));
+
+ $item = $CONFIG->externals_map['css']['key'];
+ $this->assertTrue($CONFIG->externals['css']->contains($item));
+
+ $priority = $CONFIG->externals['css']->getPriority($item);
+ $this->assertTrue($priority !== false);
+
+ $item = $CONFIG->externals['css']->getElement($priority);
+ $this->assertIdentical('http://test1.com', $item->url);
}
/**
@@ -134,21 +153,43 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
$base = trim(elgg_get_site_url(), "/");
$urls = array('id1' => "$base/urla", 'id2' => "$base/urlb", 'id3' => "$base/urlc");
+
foreach ($urls as $id => $url) {
elgg_register_js($id, $url);
}
$result = elgg_unregister_js('id1');
$this->assertTrue($result);
- @$this->assertNULL($CONFIG->externals['js']['head']['id1']);
+
+ $js = $CONFIG->externals['js'];
+ $elements = $js->getElements();
+ $this->assertFalse(isset($CONFIG->externals_map['js']['id1']));
+
+ foreach ($elements as $element) {
+ $this->assertFalse($element->name == 'id1');
+ }
$result = elgg_unregister_js('id1');
$this->assertFalse($result);
+
$result = elgg_unregister_js('', 'does_not_exist');
$this->assertFalse($result);
$result = elgg_unregister_js('id2');
- $this->assertIdentical($urls['id3'], $CONFIG->externals['js']['id3']->url);
+ $elements = $js->getElements();
+
+ $this->assertFalse(isset($CONFIG->externals_map['js']['id2']));
+ foreach ($elements as $element) {
+ $this->assertFalse($element->name == 'id2');
+ }
+
+ $this->assertTrue(isset($CONFIG->externals_map['js']['id3']));
+
+ $priority = $CONFIG->externals['js']->getPriority($CONFIG->externals_map['js']['id3']);
+ $this->assertTrue($priority !== false);
+
+ $item = $CONFIG->externals['js']->getElement($priority);
+ $this->assertIdentical($urls['id3'], $item->url);
}
/**
@@ -161,6 +202,7 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
elgg_load_js('key');
$result = elgg_register_js('key', 'http://test1.com', 'footer');
$this->assertTrue($result);
+
$js_urls = elgg_get_loaded_js('footer');
$this->assertIdentical(array('http://test1.com'), $js_urls);
}
@@ -173,7 +215,12 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
$base = trim(elgg_get_site_url(), "/");
- $urls = array('id1' => "$base/urla", 'id2' => "$base/urlb", 'id3' => "$base/urlc");
+ $urls = array(
+ 'id1' => "$base/urla",
+ 'id2' => "$base/urlb",
+ 'id3' => "$base/urlc"
+ );
+
foreach ($urls as $id => $url) {
elgg_register_js($id, $url);
elgg_load_js($id);
@@ -187,4 +234,275 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
$js_urls = elgg_get_loaded_js('footer');
$this->assertIdentical(array(), $js_urls);
}
-}
+
+ // test ElggPriorityList
+ public function testElggPriorityListAdd() {
+ $pl = new ElggPriorityList();
+ $elements = array(
+ 'Test value',
+ 'Test value 2',
+ 'Test value 3'
+ );
+
+ shuffle($elements);
+
+ foreach ($elements as $element) {
+ $this->assertTrue($pl->add($element) !== false);
+ }
+
+ $test_elements = $pl->getElements();
+
+ $this->assertTrue(is_array($test_elements));
+
+ foreach ($test_elements as $i => $element) {
+ // should be in the array
+ $this->assertTrue(in_array($element, $elements));
+
+ // should be the only element, so priority 0
+ $this->assertEqual($i, array_search($element, $elements));
+ }
+ }
+
+ public function testElggPriorityListAddWithPriority() {
+ $pl = new ElggPriorityList();
+
+ $elements = array(
+ 10 => 'Test Element 10',
+ 5 => 'Test Element 5',
+ 0 => 'Test Element 0',
+ 100 => 'Test Element 100',
+ -1 => 'Test Element -1',
+ -5 => 'Test Element -5'
+ );
+
+ foreach ($elements as $priority => $element) {
+ $pl->add($element, $priority);
+ }
+
+ $test_elements = $pl->getElements();
+
+ // should be sorted by priority
+ $elements_sorted = array(
+ -5 => 'Test Element -5',
+ -1 => 'Test Element -1',
+ 0 => 'Test Element 0',
+ 5 => 'Test Element 5',
+ 10 => 'Test Element 10',
+ 100 => 'Test Element 100',
+ );
+
+ $this->assertIdentical($elements_sorted, $test_elements);
+
+ foreach ($test_elements as $priority => $element) {
+ $this->assertIdentical($elements[$priority], $element);
+ }
+ }
+
+ public function testElggPriorityListGetNextPriority() {
+ $pl = new ElggPriorityList();
+
+ $elements = array(
+ 2 => 'Test Element',
+ 0 => 'Test Element 2',
+ -2 => 'Test Element 3',
+ );
+
+ foreach ($elements as $priority => $element) {
+ $pl->add($element, $priority);
+ }
+
+ // we're not specifying a priority so it should be the next consecutive to 0.
+ $this->assertEqual(1, $pl->getNextPriority());
+
+ // add another one at priority 1
+ $pl->add('Test Element 1');
+
+ // next consecutive to 0 is now 3.
+ $this->assertEqual(3, $pl->getNextPriority());
+ }
+
+ public function testElggPriorityListRemove() {
+ $pl = new ElggPriorityList();
+
+ $elements = array();
+ for ($i=0; $i<3; $i++) {
+ $element = new stdClass();
+ $element->name = "Test Element $i";
+ $element->someAttribute = rand(0, 9999);
+ $elements[] = $element;
+ $pl->add($element);
+ }
+
+ $pl->remove($elements[1]);
+
+ $test_elements = $pl->getElements();
+
+ // make sure it's gone.
+ $this->assertTrue(2, count($test_elements));
+ $this->assertIdentical($elements[0], $test_elements[0]);
+ $this->assertIdentical($elements[2], $test_elements[2]);
+ }
+
+ public function testElggPriorityListMove() {
+ $pl = new ElggPriorityList();
+
+ $elements = array(
+ -5 => 'Test Element -5',
+ 0 => 'Test Element 0',
+ 5 => 'Test Element 5',
+ );
+
+ foreach ($elements as $priority => $element) {
+ $pl->add($element, $priority);
+ }
+
+ $this->assertTrue($pl->move($elements[-5], 10));
+
+ // check it's at the new place
+ $this->assertIdentical($elements[-5], $pl->getElement(10));
+
+ // check it's not at the old
+ $this->assertFalse($pl->getElement(-5));
+ }
+
+ public function testElggPriorityListConstructor() {
+ $elements = array(
+ 10 => 'Test Element 10',
+ 5 => 'Test Element 5',
+ 0 => 'Test Element 0',
+ 100 => 'Test Element 100',
+ -1 => 'Test Element -1',
+ -5 => 'Test Element -5'
+ );
+
+ $pl = new ElggPriorityList($elements);
+ $test_elements = $pl->getElements();
+
+ $elements_sorted = array(
+ -5 => 'Test Element -5',
+ -1 => 'Test Element -1',
+ 0 => 'Test Element 0',
+ 5 => 'Test Element 5',
+ 10 => 'Test Element 10',
+ 100 => 'Test Element 100',
+ );
+
+ $this->assertIdentical($elements_sorted, $test_elements);
+ }
+
+ public function testElggPriorityListGetPriority() {
+ $pl = new ElggPriorityList();
+
+ $elements = array(
+ 'Test element 0',
+ 'Test element 1',
+ 'Test element 2',
+ );
+
+ foreach ($elements as $element) {
+ $pl->add($element);
+ }
+
+ $this->assertIdentical(0, $pl->getPriority($elements[0]));
+ $this->assertIdentical(1, $pl->getPriority($elements[1]));
+ $this->assertIdentical(2, $pl->getPriority($elements[2]));
+ }
+
+ public function testElggPriorityListGetElement() {
+ $pl = new ElggPriorityList();
+ $priorities = array();
+
+ $elements = array(
+ 'Test element 0',
+ 'Test element 1',
+ 'Test element 2',
+ );
+
+ foreach ($elements as $element) {
+ $priorities[] = $pl->add($element);
+ }
+
+ $this->assertIdentical($elements[0], $pl->getElement($priorities[0]));
+ $this->assertIdentical($elements[1], $pl->getElement($priorities[1]));
+ $this->assertIdentical($elements[2], $pl->getElement($priorities[2]));
+ }
+
+ public function testElggPriorityListPriorityCollision() {
+ $pl = new ElggPriorityList();
+
+ $elements = array(
+ 5 => 'Test element 5',
+ 6 => 'Test element 6',
+ 0 => 'Test element 0',
+ );
+
+ foreach ($elements as $priority => $element) {
+ $pl->add($element, $priority);
+ }
+
+ // add at a colliding priority
+ $pl->add('Colliding element', 5);
+
+ // should float to the top closest to 5, so 7
+ $this->assertEqual(7, $pl->getPriority('Colliding element'));
+ }
+
+ public function testElggPriorityListIterator() {
+ $elements = array(
+ -5 => 'Test element -5',
+ 0 => 'Test element 0',
+ 5 => 'Test element 5'
+ );
+
+ $pl = new ElggPriorityList($elements);
+
+ foreach ($pl as $priority => $element) {
+ $this->assertIdentical($elements[$priority], $element);
+ }
+ }
+
+ public function testElggPriorityListCountable() {
+ $pl = new ElggPriorityList();
+
+ $this->assertEqual(0, count($pl));
+
+ $pl->add('Test element 0');
+ $this->assertEqual(1, count($pl));
+
+ $pl->add('Test element 1');
+ $this->assertEqual(2, count($pl));
+
+ $pl->add('Test element 2');
+ $this->assertEqual(3, count($pl));
+ }
+
+ public function testElggPriorityListUserSort() {
+ $elements = array(
+ 'A',
+ 'B',
+ 'C',
+ 'D',
+ 'E',
+ );
+
+ $elements_sorted_string = $elements;
+
+ shuffle($elements);
+ $pl = new ElggPriorityList($elements);
+
+ // will sort by priority
+ $test_elements = $pl->getElements();
+ $this->assertIdentical($elements, $test_elements);
+
+ function test_sort($elements) {
+ sort($elements, SORT_LOCALE_STRING);
+ return $elements;
+ }
+
+ // force a new sort using our function
+ $pl->sort('test_sort');
+ $test_elements = $pl->getElements();
+
+ $this->assertIdentical($elements_sorted_string, $test_elements);
+ }
+} \ No newline at end of file