diff options
Diffstat (limited to 'engine/lib')
| -rw-r--r-- | engine/lib/annotations.php | 10 | ||||
| -rw-r--r-- | engine/lib/elgglib.php | 3 | ||||
| -rw-r--r-- | engine/lib/entities.php | 94 | ||||
| -rw-r--r-- | engine/lib/group.php | 1 | ||||
| -rw-r--r-- | engine/lib/metadata.php | 14 | ||||
| -rw-r--r-- | engine/lib/metastrings.php | 7 | ||||
| -rw-r--r-- | engine/lib/navigation.php | 9 | ||||
| -rw-r--r-- | engine/lib/output.php | 8 | ||||
| -rw-r--r-- | engine/lib/sessions.php | 3 | ||||
| -rw-r--r-- | engine/lib/statistics.php | 10 | ||||
| -rw-r--r-- | engine/lib/views.php | 2 | 
11 files changed, 127 insertions, 34 deletions
diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php index 81755f169..124e67e0f 100644 --- a/engine/lib/annotations.php +++ b/engine/lib/annotations.php @@ -419,8 +419,8 @@ function elgg_list_entities_from_annotations($options = array()) {  function elgg_get_entities_from_annotation_calculation($options) {  	$db_prefix = elgg_get_config('dbprefix');  	$defaults = array( -		'calculation'	=>	'sum', -		'order_by'		=>	'annotation_calculation desc' +		'calculation' => 'sum', +		'order_by' => 'annotation_calculation desc'  	);  	$options = array_merge($defaults, $options); @@ -457,6 +457,12 @@ function elgg_get_entities_from_annotation_calculation($options) {   * @return string   */  function elgg_list_entities_from_annotation_calculation($options) { +	$defaults = array( +		'calculation' => 'sum', +		'order_by' => 'annotation_calculation desc' +	); +	$options = array_merge($defaults, $options); +  	return elgg_list_entities($options, 'elgg_get_entities_from_annotation_calculation');  } diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php index fb652a141..b5ef7e572 100644 --- a/engine/lib/elgglib.php +++ b/engine/lib/elgglib.php @@ -2247,6 +2247,9 @@ function elgg_api_test($hook, $type, $value, $params) {  /**#@+   * Controls access levels on ElggEntity entities, metadata, and annotations.   * + * @warning ACCESS_DEFAULT is a place holder for the input/access view. Do not + * use it when saving an entity. + *    * @var int   */  define('ACCESS_DEFAULT', -1); diff --git a/engine/lib/entities.php b/engine/lib/entities.php index 15ab1170e..997db79d2 100644 --- a/engine/lib/entities.php +++ b/engine/lib/entities.php @@ -17,6 +17,15 @@ global $ENTITY_CACHE;  $ENTITY_CACHE = array();  /** + * GUIDs of entities banned from the entity cache (during this request) + * + * @global array $ENTITY_CACHE_DISABLED_GUIDS + * @access private + */ +global $ENTITY_CACHE_DISABLED_GUIDS; +$ENTITY_CACHE_DISABLED_GUIDS = array(); + +/**   * Cache subtypes and related class names.   *   * @global array|null $SUBTYPE_CACHE array once populated from DB, initially null @@ -26,6 +35,34 @@ global $SUBTYPE_CACHE;  $SUBTYPE_CACHE = null;  /** + * Remove this entity from the entity cache and make sure it is not re-added + * + * @param int $guid The entity guid + * + * @access private + * @todo this is a workaround until #5604 can be implemented + */ +function _elgg_disable_caching_for_entity($guid) { +	global $ENTITY_CACHE_DISABLED_GUIDS; + +	_elgg_invalidate_cache_for_entity($guid); +	$ENTITY_CACHE_DISABLED_GUIDS[$guid] = true; +} + +/** + * Allow this entity to be stored in the entity cache + * + * @param int $guid The entity guid + * + * @access private + */ +function _elgg_enable_caching_for_entity($guid) { +	global $ENTITY_CACHE_DISABLED_GUIDS; + +	unset($ENTITY_CACHE_DISABLED_GUIDS[$guid]); +} + +/**   * Invalidate this class's entry in the cache.   *   * @param int $guid The entity guid @@ -57,7 +94,7 @@ function _elgg_invalidate_cache_for_entity($guid) {   * @todo Use an ElggCache object   */  function _elgg_cache_entity(ElggEntity $entity) { -	global $ENTITY_CACHE; +	global $ENTITY_CACHE, $ENTITY_CACHE_DISABLED_GUIDS;  	// Don't cache non-plugin entities while access control is off, otherwise they could be  	// exposed to users who shouldn't see them when control is re-enabled. @@ -65,6 +102,11 @@ function _elgg_cache_entity(ElggEntity $entity) {  		return;  	} +	$guid = $entity->getGUID(); +	if (isset($ENTITY_CACHE_DISABLED_GUIDS[$guid])) { +		return; +	} +  	// Don't store too many or we'll have memory problems  	// @todo Pick a less arbitrary limit  	if (count($ENTITY_CACHE) > 256) { @@ -79,7 +121,7 @@ function _elgg_cache_entity(ElggEntity $entity) {  		elgg_get_metadata_cache()->clear($random_guid);  	} -	$ENTITY_CACHE[$entity->guid] = $entity; +	$ENTITY_CACHE[$guid] = $entity;  }  /** @@ -407,7 +449,7 @@ function update_subtype($type, $subtype, $class = '') {   * @param int $time_created   The time creation timestamp   *   * @return bool - * @link http://docs.elgg.org/DataModel/Entities + * @throws InvalidParameterException   * @access private   */  function update_entity($guid, $owner_guid, $access_id, $container_guid = null, $time_created = null) { @@ -430,6 +472,10 @@ function update_entity($guid, $owner_guid, $access_id, $container_guid = null, $  		$time_created = (int) $time_created;  	} +	if ($access_id == ACCESS_DEFAULT) { +		throw new InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in elgglib.h'); +	} +  	if ($entity && $entity->canEdit()) {  		if (elgg_trigger_event('update', $entity->type, $entity)) {  			$ret = update_data("UPDATE {$CONFIG->dbprefix}entities @@ -556,7 +602,6 @@ $container_guid = 0) {  	$type = sanitise_string($type);  	$subtype_id = add_subtype($type, $subtype);  	$owner_guid = (int)$owner_guid; -	$access_id = (int)$access_id;  	$time = time();  	if ($site_guid == 0) {  		$site_guid = $CONFIG->site_guid; @@ -565,6 +610,10 @@ $container_guid = 0) {  	if ($container_guid == 0) {  		$container_guid = $owner_guid;  	} +	$access_id = (int)$access_id; +	if ($access_id == ACCESS_DEFAULT) { +		throw new InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in elgglib.h'); +	}  	$user_guid = elgg_get_logged_in_user_guid();  	if (!can_write_to_container($user_guid, $owner_guid, $type, $subtype)) { @@ -712,7 +761,7 @@ function get_entity($guid) {  	// @todo We need a single Memcache instance with a shared pool of namespace wrappers. This function would pull an instance from the pool.  	static $shared_cache; -	// We could also use: if (!(int) $guid) { return FALSE },  +	// We could also use: if (!(int) $guid) { return FALSE },  	// but that evaluates to a false positive for $guid = TRUE.  	// This is a bit slower, but more thorough.  	if (!is_numeric($guid) || $guid === 0 || $guid === '0') { @@ -884,6 +933,8 @@ function elgg_get_entities(array $options = array()) {  		'joins'					=>	array(),  		'callback'				=> 'entity_row_to_elggstar', + +		'__ElggBatch'			=> null,  	);  	$options = array_merge($defaults, $options); @@ -1001,7 +1052,7 @@ function elgg_get_entities(array $options = array()) {  		}  		if ($options['callback'] === 'entity_row_to_elggstar') { -			$dt = _elgg_fetch_entities_from_sql($query); +			$dt = _elgg_fetch_entities_from_sql($query, $options['__ElggBatch']);  		} else {  			$dt = get_data($query, $options['callback']);  		} @@ -1036,13 +1087,14 @@ function elgg_get_entities(array $options = array()) {  /**   * Return entities from an SQL query generated by elgg_get_entities.   * - * @param string $sql + * @param string    $sql + * @param ElggBatch $batch   * @return ElggEntity[]   *   * @access private   * @throws LogicException   */ -function _elgg_fetch_entities_from_sql($sql) { +function _elgg_fetch_entities_from_sql($sql, ElggBatch $batch = null) {  	static $plugin_subtype;  	if (null === $plugin_subtype) {  		$plugin_subtype = get_subtype_id('object', 'plugin'); @@ -1119,6 +1171,11 @@ function _elgg_fetch_entities_from_sql($sql) {  			} catch (IncompleteEntityException $e) {  				// don't let incomplete entities throw fatal errors  				unset($rows[$i]); + +				// report incompletes to the batch process that spawned this query +				if ($batch) { +					$batch->reportIncompleteEntity($row); +				}  			}  		}  	} @@ -1416,8 +1473,10 @@ function elgg_list_entities(array $options = array(), $getter = 'elgg_get_entiti  	global $autofeed;  	$autofeed = true; +	$offset_key = isset($options['offset_key']) ? $options['offset_key'] : 'offset'; +  	$defaults = array( -		'offset' => (int) max(get_input('offset', 0), 0), +		'offset' => (int) max(get_input($offset_key, 0), 0),  		'limit' => (int) max(get_input('limit', 10), 0),  		'full_view' => TRUE,  		'list_type_toggle' => FALSE, @@ -2069,7 +2128,7 @@ function can_edit_entity_metadata($entity_guid, $user_guid = 0, $metadata = null  		$return = null; -		if ($metadata->owner_guid == 0) { +		if ($metadata && ($metadata->owner_guid == 0)) {  			$return = true;  		}  		if (is_null($return)) { @@ -2470,11 +2529,18 @@ function update_entity_last_action($guid, $posted = NULL) {  function entities_gc() {  	global $CONFIG; -	$tables = array ('sites_entity', 'objects_entity', 'groups_entity', 'users_entity'); +	$tables = array( +		'site' => 'sites_entity', +		'object' => 'objects_entity', +		'group' => 'groups_entity', +		'user' => 'users_entity' +	); -	foreach ($tables as $table) { -		delete_data("DELETE from {$CONFIG->dbprefix}{$table} -			where guid NOT IN (SELECT guid from {$CONFIG->dbprefix}entities)"); +	foreach ($tables as $type => $table) { +		delete_data("DELETE FROM {$CONFIG->dbprefix}{$table} +			WHERE guid NOT IN (SELECT guid FROM {$CONFIG->dbprefix}entities)"); +		delete_data("DELETE FROM {$CONFIG->dbprefix}entities +			WHERE type = '$type' AND guid NOT IN (SELECT guid FROM {$CONFIG->dbprefix}{$table})");  	}  } diff --git a/engine/lib/group.php b/engine/lib/group.php index 359bc59c2..6ded8a825 100644 --- a/engine/lib/group.php +++ b/engine/lib/group.php @@ -240,6 +240,7 @@ function leave_group($group_guid, $user_guid) {   */  function get_users_membership($user_guid) {  	$options = array( +		'type' => 'group',  		'relationship' => 'member',  		'relationship_guid' => $user_guid,  		'inverse_relationship' => false, diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php index 43f7d5d6e..d2f8d4cd4 100644 --- a/engine/lib/metadata.php +++ b/engine/lib/metadata.php @@ -191,19 +191,19 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i  	}  	// Add the metastring -	$value = add_metastring($value); -	if (!$value) { +	$value_id = add_metastring($value); +	if (!$value_id) {  		return false;  	} -	$name = add_metastring($name); -	if (!$name) { +	$name_id = add_metastring($name); +	if (!$name_id) {  		return false;  	}  	// If ok then add it  	$query = "UPDATE {$CONFIG->dbprefix}metadata" -		. " set name_id='$name', value_id='$value', value_type='$value_type', access_id=$access_id," +		. " set name_id='$name_id', value_id='$value_id', value_type='$value_type', access_id=$access_id,"  		. " owner_guid=$owner_guid where id=$id";  	$result = update_data($query); @@ -402,9 +402,11 @@ function elgg_enable_metadata(array $options) {   *                                         'operand' => '=',   *                                         'case_sensitive' => TRUE   *                                        ) - * 	                             Currently if multiple values are sent via + *                               Currently if multiple values are sent via   *                               an array (value => array('value1', 'value2')   *                               the pair's operand will be forced to "IN". + *                               If passing "IN" as the operand and a string as the value,  + *                               the value must be a properly quoted and escaped string.   *   * 	metadata_name_value_pairs_operator => NULL|STR The operator to use for combining   *                                        (name = value) OPERATOR (name = value); default AND diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php index 39a81c6d0..57d876c06 100644 --- a/engine/lib/metastrings.php +++ b/engine/lib/metastrings.php @@ -425,7 +425,7 @@ function elgg_get_metastring_based_objects($options) {  		$wheres[] = get_access_sql_suffix('n_table');  	} -	if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) { +	if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) {  		$selects = array_unique($selects);  		// evalutate selects  		$select_str = ''; @@ -436,6 +436,9 @@ function elgg_get_metastring_based_objects($options) {  		}  		$query = "SELECT DISTINCT n_table.*{$select_str} FROM {$db_prefix}$type n_table"; +	} elseif ($options['count']) { +		// count is over the entities +		$query = "SELECT count(DISTINCT e.guid) as calculation FROM {$db_prefix}$type n_table";  	} else {  		$query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table";  	} @@ -464,7 +467,7 @@ function elgg_get_metastring_based_objects($options) {  			$defaults['order_by']);  	} -	if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) { +	if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) {  		if (isset($options['group_by'])) {  			$options['group_by'] = sanitise_string($options['group_by']);  			$query .= " GROUP BY {$options['group_by']}"; diff --git a/engine/lib/navigation.php b/engine/lib/navigation.php index 118a7214c..ab9cc05e8 100644 --- a/engine/lib/navigation.php +++ b/engine/lib/navigation.php @@ -218,7 +218,7 @@ function elgg_push_breadcrumb($title, $link = NULL) {  	}  	// avoid key collisions. -	$CONFIG->breadcrumbs[] = array('title' => $title, 'link' => $link); +	$CONFIG->breadcrumbs[] = array('title' => elgg_get_excerpt($title, 100), 'link' => $link);  }  /** @@ -323,7 +323,8 @@ function elgg_site_menu_setup($hook, $type, $return, $params) {  	}  	if (!$selected) { -		// nothing selected, match name to context +		// nothing selected, match name to context or match url +		$current_url = current_page_url();  		foreach ($return as $section_name => $section) {  			foreach ($section as $key => $item) {  				// only highlight internal links @@ -332,6 +333,10 @@ function elgg_site_menu_setup($hook, $type, $return, $params) {  						$return[$section_name][$key]->setSelected(true);  						break 2;  					} +					if ($item->getHref() == $current_url) { +						$return[$section_name][$key]->setSelected(true); +						break 2; +					}  				}  			}  		} diff --git a/engine/lib/output.php b/engine/lib/output.php index 5adc01053..6172a5c8d 100644 --- a/engine/lib/output.php +++ b/engine/lib/output.php @@ -27,16 +27,16 @@ function parse_urls($text) {  	// By default htmlawed rewrites tags to this format.  	// if PHP supported conditional negative lookbehinds we could use this:  	// $r = preg_replace_callback('/(?<!=)(?<![ ])?(?<!["\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\!\(\),]+)/i', -	$r = preg_replace_callback('/(?<![=\/"\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\(\)]+)/i', +	$r = preg_replace_callback('/(?<![=\/"\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\']+)/i',  	create_function(  		'$matches',  		'  			$url = $matches[1]; -			$punc = \'\'; +			$punc = "";  			$last = substr($url, -1, 1); -			if (in_array($last, array(".", "!", ","))) { +			if (in_array($last, array(".", "!", ",", "(", ")"))) {  				$punc = $last; -				$url = rtrim($url, ".!,"); +				$url = rtrim($url, ".!,()");  			}  			$urltext = str_replace("/", "/<wbr />", $url);  			return "<a href=\"$url\" rel=\"nofollow\">$urltext</a>$punc"; diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php index a34c2045b..fb28e1e9a 100644 --- a/engine/lib/sessions.php +++ b/engine/lib/sessions.php @@ -87,6 +87,9 @@ function elgg_is_admin_logged_in() {   */  function elgg_is_admin_user($user_guid) {  	global $CONFIG; + +	$user_guid = (int)$user_guid; +  	// cannot use magic metadata here because of recursion  	// must support the old way of getting admin from metadata diff --git a/engine/lib/statistics.php b/engine/lib/statistics.php index 0c9a3c945..4cb0bb0b8 100644 --- a/engine/lib/statistics.php +++ b/engine/lib/statistics.php @@ -95,13 +95,17 @@ function get_number_users($show_deactivated = false) {   * @return string    */  function get_online_users() { -	$count = find_active_users(600, 10, 0, true); -	$objects = find_active_users(600, 10); +	$limit = max(0, (int) get_input("limit", 10)); +	$offset = max(0, (int) get_input("offset", 0)); +	 +	$count = find_active_users(600, $limit, $offset, true); +	$objects = find_active_users(600, $limit, $offset);  	if ($objects) {  		return elgg_view_entity_list($objects, array(  			'count' => $count, -			'limit' => 10, +			'limit' => $limit, +			'offset' => $offset  		));  	}  	return ''; diff --git a/engine/lib/views.php b/engine/lib/views.php index c4b349fc6..65ba20204 100644 --- a/engine/lib/views.php +++ b/engine/lib/views.php @@ -1638,7 +1638,7 @@ function elgg_views_boot() {  	}  	// set default icon sizes - can be overridden in settings.php or with plugin -	if (!$CONFIG->icon_sizes) { +	if (!isset($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),  | 
