aboutsummaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/classes/ElggBatch.php95
-rw-r--r--engine/classes/ElggCache.php8
-rw-r--r--engine/classes/ElggDiskFilestore.php2
-rw-r--r--engine/classes/ElggEntity.php154
-rw-r--r--engine/classes/ElggExtender.php22
-rw-r--r--engine/classes/ElggFileCache.php19
-rw-r--r--engine/classes/ElggGroup.php30
-rw-r--r--engine/classes/ElggMemcache.php24
-rw-r--r--engine/classes/ElggMenuBuilder.php10
-rw-r--r--engine/classes/ElggMenuItem.php22
-rw-r--r--engine/classes/ElggMetadata.php7
-rw-r--r--engine/classes/ElggObject.php31
-rw-r--r--engine/classes/ElggPlugin.php68
-rw-r--r--engine/classes/ElggPluginManifest.php33
-rw-r--r--engine/classes/ElggPluginPackage.php2
-rw-r--r--engine/classes/ElggRelationship.php6
-rw-r--r--engine/classes/ElggRiverItem.php14
-rw-r--r--engine/classes/ElggSite.php37
-rw-r--r--engine/classes/ElggUser.php65
-rw-r--r--engine/classes/ElggWidget.php57
-rw-r--r--engine/classes/ODDDocument.php2
-rw-r--r--engine/classes/ODDEntity.php72
-rw-r--r--engine/classes/ODDMetaData.php39
-rw-r--r--engine/classes/ODDRelationship.php33
-rw-r--r--engine/classes/SuccessResult.php2
-rw-r--r--engine/classes/XMLRPCCall.php4
-rw-r--r--engine/handlers/cache_handler.php21
-rw-r--r--engine/handlers/export_handler.php6
-rw-r--r--engine/lib/access.php58
-rw-r--r--engine/lib/actions.php18
-rw-r--r--engine/lib/admin.php25
-rw-r--r--engine/lib/annotations.php60
-rw-r--r--engine/lib/cache.php175
-rw-r--r--engine/lib/configuration.php109
-rw-r--r--engine/lib/database.php41
-rw-r--r--engine/lib/deprecated-1.8.php6
-rw-r--r--engine/lib/elgglib.php147
-rw-r--r--engine/lib/entities.php150
-rw-r--r--engine/lib/extender.php7
-rw-r--r--engine/lib/filestore.php8
-rw-r--r--engine/lib/group.php26
-rw-r--r--engine/lib/input.php4
-rw-r--r--engine/lib/languages.php124
-rw-r--r--engine/lib/metadata.php81
-rw-r--r--engine/lib/metastrings.php29
-rw-r--r--engine/lib/navigation.php10
-rw-r--r--engine/lib/notification.php1
-rw-r--r--engine/lib/objects.php7
-rw-r--r--engine/lib/output.php22
-rw-r--r--engine/lib/pagehandler.php3
-rw-r--r--engine/lib/pageowner.php7
-rw-r--r--engine/lib/plugins.php46
-rw-r--r--engine/lib/private_settings.php2
-rw-r--r--engine/lib/relationships.php4
-rw-r--r--engine/lib/river.php22
-rw-r--r--engine/lib/sessions.php21
-rw-r--r--engine/lib/sites.php40
-rw-r--r--engine/lib/statistics.php6
-rw-r--r--engine/lib/system_log.php34
-rw-r--r--engine/lib/upgrades/2011010101.php2
-rw-r--r--engine/lib/upgrades/2011030700-1.8_svn-blog_status_metadata-4645225d7b440876.php3
-rw-r--r--engine/lib/upgrades/2011061200-1.8b1-sites_need_a_site_guid-6d9dcbf46c0826cc.php1
-rw-r--r--engine/lib/upgrades/2011123100-1.8.2-fix_friend_river-b17e7ff8345c2269.php12
-rw-r--r--engine/lib/upgrades/2011123101-1.8.2-fix_blog_status-b14c2a0e7b9e7d55.php25
-rw-r--r--engine/lib/upgrades/2012012000-1.8.3-ip_in_syslog-87fe0f068cf62428.php12
-rw-r--r--engine/lib/upgrades/2012012100-1.8.3-system_cache-93100e7d55a24a11.php13
-rw-r--r--engine/lib/upgrades/2012041800-1.8.3-dont_filter_passwords-c0ca4a18b38ae2bc.php11
-rw-r--r--engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php13
-rw-r--r--engine/lib/user_settings.php6
-rw-r--r--engine/lib/users.php62
-rw-r--r--engine/lib/views.php85
-rw-r--r--engine/lib/web_services.php2
-rw-r--r--engine/lib/widgets.php5
-rw-r--r--engine/schema/mysql.sql1
-rw-r--r--engine/settings.example.php2
-rw-r--r--engine/start.php111
-rw-r--r--engine/tests/api/annotations.php24
-rw-r--r--engine/tests/api/helpers.php83
-rw-r--r--engine/tests/api/metadata.php111
-rw-r--r--engine/tests/api/metastrings.php6
-rw-r--r--engine/tests/objects/entities.php35
-rw-r--r--engine/tests/objects/objects.php92
-rw-r--r--engine/tests/regression/trac_bugs.php18
83 files changed, 1923 insertions, 990 deletions
diff --git a/engine/classes/ElggBatch.php b/engine/classes/ElggBatch.php
index 62128e34f..c1a77a0d9 100644
--- a/engine/classes/ElggBatch.php
+++ b/engine/classes/ElggBatch.php
@@ -3,47 +3,51 @@
* Efficiently run operations on batches of results for any function
* that supports an options array.
*
- * This is usually used with elgg_get_entities() and friends, elgg_get_annotations()
- * and elgg_get_metadata().
+ * This is usually used with elgg_get_entities() and friends,
+ * elgg_get_annotations(), and elgg_get_metadata().
*
- * If you pass a valid PHP callback, all results will be run through that callback.
- * You can still foreach() through the result set after. Valid PHP callbacks
- * can be a string, an array, or a closure.
+ * If you pass a valid PHP callback, all results will be run through that
+ * callback. You can still foreach() through the result set after. Valid
+ * PHP callbacks can be a string, an array, or a closure.
* {@link http://php.net/manual/en/language.pseudo-types.php}
*
- * The callback function must accept 3 arguments: an entity, the getter used, and the options used.
+ * The callback function must accept 3 arguments: an entity, the getter
+ * used, and the options used.
*
- * Results from the callback are stored in callbackResult.
- * If the callback returns only booleans, callbackResults will be the combined
- * result of all calls.
+ * Results from the callback are stored in callbackResult. If the callback
+ * returns only booleans, callbackResults will be the combined result of
+ * all calls. If no entities are processed, callbackResults will be null.
*
- * If the callback returns anything else, callbackresult will be an indexed array
- * of whatever the callback returns. If returning error handling information,
- * you should include enough information to determine which result you're referring
- * to.
+ * If the callback returns anything else, callbackresult will be an indexed
+ * array of whatever the callback returns. If returning error handling
+ * information, you should include enough information to determine which
+ * result you're referring to.
*
* Don't combine returning bools and returning something else.
*
* Note that returning false will not stop the foreach.
*
+ * @warning If your callback or foreach loop deletes or disable entities
+ * you MUST call setIncrementOffset(false) or set that when instantiating.
+ * This forces the offset to stay what it was in the $options array.
+ *
* @example
* <code>
+ * // using foreach
* $batch = new ElggBatch('elgg_get_entities', array());
+ * $batch->setIncrementOffset(false);
*
* foreach ($batch as $entity) {
* $entity->disable();
* }
*
+ * // using both a callback
* $callback = function($result, $getter, $options) {
- * var_dump("Going to delete annotation id: $result->id");
+ * var_dump("Looking at annotation id: $result->id");
* return true;
* }
*
* $batch = new ElggBatch('elgg_get_annotations', array('guid' => 2), $callback);
- *
- * foreach ($batch as $annotation) {
- * $annotation->delete();
- * }
* </code>
*
* @package Elgg.Core
@@ -92,7 +96,7 @@ class ElggBatch
/**
* Stop after this many results.
*
- * @var unknown_type
+ * @var int
*/
private $limit = 0;
@@ -139,6 +143,13 @@ class ElggBatch
public $callbackResult = null;
/**
+ * If false, offset will not be incremented. This is used for callbacks/loops that delete.
+ *
+ * @var bool
+ */
+ private $incrementOffset = true;
+
+ /**
* Batches operations on any elgg_get_*() or compatible function that supports
* an options array.
*
@@ -147,19 +158,27 @@ class ElggBatch
*
* @param string $getter The function used to get objects. Usually
* an elgg_get_*() function, but can be any valid PHP callback.
- * @param array $options The options array to pass to the getter function
+ * @param array $options The options array to pass to the getter function. If limit is
+ * not set, 10 is used as the default. In most cases that is not
+ * what you want.
* @param mixed $callback An optional callback function that all results will be passed
* to upon load. The callback needs to accept $result, $getter,
* $options.
* @param int $chunk_size The number of entities to pull in before requesting more.
* You have to balance this between running out of memory in PHP
* and hitting the db server too often.
+ * @param bool $inc_offset Increment the offset on each fetch. This must be false for
+ * callbacks that delete rows. You can set this after the
+ * object is created with {@see ElggBatch::setIncrementOffset()}.
*/
- public function __construct($getter, $options, $callback = null, $chunk_size = 25) {
+ public function __construct($getter, $options, $callback = null, $chunk_size = 25,
+ $inc_offset = true) {
+
$this->getter = $getter;
$this->options = $options;
$this->callback = $callback;
$this->chunkSize = $chunk_size;
+ $this->setIncrementOffset($inc_offset);
if ($this->chunkSize <= 0) {
$this->chunkSize = 25;
@@ -172,7 +191,7 @@ class ElggBatch
// if passed a callback, create a new ElggBatch with the same options
// and pass each to the callback.
if ($callback && is_callable($callback)) {
- $batch = new ElggBatch($getter, $options, null, $chunk_size);
+ $batch = new ElggBatch($getter, $options, null, $chunk_size, $inc_offset);
$all_results = null;
@@ -234,20 +253,24 @@ class ElggBatch
}
// if original limit < chunk size, set limit to original limit
+ // else if the number of results we'll fetch if greater than the original limit
if ($this->limit < $this->chunkSize) {
$limit = $this->limit;
- }
-
- // if the number of results we'll fetch is greater than the original limit,
- // set the limit to the number of results remaining in the original limit
- elseif ($this->retrievedResults + $this->chunkSize > $this->limit) {
+ } elseif ($this->retrievedResults + $this->chunkSize > $this->limit) {
+ // set the limit to the number of results remaining in the original limit
$limit = $this->limit - $this->retrievedResults;
}
}
+ if ($this->incrementOffset) {
+ $offset = $this->offset + $this->retrievedResults;
+ } else {
+ $offset = $this->offset;
+ }
+
$current_options = array(
'limit' => $limit,
- 'offset' => $this->offset + $this->retrievedResults
+ 'offset' => $offset
);
$options = array_merge($this->options, $current_options);
@@ -270,6 +293,16 @@ class ElggBatch
}
/**
+ * Increment the offset from the original options array? Setting to
+ * false is required for callbacks that delete rows.
+ *
+ * @param bool $increment
+ */
+ public function setIncrementOffset($increment = true) {
+ $this->incrementOffset = (bool) $increment;
+ }
+
+ /**
* Implements Iterator
*/
@@ -319,13 +352,13 @@ class ElggBatch
*/
public function next() {
// if we'll be at the end.
- if ($this->processedResults + 1 >= $this->limit && $this->limit > 0) {
+ if (($this->processedResults + 1) >= $this->limit && $this->limit > 0) {
$this->results = array();
return false;
}
// if we'll need new results.
- if ($this->resultIndex + 1 >= $this->chunkSize) {
+ if (($this->resultIndex + 1) >= $this->chunkSize) {
if (!$this->getNextResultsChunk()) {
$this->results = array();
return false;
@@ -356,4 +389,4 @@ class ElggBatch
$key = key($this->results);
return ($key !== NULL && $key !== FALSE);
}
-} \ No newline at end of file
+}
diff --git a/engine/classes/ElggCache.php b/engine/classes/ElggCache.php
index 5c2cafcb7..4317f4be9 100644
--- a/engine/classes/ElggCache.php
+++ b/engine/classes/ElggCache.php
@@ -29,7 +29,7 @@ abstract class ElggCache implements ArrayAccess {
*
* @return void
*
- * @deprecated 1.8 Use ElggAccess:setVariable()
+ * @deprecated 1.8 Use ElggCache:setVariable()
*/
public function set_variable($variable, $value) {
elgg_deprecated_notice('ElggCache::set_variable() is deprecated by ElggCache::setVariable()', 1.8);
@@ -191,8 +191,8 @@ abstract class ElggCache implements ArrayAccess {
*
* @see ArrayAccess::offsetSet()
*
- * @param mixed $key The key (offset) to assign the value to.
- * @param mixed $value The value to set.
+ * @param mixed $key The key (offset) to assign the value to.
+ * @param mixed $value The value to set.
*
* @return void
*/
@@ -205,7 +205,7 @@ abstract class ElggCache implements ArrayAccess {
*
* @see ArrayAccess::offsetGet()
*
- * @param mixed $offset The key (offset) to retrieve.
+ * @param mixed $key The key (offset) to retrieve.
*
* @return mixed
*/
diff --git a/engine/classes/ElggDiskFilestore.php b/engine/classes/ElggDiskFilestore.php
index 11b2bd947..f00376481 100644
--- a/engine/classes/ElggDiskFilestore.php
+++ b/engine/classes/ElggDiskFilestore.php
@@ -205,7 +205,7 @@ class ElggDiskFilestore extends ElggFilestore {
$owner = elgg_get_logged_in_user_entity();
}
- if ((!$owner) || (!$owner->username)) {
+ if (!$owner) {
$msg = elgg_echo('InvalidParameterException:MissingOwner',
array($file->getFilename(), $file->guid));
throw new InvalidParameterException($msg);
diff --git a/engine/classes/ElggEntity.php b/engine/classes/ElggEntity.php
index df87082fe..77c2bbf4d 100644
--- a/engine/classes/ElggEntity.php
+++ b/engine/classes/ElggEntity.php
@@ -24,7 +24,6 @@
*
* @package Elgg.Core
* @subpackage DataModel.Entities
- * @link http://docs.elgg.org/DataModel/ElggEntity
*
* @property string $type object, user, group, or site (read-only after save)
* @property string $subtype Further clarifies the nature of the entity (read-only after save)
@@ -201,8 +200,11 @@ abstract class ElggEntity extends ElggData implements
/**
* Sets the value of a property.
*
- * If $name is defined in $this->attributes that value is set, otherwise it will
- * set the appropriate item of metadata.
+ * If $name is defined in $this->attributes that value is set, otherwise it is
+ * saved as metadata.
+ *
+ * @warning Metadata set this way will inherit the entity's owner and access ID. If you want
+ * to set metadata with a different owner, use create_metadata().
*
* @warning It is important that your class populates $this->attributes with keys
* for all base attributes, anything not in their gets set as METADATA.
@@ -248,7 +250,12 @@ abstract class ElggEntity extends ElggData implements
public function getMetaData($name) {
if ((int) ($this->guid) == 0) {
if (isset($this->temp_metadata[$name])) {
- return $this->temp_metadata[$name];
+ // md is returned as an array only if more than 1 entry
+ if (count($this->temp_metadata[$name]) == 1) {
+ return $this->temp_metadata[$name][0];
+ } else {
+ return $this->temp_metadata[$name];
+ }
} else {
return null;
}
@@ -291,80 +298,78 @@ abstract class ElggEntity extends ElggData implements
/**
* Set a piece of metadata.
*
- * @tip Plugin authors should use the magic methods.
+ * Plugin authors should use the magic methods or create_metadata().
+ *
+ * @warning The metadata will inherit the parent entity's owner and access ID.
+ * If you want to write metadata with a different owner, use create_metadata().
*
* @access private
*
* @param string $name Name of the metadata
- * @param mixed $value Value of the metadata
+ * @param mixed $value Value of the metadata (doesn't support assoc arrays)
* @param string $value_type Types supported: integer and string. Will auto-identify if not set
* @param bool $multiple Allow multiple values for a single name (doesn't support assoc arrays)
*
* @return bool
*/
- public function setMetaData($name, $value, $value_type = "", $multiple = false) {
- $delete_first = false;
- // if multiple is set that always means don't delete.
- // if multiple isn't set it means override. set it to true on arrays for the foreach.
- if (!$multiple) {
- $delete_first = true;
- $multiple = is_array($value);
- }
-
- if (!$this->guid) {
- // real metadata only returns as an array if there are multiple elements
- if (is_array($value) && count($value) == 1) {
- $value = $value[0];
- }
-
- $value_is_array = is_array($value);
+ public function setMetaData($name, $value, $value_type = null, $multiple = false) {
- if (!isset($this->temp_metadata[$name]) || $delete_first) {
- // need to remove the indexes because real metadata doesn't have them.
- if ($value_is_array) {
- $this->temp_metadata[$name] = array_values($value);
- } else {
- $this->temp_metadata[$name] = $value;
- }
- } else {
- // multiple is always true at this point.
- // if we're setting multiple and temp isn't array, it needs to be.
- if (!is_array($this->temp_metadata[$name])) {
- $this->temp_metadata[$name] = array($this->temp_metadata[$name]);
- }
-
- if ($value_is_array) {
- $this->temp_metadata[$name] = array_merge($this->temp_metadata[$name], array_values($value));
- } else {
- $this->temp_metadata[$name][] = $value;
- }
- }
+ // normalize value to an array that we will loop over
+ // remove indexes if value already an array.
+ if (is_array($value)) {
+ $value = array_values($value);
} else {
- if ($delete_first) {
+ $value = array($value);
+ }
+
+ // saved entity. persist md to db.
+ if ($this->guid) {
+ // if overwriting, delete first.
+ if (!$multiple) {
$options = array(
'guid' => $this->getGUID(),
'metadata_name' => $name,
'limit' => 0
);
- // @todo this doesn't check if it exists so we can't handle failed deletes
- // is it worth the overhead of more SQL calls to check?
- elgg_delete_metadata($options);
- }
- // save into real metadata
- if (!is_array($value)) {
- $value = array($value);
+ // @todo in 1.9 make this return false if can't add metadata
+ // http://trac.elgg.org/ticket/4520
+ //
+ // need to remove access restrictions right now to delete
+ // because this is the expected behavior
+ $ia = elgg_set_ignore_access(true);
+ if (false === elgg_delete_metadata($options)) {
+ return false;
+ }
+ elgg_set_ignore_access($ia);
}
- foreach ($value as $v) {
- $result = create_metadata($this->getGUID(), $name, $v, $value_type,
- $this->getOwnerGUID(), $this->getAccessId(), $multiple);
- if (!$result) {
+ // add new md
+ $result = true;
+ foreach ($value as $value_tmp) {
+ // at this point $value should be appended because it was cleared above if needed.
+ $md_id = create_metadata($this->getGUID(), $name, $value_tmp, $value_type,
+ $this->getOwnerGUID(), $this->getAccessId(), true);
+ if (!$md_id) {
return false;
}
}
+
+ return $result;
}
- return true;
+ // unsaved entity. store in temp array
+ // returning single entries instead of an array of 1 element is decided in
+ // getMetaData(), just like pulling from the db.
+ else {
+ // if overwrite, delete first
+ if (!$multiple || !isset($this->temp_metadata[$name])) {
+ $this->temp_metadata[$name] = array();
+ }
+
+ // add new md
+ $this->temp_metadata[$name] = array_merge($this->temp_metadata[$name], $value);
+ return true;
+ }
}
/**
@@ -575,7 +580,6 @@ abstract class ElggEntity extends ElggData implements
* @param mixed $value Value of private setting
*
* @return bool
- * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings
*/
function setPrivateSetting($name, $value) {
if ((int) $this->guid > 0) {
@@ -734,8 +738,6 @@ abstract class ElggEntity extends ElggData implements
* @param string $vartype The type of annotation value
*
* @return bool
- *
- * @link http://docs.elgg.org/DataModel/Annotations
*/
function annotate($name, $value, $access_id = ACCESS_PRIVATE, $owner_id = 0, $vartype = "") {
if ((int) $this->guid > 0) {
@@ -1311,12 +1313,16 @@ abstract class ElggEntity extends ElggData implements
/**
* Loads attributes from the entities table into the object.
*
- * @param int $guid GUID of Entity
+ * @param mixed $guid GUID of entity or stdClass object from entities table
*
* @return bool
*/
protected function load($guid) {
- $row = get_entity_as_row($guid);
+ if ($guid instanceof stdClass) {
+ $row = $guid;
+ } else {
+ $row = get_entity_as_row($guid);
+ }
if ($row) {
// Create the array if necessary - all subclasses should test before creating
@@ -1583,36 +1589,36 @@ abstract class ElggEntity extends ElggData implements
foreach ($this->attributes as $k => $v) {
$meta = NULL;
- if (in_array( $k, $exportable_values)) {
+ if (in_array($k, $exportable_values)) {
switch ($k) {
- case 'guid' : // Dont use guid in OpenDD
- case 'type' : // Type and subtype already taken care of
- case 'subtype' :
- break;
+ case 'guid': // Dont use guid in OpenDD
+ case 'type': // Type and subtype already taken care of
+ case 'subtype':
+ break;
- case 'time_created' : // Created = published
+ case 'time_created': // Created = published
$odd->setAttribute('published', date("r", $v));
- break;
+ break;
- case 'site_guid' : // Container
+ case 'site_guid': // Container
$k = 'site_uuid';
$v = guid_to_uuid($v);
$meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
- break;
+ break;
- case 'container_guid' : // Container
+ case 'container_guid': // Container
$k = 'container_uuid';
$v = guid_to_uuid($v);
$meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
- break;
+ break;
- case 'owner_guid' : // Convert owner guid to uuid, this will be stored in metadata
+ case 'owner_guid': // Convert owner guid to uuid, this will be stored in metadata
$k = 'owner_uuid';
$v = guid_to_uuid($v);
$meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
- break;
+ break;
- default :
+ default:
$meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
}
diff --git a/engine/classes/ElggExtender.php b/engine/classes/ElggExtender.php
index d6f79d18d..d94bad837 100644
--- a/engine/classes/ElggExtender.php
+++ b/engine/classes/ElggExtender.php
@@ -3,8 +3,7 @@
* The base class for ElggEntity extenders.
*
* Extenders allow you to attach extended information to an
- * ElggEntity. Core supports two: ElggAnnotation, ElggMetadata,
- * and ElggRelationship
+ * ElggEntity. Core supports two: ElggAnnotation and ElggMetadata.
*
* Saving the extender data to database is handled by the child class.
*
@@ -16,9 +15,24 @@
* @link http://docs.elgg.org/DataModel/Extenders
* @see ElggAnnotation
* @see ElggMetadata
+ *
+ * @property string $type annotation or metadata (read-only after save)
+ * @property int $id The unique identifier (read-only)
+ * @property int $entity_guid The GUID of the entity that this extender describes
+ * @property int $access_id Specifies the visibility level of this extender
+ * @property string $name The name of this extender
+ * @property mixed $value The value of the extender (int or string)
+ * @property int $time_created A UNIX timestamp of when the extender was created (read-only, set on first save)
*/
-abstract class ElggExtender extends ElggData
-{
+abstract class ElggExtender extends ElggData {
+
+ /**
+ * (non-PHPdoc)
+ *
+ * @see ElggData::initializeAttributes()
+ *
+ * @return void
+ */
protected function initializeAttributes() {
parent::initializeAttributes();
diff --git a/engine/classes/ElggFileCache.php b/engine/classes/ElggFileCache.php
index 8304372dc..34178d452 100644
--- a/engine/classes/ElggFileCache.php
+++ b/engine/classes/ElggFileCache.php
@@ -161,12 +161,25 @@ class ElggFileCache extends ElggCache {
}
/**
- * This was probably meant to delete everything?
+ * Delete all files in the directory of this file cache
*
* @return void
*/
public function clear() {
- // @todo writeme
+ $dir = $this->getVariable("cache_path");
+
+ $exclude = array(".", "..");
+
+ $files = scandir($dir);
+ if (!$files) {
+ return;
+ }
+
+ foreach ($files as $f) {
+ if (!in_array($f, $exclude)) {
+ unlink($dir . $f);
+ }
+ }
}
/**
@@ -184,7 +197,7 @@ class ElggFileCache extends ElggCache {
return;
}
- $exclude = array(".","..");
+ $exclude = array(".", "..");
$files = scandir($dir);
if (!$files) {
diff --git a/engine/classes/ElggGroup.php b/engine/classes/ElggGroup.php
index 0190e5eac..f7f67bf41 100644
--- a/engine/classes/ElggGroup.php
+++ b/engine/classes/ElggGroup.php
@@ -5,6 +5,9 @@
*
* @package Elgg.Core
* @subpackage Groups
+ *
+ * @property string $name A short name that captures the purpose of the group
+ * @property string $description A longer body of content that gives more details about the group
*/
class ElggGroup extends ElggEntity
implements Friendable {
@@ -26,12 +29,12 @@ class ElggGroup extends ElggEntity
}
/**
- * Construct a new user entity, optionally from a given id value.
+ * Construct a new group entity, optionally from a given guid value.
*
* @param mixed $guid If an int, load that GUID.
- * If a db row then will attempt to load the rest of the data.
+ * If an entity table db row, then will load the rest of the data.
*
- * @throws Exception if there was a problem creating the user.
+ * @throws Exception if there was a problem creating the group.
*/
function __construct($guid = null) {
$this->initializeAttributes();
@@ -40,15 +43,15 @@ class ElggGroup extends ElggEntity
$this->initialise_attributes(false);
if (!empty($guid)) {
- // Is $guid is a DB row - either a entity row, or a user table row.
+ // Is $guid is a entity table DB row
if ($guid instanceof stdClass) {
// Load the rest
- if (!$this->load($guid->guid)) {
+ if (!$this->load($guid)) {
$msg = elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid->guid));
throw new IOException($msg);
}
- // Is $guid is an ElggGroup? Use a copy constructor
+ // Is $guid is an ElggGroup? Use a copy constructor
} else if ($guid instanceof ElggGroup) {
elgg_deprecated_notice('This type of usage of the ElggGroup constructor was deprecated. Please use the clone method.', 1.7);
@@ -56,11 +59,11 @@ class ElggGroup extends ElggEntity
$this->attributes[$key] = $value;
}
- // Is this is an ElggEntity but not an ElggGroup = ERROR!
+ // Is this is an ElggEntity but not an ElggGroup = ERROR!
} else if ($guid instanceof ElggEntity) {
throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggGroup'));
- // We assume if we have got this far, $guid is an int
+ // Is it a GUID
} else if (is_numeric($guid)) {
if (!$this->load($guid)) {
throw new IOException(elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid)));
@@ -316,11 +319,9 @@ class ElggGroup extends ElggEntity
}
/**
- * Override the load function.
- * This function will ensure that all data is loaded (were possible), so
- * if only part of the ElggGroup is loaded, it'll load the rest.
+ * Load the ElggGroup data from the database
*
- * @param int $guid GUID of an ElggGroup entity
+ * @param mixed $guid GUID of an ElggGroup entity or database row from entity table
*
* @return bool
*/
@@ -330,6 +331,11 @@ class ElggGroup extends ElggEntity
return false;
}
+ // Only work with GUID from here
+ if ($guid instanceof stdClass) {
+ $guid = $guid->guid;
+ }
+
// Check the type
if ($this->attributes['type'] != 'group') {
$msg = elgg_echo('InvalidClassException:NotValidElggStar', array($guid, get_class()));
diff --git a/engine/classes/ElggMemcache.php b/engine/classes/ElggMemcache.php
index a54c29723..f27b017d0 100644
--- a/engine/classes/ElggMemcache.php
+++ b/engine/classes/ElggMemcache.php
@@ -114,27 +114,11 @@ class ElggMemcache extends ElggSharedMemoryCache {
* Combine a key with the namespace.
* Memcache can only accept <250 char key. If the given key is too long it is shortened.
*
- * @deprecated 1.8 Use ElggMemcache::_makeMemcacheKey()
- *
- * @param string $key The key
- *
- * @return string The new key.
- */
- private function make_memcache_key($key) {
- elgg_deprecated_notice('ElggMemcache::make_memcache_key() is deprecated by ::_makeMemcacheKey()', 1.8);
-
- return $this->_makeMemcacheKey($key);
- }
-
- /**
- * Combine a key with the namespace.
- * Memcache can only accept <250 char key. If the given key is too long it is shortened.
- *
* @param string $key The key
*
* @return string The new key.
*/
- private function _makeMemcacheKey($key) {
+ private function makeMemcacheKey($key) {
$prefix = $this->getNamespace() . ":";
if (strlen($prefix . $key) > 250) {
@@ -154,7 +138,7 @@ class ElggMemcache extends ElggSharedMemoryCache {
* @return bool
*/
public function save($key, $data, $expires = null) {
- $key = $this->_makeMemcacheKey($key);
+ $key = $this->makeMemcacheKey($key);
if ($expires === null) {
$expires = $this->expires;
@@ -178,7 +162,7 @@ class ElggMemcache extends ElggSharedMemoryCache {
* @return mixed
*/
public function load($key, $offset = 0, $limit = null) {
- $key = $this->_makeMemcacheKey($key);
+ $key = $this->makeMemcacheKey($key);
$result = $this->memcache->get($key);
if ($result === false) {
@@ -196,7 +180,7 @@ class ElggMemcache extends ElggSharedMemoryCache {
* @return bool
*/
public function delete($key) {
- $key = $this->_makeMemcacheKey($key);
+ $key = $this->makeMemcacheKey($key);
return $this->memcache->delete($key, 0);
}
diff --git a/engine/classes/ElggMenuBuilder.php b/engine/classes/ElggMenuBuilder.php
index cadfee7f5..de0017599 100644
--- a/engine/classes/ElggMenuBuilder.php
+++ b/engine/classes/ElggMenuBuilder.php
@@ -4,8 +4,7 @@
*
* @package Elgg.Core
* @subpackage Navigation
- *
- * @since 1.8.0
+ * @since 1.8.0
*/
class ElggMenuBuilder {
@@ -16,16 +15,16 @@ class ElggMenuBuilder {
/**
* ElggMenuBuilder constructor
*
- * @param string $name Identifier of the menu
+ * @param array $menu Array of ElggMenuItem objects
*/
- public function __construct($menu) {
+ public function __construct(array $menu) {
$this->menu = $menu;
}
/**
* Get a prepared menu array
*
- * @param mixed $sort_by
+ * @param mixed $sort_by Method to sort the menu by. @see ElggMenuBuilder::sort()
* @return array
*/
public function getMenu($sort_by = 'text') {
@@ -80,6 +79,7 @@ class ElggMenuBuilder {
/**
* Group the menu items into sections
+ *
* @return void
*/
protected function setupSections() {
diff --git a/engine/classes/ElggMenuItem.php b/engine/classes/ElggMenuItem.php
index 62547134a..4bc9144d4 100644
--- a/engine/classes/ElggMenuItem.php
+++ b/engine/classes/ElggMenuItem.php
@@ -2,12 +2,11 @@
/**
* Elgg Menu Item
*
- * @package Elgg.Core
- * @subpackage Navigation
- *
* To create a menu item that is not a link, pass false for $href.
*
- * @since 1.8.0
+ * @package Elgg.Core
+ * @subpackage Navigation
+ * @since 1.8.0
*/
class ElggMenuItem {
@@ -70,9 +69,9 @@ class ElggMenuItem {
/**
* ElggMenuItem constructor
*
- * @param string $name Identifier of the menu item
- * @param string $text Display text of the menu item
- * @param string $href URL of the menu item (false if not a link)
+ * @param string $name Identifier of the menu item
+ * @param string $text Display text of the menu item
+ * @param string $href URL of the menu item (false if not a link)
*/
public function __construct($name, $text, $href) {
//$this->name = $name;
@@ -182,7 +181,7 @@ class ElggMenuItem {
/**
* Set the identifier of the menu item
*
- * @param string Unique identifier
+ * @param string $name Unique identifier
* @return void
*/
public function setName($name) {
@@ -491,7 +490,7 @@ class ElggMenuItem {
/**
* Set the parent menu item
*
- * @param ElggMenuItem $parent
+ * @param ElggMenuItem $parent The parent of this menu item
* @return void
*/
public function setParent($parent) {
@@ -510,7 +509,7 @@ class ElggMenuItem {
/**
* Add a child menu item
*
- * @param ElggMenuItem $item
+ * @param ElggMenuItem $item A child menu item
* @return void
*/
public function addChild($item) {
@@ -549,9 +548,8 @@ class ElggMenuItem {
/**
* Get the menu item content (usually a link)
*
- * @params array $vars Options to pass to output/url if a link
+ * @param array $vars Options to pass to output/url if a link
* @return string
- *
* @todo View code in a model. How do we feel about that?
*/
public function getContent(array $vars = array()) {
diff --git a/engine/classes/ElggMetadata.php b/engine/classes/ElggMetadata.php
index 32e7b32f1..634a122e5 100644
--- a/engine/classes/ElggMetadata.php
+++ b/engine/classes/ElggMetadata.php
@@ -9,6 +9,13 @@
*/
class ElggMetadata extends ElggExtender {
+ /**
+ * (non-PHPdoc)
+ *
+ * @see ElggData::initializeAttributes()
+ *
+ * @return void
+ */
protected function initializeAttributes() {
parent::initializeAttributes();
diff --git a/engine/classes/ElggObject.php b/engine/classes/ElggObject.php
index 0b8340697..b4bae6825 100644
--- a/engine/classes/ElggObject.php
+++ b/engine/classes/ElggObject.php
@@ -14,6 +14,10 @@
*
* @package Elgg.Core
* @subpackage DataModel.Object
+ *
+ * @property string $title The title, name, or summary of this object
+ * @property string $description The body, description, or content of the object
+ * @property array $tags Array of tags that describe the object
*/
class ElggObject extends ElggEntity {
@@ -37,12 +41,12 @@ class ElggObject extends ElggEntity {
*
* If no arguments are passed, create a new entity.
*
- * If an argument is passed attempt to load a full Object entity. Arguments
- * can be:
+ * If an argument is passed, attempt to load a full ElggObject entity.
+ * Arguments can be:
* - The GUID of an object entity.
- * - A DB result object with a guid property
+ * - A DB result object from the entities table with a guid property
*
- * @param mixed $guid If an int, load that GUID. If a db row then will attempt to
+ * @param mixed $guid If an int, load that GUID. If a db row, then will attempt to
* load the rest of the data.
*
* @throws IOException If passed an incorrect guid
@@ -55,15 +59,15 @@ class ElggObject extends ElggEntity {
$this->initialise_attributes(false);
if (!empty($guid)) {
- // Is $guid is a DB row - either a entity row, or a object table row.
+ // Is $guid is a DB row from the entity table
if ($guid instanceof stdClass) {
// Load the rest
- if (!$this->load($guid->guid)) {
+ if (!$this->load($guid)) {
$msg = elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid->guid));
throw new IOException($msg);
}
- // Is $guid is an ElggObject? Use a copy constructor
+ // Is $guid is an ElggObject? Use a copy constructor
} else if ($guid instanceof ElggObject) {
elgg_deprecated_notice('This type of usage of the ElggObject constructor was deprecated. Please use the clone method.', 1.7);
@@ -71,11 +75,11 @@ class ElggObject extends ElggEntity {
$this->attributes[$key] = $value;
}
- // Is this is an ElggEntity but not an ElggObject = ERROR!
+ // Is this is an ElggEntity but not an ElggObject = ERROR!
} else if ($guid instanceof ElggEntity) {
throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggObject'));
- // We assume if we have got this far, $guid is an int
+ // Is it a GUID
} else if (is_numeric($guid)) {
if (!$this->load($guid)) {
throw new IOException(elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid)));
@@ -89,17 +93,22 @@ class ElggObject extends ElggEntity {
/**
* Loads the full ElggObject when given a guid.
*
- * @param int $guid Guid of an ElggObject
+ * @param mixed $guid GUID of an ElggObject or the stdClass object from entities table
*
* @return bool
* @throws InvalidClassException
*/
protected function load($guid) {
- // Test to see if we have the generic stuff
+ // Load data from entity table if needed
if (!parent::load($guid)) {
return false;
}
+ // Only work with GUID from here
+ if ($guid instanceof stdClass) {
+ $guid = $guid->guid;
+ }
+
// Check the type
if ($this->attributes['type'] != 'object') {
$msg = elgg_echo('InvalidClassException:NotValidElggStar', array($guid, get_class()));
diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php
index c4d6ec034..8c9093834 100644
--- a/engine/classes/ElggPlugin.php
+++ b/engine/classes/ElggPlugin.php
@@ -79,6 +79,68 @@ class ElggPlugin extends ElggObject {
}
/**
+ * Overridden from ElggEntity and ElggObject::load(). Core always inits plugins with
+ * a query joined to the objects_entity table, so all the info is there.
+ *
+ * @param mixed $guid GUID of an ElggObject or the stdClass object from entities table
+ *
+ * @return bool
+ * @throws InvalidClassException
+ */
+ protected function load($guid) {
+
+ $expected_attributes = $this->attributes;
+ unset($expected_attributes['tables_split']);
+ unset($expected_attributes['tables_loaded']);
+
+ // this was loaded with a full join
+ $needs_loaded = false;
+
+ if ($guid instanceof stdClass) {
+ $row = (array) $guid;
+ $missing_attributes = array_diff_key($expected_attributes, $row);
+ if ($missing_attributes) {
+ $needs_loaded = true;
+ $old_guid = $guid;
+ $guid = $row['guid'];
+ } else {
+ $this->attributes = $row;
+ }
+ } else {
+ $needs_loaded = true;
+ }
+
+ if ($needs_loaded) {
+ $entity = (array) get_entity_as_row($guid);
+ $object = (array) get_object_entity_as_row($guid);
+
+ if (!$entity || !$object) {
+ return false;
+ }
+
+ $this->attributes = array_merge($this->attributes, $entity, $object);
+ }
+
+ $this->attributes['tables_loaded'] = 2;
+
+ // Check the type
+ if ($this->attributes['type'] != 'object') {
+ $msg = elgg_echo('InvalidClassException:NotValidElggStar', array($guid, get_class()));
+ throw new InvalidClassException($msg);
+ }
+
+ // guid needs to be an int http://trac.elgg.org/ticket/4111
+ $this->attributes['guid'] = (int)$this->attributes['guid'];
+
+ // cache the entity
+ if ($this->attributes['guid']) {
+ cache_entity($this);
+ }
+
+ return true;
+ }
+
+ /**
* Save the plugin object. Make sure required values exist.
*
* @see ElggObject::save()
@@ -707,9 +769,9 @@ class ElggPlugin extends ElggObject {
* @throws PluginException
*/
public function start($flags) {
-// if (!$this->canActivate()) {
-// return false;
-// }
+ //if (!$this->canActivate()) {
+ // return false;
+ //}
// include classes
if ($flags & ELGG_PLUGIN_REGISTER_CLASSES) {
diff --git a/engine/classes/ElggPluginManifest.php b/engine/classes/ElggPluginManifest.php
index 7592eb667..7e79c15c8 100644
--- a/engine/classes/ElggPluginManifest.php
+++ b/engine/classes/ElggPluginManifest.php
@@ -319,12 +319,26 @@ class ElggPluginManifest {
* @return array
*/
public function getCategories() {
+ $bundled_plugins = array('blog', 'bookmarks', 'categories',
+ 'custom_index', 'dashboard', 'developers', 'diagnostics',
+ 'embed', 'externalpages', 'file', 'garbagecollector',
+ 'groups', 'htmlawed', 'invitefriends', 'likes',
+ 'logbrowser', 'logrotate', 'members', 'messageboard',
+ 'messages', 'notifications', 'oauth_api', 'pages', 'profile',
+ 'reportedcontent', 'search', 'tagcloud', 'thewire', 'tinymce',
+ 'twitter', 'twitter_api', 'uservalidationbyemail', 'zaudio',
+ );
+
$cats = $this->parser->getAttribute('category');
if (!$cats) {
$cats = array();
}
+ if (in_array('bundled', $cats) && !in_array($this->getPluginID(), $bundled_plugins)) {
+ unset($cats[array_search('bundled', $cats)]);
+ }
+
return $cats;
}
@@ -592,4 +606,23 @@ class ElggPluginManifest {
return $return;
}
+
+ /**
+ * Returns a category's friendly name. This can be localized by
+ * defining the string 'admin:plugins:category:<category>'. If no
+ * localization is found, returns the category with _ and - converted to ' '
+ * and then ucwords()'d.
+ *
+ * @param str $category The category as defined in the manifest.
+ * @return str A human-readable category
+ */
+ static public function getFriendlyCategory($category) {
+ $cat_raw_string = "admin:plugins:category:$category";
+ $cat_display_string = elgg_echo($cat_raw_string);
+ if ($cat_display_string == $cat_raw_string) {
+ $category = str_replace(array('-', '_'), ' ', $category);
+ $cat_display_string = ucwords($category);
+ }
+ return $cat_display_string;
+ }
}
diff --git a/engine/classes/ElggPluginPackage.php b/engine/classes/ElggPluginPackage.php
index d240af477..2dc4bdb3d 100644
--- a/engine/classes/ElggPluginPackage.php
+++ b/engine/classes/ElggPluginPackage.php
@@ -303,6 +303,8 @@ class ElggPluginPackage {
/**
* Returns an array of present and readable text files
+ *
+ * @return array
*/
public function getTextFilenames() {
return $this->textFiles;
diff --git a/engine/classes/ElggRelationship.php b/engine/classes/ElggRelationship.php
index 2d9a32cbd..efc0f7eff 100644
--- a/engine/classes/ElggRelationship.php
+++ b/engine/classes/ElggRelationship.php
@@ -4,6 +4,12 @@
*
* @package Elgg.Core
* @subpackage Core
+ *
+ * @property int $id The unique identifier (read-only)
+ * @property int $guid_one The GUID of the subject of the relationship
+ * @property string $relationship The name of the relationship
+ * @property int $guid_two The GUID of the object of the relationship
+ * @property int $time_created A UNIX timestamp of when the relationship was created (read-only, set on first save)
*/
class ElggRelationship extends ElggData implements
Importable
diff --git a/engine/classes/ElggRiverItem.php b/engine/classes/ElggRiverItem.php
index fcc8f9c85..d3d09cd91 100644
--- a/engine/classes/ElggRiverItem.php
+++ b/engine/classes/ElggRiverItem.php
@@ -4,9 +4,19 @@
*
* @package Elgg.Core
* @subpackage Core
+ *
+ * @property int $id The unique identifier (read-only)
+ * @property int $subject_guid The GUID of the actor
+ * @property int $object_guid The GUID of the object
+ * @property int $annotation_id The ID of the annotation involved in the action
+ * @property string $type The type of one of the entities involved in the action
+ * @property string $subtype The subtype of one of the entities involved in the action
+ * @property string $action_type The name of the action
+ * @property string $view The view for displaying this river item
+ * @property int $access_id The visibility of the river item
+ * @property int $posted UNIX timestamp when the action occurred
*/
-class ElggRiverItem
-{
+class ElggRiverItem {
public $id;
public $subject_guid;
public $object_guid;
diff --git a/engine/classes/ElggSite.php b/engine/classes/ElggSite.php
index 3ccb146fb..e793ab9c6 100644
--- a/engine/classes/ElggSite.php
+++ b/engine/classes/ElggSite.php
@@ -21,6 +21,10 @@
* @package Elgg.Core
* @subpackage DataMode.Site
* @link http://docs.elgg.org/DataModel/Sites
+ *
+ * @property string $name The name or title of the website
+ * @property string $description A motto, mission statement, or description of the website
+ * @property string $url The root web address for the site, including trailing slash
*/
class ElggSite extends ElggEntity {
@@ -53,8 +57,8 @@ class ElggSite extends ElggEntity {
* - A URL as stored in ElggSite->url
* - A DB result object with a guid property
*
- * @param mixed $guid If an int, load that GUID. If a db row then will attempt
- * to load the rest of the data.
+ * @param mixed $guid If an int, load that GUID. If a db row then will
+ * load the rest of the data.
*
* @throws IOException If passed an incorrect guid
* @throws InvalidParameterException If passed an Elgg* Entity that isn't an ElggSite
@@ -66,15 +70,15 @@ class ElggSite extends ElggEntity {
$this->initialise_attributes(false);
if (!empty($guid)) {
- // Is $guid is a DB row - either a entity row, or a site table row.
+ // Is $guid is a DB entity table row
if ($guid instanceof stdClass) {
// Load the rest
- if (!$this->load($guid->guid)) {
+ if (!$this->load($guid)) {
$msg = elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid->guid));
throw new IOException($msg);
}
- // Is $guid is an ElggSite? Use a copy constructor
+ // Is $guid is an ElggSite? Use a copy constructor
} else if ($guid instanceof ElggSite) {
elgg_deprecated_notice('This type of usage of the ElggSite constructor was deprecated. Please use the clone method.', 1.7);
@@ -82,18 +86,18 @@ class ElggSite extends ElggEntity {
$this->attributes[$key] = $value;
}
- // Is this is an ElggEntity but not an ElggSite = ERROR!
+ // Is this is an ElggEntity but not an ElggSite = ERROR!
} else if ($guid instanceof ElggEntity) {
throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggSite'));
- // See if this is a URL
+ // See if this is a URL
} else if (strpos($guid, "http") !== false) {
$guid = get_site_by_url($guid);
foreach ($guid->attributes as $key => $value) {
$this->attributes[$key] = $value;
}
- // We assume if we have got this far, $guid is an int
+ // Is it a GUID
} else if (is_numeric($guid)) {
if (!$this->load($guid)) {
throw new IOException(elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid)));
@@ -107,7 +111,7 @@ class ElggSite extends ElggEntity {
/**
* Loads the full ElggSite when given a guid.
*
- * @param int $guid Guid of ElggSite entity
+ * @param mixed $guid GUID of ElggSite entity or database row object
*
* @return bool
* @throws InvalidClassException
@@ -118,6 +122,11 @@ class ElggSite extends ElggEntity {
return false;
}
+ // Only work with GUID from here
+ if ($guid instanceof stdClass) {
+ $guid = $guid->guid;
+ }
+
// Check the type
if ($this->attributes['type'] != 'site') {
$msg = elgg_echo('InvalidClassException:NotValidElggStar', array($guid, get_class()));
@@ -192,7 +201,7 @@ class ElggSite extends ElggEntity {
*
* @note You cannot disable the current site.
*
- * @param string $reason Optional reason for disabling
+ * @param string $reason Optional reason for disabling
* @param bool $recursive Recursively disable all contained entities?
*
* @return bool
@@ -215,7 +224,7 @@ class ElggSite extends ElggEntity {
* accepted by elgg_get_entities(). Common parameters
* include 'limit', and 'offset'.
* Note: this was $limit before version 1.8
- * @param int $offset Offset @deprecated parameter
+ * @param int $offset Offset @deprecated parameter
*
* @todo remove $offset in 2.0
*
@@ -231,6 +240,7 @@ class ElggSite extends ElggEntity {
}
$defaults = array(
+ 'site_guids' => ELGG_ENTITIES_ANY_VALUE,
'relationship' => 'member_of_site',
'relationship_guid' => $this->getGUID(),
'inverse_relationship' => TRUE,
@@ -254,6 +264,7 @@ class ElggSite extends ElggEntity {
*/
public function listMembers($options = array()) {
$defaults = array(
+ 'site_guids' => ELGG_ENTITIES_ANY_VALUE,
'relationship' => 'member_of_site',
'relationship_guid' => $this->getGUID(),
'inverse_relationship' => TRUE,
@@ -411,6 +422,8 @@ class ElggSite extends ElggEntity {
// default public pages
$defaults = array(
+ 'walled_garden/.*',
+ 'login',
'action/login',
'register',
'action/register',
@@ -427,6 +440,8 @@ class ElggSite extends ElggEntity {
'js/.*',
'cache/css/.*',
'cache/js/.*',
+ 'cron/.*',
+ 'services/.*',
);
// include a hook for plugin authors to include public pages
diff --git a/engine/classes/ElggUser.php b/engine/classes/ElggUser.php
index a1c7147a5..d7bb89265 100644
--- a/engine/classes/ElggUser.php
+++ b/engine/classes/ElggUser.php
@@ -6,6 +6,15 @@
*
* @package Elgg.Core
* @subpackage DataModel.User
+ *
+ * @property string $name The display name that the user will be known by in the network
+ * @property string $username The short, reference name for the user in the network
+ * @property string $email The email address to which Elgg will send email notifications
+ * @property string $language The language preference of the user (ISO 639-1 formatted)
+ * @property string $banned 'yes' if the user is banned from the network, 'no' otherwise
+ * @property string $admin 'yes' if the user is an administrator of the network, 'no' otherwise
+ * @property string $password The hashed password of the user
+ * @property string $salt The salt used to secure the password before hashing
*/
class ElggUser extends ElggEntity
implements Friendable {
@@ -38,7 +47,7 @@ class ElggUser extends ElggEntity
* Construct a new user entity, optionally from a given id value.
*
* @param mixed $guid If an int, load that GUID.
- * If a db row then will attempt to load the rest of the data.
+ * If an entity table db row then will load the rest of the data.
*
* @throws Exception if there was a problem creating the user.
*/
@@ -49,15 +58,15 @@ class ElggUser extends ElggEntity
$this->initialise_attributes(false);
if (!empty($guid)) {
- // Is $guid is a DB row - either a entity row, or a user table row.
+ // Is $guid is a DB entity row
if ($guid instanceof stdClass) {
// Load the rest
- if (!$this->load($guid->guid)) {
+ if (!$this->load($guid)) {
$msg = elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid->guid));
throw new IOException($msg);
}
- // See if this is a username
+ // See if this is a username
} else if (is_string($guid)) {
$user = get_user_by_username($guid);
if ($user) {
@@ -66,7 +75,7 @@ class ElggUser extends ElggEntity
}
}
- // Is $guid is an ElggUser? Use a copy constructor
+ // Is $guid is an ElggUser? Use a copy constructor
} else if ($guid instanceof ElggUser) {
elgg_deprecated_notice('This type of usage of the ElggUser constructor was deprecated. Please use the clone method.', 1.7);
@@ -74,11 +83,11 @@ class ElggUser extends ElggEntity
$this->attributes[$key] = $value;
}
- // Is this is an ElggEntity but not an ElggUser = ERROR!
+ // Is this is an ElggEntity but not an ElggUser = ERROR!
} else if ($guid instanceof ElggEntity) {
throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggUser'));
- // We assume if we have got this far, $guid is an int
+ // Is it a GUID
} else if (is_numeric($guid)) {
if (!$this->load($guid)) {
throw new IOException(elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid)));
@@ -90,13 +99,11 @@ class ElggUser extends ElggEntity
}
/**
- * Override the load function.
- * This function will ensure that all data is loaded (were possible), so
- * if only part of the ElggUser is loaded, it'll load the rest.
+ * Load the ElggUser data from the database
*
- * @param int $guid ElggUser GUID
+ * @param mixed $guid ElggUser GUID or stdClass database row from entity table
*
- * @return true|false
+ * @return bool
*/
protected function load($guid) {
// Test to see if we have the generic stuff
@@ -104,6 +111,11 @@ class ElggUser extends ElggEntity
return false;
}
+ // Only work with GUID from here
+ if ($guid instanceof stdClass) {
+ $guid = $guid->guid;
+ }
+
// Check the type
if ($this->attributes['type'] != 'user') {
$msg = elgg_echo('InvalidClassException:NotValidElggStar', array($guid, get_class()));
@@ -132,7 +144,7 @@ class ElggUser extends ElggEntity
/**
* Saves this user to the database.
*
- * @return true|false
+ * @return bool
*/
public function save() {
// Save generic stuff
@@ -252,7 +264,7 @@ class ElggUser extends ElggEntity
* @param int $limit The number of results to return
* @param int $offset Any indexing offset
*
- * @return bool
+ * @return array
*/
function getSites($subtype = "", $limit = 10, $offset = 0) {
return get_user_sites($this->getGUID(), $subtype, $limit, $offset);
@@ -263,7 +275,7 @@ class ElggUser extends ElggEntity
*
* @param int $site_guid The guid of the site to add it to
*
- * @return true|false
+ * @return bool
*/
function addToSite($site_guid) {
return add_site_user($site_guid, $this->getGUID());
@@ -274,7 +286,7 @@ class ElggUser extends ElggEntity
*
* @param int $site_guid The guid of the site to remove it from
*
- * @return true|false
+ * @return bool
*/
function removeFromSite($site_guid) {
return remove_site_user($site_guid, $this->getGUID());
@@ -285,7 +297,7 @@ class ElggUser extends ElggEntity
*
* @param int $friend_guid The GUID of the user to add
*
- * @return true|false Depending on success
+ * @return bool
*/
function addFriend($friend_guid) {
return user_add_friend($this->getGUID(), $friend_guid);
@@ -296,7 +308,7 @@ class ElggUser extends ElggEntity
*
* @param int $friend_guid The GUID of the user to remove
*
- * @return true|false Depending on success
+ * @return bool
*/
function removeFriend($friend_guid) {
return user_remove_friend($this->getGUID(), $friend_guid);
@@ -305,8 +317,7 @@ class ElggUser extends ElggEntity
/**
* Determines whether or not this user is a friend of the currently logged in user
*
- *
- * @return true|false
+ * @return bool
*/
function isFriend() {
return $this->isFriendOf(elgg_get_logged_in_user_guid());
@@ -317,7 +328,7 @@ class ElggUser extends ElggEntity
*
* @param int $user_guid The GUID of the user to check against
*
- * @return true|false
+ * @return bool
*/
function isFriendsWith($user_guid) {
return user_is_friend($this->getGUID(), $user_guid);
@@ -328,7 +339,7 @@ class ElggUser extends ElggEntity
*
* @param int $user_guid The GUID of the user to check against
*
- * @return true|false
+ * @return bool
*/
function isFriendOf($user_guid) {
return user_is_friend($user_guid, $this->getGUID());
@@ -376,7 +387,6 @@ class ElggUser extends ElggEntity
'relationship' => 'friend',
'relationship_guid' => $this->guid,
'limit' => $limit,
- 'offset' => get_input('offset', 0),
'full_view' => false,
);
@@ -450,7 +460,14 @@ class ElggUser extends ElggEntity
* @return array|false
*/
public function getObjects($subtype = "", $limit = 10, $offset = 0) {
- return get_user_objects($this->getGUID(), $subtype, $limit, $offset);
+ $params = array(
+ 'type' => 'object',
+ 'subtype' => $subtype,
+ 'owner_guid' => $this->getGUID(),
+ 'limit' => $limit,
+ 'offset' => $offset
+ );
+ return elgg_get_entities($params);
}
/**
diff --git a/engine/classes/ElggWidget.php b/engine/classes/ElggWidget.php
index 0eb83913b..99708f66a 100644
--- a/engine/classes/ElggWidget.php
+++ b/engine/classes/ElggWidget.php
@@ -115,6 +115,8 @@ class ElggWidget extends ElggObject {
$options = array(
'type' => 'object',
'subtype' => 'widget',
+ 'container_guid' => $this->container_guid,
+ 'limit' => false,
'private_setting_name_value_pairs' => array(
array('name' => 'context', 'value' => $this->getContext()),
array('name' => 'column', 'value' => $column)
@@ -129,21 +131,60 @@ class ElggWidget extends ElggObject {
usort($widgets, create_function('$a,$b','return (int)$a->order > (int)$b->order;'));
+ // remove widgets from inactive plugins
+ $widget_types = elgg_get_widget_types($this->context);
+ $inactive_widgets = array();
+ foreach ($widgets as $index => $widget) {
+ if (!array_key_exists($widget->handler, $widget_types)) {
+ $inactive_widgets[] = $widget;
+ unset($widgets[$index]);
+ }
+ }
+
if ($rank == 0) {
// top of the column
- $this->order = $widgets[0]->order - 10;
- } elseif ($rank == count($widgets)) {
- // bottom of the column
+ $this->order = reset($widgets)->order - 10;
+ } elseif ($rank == (count($widgets) - 1)) {
+ // bottom of the column of active widgets
$this->order = end($widgets)->order + 10;
} else {
- // reorder widgets that are below
- $this->order = $widgets[$rank]->order;
- for ($index = $rank; $index < count($widgets); $index++) {
- if ($widgets[$index]->guid != $this->guid) {
- $widgets[$index]-> order += 10;
+ // reorder widgets
+
+ // remove the widget that's being moved from the array
+ foreach ($widgets as $index => $widget) {
+ if ($widget->guid == $this->guid) {
+ unset($widgets[$index]);
+ }
+ }
+
+ // split the array in two and recombine with the moved widget in middle
+ $before = array_slice($widgets, 0, $rank);
+ array_push($before, $this);
+ $after = array_slice($widgets, $rank);
+ $widgets = array_merge($before, $after);
+ ksort($widgets);
+ $order = 0;
+ foreach ($widgets as $widget) {
+ $widget->order = $order;
+ $order += 10;
+ }
+ }
+
+ // put inactive widgets at the bottom
+ if ($inactive_widgets) {
+ $bottom = 0;
+ foreach ($widgets as $widget) {
+ if ($widget->order > $bottom) {
+ $bottom = $widget->order;
}
}
+ $bottom += 10;
+ foreach ($inactive_widgets as $widget) {
+ $widget->order = $bottom;
+ $bottom += 10;
+ }
}
+
$this->column = $column;
}
diff --git a/engine/classes/ODDDocument.php b/engine/classes/ODDDocument.php
index 4d185aba5..540c35a3b 100644
--- a/engine/classes/ODDDocument.php
+++ b/engine/classes/ODDDocument.php
@@ -70,8 +70,8 @@ class ODDDocument implements Iterator {
public function addElement(ODD $element) {
if (!is_array($this->elements)) {
$this->elements = array();
- $this->elements[] = $element;
}
+ $this->elements[] = $element;
}
/**
diff --git a/engine/classes/ODDEntity.php b/engine/classes/ODDEntity.php
index ab3a49168..e9bb5da6a 100644
--- a/engine/classes/ODDEntity.php
+++ b/engine/classes/ODDEntity.php
@@ -32,75 +32,3 @@ class ODDEntity extends ODD {
return "entity";
}
}
-
-/**
- * ODD Metadata class.
- *
- * @package Elgg.Core
- * @subpackage ODD
- */
-class ODDMetaData extends ODD {
-
- /**
- * New ODD metadata
- *
- * @param unknown_type $uuid Unique ID
- * @param unknown_type $entity_uuid Another unique ID
- * @param unknown_type $name Name
- * @param unknown_type $value Value
- * @param unknown_type $type Type
- * @param unknown_type $owner_uuid Owner ID
- */
- function __construct($uuid, $entity_uuid, $name, $value, $type = "", $owner_uuid = "") {
- parent::__construct();
-
- $this->setAttribute('uuid', $uuid);
- $this->setAttribute('entity_uuid', $entity_uuid);
- $this->setAttribute('name', $name);
- $this->setAttribute('type', $type);
- $this->setAttribute('owner_uuid', $owner_uuid);
- $this->setBody($value);
- }
-
- /**
- * Returns 'metadata'
- *
- * @return 'metadata'
- */
- protected function getTagName() {
- return "metadata";
- }
-}
-
-/**
- * ODD Relationship class.
- *
- * @package Elgg
- * @subpackage Core
- */
-class ODDRelationship extends ODD {
-
- /**
- * New ODD Relationship
- *
- * @param unknown_type $uuid1 First UUID
- * @param unknown_type $type Type of telationship
- * @param unknown_type $uuid2 Second UUId
- */
- function __construct($uuid1, $type, $uuid2) {
- parent::__construct();
-
- $this->setAttribute('uuid1', $uuid1);
- $this->setAttribute('type', $type);
- $this->setAttribute('uuid2', $uuid2);
- }
-
- /**
- * Returns 'relationship'
- *
- * @return 'relationship'
- */
- protected function getTagName() {
- return "relationship";
- }
-}
diff --git a/engine/classes/ODDMetaData.php b/engine/classes/ODDMetaData.php
new file mode 100644
index 000000000..58862e0fb
--- /dev/null
+++ b/engine/classes/ODDMetaData.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * ODD Metadata class.
+ *
+ * @package Elgg.Core
+ * @subpackage ODD
+ */
+class ODDMetaData extends ODD {
+
+ /**
+ * New ODD metadata
+ *
+ * @param unknown_type $uuid Unique ID
+ * @param unknown_type $entity_uuid Another unique ID
+ * @param unknown_type $name Name
+ * @param unknown_type $value Value
+ * @param unknown_type $type Type
+ * @param unknown_type $owner_uuid Owner ID
+ */
+ function __construct($uuid, $entity_uuid, $name, $value, $type = "", $owner_uuid = "") {
+ parent::__construct();
+
+ $this->setAttribute('uuid', $uuid);
+ $this->setAttribute('entity_uuid', $entity_uuid);
+ $this->setAttribute('name', $name);
+ $this->setAttribute('type', $type);
+ $this->setAttribute('owner_uuid', $owner_uuid);
+ $this->setBody($value);
+ }
+
+ /**
+ * Returns 'metadata'
+ *
+ * @return 'metadata'
+ */
+ protected function getTagName() {
+ return "metadata";
+ }
+}
diff --git a/engine/classes/ODDRelationship.php b/engine/classes/ODDRelationship.php
new file mode 100644
index 000000000..2906b1c73
--- /dev/null
+++ b/engine/classes/ODDRelationship.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * ODD Relationship class.
+ *
+ * @package Elgg
+ * @subpackage Core
+ */
+class ODDRelationship extends ODD {
+
+ /**
+ * New ODD Relationship
+ *
+ * @param unknown_type $uuid1 First UUID
+ * @param unknown_type $type Type of telationship
+ * @param unknown_type $uuid2 Second UUId
+ */
+ function __construct($uuid1, $type, $uuid2) {
+ parent::__construct();
+
+ $this->setAttribute('uuid1', $uuid1);
+ $this->setAttribute('type', $type);
+ $this->setAttribute('uuid2', $uuid2);
+ }
+
+ /**
+ * Returns 'relationship'
+ *
+ * @return 'relationship'
+ */
+ protected function getTagName() {
+ return "relationship";
+ }
+}
diff --git a/engine/classes/SuccessResult.php b/engine/classes/SuccessResult.php
index c8578a2cf..ab5468ad8 100644
--- a/engine/classes/SuccessResult.php
+++ b/engine/classes/SuccessResult.php
@@ -15,7 +15,7 @@ class SuccessResult extends GenericResult {
*
* @param string $result The result
*/
- public function SuccessResult($result) {
+ public function __construct($result) {
$this->setResult($result);
$this->setStatusCode(SuccessResult::$RESULT_SUCCESS);
}
diff --git a/engine/classes/XMLRPCCall.php b/engine/classes/XMLRPCCall.php
index 8eeba0c29..fd28f1e3e 100644
--- a/engine/classes/XMLRPCCall.php
+++ b/engine/classes/XMLRPCCall.php
@@ -18,7 +18,7 @@ class XMLRPCCall {
* @param string $xml XML
*/
function __construct($xml) {
- $this->_parse($xml);
+ $this->parse($xml);
}
/**
@@ -45,7 +45,7 @@ class XMLRPCCall {
*
* @return void
*/
- private function _parse($xml) {
+ private function parse($xml) {
$xml = xml_to_object($xml);
// sanity check
diff --git a/engine/handlers/cache_handler.php b/engine/handlers/cache_handler.php
index 94a0e64e9..b332ec379 100644
--- a/engine/handlers/cache_handler.php
+++ b/engine/handlers/cache_handler.php
@@ -60,26 +60,31 @@ preg_match($regex, $request, $matches);
$type = $matches[1];
$viewtype = $matches[2];
$view = $matches[3];
+$ts = $matches[4];
+
+// If is the same ETag, content didn't changed.
+$etag = $ts;
+if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
+ header("HTTP/1.1 304 Not Modified");
+ exit;
+}
switch ($type) {
case 'css':
header("Content-type: text/css", true);
- header('Expires: ' . date('r', strtotime("+6 months")), true);
- header("Pragma: public", true);
- header("Cache-Control: public", true);
-
$view = "css/$view";
break;
case 'js':
header('Content-type: text/javascript', true);
- header('Expires: ' . date('r', strtotime("+6 months")), true);
- header("Pragma: public", true);
- header("Cache-Control: public", true);
-
$view = "js/$view";
break;
}
+header('Expires: ' . date('r', strtotime("+6 months")), true);
+header("Pragma: public", true);
+header("Cache-Control: public", true);
+header("ETag: $etag");
+
$filename = $dataroot . 'views_simplecache/' . md5($viewtype . $view);
if (file_exists($filename)) {
diff --git a/engine/handlers/export_handler.php b/engine/handlers/export_handler.php
index b91a037e8..aa5214c23 100644
--- a/engine/handlers/export_handler.php
+++ b/engine/handlers/export_handler.php
@@ -72,8 +72,10 @@ if (($guid != "") && ($type == "") && ($id_or_name == "")) {
$r = get_relationship($id_or_name);
break;
case 'volatile' :
- $m = elgg_trigger_plugin_hook('volatile', 'metadata',
- array('guid' => $guid, 'varname' => $id_or_name));
+ $m = elgg_trigger_plugin_hook('volatile', 'metadata', array(
+ 'guid' => $guid,
+ 'varname' => $id_or_name,
+ ));
break;
default :
diff --git a/engine/lib/access.php b/engine/lib/access.php
index 08b9283cd..e8b3b0d52 100644
--- a/engine/lib/access.php
+++ b/engine/lib/access.php
@@ -31,7 +31,7 @@ function get_access_list($user_id = 0, $site_id = 0, $flush = false) {
global $CONFIG, $init_finished;
static $access_list;
- if (!isset($access_list) || !$init_finished) {
+ if (!isset($access_list)) {
$access_list = array();
}
@@ -49,9 +49,16 @@ function get_access_list($user_id = 0, $site_id = 0, $flush = false) {
return $access_list[$user_id];
}
- $access_list[$user_id] = "(" . implode(",", get_access_array($user_id, $site_id, $flush)) . ")";
+ $access = "(" . implode(",", get_access_array($user_id, $site_id, $flush)) . ")";
- return $access_list[$user_id];
+ // only cache if done with init and access is enabled (unless admin user)
+ // session is loaded before init is finished, so don't need to check for user session
+ if ($init_finished && (elgg_is_admin_logged_in() || !elgg_get_ignore_access())) {
+ $access_list[$user_id] = $access;
+ return $access_list[$user_id];
+ } else {
+ return $access;
+ }
}
/**
@@ -83,7 +90,7 @@ function get_access_array($user_id = 0, $site_id = 0, $flush = false) {
// this cache might be redundant. But db cache is flushed on every db write.
static $access_array;
- if (!isset($access_array) || (!isset($init_finished)) || (!$init_finished)) {
+ if (!isset($access_array)) {
$access_array = array();
}
@@ -137,12 +144,12 @@ function get_access_array($user_id = 0, $site_id = 0, $flush = false) {
$tmp_access_array[] = ACCESS_PRIVATE;
}
- $access_array[$user_id] = $tmp_access_array;
- } else {
- // No user id logged in so we can only access public info
- $tmp_return = $tmp_access_array;
+ // only cache if done with init and access is enabled (unless admin user)
+ // session is loaded before init is finished, so don't need to check for user session
+ if ($init_finished && (elgg_is_admin_logged_in() || !elgg_get_ignore_access())) {
+ $access_array[$user_id] = $tmp_access_array;
+ }
}
-
} else {
$tmp_access_array = $access_array[$user_id];
}
@@ -671,8 +678,10 @@ function add_user_to_access_collection($user_guid, $collection_id) {
return false;
}
+ // if someone tries to insert the same data twice, we do a no-op on duplicate key
$q = "INSERT INTO {$CONFIG->dbprefix}access_collection_membership
- SET access_collection_id = {$collection_id}, user_guid = {$user_guid}";
+ SET access_collection_id = $collection_id, user_guid = $user_guid
+ ON DUPLICATE KEY UPDATE user_guid = user_guid";
$result = insert_data($q);
return $result !== false;
@@ -838,7 +847,7 @@ function elgg_list_entities_from_access_id(array $options = array()) {
*
* @param int $entity_access_id The entity's access id
*
- * @return string 'Public', 'Private', etc. or false if error.
+ * @return string 'Public', 'Private', etc.
* @since 1.7.0
* @todo I think this probably wants get_access_array() instead of get_write_access_array(),
* but those two functions return different types of arrays.
@@ -849,15 +858,12 @@ function get_readable_access_level($entity_access_id) {
//get the access level for object in readable string
$options = get_write_access_array();
- //@todo Really? Use array_key_exists()
- foreach ($options as $key => $option) {
- if ($key == $access) {
- $entity_acl = htmlentities($option, ENT_QUOTES, 'UTF-8');
- return $entity_acl;
- break;
- }
+ if (array_key_exists($access, $options)) {
+ return $options[$access];
}
- return false;
+
+ // return 'Limited' if the user does not have access to the access collection
+ return elgg_echo('access:limited:label');
}
/**
@@ -947,7 +953,8 @@ function elgg_get_access_object() {
*
* @global bool $init_finished
* @access private
- * @todo investigate why this is needed
+ * @todo This is required to tell the access system to start caching because
+ * calls are made while in ignore access mode and before the user is logged in.
*/
$init_finished = false;
@@ -987,9 +994,9 @@ function elgg_override_permissions($hook, $type, $value, $params) {
}
// don't do this so ignore access still works with no one logged in
-// if (!$user instanceof ElggUser) {
-// return false;
-// }
+ //if (!$user instanceof ElggUser) {
+ // return false;
+ //}
// check for admin
if ($user_guid && elgg_is_admin_user($user_guid)) {
@@ -1015,8 +1022,9 @@ function access_test($hook, $type, $value, $params) {
return $value;
}
-// This function will let us know when 'init' has finished
-elgg_register_event_handler('init', 'system', 'access_init', 9999);
+// Tell the access functions the system has booted, plugins are loaded,
+// and the user is logged in so it can start caching
+elgg_register_event_handler('ready', 'system', 'access_init');
// For overrided permissions
elgg_register_plugin_hook_handler('permissions_check', 'all', 'elgg_override_permissions');
diff --git a/engine/lib/actions.php b/engine/lib/actions.php
index f415842ab..3a7c02488 100644
--- a/engine/lib/actions.php
+++ b/engine/lib/actions.php
@@ -273,8 +273,19 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL)
} else if ($visibleerrors) {
register_error(elgg_echo('actiongatekeeper:tokeninvalid'));
}
- } else if ($visibleerrors) {
- register_error(elgg_echo('actiongatekeeper:missingfields'));
+ } else {
+ if (! empty($_SERVER['CONTENT_LENGTH']) && empty($_POST)) {
+ // The size of $_POST or uploaded file has exceed the size limit
+ $error_msg = elgg_trigger_plugin_hook('action_gatekeeper:upload_exceeded_msg', 'all', array(
+ 'post_size' => $_SERVER['CONTENT_LENGTH'],
+ 'visible_errors' => $visibleerrors,
+ ), elgg_echo('actiongatekeeper:uploadexceeded'));
+ } else {
+ $error_msg = elgg_echo('actiongatekeeper:missingfields');
+ }
+ if ($visibleerrors) {
+ register_error($error_msg);
+ }
}
return FALSE;
@@ -459,8 +470,7 @@ function ajax_forward_hook($hook, $type, $reason, $params) {
// however some browsers will not accept the JSON MIME type.
if (stripos($_SERVER['HTTP_ACCEPT'], 'application/json') === FALSE) {
header("Content-type: text/plain");
- }
- else {
+ } else {
header("Content-type: application/json");
}
diff --git a/engine/lib/admin.php b/engine/lib/admin.php
index a191d740b..b65d98c95 100644
--- a/engine/lib/admin.php
+++ b/engine/lib/admin.php
@@ -79,6 +79,10 @@ function elgg_add_admin_notice($id, $message) {
if (elgg_admin_notice_exists($id)) {
return false;
}
+
+ // need to handle when no one is logged in
+ $old_ia = elgg_set_ignore_access(true);
+
$admin_notice = new ElggObject();
$admin_notice->subtype = 'admin_notice';
// admins can see ACCESS_PRIVATE but no one else can.
@@ -86,13 +90,16 @@ function elgg_add_admin_notice($id, $message) {
$admin_notice->admin_notice_id = $id;
$admin_notice->description = $message;
- return $admin_notice->save();
+ $result = $admin_notice->save();
+
+ elgg_set_ignore_access($old_ia);
+
+ return (bool)$result;
}
- return FALSE;
+ return false;
}
-
/**
* Remove an admin notice by ID.
*
@@ -172,10 +179,10 @@ function elgg_admin_notice_exists($id) {
*
* This function handles registering the parent if it has not been registered.
*
- * @param string $section The menu section to add to
- * @param string $menu_id The unique ID of section
- * @param string $parent_id If a child section, the parent section id
- * @param int $priority The menu item priority
+ * @param string $section The menu section to add to
+ * @param string $menu_id The unique ID of section
+ * @param string $parent_id If a child section, the parent section id
+ * @param int $priority The menu item priority
*
* @return bool
* @since 1.8.0
@@ -237,6 +244,7 @@ function admin_init() {
elgg_register_action('profile/fields/delete', '', 'admin');
elgg_register_action('profile/fields/reorder', '', 'admin');
+ elgg_register_simplecache_view('css/admin');
elgg_register_simplecache_view('js/admin');
$url = elgg_get_simplecache_url('js', 'admin');
elgg_register_js('elgg.admin', $url);
@@ -255,6 +263,7 @@ function admin_init() {
// statistics
elgg_register_admin_menu_item('administer', 'statistics', null, 20);
elgg_register_admin_menu_item('administer', 'overview', 'statistics');
+ elgg_register_admin_menu_item('administer', 'server', 'statistics');
// users
elgg_register_admin_menu_item('administer', 'users', null, 20);
@@ -563,7 +572,7 @@ function admin_markdown_page_handler($pages) {
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');
+ echo elgg_view_page($error, $body, 'admin');
return true;
}
diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php
index bfd40d1e8..2036ccd61 100644
--- a/engine/lib/annotations.php
+++ b/engine/lib/annotations.php
@@ -95,8 +95,6 @@ $owner_guid = 0, $access_id = ACCESS_PRIVATE) {
$entity = get_entity($entity_guid);
if (elgg_trigger_event('annotate', $entity->type, $entity)) {
- system_log($entity, 'annotate');
-
// If ok then add it
$result = insert_data("INSERT into {$CONFIG->dbprefix}annotations
(entity_guid, name_id, value_id, value_type, owner_guid, time_created, access_id) VALUES
@@ -163,13 +161,9 @@ function update_annotation($annotation_id, $name, $value, $value_type, $owner_gu
where id=$annotation_id and $access");
if ($result !== false) {
+ // @todo add plugin hook that sends old and new annotation information before db access
$obj = elgg_get_annotation_from_id($annotation_id);
- if (elgg_trigger_event('update', 'annotation', $obj)) {
- return true;
- } else {
- // @todo add plugin hook that sends old and new annotation information before db access
- elgg_delete_annotation_by_id($annotation_id);
- }
+ elgg_trigger_event('update', 'annotation', $obj);
}
return $result;
@@ -183,21 +177,23 @@ function update_annotation($annotation_id, $name, $value, $value_type, $owner_gu
*
* @param array $options Array in format:
*
- * annotation_names => NULL|ARR Annotation names
- *
- * annotation_values => NULL|ARR Annotation values
- *
- * annotation_ids => NULL|ARR annotation ids
- *
- * annotation_case_sensitive => BOOL Overall Case sensitive
- *
- * annotation_owner_guids => NULL|ARR guids for annotation owners
+ * annotation_names => NULL|ARR Annotation names
+ * annotation_values => NULL|ARR Annotation values
+ * annotation_ids => NULL|ARR annotation ids
+ * annotation_case_sensitive => BOOL Overall Case sensitive
+ * annotation_owner_guids => NULL|ARR guids for annotation owners
+ * annotation_created_time_lower => INT Lower limit for created time.
+ * annotation_created_time_upper => INT Upper limit for created time.
+ * annotation_calculation => STR Perform the MySQL function on the annotation values returned.
+ * Do not confuse this "annotation_calculation" option with the
+ * "calculation" option to elgg_get_entities_from_annotation_calculation().
+ * The "annotation_calculation" option causes this function to
+ * return the result of performing a mathematical calculation on
+ * all annotations that match the query instead of ElggAnnotation
+ * objects.
+ * See the docs for elgg_get_entities_from_annotation_calculation()
+ * for the proper use of the "calculation" option.
*
- * annotation_created_time_lower => INT Lower limit for created time.
- *
- * annotation_created_time_upper => INT Upper limit for created time.
- *
- * annotation_calculation => STR Perform the MySQL function on the annotation values returned.
*
* @return mixed
* @since 1.8.0
@@ -211,9 +207,11 @@ function elgg_get_annotations(array $options = array()) {
* Deletes annotations based on $options.
*
* @warning Unlike elgg_get_annotations() this will not accept an empty options array!
+ * This requires at least one constraint: annotation_owner_guid(s),
+ * annotation_name(s), annotation_value(s), or guid(s) must be set.
*
* @param array $options An options array. {@See elgg_get_annotations()}
- * @return mixed
+ * @return mixed Null if the metadata name is invalid. Bool on success or fail.
* @since 1.8.0
*/
function elgg_delete_annotations(array $options) {
@@ -222,7 +220,7 @@ function elgg_delete_annotations(array $options) {
}
$options['metastring_type'] = 'annotations';
- return elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback');
+ return elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback', false);
}
/**
@@ -239,8 +237,8 @@ function elgg_disable_annotations(array $options) {
return false;
}
- $options['metastrings_type'] = 'annotations';
- return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback');
+ $options['metastring_type'] = 'annotations';
+ return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback', false);
}
/**
@@ -388,8 +386,14 @@ function elgg_list_entities_from_annotations($options = array()) {
* Get entities ordered by a mathematical calculation on annotation values
*
* @param array $options An options array:
- * 'annotation_calculation' => The calculation to use. Must be a valid MySQL function.
+ * 'calculation' => The calculation to use. Must be a valid MySQL function.
* Defaults to sum. Result selected as 'annotation_calculation'.
+ * Don't confuse this "calculation" option with the
+ * "annotation_calculation" option to elgg_get_annotations().
+ * This "calculation" option is applied to each entity's set of
+ * annotations and is selected as annotation_calculation for that row.
+ * See the docs for elgg_get_annotations() for proper use of the
+ * "annotation_calculation" option.
* 'order_by' => The order for the sorting. Defaults to 'annotation_calculation desc'.
* 'annotation_names' => The names of annotations on the entity.
* 'annotation_values' => The values of annotations on the entity.
@@ -545,8 +549,8 @@ function elgg_comment_url_handler(ElggAnnotation $comment) {
/**
* Register an annotation url handler.
*
- * @param string $function_name The function.
* @param string $extender_name The name, default 'all'.
+ * @param string $function_name The function.
*
* @return string
*/
diff --git a/engine/lib/cache.php b/engine/lib/cache.php
index a6ebe2a30..be1c43e14 100644
--- a/engine/lib/cache.php
+++ b/engine/lib/cache.php
@@ -10,15 +10,14 @@
/* Filepath Cache */
/**
- * Returns an ElggCache object suitable for caching view
- * file load paths to disk under $CONFIG->dataroot.
+ * Returns an ElggCache object suitable for caching system information
*
* @todo Can this be done in a cleaner way?
* @todo Swap to memcache etc?
*
- * @return ElggFileCache A cache object suitable for caching file load paths.
+ * @return ElggFileCache
*/
-function elgg_get_filepath_cache() {
+function elgg_get_system_cache() {
global $CONFIG;
/**
@@ -27,35 +26,34 @@ function elgg_get_filepath_cache() {
static $FILE_PATH_CACHE;
if (!$FILE_PATH_CACHE) {
- $FILE_PATH_CACHE = new ElggFileCache($CONFIG->dataroot);
+ $FILE_PATH_CACHE = new ElggFileCache($CONFIG->dataroot . 'system_cache/');
}
return $FILE_PATH_CACHE;
}
/**
- * Function which resets the file path cache.
+ * Reset the system cache by deleting the caches
*
+ * @return void
*/
-function elgg_filepath_cache_reset() {
- $cache = elgg_get_filepath_cache();
- $view_types_result = $cache->delete('view_types');
- $views_result = $cache->delete('views');
- return $view_types_result && $views_result;
+function elgg_reset_system_cache() {
+ $cache = elgg_get_system_cache();
+ $cache->clear();
}
/**
- * Saves a filepath cache.
+ * Saves a system cache.
*
- * @param string $type
- * @param string $data
+ * @param string $type The type or identifier of the cache
+ * @param string $data The data to be saved
* @return bool
*/
-function elgg_filepath_cache_save($type, $data) {
+function elgg_save_system_cache($type, $data) {
global $CONFIG;
- if ($CONFIG->viewpath_cache_enabled) {
- $cache = elgg_get_filepath_cache();
+ if ($CONFIG->system_cache_enabled) {
+ $cache = elgg_get_system_cache();
return $cache->save($type, $data);
}
@@ -63,16 +61,16 @@ function elgg_filepath_cache_save($type, $data) {
}
/**
- * Retrieve the contents of the filepath cache.
+ * Retrieve the contents of a system cache.
*
* @param string $type The type of cache to load
* @return string
*/
-function elgg_filepath_cache_load($type) {
+function elgg_load_system_cache($type) {
global $CONFIG;
- if ($CONFIG->viewpath_cache_enabled) {
- $cache = elgg_get_filepath_cache();
+ if ($CONFIG->system_cache_enabled) {
+ $cache = elgg_get_system_cache();
$cached_data = $cache->load($type);
if ($cached_data) {
@@ -84,35 +82,74 @@ function elgg_filepath_cache_load($type) {
}
/**
- * Enables the views file paths disk cache.
+ * Enables the system disk cache.
*
- * Uses the 'viewpath_cache_enabled' datalist with a boolean value.
- * Resets the views paths cache.
+ * Uses the 'system_cache_enabled' datalist with a boolean value.
+ * Resets the system cache.
*
* @return void
*/
-function elgg_enable_filepath_cache() {
+function elgg_enable_system_cache() {
global $CONFIG;
- datalist_set('viewpath_cache_enabled', 1);
- $CONFIG->viewpath_cache_enabled = 1;
- elgg_filepath_cache_reset();
+ datalist_set('system_cache_enabled', 1);
+ $CONFIG->system_cache_enabled = 1;
+ elgg_reset_system_cache();
}
/**
- * Disables the views file paths disk cache.
+ * Disables the system disk cache.
*
- * Uses the 'viewpath_cache_enabled' datalist with a boolean value.
- * Resets the views paths cache.
+ * Uses the 'system_cache_enabled' datalist with a boolean value.
+ * Resets the system cache.
*
* @return void
*/
-function elgg_disable_filepath_cache() {
+function elgg_disable_system_cache() {
global $CONFIG;
- datalist_set('viewpath_cache_enabled', 0);
- $CONFIG->viewpath_cache_enabled = 0;
- elgg_filepath_cache_reset();
+ datalist_set('system_cache_enabled', 0);
+ $CONFIG->system_cache_enabled = 0;
+ elgg_reset_system_cache();
+}
+
+/** @todo deprecate in Elgg 1.9 **/
+
+/**
+ * @access private
+ */
+function elgg_get_filepath_cache() {
+ return elgg_get_system_cache();
+}
+/**
+ * @access private
+ */
+function elgg_filepath_cache_reset() {
+ return elgg_reset_system_cache();
+}
+/**
+ * @access private
+ */
+function elgg_filepath_cache_save($type, $data) {
+ return elgg_save_system_cache($type, $data);
+}
+/**
+ * @access private
+ */
+function elgg_filepath_cache_load($type) {
+ return elgg_load_system_cache($type);
+}
+/**
+ * @access private
+ */
+function elgg_enable_filepath_cache() {
+ return elgg_enable_system_cache();
+}
+/**
+ * @access private
+ */
+function elgg_disable_filepath_cache() {
+ return elgg_disable_system_cache();
}
/* Simplecache */
@@ -332,7 +369,7 @@ function elgg_invalidate_simplecache() {
$return = true;
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
- $return = $return && unlink($CONFIG->dataroot . 'views_simplecache/' . $file);
+ $return &= unlink($CONFIG->dataroot . 'views_simplecache/' . $file);
}
}
closedir($handle);
@@ -345,9 +382,71 @@ function elgg_invalidate_simplecache() {
}
foreach ($viewtypes as $viewtype) {
- $return = $return && datalist_set("simplecache_lastupdate_$viewtype", 0);
- $return = $return && datalist_set("simplecache_lastcached_$viewtype", 0);
+ $return &= datalist_set("simplecache_lastupdate_$viewtype", 0);
+ $return &= datalist_set("simplecache_lastcached_$viewtype", 0);
}
return $return;
}
+
+/**
+ * @see elgg_reset_system_cache()
+ * @access private
+ */
+function _elgg_load_cache() {
+ global $CONFIG;
+
+ $CONFIG->system_cache_loaded = false;
+
+ $CONFIG->views = new stdClass();
+ $data = elgg_load_system_cache('view_locations');
+ if (!is_string($data)) {
+ return;
+ }
+ $CONFIG->views->locations = unserialize($data);
+
+ $data = elgg_load_system_cache('view_types');
+ if (!is_string($data)) {
+ return;
+ }
+ $CONFIG->view_types = unserialize($data);
+
+ $CONFIG->system_cache_loaded = true;
+}
+
+/**
+ * @access private
+ */
+function _elgg_cache_init() {
+ global $CONFIG;
+
+ $viewtype = elgg_get_viewtype();
+
+ // Regenerate the simple cache if expired.
+ // Don't do it on upgrade because upgrade does it itself.
+ // @todo - move into function and perhaps run off init system event
+ if (!defined('UPGRADING')) {
+ $lastupdate = datalist_get("simplecache_lastupdate_$viewtype");
+ $lastcached = datalist_get("simplecache_lastcached_$viewtype");
+ if ($lastupdate == 0 || $lastcached < $lastupdate) {
+ elgg_regenerate_simplecache($viewtype);
+ $lastcached = datalist_get("simplecache_lastcached_$viewtype");
+ }
+ $CONFIG->lastcache = $lastcached;
+ }
+
+ // cache system data if enabled and not loaded
+ if ($CONFIG->system_cache_enabled && !$CONFIG->system_cache_loaded) {
+ elgg_save_system_cache('view_locations', serialize($CONFIG->views->locations));
+ elgg_save_system_cache('view_types', serialize($CONFIG->view_types));
+ }
+
+ if ($CONFIG->system_cache_enabled && !$CONFIG->i18n_loaded_from_cache) {
+ reload_all_translations();
+ foreach ($CONFIG->translations as $lang => $map) {
+ elgg_save_system_cache("$lang.php", serialize($map));
+ }
+ }
+}
+
+elgg_register_event_handler('ready', 'system', '_elgg_cache_init');
diff --git a/engine/lib/configuration.php b/engine/lib/configuration.php
index 615063f3d..305aa00b6 100644
--- a/engine/lib/configuration.php
+++ b/engine/lib/configuration.php
@@ -3,8 +3,9 @@
* Elgg configuration procedural code.
*
* Includes functions for manipulating the configuration values stored in the database
- * Plugin authors should use the {@link get_config()}, {@link set_config()},
- * and {@unset_config()} functions to access or update config values.
+ * Plugin authors should use the {@link elgg_get_config()}, {@link elgg_set_config()},
+ * {@link elgg_save_config()}, and {@unset_config()} functions to access or update
+ * config values.
*
* Elgg's configuration is split among 2 tables and 1 file:
* - dbprefix_config
@@ -302,7 +303,7 @@ function datalist_set($name, $value) {
. " set name = '{$sanitised_name}', value = '{$sanitised_value}'"
. " ON DUPLICATE KEY UPDATE value='{$sanitised_value}'");
- if ($success) {
+ if ($success !== FALSE) {
$DATALIST_CACHE[$name] = $value;
return true;
} else {
@@ -475,10 +476,12 @@ function get_config($name, $site_guid = 0) {
break;
}
+ // @todo these haven't really been implemented in Elgg 1.8. Complete in 1.9.
// show dep message
if ($new_name) {
+ // $msg = "Config value $name has been renamed as $new_name";
$name = $new_name;
- elgg_deprecated_notice($msg, $dep_version);
+ // elgg_deprecated_notice($msg, $dep_version);
}
// decide from where to return the value
@@ -517,10 +520,10 @@ function get_all_config($site_guid = 0) {
$site_guid = (int) $site_guid;
if ($site_guid == 0) {
- $site_guid = (int) $CONFIG->site_id;
+ $site_guid = (int) $CONFIG->site_guid;
}
- if ($result = get_data("SELECT * from {$CONFIG->dbprefix}config where site_guid = {$site_guid}")) {
+ if ($result = get_data("SELECT * FROM {$CONFIG->dbprefix}config WHERE site_guid = $site_guid")) {
foreach ($result as $r) {
$name = $r->name;
$value = $r->value;
@@ -533,37 +536,49 @@ function get_all_config($site_guid = 0) {
}
/**
- * Sets defaults for or attempts to autodetect some common config values and
- * loads them into $CONFIG.
+ * Loads configuration related to this site
*
- * @return true
+ * This loads from the config database table and the site entity
* @access private
*/
-function set_default_config() {
+function _elgg_load_site_config() {
global $CONFIG;
- $install_root = str_replace("\\", "/", dirname(dirname(dirname(__FILE__))));
-
- // @todo this seldom works right.
- $pathpart = str_replace("//", "/", str_replace($_SERVER['DOCUMENT_ROOT'], "", $install_root));
- if (substr($pathpart, 0, 1) != "/") {
- $pathpart = "/" . $pathpart;
+ $CONFIG->site_guid = (int) datalist_get('default_site');
+ $CONFIG->site_id = $CONFIG->site_guid;
+ $CONFIG->site = get_entity($CONFIG->site_guid);
+ if (!$CONFIG->site) {
+ throw new InstallationException(elgg_echo('InstallationException:SiteNotInstalled'));
}
- $www_root = "http://" . $_SERVER['HTTP_HOST'] . $pathpart;
+ $CONFIG->wwwroot = $CONFIG->site->url;
+ $CONFIG->sitename = $CONFIG->site->name;
+ $CONFIG->sitedescription = $CONFIG->site->description;
+ $CONFIG->siteemail = $CONFIG->site->email;
+ $CONFIG->url = $CONFIG->wwwroot;
+
+ get_all_config();
+}
+
+/**
+ * Loads configuration related to Elgg as an application
+ *
+ * This loads from the datalists database table
+ * @access private
+ */
+function _elgg_load_application_config() {
+ global $CONFIG;
+
+ $install_root = str_replace("\\", "/", dirname(dirname(dirname(__FILE__))));
$defaults = array(
'path' => "$install_root/",
'view_path' => "$install_root/views/",
'plugins_path' => "$install_root/mod/",
- 'wwwroot' => $www_root,
- 'url' => $www_root,
- 'site_name' => 'New Elgg site',
'language' => 'en',
- // compatibility with old names for ppl not using get_config()
+ // compatibility with old names for plugins not using elgg_get_config()
'viewpath' => "$install_root/views/",
'pluginspath' => "$install_root/mod/",
- 'sitename' => 'New Elgg site',
);
foreach ($defaults as $name => $value) {
@@ -572,25 +587,6 @@ function set_default_config() {
}
}
- $CONFIG->context = array();
-
- return true;
-}
-
-/**
- * Loads values into $CONFIG.
- *
- * If Elgg is installed, this function pulls all rows from dbprefix_config
- * and cherry picks some values from dbprefix_datalists. This also extracts
- * some commonly used values from the default site object.
- *
- * @elgg_event boot system
- * @return true|null
- * @access private
- */
-function configuration_boot() {
- global $CONFIG;
-
$path = datalist_get('path');
if (!empty($path)) {
$CONFIG->path = $path;
@@ -605,22 +601,23 @@ function configuration_boot() {
} else {
$CONFIG->simplecache_enabled = 1;
}
- $viewpath_cache_enabled = datalist_get('viewpath_cache_enabled');
- if ($viewpath_cache_enabled !== false) {
- $CONFIG->viewpath_cache_enabled = $viewpath_cache_enabled;
+ $system_cache_enabled = datalist_get('system_cache_enabled');
+ if ($system_cache_enabled !== false) {
+ $CONFIG->system_cache_enabled = $system_cache_enabled;
} else {
- $CONFIG->viewpath_cache_enabled = 1;
+ $CONFIG->system_cache_enabled = 1;
}
- if (isset($CONFIG->site) && ($CONFIG->site instanceof ElggSite)) {
- $CONFIG->wwwroot = $CONFIG->site->url;
- $CONFIG->sitename = $CONFIG->site->name;
- $CONFIG->sitedescription = $CONFIG->site->description;
- $CONFIG->siteemail = $CONFIG->site->email;
- }
- $CONFIG->url = $CONFIG->wwwroot;
- // Load default settings from database
- get_all_config();
-}
+ // initialize context here so it is set before the get_input call
+ $CONFIG->context = array();
+
+ // needs to be set before system, init for links in html head
+ $viewtype = get_input('view', 'default');
+ $lastcached = datalist_get("simplecache_lastcached_$viewtype");
+ $CONFIG->lastcache = $lastcached;
-elgg_register_event_handler('boot', 'system', 'configuration_boot', 10);
+ $CONFIG->i18n_loaded_from_cache = false;
+
+ // this must be synced with the enum for the entities table
+ $CONFIG->entity_types = array('group', 'object', 'site', 'user');
+}
diff --git a/engine/lib/database.php b/engine/lib/database.php
index c44fdf1fd..cc2b99f6a 100644
--- a/engine/lib/database.php
+++ b/engine/lib/database.php
@@ -189,22 +189,6 @@ function db_delayedexecution_shutdown_hook() {
}
/**
- * Registers shutdown functions for database profiling and delayed queries.
- *
- * @note Database connections are established upon first call to database.
- *
- * @return true
- * @elgg_event_handler boot system
- * @access private
- */
-function init_db() {
- register_shutdown_function('db_delayedexecution_shutdown_hook');
- register_shutdown_function('db_profiling_shutdown_hook');
-
- return true;
-}
-
-/**
* Returns (if required, also creates) a database link resource.
*
* Database link resources are stored in the {@link $dblink} global. These
@@ -728,9 +712,9 @@ function sanitize_string($string) {
/**
* Sanitises an integer for database use.
*
- * @param int $int Integer
- * @param bool[optional] $signed Whether negative values should be allowed (true)
- * @return int Sanitised integer
+ * @param int $int Value to be sanitized
+ * @param bool $signed Whether negative values should be allowed (true)
+ * @return int
*/
function sanitise_int($int, $signed = true) {
$int = (int) $int;
@@ -745,18 +729,25 @@ function sanitise_int($int, $signed = true) {
}
/**
- * Sanitises an integer for database use.
+ * Sanitizes an integer for database use.
* Wrapper function for alternate English spelling (@see sanitise_int)
*
- * @param int $int Integer
- * @param bool[optional] $signed Whether negative values should be allowed (true)
- * @return int Sanitised integer
+ * @param int $int Value to be sanitized
+ * @param bool $signed Whether negative values should be allowed (true)
+ * @return int
*/
function sanitize_int($int, $signed = true) {
return sanitise_int($int, $signed);
}
/**
- * @elgg_register_event boot system init_db
+ * Registers shutdown functions for database profiling and delayed queries.
+ *
+ * @access private
*/
-elgg_register_event_handler('boot', 'system', 'init_db', 0);
+function init_db() {
+ register_shutdown_function('db_delayedexecution_shutdown_hook');
+ register_shutdown_function('db_profiling_shutdown_hook');
+}
+
+elgg_register_event_handler('init', 'system', 'init_db');
diff --git a/engine/lib/deprecated-1.8.php b/engine/lib/deprecated-1.8.php
index e1866498b..4b9d41543 100644
--- a/engine/lib/deprecated-1.8.php
+++ b/engine/lib/deprecated-1.8.php
@@ -1674,7 +1674,7 @@ function get_plugin_list() {
* otherwise you may experience view display artifacts. Do this with the following code:
*
* elgg_regenerate_simplecache();
- * elgg_filepath_cache_reset();
+ * elgg_reset_system_cache();
*
* @deprecated 1.8 Use elgg_generate_plugin_entities() and elgg_set_plugin_priorities()
*
@@ -1841,7 +1841,7 @@ function get_installed_plugins($status = 'all') {
* otherwise you may experience view display artifacts. Do this with the following code:
*
* elgg_regenerate_simplecache();
- * elgg_filepath_cache_reset();
+ * elgg_reset_system_cache();
*
* @deprecated 1.8 Use ElggPlugin->activate()
*
@@ -1882,7 +1882,7 @@ function enable_plugin($plugin, $site_guid = null) {
* otherwise you may experience view display artifacts. Do this with the following code:
*
* elgg_regenerate_simplecache();
- * elgg_filepath_cache_reset();
+ * elgg_reset_system_cache();
*
* @deprecated 1.8 Use ElggPlugin->deactivate()
*
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index 57d602450..62cb2d5bb 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -995,7 +995,8 @@ function elgg_trigger_plugin_hook($hook, $type, $params = null, $returnvalue = n
* @access private
*/
function _elgg_php_exception_handler($exception) {
- error_log("*** FATAL EXCEPTION *** : " . $exception);
+ $timestamp = time();
+ error_log("Exception #$timestamp: $exception");
// Wipe any existing output buffer
ob_end_clean();
@@ -1011,7 +1012,17 @@ function _elgg_php_exception_handler($exception) {
$CONFIG->pagesetupdone = true;
elgg_set_viewtype('failsafe');
- $body = elgg_view("messages/exceptions/exception", array('object' => $exception));
+ if (elgg_is_admin_logged_in()) {
+ $body = elgg_view("messages/exceptions/admin_exception", array(
+ 'object' => $exception,
+ 'ts' => $timestamp
+ ));
+ } else {
+ $body = elgg_view("messages/exceptions/exception", array(
+ 'object' => $exception,
+ 'ts' => $timestamp
+ ));
+ }
echo elgg_view_page(elgg_echo('exception:title'), $body);
} catch (Exception $e) {
$timestamp = time();
@@ -1042,12 +1053,14 @@ function _elgg_php_exception_handler($exception) {
*
* @return true
* @access private
+ * @todo Replace error_log calls with elgg_log calls.
*/
function _elgg_php_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
$error = date("Y-m-d H:i:s (T)") . ": \"$errmsg\" in file $filename (line $linenum)";
switch ($errno) {
case E_USER_ERROR:
+ case E_RECOVERABLE_ERROR: // (e.g. type hint violation)
error_log("PHP ERROR: $error");
register_error("ERROR: $error");
@@ -1081,8 +1094,8 @@ function _elgg_php_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
*
* @note No messages will be displayed unless debugging has been enabled.
*
- * @param str $message User message
- * @param str $level NOTICE | WARNING | ERROR | DEBUG
+ * @param string $message User message
+ * @param string $level NOTICE | WARNING | ERROR | DEBUG
*
* @return bool
* @since 1.7.0
@@ -1144,9 +1157,11 @@ function elgg_dump($value, $to_screen = TRUE, $level = 'NOTICE') {
global $CONFIG;
// plugin can return false to stop the default logging method
- $params = array('level' => $level,
- 'msg' => $value,
- 'to_screen' => $to_screen);
+ $params = array(
+ 'level' => $level,
+ 'msg' => $value,
+ 'to_screen' => $to_screen,
+ );
if (!elgg_trigger_plugin_hook('debug', 'log', $params, true)) {
return;
}
@@ -1172,7 +1187,9 @@ function elgg_dump($value, $to_screen = TRUE, $level = 'NOTICE') {
*
* This function either displays or logs the deprecation message,
* depending upon the deprecation policies in {@link CODING.txt}.
- * Logged messages are sent with the level of 'WARNING'.
+ * Logged messages are sent with the level of 'WARNING'. Only admins
+ * get visual deprecation notices. When non-admins are logged in, the
+ * notices are sent to PHP's log through elgg_dump().
*
* A user-visual message will be displayed if $dep_version is greater
* than 1 minor releases lower than the current Elgg version, or at all
@@ -1183,11 +1200,12 @@ function elgg_dump($value, $to_screen = TRUE, $level = 'NOTICE') {
*
* @see CODING.txt
*
- * @param str $msg Message to log / display.
- * @param str $dep_version Human-readable *release* version: 1.7, 1.7.3
- * @param int $backtrace_level How many levels back to display the backtrace. Useful if calling from
- * functions that are called from other places (like elgg_view()). Set
- * to -1 for a full backtrace.
+ * @param string $msg Message to log / display.
+ * @param string $dep_version Human-readable *release* version: 1.7, 1.8, ...
+ * @param int $backtrace_level How many levels back to display the backtrace.
+ * Useful if calling from functions that are called
+ * from other places (like elgg_view()). Set to -1
+ * for a full backtrace.
*
* @return bool
* @since 1.7.0
@@ -1196,13 +1214,13 @@ function elgg_deprecated_notice($msg, $dep_version, $backtrace_level = 1) {
// if it's a major release behind, visual and logged
// if it's a 1 minor release behind, visual and logged
// if it's for current minor release, logged.
- // bugfixes don't matter because you're not deprecating between them, RIGHT?
+ // bugfixes don't matter because we are not deprecating between them
if (!$dep_version) {
- return FALSE;
+ return false;
}
- $elgg_version = get_version(TRUE);
+ $elgg_version = get_version(true);
$elgg_version_arr = explode('.', $elgg_version);
$elgg_major_version = (int)$elgg_version_arr[0];
$elgg_minor_version = (int)$elgg_version_arr[1];
@@ -1210,16 +1228,16 @@ function elgg_deprecated_notice($msg, $dep_version, $backtrace_level = 1) {
$dep_major_version = (int)$dep_version;
$dep_minor_version = 10 * ($dep_version - $dep_major_version);
- $visual = FALSE;
+ $visual = false;
if (($dep_major_version < $elgg_major_version) ||
($dep_minor_version < $elgg_minor_version)) {
- $visual = TRUE;
+ $visual = true;
}
$msg = "Deprecated in $dep_major_version.$dep_minor_version: $msg";
- if ($visual) {
+ if ($visual && elgg_is_admin_logged_in()) {
register_error($msg);
}
@@ -1247,9 +1265,9 @@ function elgg_deprecated_notice($msg, $dep_version, $backtrace_level = 1) {
$msg .= implode("<br /> -> ", $stack);
- elgg_log($msg, 'WARNING');
+ elgg_dump($msg, elgg_is_admin_logged_in(), 'WARNING');
- return TRUE;
+ return true;
}
/**
@@ -1772,6 +1790,12 @@ function elgg_ajax_page_handler($page) {
unset($page[0]);
$view = implode('/', $page);
+ $allowed_views = elgg_get_config('allowed_ajax_views');
+ if (!array_key_exists($view, $allowed_views)) {
+ header('HTTP/1.1 403 Forbidden');
+ exit;
+ }
+
// pull out GET parameters through filter
$vars = array();
foreach ($_GET as $name => $value) {
@@ -1948,7 +1972,7 @@ function elgg_is_valid_options_for_batch_operation($options, $type) {
// at least one of these is required.
$required = array(
// generic restraints
- 'guid', 'guids', 'limit'
+ 'guid', 'guids'
);
switch ($type) {
@@ -1992,17 +2016,31 @@ function elgg_is_valid_options_for_batch_operation($options, $type) {
*
* @link http://docs.elgg.org/Tutorials/WalledGarden
* @elgg_plugin_hook index system
+ *
+ * @param string $hook The name of the hook
+ * @param string $type The type of hook
+ * @param bool $value Has a plugin already rendered an index page?
+ * @param array $params Array of parameters (should be empty)
* @return bool
* @access private
*/
-function elgg_walled_garden_index() {
- elgg_register_css('elgg.walled_garden', '/css/walled_garden.css');
+function elgg_walled_garden_index($hook, $type, $value, $params) {
+ if ($value) {
+ // do not create a second index page so return
+ return;
+ }
+
elgg_load_css('elgg.walled_garden');
- elgg_register_js('elgg.walled_garden', '/js/walled_garden.js');
elgg_load_js('elgg.walled_garden');
- $body = elgg_view('core/walled_garden/body');
+ $content = elgg_view('core/walled_garden/login');
+ $params = array(
+ 'content' => $content,
+ 'class' => 'elgg-walledgarden-double',
+ 'id' => 'elgg-walledgarden-login',
+ );
+ $body = elgg_view_layout('walled_garden', $params);
echo elgg_view_page('', $body, 'walled_garden');
// return true to prevent other plugins from adding a front page
@@ -2010,6 +2048,24 @@ function elgg_walled_garden_index() {
}
/**
+ * Serve walled garden sections
+ *
+ * @param array $page Array of URL segments
+ * @return string
+ * @access private
+ */
+function _elgg_walled_garden_ajax_handler($page) {
+ $view = $page[0];
+ $params = array(
+ 'content' => elgg_view("core/walled_garden/$view"),
+ 'class' => 'elgg-walledgarden-single hidden',
+ 'id' => str_replace('_', '-', "elgg-walledgarden-$view"),
+ );
+ echo elgg_view_layout('walled_garden', $params);
+ return true;
+}
+
+/**
* Checks the status of the Walled Garden and forwards to a login page
* if required.
*
@@ -2026,6 +2082,11 @@ function elgg_walled_garden_index() {
function elgg_walled_garden() {
global $CONFIG;
+ elgg_register_css('elgg.walled_garden', '/css/walled_garden.css');
+ elgg_register_js('elgg.walled_garden', '/js/walled_garden.js');
+
+ elgg_register_page_handler('walled_garden', '_elgg_walled_garden_ajax_handler');
+
// check for external page view
if (isset($CONFIG->site) && $CONFIG->site instanceof ElggSite) {
$CONFIG->site->checkWalledGarden();
@@ -2033,6 +2094,38 @@ function elgg_walled_garden() {
}
/**
+ * Boots the engine
+ *
+ * 1. sets error handlers
+ * 2. connects to database
+ * 3. verifies the installation suceeded
+ * 4. loads application configuration
+ * 5. loads i18n data
+ * 6. loads site configuration
+ *
+ * @access private
+ */
+function _elgg_engine_boot() {
+ // Register the error handlers
+ set_error_handler('_elgg_php_error_handler');
+ set_exception_handler('_elgg_php_exception_handler');
+
+ setup_db_connections();
+
+ verify_installation();
+
+ _elgg_load_application_config();
+
+ _elgg_load_site_config();
+
+ _elgg_session_boot();
+
+ _elgg_load_cache();
+
+ _elgg_load_translations();
+}
+
+/**
* Elgg's main init.
*
* Handles core actions for comments, the JS pagehandler, and the shutdown function.
@@ -2058,6 +2151,7 @@ function elgg_init() {
elgg_register_js('jquery.easing', 'vendors/jquery/jquery.easing.1.3.packed.js');
elgg_register_js('elgg.avatar_cropper', 'js/lib/ui.avatar_cropper.js');
elgg_register_js('jquery.imgareaselect', 'vendors/jquery/jquery.imgareaselect-0.9.8/scripts/jquery.imgareaselect.min.js');
+ elgg_register_js('elgg.ui.river', 'js/lib/ui.river.js');
elgg_register_css('jquery.imgareaselect', 'vendors/jquery/jquery.imgareaselect-0.9.8/css/imgareaselect-deprecated.css');
@@ -2155,6 +2249,7 @@ define('REFERRER', -1);
define('REFERER', -1);
elgg_register_event_handler('init', 'system', 'elgg_init');
+elgg_register_event_handler('boot', 'system', '_elgg_engine_boot', 1);
elgg_register_plugin_hook_handler('unit_test', 'system', 'elgg_api_test');
elgg_register_event_handler('init', 'system', 'add_custom_menu_items', 1000);
diff --git a/engine/lib/entities.php b/engine/lib/entities.php
index daced6740..d950261a2 100644
--- a/engine/lib/entities.php
+++ b/engine/lib/entities.php
@@ -331,7 +331,7 @@ function remove_subtype($type, $subtype) {
}
/**
- * Update a registered ElggEntity type, subtype, and classname
+ * Update a registered ElggEntity type, subtype, and class name
*
* @param string $type Type
* @param string $subtype Subtype
@@ -340,7 +340,7 @@ function remove_subtype($type, $subtype) {
* @return bool
*/
function update_subtype($type, $subtype, $class = '') {
- global $CONFIG;
+ global $CONFIG, $SUBTYPE_CACHE;
if (!$id = get_subtype_id($type, $subtype)) {
return FALSE;
@@ -348,10 +348,16 @@ function update_subtype($type, $subtype, $class = '') {
$type = sanitise_string($type);
$subtype = sanitise_string($subtype);
- return update_data("UPDATE {$CONFIG->dbprefix}entity_subtypes
+ $result = update_data("UPDATE {$CONFIG->dbprefix}entity_subtypes
SET type = '$type', subtype = '$subtype', class = '$class'
WHERE id = $id
");
+
+ if ($result && isset($SUBTYPE_CACHE[$id])) {
+ $SUBTYPE_CACHE[$id]->class = $class;
+ }
+
+ return $result;
}
/**
@@ -738,6 +744,7 @@ function elgg_entity_exists($guid) {
* Joined with subtypes by AND. See below)
*
* subtypes => NULL|STR entity subtype (SQL: subtype IN ('subtype1', 'subtype2))
+ * Use ELGG_ENTITIES_NO_VALUE for no subtype.
*
* type_subtype_pairs => NULL|ARR (array('type' => 'subtype'))
* (type = '$type' AND subtype = '$subtype') pairs
@@ -923,7 +930,7 @@ function elgg_get_entities(array $options = array()) {
}
if ($options['limit']) {
- $limit = sanitise_int($options['limit']);
+ $limit = sanitise_int($options['limit'], false);
$offset = sanitise_int($options['offset'], false);
$query .= " LIMIT $offset, $limit";
}
@@ -960,8 +967,8 @@ function elgg_get_entity_type_subtype_where_sql($table, $types, $subtypes, $pair
return '';
}
- // these are the only valid types for entities in elgg as defined in the DB.
- $valid_types = array('object', 'user', 'group', 'site');
+ // these are the only valid types for entities in elgg
+ $valid_types = elgg_get_config('entity_types');
// pairs override
$wheres = array();
@@ -1378,34 +1385,33 @@ function disable_entity($guid, $reason = "", $recursive = true) {
}
if ($recursive) {
- // Temporary token overriding access controls
- // @todo Do this better.
- static $__RECURSIVE_DELETE_TOKEN;
- // Make it slightly harder to guess
- $__RECURSIVE_DELETE_TOKEN = md5(elgg_get_logged_in_user_guid());
-
- $sub_entities = get_data("SELECT * from {$CONFIG->dbprefix}entities
- WHERE container_guid=$guid
- or owner_guid=$guid
- or site_guid=$guid", 'entity_row_to_elggstar');
+ $hidden = 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
+ OR site_guid = $guid
+ ) AND enabled='yes'", 'entity_row_to_elggstar');
if ($sub_entities) {
foreach ($sub_entities as $e) {
+ add_entity_relationship($e->guid, 'disabled_with', $entity->guid);
$e->disable($reason);
}
}
-
- $__RECURSIVE_DELETE_TOKEN = null;
+ access_show_hidden_entities($hidden);
+ elgg_set_ignore_access($ia);
}
$entity->disableMetadata();
$entity->disableAnnotations();
- // relationships can't be disabled. hope they join to the entities table.
- //$entity->disableRelationships();
$res = update_data("UPDATE {$CONFIG->dbprefix}entities
- set enabled='no'
- where guid={$guid}");
+ SET enabled = 'no'
+ WHERE guid = $guid");
return $res;
}
@@ -1420,40 +1426,52 @@ function disable_entity($guid, $reason = "", $recursive = true) {
* @warning In order to enable an entity using ElggEntity::enable(),
* you must first use {@link access_show_hidden_entities()}.
*
- * @param int $guid GUID of entity to enable
+ * @param int $guid GUID of entity to enable
+ * @param bool $recursive Recursively enable all entities disabled with the entity?
*
* @return bool
*/
-function enable_entity($guid) {
+function enable_entity($guid, $recursive = true) {
global $CONFIG;
$guid = (int)$guid;
// Override access only visible entities
- $access_status = access_get_show_hidden_status();
+ $old_access_status = access_get_show_hidden_status();
access_show_hidden_entities(true);
+ $result = false;
if ($entity = get_entity($guid)) {
if (elgg_trigger_event('enable', $entity->type, $entity)) {
if ($entity->canEdit()) {
- access_show_hidden_entities($access_status);
-
$result = update_data("UPDATE {$CONFIG->dbprefix}entities
- set enabled='yes'
- where guid={$guid}");
+ SET enabled = 'yes'
+ WHERE guid = $guid");
$entity->deleteMetadata('disable_reason');
$entity->enableMetadata();
$entity->enableAnnotations();
- return $result;
+ if ($recursive) {
+ $disabled_with_it = elgg_get_entities_from_relationship(array(
+ 'relationship' => 'disabled_with',
+ 'relationship_guid' => $entity->guid,
+ 'inverse_relationship' => true,
+ 'limit' => 0,
+ ));
+
+ foreach ($disabled_with_it as $e) {
+ $e->enable();
+ remove_entity_relationship($e->guid, 'disabled_with', $entity->guid);
+ }
+ }
}
}
}
- access_show_hidden_entities($access_status);
- return false;
+ access_show_hidden_entities($old_access_status);
+ return $result;
}
/**
@@ -1510,18 +1528,23 @@ 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
- or site_guid=$guid", 'entity_row_to_elggstar');
- if ($sub_entities) {
- foreach ($sub_entities as $e) {
- // check for equality so that an entity that is its own
- // owner or container does not cause infinite loop
- if ($e->guid != $guid) {
- $e->delete(true);
- }
- }
+
+ // @todo there was logic in the original code that ignored
+ // entities with owner or container guids of themselves.
+ // this should probably be prevented in ElggEntity instead of checked for here
+ $options = array(
+ 'wheres' => array(
+ "((container_guid = $guid OR owner_guid = $guid OR site_guid = $guid)"
+ . " AND guid != $guid)"
+ ),
+ 'limit' => 0
+ );
+
+ $batch = new ElggBatch('elgg_get_entities', $options);
+ $batch->setIncrementOffset(false);
+
+ foreach ($batch as $e) {
+ $e->delete(true);
}
access_show_hidden_entities($entity_disable_override);
@@ -1751,7 +1774,7 @@ function import_entity_plugin_hook($hook, $entity_type, $returnvalue, $params) {
if ($tmp) {
// Make sure its saved
if (!$tmp->save()) {
- elgg_echo('ImportException:ProblemSaving', array($element->getAttribute('uuid')));
+ $msg = elgg_echo('ImportException:ProblemSaving', array($element->getAttribute('uuid')));
throw new ImportException($msg);
}
@@ -1955,7 +1978,7 @@ function elgg_register_entity_type($type, $subtype = null) {
global $CONFIG;
$type = strtolower($type);
- if (!in_array($type, array('object', 'site', 'group', 'user'))) {
+ if (!in_array($type, $CONFIG->entity_types)) {
return FALSE;
}
@@ -1990,7 +2013,7 @@ function unregister_entity_type($type, $subtype) {
global $CONFIG;
$type = strtolower($type);
- if (!in_array($type, array('object', 'site', 'group', 'user'))) {
+ if (!in_array($type, $CONFIG->entity_types)) {
return FALSE;
}
@@ -2158,31 +2181,8 @@ function elgg_list_registered_entities(array $options = array()) {
$entities = array();
}
- return elgg_view_entity_list($entities, $count, $options['offset'],
- $options['limit'], $options['full_view'], $options['list_type_toggle'], $options['pagination']);
-}
-
-/**
- * Check the recursive delete permissions token.
- *
- * If an entity is deleted recursively, a permissions override is required to allow
- * contained or owned entities to be removed.
- *
- * @return bool
- * @elgg_plugin_hook_handler permissions_check all
- * @elgg_plugin_hook_handler permissions_check:metadata all
- * @access private
- */
-function recursive_delete_permissions_check() {
- static $__RECURSIVE_DELETE_TOKEN;
-
- if ((elgg_is_logged_in()) && ($__RECURSIVE_DELETE_TOKEN)
- && (strcmp($__RECURSIVE_DELETE_TOKEN, md5(elgg_get_logged_in_user_guid())))) {
- return true;
- }
-
- // consult next function
- return NULL;
+ $options['count'] = $count;
+ return elgg_view_entity_list($entities, $options);
}
/**
@@ -2299,11 +2299,6 @@ function entities_init() {
elgg_register_plugin_hook_handler('unit_test', 'system', 'entities_test');
- // Allow a permission override for recursive entity deletion
- // @todo Can this be done better?
- elgg_register_plugin_hook_handler('permissions_check', 'all', 'recursive_delete_permissions_check');
- elgg_register_plugin_hook_handler('permissions_check:metadata', 'all', 'recursive_delete_permissions_check');
-
elgg_register_plugin_hook_handler('gc', 'system', 'entities_gc');
}
@@ -2318,3 +2313,4 @@ elgg_register_plugin_hook_handler('volatile', 'metadata', 'volatile_data_export_
/** Register init system event **/
elgg_register_event_handler('init', 'system', 'entities_init');
+
diff --git a/engine/lib/extender.php b/engine/lib/extender.php
index 51fc62c30..43421342c 100644
--- a/engine/lib/extender.php
+++ b/engine/lib/extender.php
@@ -105,6 +105,7 @@ function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params)
// Save
if (!$entity->save()) {
+ $attr_name = $element->getAttribute('name');
$msg = elgg_echo('ImportException:ProblemUpdatingMeta', array($attr_name, $entity_uuid));
throw new ImportException($msg);
}
@@ -120,7 +121,7 @@ function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params)
* @param string $type 'metadata' or 'annotation'
* @param int $user_guid The GUID of the user
*
- * @return true|false
+ * @return bool
*/
function can_edit_extender($extender_id, $type, $user_guid = 0) {
if (!elgg_is_logged_in()) {
@@ -155,7 +156,7 @@ function can_edit_extender($extender_id, $type, $user_guid = 0) {
}
// Trigger plugin hooks
- $params = array('entity' => $entity, 'user' => $user);
+ $params = array('entity' => $extender->getEntity(), 'user' => $user);
return elgg_trigger_plugin_hook('permissions_check', $type, $params, false);
}
@@ -164,9 +165,9 @@ function can_edit_extender($extender_id, $type, $user_guid = 0) {
* It is recommended that you do not call this directly, instead use
* 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 ('annotation', 'metadata')
* @param string $extender_name The name of the extender
+ * @param string $function_name The function to register
*
* @return bool
*/
diff --git a/engine/lib/filestore.php b/engine/lib/filestore.php
index a13d8aa27..93a127257 100644
--- a/engine/lib/filestore.php
+++ b/engine/lib/filestore.php
@@ -18,7 +18,7 @@
*/
function get_dir_size($dir, $totalsize = 0) {
$handle = @opendir($dir);
- while ($file = @readdir ($handle)) {
+ while ($file = @readdir($handle)) {
if (eregi("^\.{1,2}$", $file)) {
continue;
}
@@ -149,6 +149,12 @@ $x1 = 0, $y1 = 0, $x2 = 0, $y2 = 0, $upscale = FALSE) {
return FALSE;
}
+ // color transparencies white (default is black)
+ imagefilledrectangle(
+ $new_image, 0, 0, $params['newwidth'], $params['newheight'],
+ imagecolorallocate($new_image, 255, 255, 255)
+ );
+
$rtn_code = imagecopyresampled( $new_image,
$original_image,
0,
diff --git a/engine/lib/group.php b/engine/lib/group.php
index 29330eeca..feb1f1e7f 100644
--- a/engine/lib/group.php
+++ b/engine/lib/group.php
@@ -261,16 +261,24 @@ function group_gatekeeper($forward = true) {
if ($group = elgg_get_page_owner_entity()) {
if ($group instanceof ElggGroup) {
$url = $group->getURL();
- if (
- ((!elgg_is_logged_in()) && (!$group->isPublicMembership())) ||
- ((!$group->isMember(elgg_get_logged_in_user_entity()) && (!$group->isPublicMembership())))
- ) {
- $allowed = false;
- }
+ if (!$group->isPublicMembership()) {
+ // closed group so must be member or an admin
+
+ if (!elgg_is_logged_in()) {
+ $allowed = false;
+ if ($forward == true) {
+ $_SESSION['last_forward_from'] = current_page_url();
+ register_error(elgg_echo('loggedinrequired'));
+ forward('', 'login');
+ }
+ } else if (!$group->isMember(elgg_get_logged_in_user_entity())) {
+ $allowed = false;
+ }
- // Admin override
- if (elgg_is_admin_logged_in()) {
- $allowed = true;
+ // Admin override
+ if (elgg_is_admin_logged_in()) {
+ $allowed = true;
+ }
}
}
}
diff --git a/engine/lib/input.php b/engine/lib/input.php
index 57e35786f..dda8211b6 100644
--- a/engine/lib/input.php
+++ b/engine/lib/input.php
@@ -188,8 +188,8 @@ function elgg_get_sticky_value($form_name, $variable = '', $default = NULL, $fil
/**
* Get all the values in a sticky form in an array
*
- * @param string $form_name The name of the form
- * @param bool $filter_result Filter for bad input if true
+ * @param string $form_name The name of the form
+ * @param bool $filter_result Filter for bad input if true
*
* @return array
* @since 1.8.0
diff --git a/engine/lib/languages.php b/engine/lib/languages.php
index 0400843af..15c48f902 100644
--- a/engine/lib/languages.php
+++ b/engine/lib/languages.php
@@ -8,6 +8,62 @@
*/
/**
+ * Given a message key, returns an appropriately translated full-text string
+ *
+ * @param string $message_key The short message code
+ * @param array $args An array of arguments to pass through vsprintf().
+ * @param string $language Optionally, the standard language code
+ * (defaults to site/user default, then English)
+ *
+ * @return string Either the translated string, the English string,
+ * or the original language string.
+ */
+function elgg_echo($message_key, $args = array(), $language = "") {
+ global $CONFIG;
+
+ static $CURRENT_LANGUAGE;
+
+ // old param order is deprecated
+ if (!is_array($args)) {
+ elgg_deprecated_notice(
+ 'As of Elgg 1.8, the 2nd arg to elgg_echo() is an array of string replacements and the 3rd arg is the language.',
+ 1.8
+ );
+
+ $language = $args;
+ $args = array();
+ }
+
+ if (!isset($CONFIG->translations)) {
+ // this means we probably had an exception before translations were initialized
+ register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
+ }
+
+ if (!$CURRENT_LANGUAGE) {
+ $CURRENT_LANGUAGE = get_language();
+ }
+ if (!$language) {
+ $language = $CURRENT_LANGUAGE;
+ }
+
+ if (isset($CONFIG->translations[$language][$message_key])) {
+ $string = $CONFIG->translations[$language][$message_key];
+ } else if (isset($CONFIG->translations["en"][$message_key])) {
+ $string = $CONFIG->translations["en"][$message_key];
+ } else {
+ $string = $message_key;
+ }
+
+ // only pass through if we have arguments to allow backward compatibility
+ // with manual sprintf() calls.
+ if ($args) {
+ $string = vsprintf($string, $args);
+ }
+
+ return $string;
+}
+
+/**
* Add a translation.
*
* Translations are arrays in the Zend Translation array format, eg:
@@ -82,56 +138,34 @@ function get_language() {
return false;
}
-/**
- * Given a message shortcode, returns an appropriately translated full-text string
- *
- * @param string $message_key The short message code
- * @param array $args An array of arguments to pass through vsprintf().
- * @param string $language Optionally, the standard language code
- * (defaults to site/user default, then English)
- *
- * @return string Either the translated string, the English string,
- * or the original language string.
- */
-function elgg_echo($message_key, $args = array(), $language = "") {
+function _elgg_load_translations() {
global $CONFIG;
- static $CURRENT_LANGUAGE;
-
- // old param order is deprecated
- if (!is_array($args)) {
- elgg_deprecated_notice(
- 'As of Elgg 1.8, the 2nd arg to elgg_echo() is an array of string replacements and the 3rd arg is the language.',
- 1.8
- );
-
- $language = $args;
- $args = array();
- }
+ if ($CONFIG->system_cache_enabled) {
+ $loaded = true;
+ $languages = array_unique(array('en', get_current_language()));
+ foreach ($languages as $language) {
+ $data = elgg_load_system_cache("$language.php");
+ if ($data) {
+ add_translation($language, unserialize($data));
+ } else {
+ $loaded = false;
+ }
+ }
- if (!$CURRENT_LANGUAGE) {
- $CURRENT_LANGUAGE = get_language();
- }
- if (!$language) {
- $language = $CURRENT_LANGUAGE;
+ if ($loaded) {
+ $CONFIG->i18n_loaded_from_cache = true;
+ // this is here to force
+ $CONFIG->language_paths[dirname(dirname(dirname(__FILE__))) . "/languages/"] = true;
+ return;
+ }
}
- if (isset($CONFIG->translations[$language][$message_key])) {
- $string = $CONFIG->translations[$language][$message_key];
- } else if (isset($CONFIG->translations["en"][$message_key])) {
- $string = $CONFIG->translations["en"][$message_key];
- } else {
- $string = $message_key;
- }
+ // load core translations from languages directory
+ register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
+}
- // only pass through if we have arguments to allow backward compatibility
- // with manual sprintf() calls.
- if ($args) {
- $string = vsprintf($string, $args);
- }
- return $string;
-}
/**
* When given a full path, finds translation files and loads them
@@ -307,9 +341,7 @@ function get_missing_language_keys($language) {
*/
function elgg_languages_init() {
$lang = get_current_language();
- elgg_register_simplecache_view("cache/js/languages/$lang");
+ elgg_register_simplecache_view("js/languages/$lang");
}
elgg_register_event_handler('init', 'system', 'elgg_languages_init');
-
-register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php
index 050e69526..0ff3a43dc 100644
--- a/engine/lib/metadata.php
+++ b/engine/lib/metadata.php
@@ -216,12 +216,11 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i
$result = update_data($query);
if ($result !== false) {
+ // @todo this event tells you the metadata has been updated, but does not
+ // let you do anything about it. What is needed is a plugin hook before
+ // the update that passes old and new values.
$obj = elgg_get_metadata_from_id($id);
- if (elgg_trigger_event('update', 'metadata', $obj)) {
- return true;
- } else {
- elgg_delete_metadata_by_id($id);
- }
+ elgg_trigger_event('update', 'metadata', $obj);
}
return $result;
@@ -270,21 +269,18 @@ $access_id = ACCESS_PRIVATE, $allow_multiple = false) {
*
* @param array $options Array in format:
*
- * metadata_names => NULL|ARR metadata names
- *
- * metadata_values => NULL|ARR metadata values
- *
-* metadata_ids => NULL|ARR metadata ids
- *
- * metadata_case_sensitive => BOOL Overall Case sensitive
- *
- * metadata_owner_guids => NULL|ARR guids for metadata owners
- *
- * metadata_created_time_lower => INT Lower limit for created time.
- *
- * metadata_created_time_upper => INT Upper limit for created time.
- *
- * metadata_calculation => STR Perform the MySQL function on the metadata values returned.
+ * metadata_names => NULL|ARR metadata names
+ * metadata_values => NULL|ARR metadata values
+ * metadata_ids => NULL|ARR metadata ids
+ * metadata_case_sensitive => BOOL Overall Case sensitive
+ * metadata_owner_guids => NULL|ARR guids for metadata owners
+ * metadata_created_time_lower => INT Lower limit for created time.
+ * metadata_created_time_upper => INT Upper limit for created time.
+ * metadata_calculation => STR Perform the MySQL function on the metadata values returned.
+ * The "metadata_calculation" option causes this function to
+ * return the result of performing a mathematical calculation on
+ * all metadata that match the query instead of returning
+ * ElggMetadata objects.
*
* @return mixed
* @since 1.8.0
@@ -298,11 +294,13 @@ function elgg_get_metadata(array $options = array()) {
* Deletes metadata based on $options.
*
* @warning Unlike elgg_get_metadata() this will not accept an empty options array!
- * This requires some constraints: metadata_owner_guid(s),
- * metadata_name(s), metadata_value(s), or limit must be set.
+ * This requires at least one constraint: metadata_owner_guid(s),
+ * metadata_name(s), metadata_value(s), or guid(s) must be set.
*
- * @param array $options An options array. {@See elgg_get_metadata()}
- * @return mixed
+ * @warning This returns null on no ops.
+ *
+ * @param array $options An options array. {@see elgg_get_metadata()}
+ * @return mixed Null if the metadata name is invalid. Bool on success or fail.
* @since 1.8.0
*/
function elgg_delete_metadata(array $options) {
@@ -311,7 +309,7 @@ function elgg_delete_metadata(array $options) {
}
$options['metastring_type'] = 'metadata';
- return elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback');
+ return elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback', false);
}
/**
@@ -319,6 +317,8 @@ function elgg_delete_metadata(array $options) {
*
* @warning Unlike elgg_get_metadata() this will not accept an empty options array!
*
+ * @warning This returns null on no ops.
+ *
* @param array $options An options array. {@See elgg_get_metadata()}
* @return mixed
* @since 1.8.0
@@ -328,8 +328,8 @@ function elgg_disable_metadata(array $options) {
return false;
}
- $options['metastrings_type'] = 'metadata';
- return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback');
+ $options['metastring_type'] = 'metadata';
+ return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback', false);
}
/**
@@ -337,6 +337,8 @@ function elgg_disable_metadata(array $options) {
*
* @warning Unlike elgg_get_metadata() this will not accept an empty options array!
*
+ * @warning This returns null on no ops.
+ *
* @param array $options An options array. {@See elgg_get_metadata()}
* @return mixed
* @since 1.8.0
@@ -403,15 +405,15 @@ function elgg_enable_metadata(array $options) {
*/
function elgg_get_entities_from_metadata(array $options = array()) {
$defaults = array(
- 'metadata_names' => ELGG_ENTITIES_ANY_VALUE,
- 'metadata_values' => ELGG_ENTITIES_ANY_VALUE,
- 'metadata_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE,
+ 'metadata_names' => ELGG_ENTITIES_ANY_VALUE,
+ 'metadata_values' => ELGG_ENTITIES_ANY_VALUE,
+ 'metadata_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE,
- 'metadata_name_value_pairs_operator'=> 'AND',
- 'metadata_case_sensitive' => TRUE,
- 'order_by_metadata' => array(),
+ 'metadata_name_value_pairs_operator' => 'AND',
+ 'metadata_case_sensitive' => TRUE,
+ 'order_by_metadata' => array(),
- 'metadata_owner_guids' => ELGG_ENTITIES_ANY_VALUE,
+ 'metadata_owner_guids' => ELGG_ENTITIES_ANY_VALUE,
);
$options = array_merge($defaults, $options);
@@ -634,7 +636,7 @@ $owner_guids = NULL) {
$i++;
}
- if ($where = implode (" $pair_operator ", $pair_wheres)) {
+ if ($where = implode(" $pair_operator ", $pair_wheres)) {
$wheres[] = "($where)";
}
}
@@ -749,7 +751,7 @@ function export_metadata_plugin_hook($hook, $entity_type, $returnvalue, $params)
/**
* Takes in a comma-separated string and returns an array of tags
- * which have been trimmed and set to lower case
+ * which have been trimmed
*
* @param string $string Comma-separated tag string
*
@@ -758,12 +760,7 @@ function export_metadata_plugin_hook($hook, $entity_type, $returnvalue, $params)
function string_to_tag_array($string) {
if (is_string($string)) {
$ar = explode(",", $string);
- // trim blank spaces
$ar = array_map('trim', $ar);
- // make lower case : [Marcus Povey 20090605 - Using mb wrapper function
- // using UTF8 safe function where available]
- $ar = array_map('elgg_strtolower', $ar);
- // Remove null values
$ar = array_filter($ar, 'is_not_null');
return $ar;
}
@@ -872,8 +869,8 @@ function metadata_update($event, $object_type, $object) {
/**
* Register a metadata url handler.
*
- * @param string $function_name The function.
* @param string $extender_name The name, default 'all'.
+ * @param string $function The function name.
*
* @return bool
*/
diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php
index 9fe9b4bff..cf6dd4d98 100644
--- a/engine/lib/metastrings.php
+++ b/engine/lib/metastrings.php
@@ -609,8 +609,7 @@ function elgg_get_metastring_sql($table, $names = null, $values = null,
}
/**
- * Normalizes metadata / annotation option names to their
- * corresponding metastrings name.
+ * Normalizes metadata / annotation option names to their corresponding metastrings name.
*
* @param array $options An options array
* @since 1.8.0
@@ -631,10 +630,10 @@ function elgg_normalize_metastrings_options(array $options = array()) {
// map the metadata_* options to metastring_* options
$map = array(
- 'names' => 'metastring_names',
- 'values' => 'metastring_values',
- 'case_sensitive' => 'metastring_case_sensitive',
- 'owner_guids' => 'metastring_owner_guids',
+ 'names' => 'metastring_names',
+ 'values' => 'metastring_values',
+ 'case_sensitive' => 'metastring_case_sensitive',
+ 'owner_guids' => 'metastring_owner_guids',
'created_time_lower' => 'metastring_created_time_lower',
'created_time_upper' => 'metastring_created_time_upper',
'calculation' => 'metastring_calculation',
@@ -717,21 +716,23 @@ function elgg_set_metastring_based_object_enabled_by_id($id, $enabled, $type) {
* @warning Unlike elgg_get_metastring_based_objects() this will not accept an
* empty options array!
*
- * @param array $options An options array. {@See elgg_get_metastring_based_objects()}
- * @param string $callback The callback to pass each result through
- * @return mixed
+ * @warning This returns null on no ops.
+ *
+ * @param array $options An options array. {@See elgg_get_metastring_based_objects()}
+ * @param string $callback The callback to pass each result through
+ * @param bool $inc_offset Increment the offset? Pass false for callbacks that delete / disable
+ *
+ * @return bool|null true on success, false on failure, null if no objects are found.
* @since 1.8.0
* @access private
*/
-function elgg_batch_metastring_based_objects(array $options, $callback) {
+function elgg_batch_metastring_based_objects(array $options, $callback, $inc_offset = true) {
if (!$options || !is_array($options)) {
return false;
}
- $batch = new ElggBatch('elgg_get_metastring_based_objects', $options, $callback);
- $r = $batch->callbackResult;
-
- return $r;
+ $batch = new ElggBatch('elgg_get_metastring_based_objects', $options, $callback, 50, $inc_offset);
+ return $batch->callbackResult;
}
/**
diff --git a/engine/lib/navigation.php b/engine/lib/navigation.php
index 956ca220a..4ff009bfb 100644
--- a/engine/lib/navigation.php
+++ b/engine/lib/navigation.php
@@ -78,7 +78,11 @@
* link_class => STR A class or classes for the <a> tag
* item_class => STR A class or classes for the <li> tag
*
- * Custom options can be added as key value pairs.
+ * Additional options that the view output/url takes can be
+ * passed in the array. If the 'confirm' key is passed, the
+ * menu link uses the 'output/confirmlink' view. Custom
+ * options can be added by using the 'data' key with the
+ * value being an associative array.
*
* @return bool
* @since 1.8.0
@@ -226,7 +230,7 @@ function elgg_pop_breadcrumb() {
global $CONFIG;
if (is_array($CONFIG->breadcrumbs)) {
- array_pop($CONFIG->breadcrumbs);
+ return array_pop($CONFIG->breadcrumbs);
}
return FALSE;
@@ -301,7 +305,7 @@ function elgg_site_menu_setup($hook, $type, $return, $params) {
// if only one item on more menu, stick it with the rest
$num_menu_items = count($return['default']);
if ($num_menu_items > ($max_display_items + 1)) {
- $return['more'] = array_splice($return['default'], $max_display_items);
+ $return['more'] = array_splice($return['default'], $max_display_items);
}
}
diff --git a/engine/lib/notification.php b/engine/lib/notification.php
index eb7e594c6..5a2f5f8ac 100644
--- a/engine/lib/notification.php
+++ b/engine/lib/notification.php
@@ -487,6 +487,7 @@ function object_notifications($event, $object_type, $object) {
// (Person defined by container_guid so we can also subscribe to groups if we want)
foreach ($NOTIFICATION_HANDLERS as $method => $foo) {
$interested_users = elgg_get_entities_from_relationship(array(
+ 'site_guids' => ELGG_ENTITIES_ANY_VALUE,
'relationship' => 'notify' . $method,
'relationship_guid' => $object->container_guid,
'inverse_relationship' => TRUE,
diff --git a/engine/lib/objects.php b/engine/lib/objects.php
index 63d0f5cef..f186c66cb 100644
--- a/engine/lib/objects.php
+++ b/engine/lib/objects.php
@@ -52,11 +52,8 @@ function create_object_entity($guid, $title, $description) {
if ($result != false) {
// Update succeeded, continue
$entity = get_entity($guid);
- if (elgg_trigger_event('update', $entity->type, $entity)) {
- return $guid;
- } else {
- $entity->delete();
- }
+ elgg_trigger_event('update', $entity->type, $entity);
+ return $guid;
}
} else {
// Update failed, attempt an insert.
diff --git a/engine/lib/output.php b/engine/lib/output.php
index 6554481f5..b1245a924 100644
--- a/engine/lib/output.php
+++ b/engine/lib/output.php
@@ -67,7 +67,7 @@ function autop($pee, $br = 1) {
$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end
$pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
$pee = preg_replace('!<p>([^<]+)\s*?(</(?:div|address|form)[^>]*>)!', "<p>$1</p>$2", $pee);
- $pee = preg_replace( '|<p>|', "$1<p>", $pee );
+ $pee = preg_replace('|<p>|', "$1<p>", $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
@@ -81,11 +81,11 @@ function autop($pee, $br = 1) {
}
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
-// if (strpos($pee, '<pre') !== false) {
-// mind the space between the ? and >. Only there because of the comment.
-// $pee = preg_replace_callback('!(<pre.*? >)(.*?)</pre>!is', 'clean_pre', $pee );
-// }
- $pee = preg_replace( "|\n</p>$|", '</p>', $pee );
+ //if (strpos($pee, '<pre') !== false) {
+ // mind the space between the ? and >. Only there because of the comment.
+ // $pee = preg_replace_callback('!(<pre.*? >)(.*?)</pre>!is', 'clean_pre', $pee );
+ //}
+ $pee = preg_replace("|\n</p>$|", '</p>', $pee);
return $pee;
}
@@ -310,15 +310,19 @@ function elgg_get_friendly_title($title) {
return $result;
}
+ // @todo not using this because of locale concerns
//$title = iconv('UTF-8', 'ASCII//TRANSLIT', $title);
+ // @todo this uses a utf8 character class. can use if
+ // we want to support utf8 in the url.
+ //$title = preg_replace('/[^\p{L}\- ]/u', '', $title);
+
// use A-Za-z0-9_ instead of \w because \w is locale sensitive
- $title = preg_replace("/[^A-Za-z0-9_ ]/", "", $title);
- $title = preg_replace("/[^\w ]/", "", $title);
+ $title = preg_replace("/[^A-Za-z0-9_\- ]/", "", $title);
$title = str_replace(" ", "-", $title);
$title = str_replace("--", "-", $title);
$title = trim($title);
- $title = strtolower($title);
+ $title = elgg_strtolower($title);
return $title;
}
diff --git a/engine/lib/pagehandler.php b/engine/lib/pagehandler.php
index ffcfc5b6a..46c7d059e 100644
--- a/engine/lib/pagehandler.php
+++ b/engine/lib/pagehandler.php
@@ -120,6 +120,7 @@ function elgg_unregister_page_handler($handler) {
* @param string $type The type of the hook
* @param bool $result The current value of the hook
* @param array $params Parameters related to the hook
+ * @return void
*/
function elgg_error_page_handler($hook, $type, $result, $params) {
if (elgg_view_exists("errors/$type")) {
@@ -128,7 +129,7 @@ function elgg_error_page_handler($hook, $type, $result, $params) {
$content = elgg_view("errors/default", $params);
}
$body = elgg_view_layout('error', array('content' => $content));
- echo elgg_view_page($title, $body, 'error');
+ echo elgg_view_page('', $body, 'error');
exit;
}
diff --git a/engine/lib/pageowner.php b/engine/lib/pageowner.php
index 9d41d74c1..0cf0e0625 100644
--- a/engine/lib/pageowner.php
+++ b/engine/lib/pageowner.php
@@ -54,7 +54,7 @@ function elgg_get_page_owner_entity() {
* Set the guid of the entity that owns this page
*
* @param int $guid The guid of the page owner
- *
+ * @return void
* @since 1.8.0
*/
function elgg_set_page_owner_guid($guid) {
@@ -173,7 +173,7 @@ function default_page_owner_handler($hook, $entity_type, $returnvalue, $params)
* @warning The context is not available until the page_handler runs (after
* the 'init, system' event processing has completed).
*
- * @param string $context The context of the page
+ * @param string $context The context of the page
* @return bool
* @since 1.8.0
*/
@@ -216,6 +216,7 @@ function elgg_get_context() {
* Push a context onto the top of the stack
*
* @param string $context The context string to add to the context stack
+ * @return void
* @since 1.8.0
*/
function elgg_push_context($context) {
@@ -244,7 +245,7 @@ function elgg_pop_context() {
* itself differently based on being on the dashboard or profile pages, it
* can check the stack.
*
- * @param string $context The context string to check for
+ * @param string $context The context string to check for
* @return bool
* @since 1.8.0
*/
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index be871d025..d5cd4fe76 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -62,7 +62,7 @@ function elgg_get_plugin_ids_in_dir($dir = null) {
$dir = elgg_get_plugins_path();
}
- $plugin_idss = array();
+ $plugin_ids = array();
$handle = opendir($dir);
if ($handle) {
@@ -93,10 +93,13 @@ function elgg_get_plugin_ids_in_dir($dir = null) {
function elgg_generate_plugin_entities() {
$site = get_config('site');
$dir = elgg_get_plugins_path();
+ $db_prefix = elgg_get_config('dbprefix');
$options = array(
'type' => 'object',
'subtype' => 'plugin',
+ 'selects' => array('plugin_oe.*'),
+ 'joins' => array("JOIN {$db_prefix}objects_entity plugin_oe on plugin_oe.guid = e.guid"),
'limit' => ELGG_ENTITIES_NO_VALUE
);
@@ -298,22 +301,20 @@ function elgg_load_plugins() {
// temporary disable all plugins if there is a file called 'disabled' in the plugin dir
if (file_exists("$plugins_path/disabled")) {
+ if (elgg_is_admin_logged_in() && elgg_in_context('admin')) {
+ system_message(elgg_echo('plugins:disabled'));
+ }
return false;
}
- // Load view caches if available
- $cached_view_paths = elgg_filepath_cache_load('views');
- $cached_view_types = elgg_filepath_cache_load('view_types');
- $cached_view_info = is_string($cached_view_paths) && is_string($cached_view_types);
-
- if ($cached_view_info) {
- $CONFIG->views = unserialize($cached_view_paths);
- $CONFIG->view_types = unserialize($cached_view_types);
-
- // don't need to register views
+ if (elgg_get_config('system_cache_loaded')) {
$start_flags = $start_flags & ~ELGG_PLUGIN_REGISTER_VIEWS;
}
+ if (elgg_get_config('i18n_loaded_from_cache')) {
+ $start_flags = $start_flags & ~ELGG_PLUGIN_REGISTER_LANGUAGES;
+ }
+
$return = true;
$plugins = elgg_get_plugins('active');
if ($plugins) {
@@ -332,12 +333,6 @@ function elgg_load_plugins() {
}
}
- // Cache results
- if (!$cached_view_info) {
- elgg_filepath_cache_save('views', serialize($CONFIG->views));
- elgg_filepath_cache_save('view_types', serialize($CONFIG->view_types));
- }
-
return $return;
}
@@ -364,7 +359,11 @@ function elgg_get_plugins($status = 'active', $site_guid = null) {
'type' => 'object',
'subtype' => 'plugin',
'limit' => ELGG_ENTITIES_NO_VALUE,
- 'joins' => array("JOIN {$db_prefix}private_settings ps on ps.entity_guid = e.guid"),
+ 'selects' => array('plugin_oe.*'),
+ 'joins' => array(
+ "JOIN {$db_prefix}private_settings ps on ps.entity_guid = e.guid",
+ "JOIN {$db_prefix}objects_entity plugin_oe on plugin_oe.guid = e.guid"
+ ),
'wheres' => array("ps.name = '$priority'"),
'order_by' => "CAST(ps.value as unsigned), e.guid"
);
@@ -439,9 +438,9 @@ function elgg_set_plugin_priorities(array $order) {
}
}
- // set the missing plugins priorities
+ // set the missing plugins' priorities
if ($return && $missing_plugins) {
- if (!$priority) {
+ if (!isset($priority)) {
$priority = 0;
}
foreach ($missing_plugins as $plugin) {
@@ -480,9 +479,10 @@ function elgg_reindex_plugin_priorities() {
*/
function elgg_namespace_plugin_private_setting($type, $name, $id = null) {
switch ($type) {
-// case 'setting':
-// $name = ELGG_PLUGIN_SETTING_PREFIX . $name;
-// break;
+ // commented out because it breaks $plugin->$name access to variables
+ //case 'setting':
+ // $name = ELGG_PLUGIN_SETTING_PREFIX . $name;
+ // break;
case 'user_setting':
if (!$id) {
diff --git a/engine/lib/private_settings.php b/engine/lib/private_settings.php
index 386af5279..1fa9bdb66 100644
--- a/engine/lib/private_settings.php
+++ b/engine/lib/private_settings.php
@@ -240,7 +240,7 @@ $pairs = NULL, $pair_operator = 'AND', $name_prefix = '') {
$i++;
}
- $where = implode (" $pair_operator ", $pair_wheres);
+ $where = implode(" $pair_operator ", $pair_wheres);
if ($where) {
$wheres[] = "($where)";
}
diff --git a/engine/lib/relationships.php b/engine/lib/relationships.php
index 5b7080b56..f50c4a485 100644
--- a/engine/lib/relationships.php
+++ b/engine/lib/relationships.php
@@ -290,7 +290,7 @@ function elgg_get_entities_from_relationship($options) {
$options['selects'] = array();
}
- $select = array('r.*');
+ $select = array('r.id');
$options['selects'] = array_merge($options['selects'], $select);
}
@@ -399,8 +399,8 @@ function elgg_list_entities_from_relationship_count($options) {
/**
* Sets the URL handler for a particular relationship type
*
- * @param string $function_name The function to register
* @param string $relationship_type The relationship type.
+ * @param string $function_name The function to register
*
* @return bool Depending on success
*/
diff --git a/engine/lib/river.php b/engine/lib/river.php
index 421813441..711832f70 100644
--- a/engine/lib/river.php
+++ b/engine/lib/river.php
@@ -44,12 +44,18 @@ $posted = 0, $annotation_id = 0) {
if ($access_id === "") {
$access_id = $object->access_id;
}
- $annotation_id = (int)$annotation_id;
$type = $object->getType();
$subtype = $object->getSubtype();
+
+ $view = sanitise_string($view);
$action_type = sanitise_string($action_type);
+ $subject_guid = sanitise_int($subject_guid);
+ $object_guid = sanitise_int($object_guid);
+ $access_id = sanitise_int($access_id);
+ $posted = sanitise_int($posted);
+ $annotation_id = sanitise_int($annotation_id);
- $params = array(
+ $values = array(
'type' => $type,
'subtype' => $subtype,
'action_type' => $action_type,
@@ -62,13 +68,13 @@ $posted = 0, $annotation_id = 0) {
);
// return false to stop insert
- $params = elgg_trigger_plugin_hook('creating', 'river', null, $params);
- if ($params == false) {
+ $values = elgg_trigger_plugin_hook('creating', 'river', null, $values);
+ if ($values == false) {
// inserting did not fail - it was just prevented
return true;
}
- extract($params);
+ extract($values);
// Attempt to save river item; return success status
$id = insert_data("insert into {$CONFIG->dbprefix}river " .
@@ -102,7 +108,7 @@ $posted = 0, $annotation_id = 0) {
*
* @warning not checking access (should we?)
*
- * @param array $options
+ * @param array $options Parameters:
* ids => INT|ARR River item id(s)
* subject_guids => INT|ARR Subject guid(s)
* object_guids => INT|ARR Object guid(s)
@@ -209,7 +215,7 @@ function elgg_delete_river(array $options = array()) {
*
* @note If using types and subtypes in a query, they are joined with an AND.
*
- * @param array $options
+ * @param array $options Parameters:
* ids => INT|ARR River item id(s)
* subject_guids => INT|ARR Subject guid(s)
* object_guids => INT|ARR Object guid(s)
@@ -542,7 +548,7 @@ function elgg_river_get_action_where_sql($types) {
/**
* Get the where clause based on river view strings
*
- * @param array $types Array of view strings
+ * @param array $views Array of view strings
*
* @return string
* @since 1.8.0
diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php
index 97a05e2e8..72ca0a1c2 100644
--- a/engine/lib/sessions.php
+++ b/engine/lib/sessions.php
@@ -127,6 +127,10 @@ function elgg_is_admin_user($user_guid) {
/**
* Perform user authentication with a given username and password.
*
+ * @warning This returns an error message on failure. Use the identical operator to check
+ * for access: if (true === elgg_authenticate()) { ... }.
+ *
+ *
* @see login
*
* @param string $username The username
@@ -355,7 +359,7 @@ function logout() {
session_destroy();
// starting a default session to store any post-logout messages.
- session_init(NULL, NULL, NULL);
+ _elgg_session_boot(NULL, NULL, NULL);
$_SESSION['msg'] = $old_msg;
return TRUE;
@@ -372,14 +376,10 @@ function logout() {
*
* @uses $_SESSION
*
- * @param string $event Event name
- * @param string $object_type Object type
- * @param mixed $object Object
- *
* @return bool
* @access private
*/
-function session_init($event, $object_type, $object) {
+function _elgg_session_boot() {
global $DB_PREFIX, $CONFIG;
// Use database for sessions
@@ -444,8 +444,8 @@ function session_init($event, $object_type, $object) {
set_last_action($_SESSION['guid']);
}
- elgg_register_action("login", '', 'public');
- elgg_register_action("logout");
+ elgg_register_action('login', '', 'public');
+ elgg_register_action('logout');
// Register a default PAM handler
register_pam_handler('pam_auth_userpass');
@@ -460,9 +460,6 @@ function session_init($event, $object_type, $object) {
return false;
}
- // Since we have loaded a new user, this user may have different language preferences
- register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
-
return true;
}
@@ -654,5 +651,3 @@ function _elgg_session_gc($maxlifetime) {
return true;
}
-
-elgg_register_event_handler("boot", "system", "session_init", 20);
diff --git a/engine/lib/sites.php b/engine/lib/sites.php
index 337b2d180..850092cad 100644
--- a/engine/lib/sites.php
+++ b/engine/lib/sites.php
@@ -231,43 +231,6 @@ function get_site_domain($guid) {
}
/**
- * Initialise site handling
- *
- * Called at the beginning of system running, to set the ID of the current site.
- * This is 0 by default, but plugins may alter this behaviour by attaching functions
- * to the sites init event and changing $CONFIG->site_id.
- *
- * @uses $CONFIG
- *
- * @param string $event Event API required parameter
- * @param string $object_type Event API required parameter
- * @param null $object Event API required parameter
- *
- * @return true
- * @access private
- */
-function sites_boot($event, $object_type, $object) {
- global $CONFIG;
-
- $site = elgg_trigger_plugin_hook("siteid", "system");
- if ($site === null || $site === false) {
- $CONFIG->site_id = (int) datalist_get('default_site');
- } else {
- $CONFIG->site_id = $site;
- }
- $CONFIG->site_guid = $CONFIG->site_id;
- $CONFIG->site = get_entity($CONFIG->site_guid);
-
- return true;
-}
-
-// Register event handlers
-elgg_register_event_handler('boot', 'system', 'sites_boot', 2);
-
-// Register with unit test
-elgg_register_plugin_hook_handler('unit_test', 'system', 'sites_test');
-
-/**
* Unit tests for sites
*
* @param sting $hook unit_test
@@ -283,3 +246,6 @@ function sites_test($hook, $type, $value, $params) {
$value[] = "{$CONFIG->path}engine/tests/objects/sites.php";
return $value;
}
+
+// Register with unit test
+elgg_register_plugin_hook_handler('unit_test', 'system', 'sites_test');
diff --git a/engine/lib/statistics.php b/engine/lib/statistics.php
index 7c170f3bb..5ee640549 100644
--- a/engine/lib/statistics.php
+++ b/engine/lib/statistics.php
@@ -95,14 +95,12 @@ function get_number_users($show_deactivated = false) {
* @return string
*/
function get_online_users() {
- $offset = get_input('offset', 0);
- $count = find_active_users(600, 10, $offset, true);
- $objects = find_active_users(600, 10, $offset);
+ $count = find_active_users(600, 10, 0, true);
+ $objects = find_active_users(600, 10);
if ($objects) {
return elgg_view_entity_list($objects, array(
'count' => $count,
- 'offset' => $offset,
'limit' => 10
));
}
diff --git a/engine/lib/system_log.php b/engine/lib/system_log.php
index fd5644135..53fa24557 100644
--- a/engine/lib/system_log.php
+++ b/engine/lib/system_log.php
@@ -11,6 +11,7 @@
* Retrieve the system log based on a number of parameters.
*
* @param int|array $by_user The guid(s) of the user(s) who initiated the event.
+ * Use 0 for unowned entries. Anything else falsey means anyone.
* @param string $event The event you are searching on.
* @param string $class The class of object it effects.
* @param string $type The type
@@ -21,11 +22,12 @@
* @param int $timebefore Lower time limit
* @param int $timeafter Upper time limit
* @param int $object_id GUID of an object
- *
+ * @param str $ip_address The IP address.
* @return mixed
*/
function get_system_log($by_user = "", $event = "", $class = "", $type = "", $subtype = "",
-$limit = 10, $offset = 0, $count = false, $timebefore = 0, $timeafter = 0, $object_id = 0) {
+$limit = 10, $offset = 0, $count = false, $timebefore = 0, $timeafter = 0, $object_id = 0,
+$ip_address = false) {
global $CONFIG;
@@ -37,16 +39,18 @@ $limit = 10, $offset = 0, $count = false, $timebefore = 0, $timeafter = 0, $obje
} else {
$by_user = (int)$by_user;
}
+
$event = sanitise_string($event);
$class = sanitise_string($class);
$type = sanitise_string($type);
$subtype = sanitise_string($subtype);
+ $ip_address = sanitise_string($ip_address);
$limit = (int)$limit;
$offset = (int)$offset;
$where = array();
- if ($by_user_orig !== "") {
+ if ($by_user_orig !== "" && $by_user_orig !== false && $by_user_orig !== null) {
if (is_int($by_user)) {
$where[] = "performed_by_guid=$by_user";
} else if (is_array($by_user)) {
@@ -75,6 +79,9 @@ $limit = 10, $offset = 0, $count = false, $timebefore = 0, $timeafter = 0, $obje
if ($object_id) {
$where[] = "object_id = " . ((int) $object_id);
}
+ if ($ip_address) {
+ $where[] = "ip_address = '$ip_address'";
+ }
$select = "*";
if ($count) {
@@ -91,7 +98,8 @@ $limit = 10, $offset = 0, $count = false, $timebefore = 0, $timeafter = 0, $obje
}
if ($count) {
- if ($numrows = get_data_row($query)) {
+ $numrows = get_data_row($query);
+ if ($numrows) {
return $numrows->count;
}
} else {
@@ -148,9 +156,8 @@ function get_object_from_log_entry($entry_id) {
* This is called by the event system and should not be called directly.
*
* @param object $object The object you're talking about.
- * @param string $event String The event being logged
- *
- * @return mixed
+ * @param string $event The event being logged
+ * @return void
*/
function system_log($object, $event) {
global $CONFIG;
@@ -158,6 +165,12 @@ function system_log($object, $event) {
static $cache_size = 0;
if ($object instanceof Loggable) {
+
+ if (datalist_get('version') < 2012012000) {
+ // this is a site that doesn't have the ip_address column yet
+ return;
+ }
+
// reset cache if it has grown too large
if (!is_array($log_cache) || $cache_size > 500) {
$log_cache = array();
@@ -171,6 +184,7 @@ function system_log($object, $event) {
$object_subtype = $object->getSubtype();
$event = sanitise_string($event);
$time = time();
+ $ip_address = sanitise_string($_SERVER['REMOTE_ADDR']);
$performed_by = elgg_get_logged_in_user_guid();
if (isset($object->access_id)) {
@@ -194,18 +208,16 @@ function system_log($object, $event) {
if (!isset($log_cache[$time][$object_id][$event])) {
$query = "INSERT DELAYED into {$CONFIG->dbprefix}system_log
(object_id, object_class, object_type, object_subtype, event,
- performed_by_guid, owner_guid, access_id, enabled, time_created)
+ performed_by_guid, owner_guid, access_id, enabled, time_created, ip_address)
VALUES
('$object_id','$object_class','$object_type', '$object_subtype', '$event',
- $performed_by, $owner_guid, $access_id, '$enabled', '$time')";
+ $performed_by, $owner_guid, $access_id, '$enabled', '$time', '$ip_address')";
insert_data($query);
$log_cache[$time][$object_id][$event] = true;
$cache_size += 1;
}
-
- return true;
}
}
diff --git a/engine/lib/upgrades/2011010101.php b/engine/lib/upgrades/2011010101.php
index b063c249b..a1ee92622 100644
--- a/engine/lib/upgrades/2011010101.php
+++ b/engine/lib/upgrades/2011010101.php
@@ -66,7 +66,7 @@ if ($old_enabled_plugins) {
// invalidate caches
elgg_invalidate_simplecache();
-elgg_filepath_cache_reset();
+elgg_reset_system_cache();
// clean up.
remove_metadata($site->guid, 'pluginorder');
diff --git a/engine/lib/upgrades/2011030700-1.8_svn-blog_status_metadata-4645225d7b440876.php b/engine/lib/upgrades/2011030700-1.8_svn-blog_status_metadata-4645225d7b440876.php
index e4ab9c137..fe2af9928 100644
--- a/engine/lib/upgrades/2011030700-1.8_svn-blog_status_metadata-4645225d7b440876.php
+++ b/engine/lib/upgrades/2011030700-1.8_svn-blog_status_metadata-4645225d7b440876.php
@@ -9,7 +9,8 @@
$ia = elgg_set_ignore_access(true);
$options = array(
'type' => 'object',
- 'subtype' => 'blog'
+ 'subtype' => 'blog',
+ 'limit' => 0,
);
$batch = new ElggBatch('elgg_get_entities', $options);
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
index 4fc59ac41..41ab29998 100644
--- 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
@@ -16,6 +16,7 @@ access_show_hidden_entities(true);
$options = array(
'type' => 'site',
'site_guid' => 0,
+ 'limit' => 0,
);
$batch = new ElggBatch('elgg_get_entities', $options);
diff --git a/engine/lib/upgrades/2011123100-1.8.2-fix_friend_river-b17e7ff8345c2269.php b/engine/lib/upgrades/2011123100-1.8.2-fix_friend_river-b17e7ff8345c2269.php
new file mode 100644
index 000000000..4dc43cd32
--- /dev/null
+++ b/engine/lib/upgrades/2011123100-1.8.2-fix_friend_river-b17e7ff8345c2269.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Elgg 1.8.2 upgrade 2011123100
+ * fix_friend_river
+ *
+ * Action type was incorrect due to previoud friends river upgrade
+ */
+
+$query = "UPDATE {$CONFIG->dbprefix}river
+ SET action_type='friend'
+ WHERE view='river/relationship/friend/create' AND action_type='create'";
+update_data($query);
diff --git a/engine/lib/upgrades/2011123101-1.8.2-fix_blog_status-b14c2a0e7b9e7d55.php b/engine/lib/upgrades/2011123101-1.8.2-fix_blog_status-b14c2a0e7b9e7d55.php
new file mode 100644
index 000000000..e351c6ac9
--- /dev/null
+++ b/engine/lib/upgrades/2011123101-1.8.2-fix_blog_status-b14c2a0e7b9e7d55.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Elgg 1.8.2 upgrade 2011123101
+ * fix_blog_status
+ *
+ * Most blog posts did not have their status properly set with 1.8 upgrade so we run
+ * the blog status upgrade again
+ */
+
+$ia = elgg_set_ignore_access(true);
+$options = array(
+ 'type' => 'object',
+ 'subtype' => 'blog',
+ 'limit' => 0,
+);
+$batch = new ElggBatch('elgg_get_entities', $options);
+
+foreach ($batch as $entity) {
+ if (!$entity->status) {
+ // create metadata owned by the original owner
+ create_metadata($entity->getGUID(), 'status', 'published', '', $entity->owner_guid,
+ $entity->access_id);
+ }
+}
+elgg_set_ignore_access($ia); \ No newline at end of file
diff --git a/engine/lib/upgrades/2012012000-1.8.3-ip_in_syslog-87fe0f068cf62428.php b/engine/lib/upgrades/2012012000-1.8.3-ip_in_syslog-87fe0f068cf62428.php
new file mode 100644
index 000000000..b9514e156
--- /dev/null
+++ b/engine/lib/upgrades/2012012000-1.8.3-ip_in_syslog-87fe0f068cf62428.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Elgg 1.8.3 upgrade 2012012000
+ * ip_in_syslog
+ *
+ * Adds a field for an IP address in the system log table
+ */
+
+$db_prefix = elgg_get_config('dbprefix');
+$q = "ALTER TABLE {$db_prefix}system_log ADD ip_address VARCHAR(15) NOT NULL AFTER time_created";
+
+update_data($q); \ No newline at end of file
diff --git a/engine/lib/upgrades/2012012100-1.8.3-system_cache-93100e7d55a24a11.php b/engine/lib/upgrades/2012012100-1.8.3-system_cache-93100e7d55a24a11.php
new file mode 100644
index 000000000..3a9aae2a1
--- /dev/null
+++ b/engine/lib/upgrades/2012012100-1.8.3-system_cache-93100e7d55a24a11.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Elgg 1.8.3 upgrade 2012012100
+ * system_cache
+ *
+ * Convert viewpath cache to system cache
+ */
+
+$value = datalist_get('viewpath_cache_enabled');
+datalist_set('system_cache_enabled', $value);
+
+$query = "DELETE FROM {$CONFIG->dbprefix}datalists WHERE name='viewpath_cache_enabled'";
+delete_data($query);
diff --git a/engine/lib/upgrades/2012041800-1.8.3-dont_filter_passwords-c0ca4a18b38ae2bc.php b/engine/lib/upgrades/2012041800-1.8.3-dont_filter_passwords-c0ca4a18b38ae2bc.php
new file mode 100644
index 000000000..b82ffbebf
--- /dev/null
+++ b/engine/lib/upgrades/2012041800-1.8.3-dont_filter_passwords-c0ca4a18b38ae2bc.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Elgg 1.8.3 upgrade 2012041800
+ * dont_filter_passwords
+ *
+ * Add admin notice that password handling has changed and if
+ * users can't login to have them reset their passwords.
+ */
+elgg_add_admin_notice('dont_filter_passwords', 'Password handling has been updated to be more secure and flexible. '
+ . 'This change may prevent a small number of users from logging in with their existing passwords. '
+ . 'If a user is unable to log in, please advise him or her to reset their password, or reset it as an admin user.');
diff --git a/engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php b/engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php
new file mode 100644
index 000000000..07732f261
--- /dev/null
+++ b/engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Elgg 1.8.3 upgrade 2012041801
+ * multiple_user_tokens
+ *
+ * Fixes http://trac.elgg.org/ticket/4291
+ * Removes the unique index on users_apisessions for user_guid and site_guid
+ */
+
+$db_prefix = elgg_get_config('dbprefix');
+$q = "ALTER TABLE {$db_prefix}users_apisessions DROP INDEX user_guid,
+ ADD INDEX user_guid (user_guid, site_guid)";
+update_data($q); \ No newline at end of file
diff --git a/engine/lib/user_settings.php b/engine/lib/user_settings.php
index af30d8f0d..e4069fb53 100644
--- a/engine/lib/user_settings.php
+++ b/engine/lib/user_settings.php
@@ -33,9 +33,9 @@ function users_settings_save() {
* @access private
*/
function elgg_set_user_password() {
- $current_password = get_input('current_password');
- $password = get_input('password');
- $password2 = get_input('password2');
+ $current_password = get_input('current_password', null, false);
+ $password = get_input('password', null, false);
+ $password2 = get_input('password2', null, false);
$user_guid = get_input('guid');
if (!$user_guid) {
diff --git a/engine/lib/users.php b/engine/lib/users.php
index 1b3cca799..241b524f9 100644
--- a/engine/lib/users.php
+++ b/engine/lib/users.php
@@ -60,13 +60,12 @@ function create_user_entity($guid, $name, $username, $password, $salt, $email, $
$row = get_entity_as_row($guid);
if ($row) {
// Exists and you have access to it
-
$query = "SELECT guid from {$CONFIG->dbprefix}users_entity where guid = {$guid}";
if ($exists = get_data_row($query)) {
$query = "UPDATE {$CONFIG->dbprefix}users_entity
- set name='$name', username='$username', password='$password', salt='$salt',
- email='$email', language='$language', code='$code', last_action = "
- . time() . " where guid = {$guid}";
+ SET name='$name', username='$username', password='$password', salt='$salt',
+ email='$email', language='$language', code='$code'
+ WHERE guid = $guid";
$result = update_data($query);
if ($result != false) {
@@ -79,7 +78,7 @@ function create_user_entity($guid, $name, $username, $password, $salt, $email, $
}
}
} else {
- // Update failed, attempt an insert.
+ // Exists query failed, attempt an insert.
$query = "INSERT into {$CONFIG->dbprefix}users_entity
(guid, name, username, password, salt, email, language, code)
values ($guid, '$name', '$username', '$password', '$salt', '$email', '$language', '$code')";
@@ -90,7 +89,7 @@ function create_user_entity($guid, $name, $username, $password, $salt, $email, $
if (elgg_trigger_event('create', $entity->type, $entity)) {
return $guid;
} else {
- $entity->delete(); //delete_entity($guid);
+ $entity->delete();
}
}
}
@@ -299,13 +298,14 @@ function get_user_sites($user_guid, $limit = 10, $offset = 0) {
$offset = (int)$offset;
return elgg_get_entities_from_relationship(array(
+ 'site_guids' => ELGG_ENTITIES_ANY_VALUE,
'relationship' => 'member_of_site',
'relationship_guid' => $user_guid,
'inverse_relationship' => FALSE,
'types' => 'site',
'limit' => $limit,
- 'offset' => $offset)
- );
+ 'offset' => $offset,
+ ));
}
/**
@@ -497,20 +497,26 @@ $timelower = 0, $timeupper = 0) {
* @param int $timelower The earliest time the entity can have been created. Default: all
* @param int $timeupper The latest time the entity can have been created. Default: all
*
- * @return string The list in a form suitable to display
+ * @return string
*/
function list_user_friends_objects($user_guid, $subtype = "", $limit = 10, $full_view = true,
$listtypetoggle = true, $pagination = true, $timelower = 0, $timeupper = 0) {
- $offset = (int) get_input('offset');
- $limit = (int) $limit;
- $count = (int) count_user_friends_objects($user_guid, $subtype, $timelower, $timeupper);
+ $offset = (int)get_input('offset');
+ $limit = (int)$limit;
+ $count = (int)count_user_friends_objects($user_guid, $subtype, $timelower, $timeupper);
$entities = get_user_friends_objects($user_guid, $subtype, $limit, $offset,
$timelower, $timeupper);
- return elgg_view_entity_list($entities, $count, $offset, $limit, $full_view,
- $listtypetoggle, $pagination);
+ return elgg_view_entity_list($entities, array(
+ 'count' => $count,
+ 'offset' => $offset,
+ 'limit' => $limit,
+ 'full_view' => $full_view,
+ 'list_type_toggle' => $listtypetoggle,
+ 'pagination' => $pagination,
+ ));
}
/**
@@ -606,11 +612,11 @@ function get_user_by_code($code) {
}
/**
- * Get an array of users from their email addresses
+ * Get an array of users from an email address
*
* @param string $email Email address.
*
- * @return Array of users
+ * @return array
*/
function get_user_by_email($email) {
global $CONFIG;
@@ -630,10 +636,10 @@ function get_user_by_email($email) {
* A function that returns a maximum of $limit users who have done something within the last
* $seconds seconds or the total count of active users.
*
- * @param int $seconds Number of seconds (default 600 = 10min)
- * @param int $limit Limit, default 10.
- * @param int $offset Offset, default 0.
- * @param bool $count Count, default false.
+ * @param int $seconds Number of seconds (default 600 = 10min)
+ * @param int $limit Limit, default 10.
+ * @param int $offset Offset, default 0.
+ * @param bool $count Count, default false.
*
* @return mixed
*/
@@ -804,6 +810,12 @@ function validate_username($username) {
$msg = elgg_echo('registration:usernametooshort', array($CONFIG->minusername));
throw new RegistrationException($msg);
}
+
+ // username in the database has a limit of 128 characters
+ if (strlen($username) > 128) {
+ $msg = elgg_echo('registration:usernametoolong', array(128));
+ throw new RegistrationException($msg);
+ }
// Blacklist for bad characters (partially nicked from mediawiki)
$blacklist = '/[' .
@@ -952,6 +964,7 @@ $allow_multiple_emails = false, $friend_guid = 0, $invitecode = '') {
$user->password = generate_user_password($user, $password);
$user->owner_guid = 0; // Users aren't owned by anyone, even if they are admin created.
$user->container_guid = 0; // Users aren't contained by anyone, even if they are admin created.
+ $user->language = get_current_language();
$user->save();
// If $friend_guid has been set, make mutual friends
@@ -962,8 +975,8 @@ $allow_multiple_emails = false, $friend_guid = 0, $invitecode = '') {
$friend_user->addFriend($user->guid);
// @todo Should this be in addFriend?
- add_to_river('friends/river/create', 'friend', $user->getGUID(), $friend_guid);
- add_to_river('friends/river/create', 'friend', $friend_guid, $user->getGUID());
+ add_to_river('river/relationship/friend/create', 'friend', $user->getGUID(), $friend_guid);
+ add_to_river('river/relationship/friend/create', 'friend', $friend_guid, $user->getGUID());
}
}
}
@@ -1485,7 +1498,7 @@ function users_pagesetup() {
if ($viewer) {
elgg_register_menu_item('topbar', array(
'name' => 'profile',
- 'href' => $viewer->getURL(),
+ 'href' => $viewer->getURL(),
'text' => elgg_view('output/img', array(
'src' => $viewer->getIconURL('topbar'),
'alt' => $viewer->name,
@@ -1544,11 +1557,12 @@ function users_init() {
elgg_register_plugin_hook_handler('register', 'menu:user_hover', 'elgg_user_hover_menu');
elgg_register_action('register', '', 'public');
- elgg_register_action('useradd', '', 'public');
+ elgg_register_action('useradd', '', 'admin');
elgg_register_action('friends/add');
elgg_register_action('friends/remove');
elgg_register_action('avatar/upload');
elgg_register_action('avatar/crop');
+ elgg_register_action('avatar/remove');
elgg_register_action('profile/edit');
elgg_register_action('friends/collections/add');
diff --git a/engine/lib/views.php b/engine/lib/views.php
index b938dd60e..c98ad4e78 100644
--- a/engine/lib/views.php
+++ b/engine/lib/views.php
@@ -103,7 +103,10 @@ function elgg_get_viewtype() {
$viewtype = get_input('view', NULL);
if ($viewtype) {
- return $viewtype;
+ // only word characters allowed.
+ if (!preg_match('[\W]', $viewtype)) {
+ return $viewtype;
+ }
}
if (isset($CONFIG->view) && !empty($CONFIG->view)) {
@@ -196,6 +199,37 @@ function elgg_does_viewtype_fallback($viewtype) {
return FALSE;
}
+/**
+ * Register a view to be available for ajax calls
+ *
+ * @param string $view The view name
+ * @return void
+ * @since 1.8.3
+ */
+function elgg_register_ajax_view($view) {
+ global $CONFIG;
+
+ if (!isset($CONFIG->allowed_ajax_views)) {
+ $CONFIG->allowed_ajax_views = array();
+ }
+
+ $CONFIG->allowed_ajax_views[$view] = true;
+}
+
+/**
+ * Unregister a view for ajax calls
+ *
+ * @param string $view The view name
+ * @return void
+ * @since 1.8.3
+ */
+function elgg_unregister_ajax_view($view) {
+ global $CONFIG;
+
+ if (isset($CONFIG->allowed_ajax_views[$view])) {
+ unset($CONFIG->allowed_ajax_views[$view]);
+ }
+}
/**
* Returns the file location for a view.
@@ -369,7 +403,7 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
$view_orig = $view;
// Trigger the pagesetup event
- if (!isset($CONFIG->pagesetupdone)) {
+ if (!isset($CONFIG->pagesetupdone) && $CONFIG->boot_complete) {
$CONFIG->pagesetupdone = true;
elgg_trigger_event('pagesetup', 'system');
}
@@ -415,7 +449,6 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
if (isset($vars['internalname']) && !isset($vars['__ignoreInternalname']) && !isset($vars['name'])) {
elgg_deprecated_notice('You should pass $vars[\'name\'] now instead of $vars[\'internalname\']', 1.8, 2);
$vars['name'] = $vars['internalname'];
- $test=false;
} elseif (isset($vars['name'])) {
if (!isset($vars['internalname'])) {
$vars['__ignoreInternalname'] = '';
@@ -530,7 +563,7 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
*
* @return void
* @since 1.7.0
- * @link http://docs.elgg.org/Views/Ejxtend
+ * @link http://docs.elgg.org/Views/Extend
* @example views/extend.php
*/
function elgg_extend_view($view, $view_extension, $priority = 501, $viewtype = '') {
@@ -939,12 +972,7 @@ function elgg_view_annotation(ElggAnnotation $annotation, array $vars = array(),
return elgg_view($view, $vars, $bypass, $debug);
}
- // @todo would be better to always make sure name is initialized properly
$name = $annotation->name;
- $intname = (int) $name;
- if ("{$intname}" == "{$name}") {
- $name = get_metastring($intname);
- }
if (empty($name)) {
return false;
}
@@ -1300,21 +1328,18 @@ function elgg_view_form($action, $form_vars = array(), $body_vars = array()) {
* @access private
*/
function elgg_view_list_item($item, array $vars = array()) {
+ global $CONFIG;
- switch ($item->getType()) {
- case 'user':
- case 'object':
- case 'group':
- case 'site':
- return elgg_view_entity($item, $vars);
- case 'annotation':
- return elgg_view_annotation($item, $vars);
- case 'river':
- return elgg_view_river_item($item, $vars);
- default:
- return false;
- break;
+ $type = $item->getType();
+ if (in_array($type, $CONFIG->entity_types)) {
+ return elgg_view_entity($item, $vars);
+ } else if ($type == 'annotation') {
+ return elgg_view_annotation($item, $vars);
+ } else if ($type == 'river') {
+ return elgg_view_river_item($item, $vars);
}
+
+ return false;
}
/**
@@ -1611,6 +1636,8 @@ function elgg_views_boot() {
elgg_register_css('elgg', $elgg_css_url);
elgg_load_css('elgg');
+ elgg_register_ajax_view('js/languages');
+
elgg_register_plugin_hook_handler('output:before', 'layout', 'elgg_views_add_rss_link');
// discover the built-in view types
@@ -1628,16 +1655,16 @@ function elgg_views_boot() {
// set default icon sizes - can be overridden in settings.php or with plugin
if (!elgg_get_config('icon_sizes')) {
$icon_sizes = array(
- 'topbar' => array('w'=>16, 'h'=>16, 'square'=>TRUE, 'upscale'=>TRUE),
- 'tiny' => array('w'=>25, 'h'=>25, 'square'=>TRUE, 'upscale'=>TRUE),
- 'small' => array('w'=>40, 'h'=>40, 'square'=>TRUE, 'upscale'=>TRUE),
- 'medium' => array('w'=>100, 'h'=>100, 'square'=>TRUE, 'upscale'=>TRUE),
- 'large' => array('w'=>200, 'h'=>200, 'square'=>FALSE, 'upscale'=>FALSE),
- 'master' => array('w'=>550, 'h'=>550, 'square'=>FALSE, 'upscale'=>FALSE),
+ 'topbar' => array('w' => 16, 'h' => 16, 'square' => TRUE, 'upscale' => TRUE),
+ 'tiny' => array('w' => 25, 'h' => 25, 'square' => TRUE, 'upscale' => TRUE),
+ 'small' => array('w' => 40, 'h' => 40, 'square' => TRUE, 'upscale' => TRUE),
+ 'medium' => array('w' => 100, 'h' => 100, 'square' => TRUE, 'upscale' => TRUE),
+ 'large' => array('w' => 200, 'h' => 200, 'square' => FALSE, 'upscale' => FALSE),
+ 'master' => array('w' => 550, 'h' => 550, 'square' => FALSE, 'upscale' => FALSE),
);
elgg_set_config('icon_sizes', $icon_sizes);
}
}
-elgg_register_event_handler('boot', 'system', 'elgg_views_boot', 1000);
+elgg_register_event_handler('boot', 'system', 'elgg_views_boot');
elgg_register_event_handler('init', 'system', 'elgg_views_handle_deprecated_views');
diff --git a/engine/lib/web_services.php b/engine/lib/web_services.php
index 1c77b757e..da3ed76a9 100644
--- a/engine/lib/web_services.php
+++ b/engine/lib/web_services.php
@@ -1165,7 +1165,7 @@ function list_all_apis() {
* @access private
*/
function auth_gettoken($username, $password) {
- if (authenticate($username, $password)) {
+ if (true === elgg_authenticate($username, $password)) {
$token = create_user_token($username);
if ($token) {
return $token;
diff --git a/engine/lib/widgets.php b/engine/lib/widgets.php
index 46f34391a..d73dd6330 100644
--- a/engine/lib/widgets.php
+++ b/engine/lib/widgets.php
@@ -316,7 +316,12 @@ function elgg_default_widgets_init() {
// override permissions for creating widget on logged out / just created entities
elgg_register_plugin_hook_handler('container_permissions_check', 'object', 'elgg_default_widgets_permissions_override');
+ // only register the callback once per event
+ $events = array();
foreach ($default_widgets as $info) {
+ $events[$info['event'] . ',' . $info['entity_type']] = $info;
+ }
+ foreach ($events as $info) {
elgg_register_event_handler($info['event'], $info['entity_type'], 'elgg_create_default_widgets');
}
}
diff --git a/engine/schema/mysql.sql b/engine/schema/mysql.sql
index 74cf2ce74..6c6e9db89 100644
--- a/engine/schema/mysql.sql
+++ b/engine/schema/mysql.sql
@@ -361,6 +361,7 @@ CREATE TABLE `prefix_system_log` (
`access_id` int(11) NOT NULL,
`enabled` enum('yes','no') NOT NULL DEFAULT 'yes',
`time_created` int(11) NOT NULL,
+ `ip_address` varchar(15) NOT NULL,
PRIMARY KEY (`id`),
KEY `object_id` (`object_id`),
KEY `object_class` (`object_class`),
diff --git a/engine/settings.example.php b/engine/settings.example.php
index 011770f89..3b139d710 100644
--- a/engine/settings.example.php
+++ b/engine/settings.example.php
@@ -107,7 +107,7 @@ $CONFIG->broken_mta = FALSE;
*
* Elgg stores each query and its results in a query cache.
* On large sites or long-running scripts, this cache can grow to be
- * large. To disable query caching, set this to FALSE.
+ * large. To disable query caching, set this to TRUE.
*
* @global bool $CONFIG->db_disable_query_cache
*/
diff --git a/engine/start.php b/engine/start.php
index 00bdc3197..5f4bded45 100644
--- a/engine/start.php
+++ b/engine/start.php
@@ -1,12 +1,12 @@
<?php
/**
- * Bootstraps and starts the Elgg engine.
+ * Bootstraps the Elgg engine.
*
* This file loads the full Elgg engine, checks the installation
- * state, then emits a series of events to finish booting Elgg:
+ * state, and triggers a series of events to finish booting Elgg:
* - {@elgg_event boot system}
- * - {@elgg_event plugins_boot system}
* - {@elgg_event init system}
+ * - {@elgg_event ready system}
*
* If Elgg is fully uninstalled, the browser will be redirected to an
* installation page.
@@ -36,13 +36,12 @@ $START_MICROTIME = microtime(true);
* Configuration values.
*
* The $CONFIG global contains configuration values required
- * for running Elgg as defined in the settings.php file. The following
- * array keys are defined by core Elgg:
+ * for running Elgg as defined in the settings.php file.
*
- * Plugin authors are encouraged to use get_config() instead of accessing the
- * global directly.
+ * Plugin authors are encouraged to use elgg_get_config() instead of accessing
+ * the global directly.
*
- * @see get_config()
+ * @see elgg_get_config()
* @see engine/settings.php
* @global stdClass $CONFIG
*/
@@ -50,59 +49,39 @@ global $CONFIG;
if (!isset($CONFIG)) {
$CONFIG = new stdClass;
}
+$CONFIG->boot_complete = false;
$lib_dir = dirname(__FILE__) . '/lib/';
-/**
- * The minimum required libs to bootstrap an Elgg installation.
- *
- * @var array
- */
-$required_files = array(
- 'elgglib.php', 'views.php', 'access.php', 'system_log.php', 'export.php',
- 'sessions.php', 'languages.php', 'pageowner.php', 'input.php', 'cache.php',
- 'output.php'
-);
-
-// include bootstraping libs
-foreach ($required_files as $file) {
- $path = $lib_dir . $file;
- if (!include($path)) {
- echo "Could not load file '$path'. "
- . 'Please check your Elgg installation for all required files.';
- exit;
- }
+// Load the bootstrapping library
+$path = $lib_dir . 'elgglib.php';
+if (!include_once($path)) {
+ echo "Could not load file '$path'. Please check your Elgg installation for all required files.";
+ exit;
}
-// Register the error handler
-set_error_handler('_elgg_php_error_handler');
-set_exception_handler('_elgg_php_exception_handler');
-
-/**
- * Load the system settings
- */
+// Load the system settings
if (!include_once(dirname(__FILE__) . "/settings.php")) {
- $msg = elgg_echo('InstallationException:CannotLoadSettings');
+ $msg = 'Elgg could not load the settings file. It does not exist or there is a file permissions issue.';
throw new InstallationException($msg);
}
// load the rest of the library files from engine/lib/
$lib_files = array(
- // these need to be loaded first.
- 'database.php', 'actions.php',
-
- 'admin.php', 'annotations.php', 'calendar.php',
- 'configuration.php', 'cron.php', 'entities.php', 'export.php',
- 'extender.php', 'filestore.php', 'group.php',
- 'location.php', 'mb_wrapper.php', 'memcache.php', 'metadata.php',
- 'metastrings.php', 'navigation.php', 'notification.php', 'objects.php',
- 'opendd.php', 'pagehandler.php', 'pam.php', 'plugins.php',
- 'private_settings.php', 'relationships.php', 'river.php', 'sites.php',
- 'statistics.php', 'tags.php', 'user_settings.php', 'users.php',
- 'upgrade.php', 'web_services.php', 'widgets.php', 'xml.php', 'xml-rpc.php',
+ 'access.php', 'actions.php', 'admin.php', 'annotations.php', 'cache.php',
+ 'calendar.php', 'configuration.php', 'cron.php', 'database.php',
+ 'entities.php', 'export.php', 'extender.php', 'filestore.php', 'group.php',
+ 'input.php', 'languages.php', 'location.php', 'mb_wrapper.php',
+ 'memcache.php', 'metadata.php', 'metastrings.php', 'navigation.php',
+ 'notification.php', 'objects.php', 'opendd.php', 'output.php',
+ 'pagehandler.php', 'pageowner.php', 'pam.php', 'plugins.php',
+ 'private_settings.php', 'relationships.php', 'river.php', 'sessions.php',
+ 'sites.php', 'statistics.php', 'system_log.php', 'tags.php',
+ 'user_settings.php', 'users.php', 'upgrade.php', 'views.php',
+ 'web_services.php', 'widgets.php', 'xml.php', 'xml-rpc.php',
- //backwards compatibility
+ // backward compatibility
'deprecated-1.7.php', 'deprecated-1.8.php',
);
@@ -110,48 +89,24 @@ foreach ($lib_files as $file) {
$file = $lib_dir . $file;
elgg_log("Loading $file...");
if (!include_once($file)) {
- $msg = sprintf(elgg_echo('InstallationException:MissingLibrary'), $file);
+ $msg = "Could not load $file";
throw new InstallationException($msg);
}
}
-// connect to db
-setup_db_connections();
-
-// confirm that the installation completed successfully
-verify_installation();
-
-// Autodetect some default configuration settings
-set_default_config();
-
-// needs to be set for links in html head
-$viewtype = get_input('view', 'default');
-$lastcached = datalist_get("simplecache_lastcached_$viewtype");
-$CONFIG->lastcache = $lastcached;
-
-// Trigger boot events for core. Plugins can't hook
-// into this because they haven't been loaded yet.
+// Connect to database, load language files, load configuration, init session
+// Plugins can't use this event because they haven't been loaded yet.
elgg_trigger_event('boot', 'system');
// Load the plugins that are active
elgg_load_plugins();
+// @todo deprecate as plugins can use 'init', 'system' event
elgg_trigger_event('plugins_boot', 'system');
-// Trigger system init event for plugins
+// Complete the boot process for both engine and plugins
elgg_trigger_event('init', 'system');
-// Regenerate the simple cache if expired.
-// Don't do it on upgrade because upgrade does it itself.
-// @todo - move into function and perhaps run off init system event
-if (!defined('UPGRADING')) {
- $lastupdate = datalist_get("simplecache_lastupdate_$viewtype");
- $lastcached = datalist_get("simplecache_lastcached_$viewtype");
- if ($lastupdate == 0 || $lastcached < $lastupdate) {
- elgg_regenerate_simplecache($viewtype);
- $lastcached = datalist_get("simplecache_lastcached_$viewtype");
- }
- $CONFIG->lastcache = $lastcached;
-}
+$CONFIG->boot_complete = true;
// System loaded and ready
elgg_trigger_event('ready', 'system');
diff --git a/engine/tests/api/annotations.php b/engine/tests/api/annotations.php
index d7551a0fa..947292970 100644
--- a/engine/tests/api/annotations.php
+++ b/engine/tests/api/annotations.php
@@ -43,4 +43,28 @@ class ElggCoreAnnotationAPITest extends ElggCoreUnitTest {
$this->object->delete();
}
+
+ public function testElggDeleteAnnotations() {
+ $e = new ElggObject();
+ $e->save();
+
+ for ($i=0; $i<30; $i++) {
+ $e->annotate('test_annotation', rand(0,10000));
+ }
+
+ $options = array(
+ 'guid' => $e->getGUID(),
+ 'limit' => 0
+ );
+
+ $annotations = elgg_get_annotations($options);
+ $this->assertIdentical(30, count($annotations));
+
+ $this->assertTrue(elgg_delete_annotations($options));
+
+ $annotations = elgg_get_annotations($options);
+ $this->assertTrue(empty($annotations));
+
+ $this->assertTrue($e->delete());
+ }
}
diff --git a/engine/tests/api/helpers.php b/engine/tests/api/helpers.php
index 77205138d..62e4471e0 100644
--- a/engine/tests/api/helpers.php
+++ b/engine/tests/api/helpers.php
@@ -518,4 +518,87 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
$this->assertIdentical($elements_sorted_string, $test_elements);
}
+
+ // see http://trac.elgg.org/ticket/4288
+ public function testElggBatchIncOffset() {
+ // normal increment
+ $options = array(
+ 'offset' => 0,
+ 'limit' => 11
+ );
+ $batch = new ElggBatch(array('ElggCoreHelpersTest', 'elgg_batch_callback_test'), $options,
+ null, 5);
+ $j = 0;
+ foreach ($batch as $e) {
+ $offset = floor($j / 5) * 5;
+ $this->assertEqual($offset, $e['offset']);
+ $this->assertEqual($j + 1, $e['index']);
+ $j++;
+ }
+
+ $this->assertEqual(11, $j);
+
+ // no increment, 0 start
+ ElggCoreHelpersTest::elgg_batch_callback_test(array(), true);
+ $options = array(
+ 'offset' => 0,
+ 'limit' => 11
+ );
+ $batch = new ElggBatch(array('ElggCoreHelpersTest', 'elgg_batch_callback_test'), $options,
+ null, 5);
+ $batch->setIncrementOffset(false);
+
+ $j = 0;
+ foreach ($batch as $e) {
+ $this->assertEqual(0, $e['offset']);
+ // should always be the same 5
+ $this->assertEqual($e['index'], $j + 1 - (floor($j / 5) * 5));
+ $j++;
+ }
+ $this->assertEqual(11, $j);
+
+ // no increment, 3 start
+ ElggCoreHelpersTest::elgg_batch_callback_test(array(), true);
+ $options = array(
+ 'offset' => 3,
+ 'limit' => 11
+ );
+ $batch = new ElggBatch(array('ElggCoreHelpersTest', 'elgg_batch_callback_test'), $options,
+ null, 5);
+ $batch->setIncrementOffset(false);
+
+ $j = 0;
+ foreach ($batch as $e) {
+ $this->assertEqual(3, $e['offset']);
+ // same 5 results
+ $this->assertEqual($e['index'], $j + 4 - (floor($j / 5) * 5));
+ $j++;
+ }
+
+ $this->assertEqual(11, $j);
+ }
+
+ static function elgg_batch_callback_test($options, $reset = false) {
+ static $count = 1;
+
+ if ($reset) {
+ $count = 1;
+ return true;
+ }
+
+ if ($count > 20) {
+ return false;
+ }
+
+ for ($j = 0; ($options['limit'] < 5) ? $j < $options['limit'] : $j < 5; $j++) {
+ $return[] = array(
+ 'offset' => $options['offset'],
+ 'limit' => $options['limit'],
+ 'count' => $count++,
+ 'index' => 1 + $options['offset'] + $j
+ );
+ }
+
+ return $return;
+ }
} \ No newline at end of file
diff --git a/engine/tests/api/metadata.php b/engine/tests/api/metadata.php
index f5b615ca8..244036f80 100644
--- a/engine/tests/api/metadata.php
+++ b/engine/tests/api/metadata.php
@@ -43,9 +43,6 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
{
$this->assertTrue(in_array($string, $this->metastrings));
}
-
- // clean up
- $this->delete_metastrings();
}
public function testElggGetEntitiesFromMetadata() {
@@ -77,7 +74,6 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
// clean up
$this->object->delete();
- $this->delete_metastrings();
}
public function testElggGetMetadataCount() {
@@ -99,20 +95,111 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
$this->object->delete();
}
+ public function testElggDeleteMetadata() {
+ $e = new ElggObject();
+ $e->save();
- protected function create_metastring($string) {
- global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
- $METASTRINGS_CACHE = $METASTRINGS_DEADNAME_CACHE = array();
+ for ($i=0; $i<30; $i++) {
+ $name = "test_metadata" . rand(0, 10000);
+ $e->$name = rand(0, 10000);
+ }
- mysql_query("INSERT INTO {$CONFIG->dbprefix}metastrings (string) VALUES ('$string')");
- $this->metastrings[$string] = mysql_insert_id();
+ $options = array(
+ 'guid' => $e->getGUID(),
+ 'limit' => 0
+ );
+
+ $md = elgg_get_metadata($options);
+ $this->assertIdentical(30, count($md));
+
+ $this->assertTrue(elgg_delete_metadata($options));
+
+ $md = elgg_get_metadata($options);
+ $this->assertTrue(empty($md));
+
+ $e->delete();
}
- protected function delete_metastrings() {
+ // Make sure metadata with multiple values is correctly deleted when re-written
+ // by another user
+ // http://trac.elgg.org/ticket/2776
+ public function test_elgg_metadata_multiple_values() {
+ $u1 = new ElggUser();
+ $u1->username = rand();
+ $u1->save();
+
+ $u2 = new ElggUser();
+ $u2->username = rand();
+ $u2->save();
+
+ $obj = new ElggObject();
+ $obj->owner_guid = $u1->guid;
+ $obj->container_guid = $u1->guid;
+ $obj->access_id = ACCESS_PUBLIC;
+ $obj->save();
+
+ $md_values = array(
+ 'one',
+ 'two',
+ 'three'
+ );
+
+ // need to fake different logins.
+ // good times without mocking.
+ $original_user = elgg_get_logged_in_user_entity();
+ $_SESSION['user'] = $u1;
+
+ elgg_set_ignore_access(false);
+
+ // add metadata as one user
+ $obj->test = $md_values;
+
+ // check only these md exists
+ $db_prefix = elgg_get_config('dbprefix');
+ $q = "SELECT * FROM {$db_prefix}metadata WHERE entity_guid = $obj->guid";
+ $data = get_data($q);
+
+ $this->assertEqual(count($md_values), count($data));
+ foreach ($data as $md_row) {
+ $md = elgg_get_metadata_from_id($md_row->id);
+ $this->assertTrue(in_array($md->value, $md_values));
+ $this->assertEqual('test', $md->name);
+ }
+
+ // add md w/ same name as a different user
+ $_SESSION['user'] = $u2;
+ $md_values2 = array(
+ 'four',
+ 'five',
+ 'six',
+ 'seven'
+ );
+
+ $obj->test = $md_values2;
+
+ $q = "SELECT * FROM {$db_prefix}metadata WHERE entity_guid = $obj->guid";
+ $data = get_data($q);
+
+ $this->assertEqual(count($md_values2), count($data));
+ foreach ($data as $md_row) {
+ $md = elgg_get_metadata_from_id($md_row->id);
+ $this->assertTrue(in_array($md->value, $md_values2));
+ $this->assertEqual('test', $md->name);
+ }
+
+ $_SESSION['user'] = $original_user;
+
+ $obj->delete();
+ $u1->delete();
+ $u2->delete();
+ }
+
+
+ protected function create_metastring($string) {
global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
$METASTRINGS_CACHE = $METASTRINGS_DEADNAME_CACHE = array();
- $strings = implode(', ', $this->metastrings);
- mysql_query("DELETE FROM {$CONFIG->dbprefix}metastrings WHERE id IN ($strings)");
+ mysql_query("INSERT INTO {$CONFIG->dbprefix}metastrings (string) VALUES ('$string')");
+ $this->metastrings[$string] = mysql_insert_id();
}
}
diff --git a/engine/tests/api/metastrings.php b/engine/tests/api/metastrings.php
index a96388217..0a8945084 100644
--- a/engine/tests/api/metastrings.php
+++ b/engine/tests/api/metastrings.php
@@ -132,7 +132,7 @@ class ElggCoreMetastringsTest extends ElggCoreUnitTest {
public function testKeepMeFromDeletingEverything() {
foreach ($this->metastringTypes as $type) {
$required = array(
- 'guid', 'guids', 'limit'
+ 'guid', 'guids'
);
switch ($type) {
@@ -160,6 +160,10 @@ class ElggCoreMetastringsTest extends ElggCoreUnitTest {
$options = array();
$this->assertFalse(elgg_is_valid_options_for_batch_operation($options, $type));
+ // limit alone isn't valid:
+ $options = array('limit' => 10);
+ $this->assertFalse(elgg_is_valid_options_for_batch_operation($options, $type));
+
foreach ($required as $key) {
$options = array();
diff --git a/engine/tests/objects/entities.php b/engine/tests/objects/entities.php
index 1772f7c1a..248b85c9e 100644
--- a/engine/tests/objects/entities.php
+++ b/engine/tests/objects/entities.php
@@ -98,7 +98,7 @@ class ElggCoreEntityTest extends ElggCoreUnitTest {
// check internal metadata array
$metadata = $this->entity->expose_metadata();
- $this->assertIdentical($metadata['existent'], 'testing');
+ $this->assertIdentical($metadata['existent'], array('testing'));
}
public function testElggEnityGetAndSetAnnotations() {
@@ -226,6 +226,39 @@ class ElggCoreEntityTest extends ElggCoreUnitTest {
$this->assertTrue($this->entity->delete());
}
+ public function testElggEntityRecursiveDisableAndEnable() {
+ global $CONFIG;
+
+ $this->save_entity();
+ $obj1 = new ElggObject();
+ $obj1->container_guid = $this->entity->getGUID();
+ $obj1->save();
+ $obj2 = new ElggObject();
+ $obj2->container_guid = $this->entity->getGUID();
+ $obj2->save();
+
+ // disable $obj2 before disabling the container
+ $this->assertTrue($obj2->disable());
+
+ // disable entities container by $this->entity
+ $this->assertTrue($this->entity->disable());
+ $entity = get_data_row("SELECT * FROM {$CONFIG->dbprefix}entities WHERE guid = '{$obj1->guid}'");
+ $this->assertIdentical($entity->enabled, 'no');
+
+ // enable entities that were disabled with the container (but not $obj2)
+ $this->assertTrue($this->entity->enable());
+ $entity = get_data_row("SELECT * FROM {$CONFIG->dbprefix}entities WHERE guid = '{$obj1->guid}'");
+ $this->assertIdentical($entity->enabled, 'yes');
+ $entity = get_data_row("SELECT * FROM {$CONFIG->dbprefix}entities WHERE guid = '{$obj2->guid}'");
+ $this->assertIdentical($entity->enabled, 'no');
+
+ // cleanup
+ $this->assertTrue($obj2->enable());
+ $this->assertTrue($obj2->delete());
+ $this->assertTrue($obj1->delete());
+ $this->assertTrue($this->entity->delete());
+ }
+
public function testElggEntityMetadata() {
// let's delete a non-existent metadata
$this->assertFalse($this->entity->deleteMetadata('important'));
diff --git a/engine/tests/objects/objects.php b/engine/tests/objects/objects.php
index 0d0df6b75..915594e0a 100644
--- a/engine/tests/objects/objects.php
+++ b/engine/tests/objects/objects.php
@@ -194,7 +194,99 @@ class ElggCoreObjectTest extends ElggCoreUnitTest {
$old = elgg_set_ignore_access(true);
}
+ // see http://trac.elgg.org/ticket/1196
+ public function testElggEntityRecursiveDisableWhenLoggedOut() {
+ $e1 = new ElggObject();
+ $e1->access_id = ACCESS_PUBLIC;
+ $e1->owner_guid = 0;
+ $e1->container_guid = 0;
+ $e1->save();
+ $guid1 = $e1->getGUID();
+
+ $e2 = new ElggObject();
+ $e2->container_guid = $guid1;
+ $e2->access_id = ACCESS_PUBLIC;
+ $e2->owner_guid = 0;
+ $e2->save();
+ $guid2 = $e2->getGUID();
+
+ // fake being logged out
+ $user = $_SESSION['user'];
+ unset($_SESSION['user']);
+ $ia = elgg_set_ignore_access(true);
+
+ $this->assertTrue(disable_entity($guid1, null, true));
+
+ // "log in" original user
+ $_SESSION['user'] = $user;
+ elgg_set_ignore_access($ia);
+
+ $this->assertFalse(get_entity($guid1));
+ $this->assertFalse(get_entity($guid2));
+
+ $db_prefix = get_config('dbprefix');
+ $q = "SELECT * FROM {$db_prefix}entities WHERE guid = $guid1";
+ $r = get_data_row($q);
+ $this->assertEqual('no', $r->enabled);
+
+ $q = "SELECT * FROM {$db_prefix}entities WHERE guid = $guid2";
+ $r = get_data_row($q);
+ $this->assertEqual('no', $r->enabled);
+
+ access_show_hidden_entities(true);
+ delete_entity($guid1);
+ delete_entity($guid2);
+ access_show_hidden_entities(false);
+ }
+
+ public function testElggRecursiveDelete() {
+ $types = array('ElggGroup', 'ElggObject', 'ElggUser', 'ElggSite');
+ $db_prefix = elgg_get_config('dbprefix');
+
+ foreach ($types as $type) {
+ $parent = new $type();
+ $this->assertTrue($parent->save());
+
+ $child = new ElggObject();
+ $child->container_guid = $parent->guid;
+ $this->assertTrue($child->save());
+
+ $grandchild = new ElggObject();
+ $grandchild->container_guid = $child->guid;
+ $this->assertTrue($grandchild->save());
+
+ $this->assertTrue($parent->delete(true));
+
+ $q = "SELECT * FROM {$db_prefix}entities WHERE guid = $parent->guid";
+ $r = get_data($q);
+ $this->assertFalse($r);
+
+ $q = "SELECT * FROM {$db_prefix}entities WHERE guid = $child->guid";
+ $r = get_data($q);
+ $this->assertFalse($r);
+ $q = "SELECT * FROM {$db_prefix}entities WHERE guid = $grandchild->guid";
+ $r = get_data($q);
+ $this->assertFalse($r);
+ }
+
+ // object that owns itself
+ // can't check container_guid because of infinite loops in can_edit_entity()
+ $obj = new ElggObject();
+ $obj->save();
+ $obj->owner_guid = $obj->guid;
+ $obj->save();
+
+ $q = "SELECT * FROM {$db_prefix}entities WHERE guid = $obj->guid";
+ $r = get_data_row($q);
+ $this->assertEqual($obj->guid, $r->owner_guid);
+
+ $this->assertTrue($obj->delete(true));
+
+ $q = "SELECT * FROM {$db_prefix}entities WHERE guid = $obj->guid";
+ $r = get_data_row($q);
+ $this->assertFalse($r);
+ }
protected function get_object_row($guid) {
global $CONFIG;
diff --git a/engine/tests/regression/trac_bugs.php b/engine/tests/regression/trac_bugs.php
index 99cf81774..26a45ab6a 100644
--- a/engine/tests/regression/trac_bugs.php
+++ b/engine/tests/regression/trac_bugs.php
@@ -199,4 +199,22 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest {
$this->assertFalse($result);
$this->assertEqual(array(), $DB_DELAYED_QUERIES);
}
+
+ /**
+ * http://trac.elgg.org/ticket/3210 - Don't remove -s in friendly titles
+ * @todo: http://trac.elgg.org/ticket/2276 - improve char encoding
+ */
+ public function test_friendly_title() {
+ $cases = array(
+ 'Simple Test' => 'simple-test',
+ 'Test top-level page' => 'test-top-level-page',
+// 'éclair' => 'éclair',
+// 'English, Español, and 日本語' => 'english-español-and-日本語'
+ );
+
+ foreach ($cases as $case => $expected) {
+ $friendly_title = elgg_get_friendly_title($case);
+ $this->assertIdentical($expected, $friendly_title);
+ }
+ }
}