diff options
39 files changed, 469 insertions, 342 deletions
| diff --git a/engine/classes/ElggBatch.php b/engine/classes/ElggBatch.php index 5d59425d0..1912f89a2 100644 --- a/engine/classes/ElggBatch.php +++ b/engine/classes/ElggBatch.php @@ -229,8 +229,9 @@ class ElggBatch  	private function getNextResultsChunk() {  		// reset memory caches after first chunk load  		if ($this->chunkIndex > 0) { -			global $DB_QUERY_CACHE, $ENTITY_CACHE; -			$DB_QUERY_CACHE = $ENTITY_CACHE = array(); +			global $ENTITY_CACHE; +			$ENTITY_CACHE = array(); +			_elgg_invalidate_query_cache();  		}  		// always reset results. diff --git a/engine/classes/ElggEntity.php b/engine/classes/ElggEntity.php index 5a63c7b15..8b3ceb551 100644 --- a/engine/classes/ElggEntity.php +++ b/engine/classes/ElggEntity.php @@ -1270,7 +1270,7 @@ abstract class ElggEntity extends ElggData implements  	public function save() {  		$guid = $this->getGUID();  		if ($guid > 0) { -			cache_entity($this); +			_elgg_cache_entity($this);  			return update_entity(  				$guid, @@ -1320,7 +1320,7 @@ abstract class ElggEntity extends ElggData implements  			$this->attributes['subtype'] = get_subtype_id($this->attributes['type'],  				$this->attributes['subtype']); -			cache_entity($this); +			_elgg_cache_entity($this);  			return $this->attributes['guid'];  		} @@ -1362,7 +1362,7 @@ abstract class ElggEntity extends ElggData implements  			// Cache object handle  			if ($this->attributes['guid']) { -				cache_entity($this); +				_elgg_cache_entity($this);  			}  			return true; diff --git a/engine/classes/ElggGroup.php b/engine/classes/ElggGroup.php index 7ab0bfa48..61f9163d5 100644 --- a/engine/classes/ElggGroup.php +++ b/engine/classes/ElggGroup.php @@ -335,7 +335,7 @@ class ElggGroup extends ElggEntity  		$this->attributes = $attrs;  		$this->attributes['tables_loaded'] = 2; -		cache_entity($this); +		_elgg_cache_entity($this);  		return true;  	} diff --git a/engine/classes/ElggLRUCache.php b/engine/classes/ElggLRUCache.php new file mode 100644 index 000000000..f51af2ed7 --- /dev/null +++ b/engine/classes/ElggLRUCache.php @@ -0,0 +1,181 @@ +<?php + +/** + * Least Recently Used Cache + * + * A fixed sized cache that removes the element used last when it reaches its + * size limit. + *  + * Based on https://github.com/cash/LRUCache + *  + * @access private + *  + * @package    Elgg.Core + * @subpackage Cache + */ +class ElggLRUCache implements ArrayAccess { +	/** @var int */ +	protected $maximumSize; + +	/** +	 * The front of the array contains the LRU element +	 * +	 * @var array +	 */ +	protected $data = array(); + +	/** +	 * Create a LRU Cache +	 * +	 * @param int $size The size of the cache +	 * @throws InvalidArgumentException +	 */ +	public function __construct($size) { +		if (!is_int($size) || $size <= 0) { +			throw new InvalidArgumentException(); +		} +		$this->maximumSize = $size; +	} + +	/** +	 * Get the value cached with this key +	 * +	 * @param int|string $key     The key. Strings that are ints are cast to ints. +	 * @param mixed      $default The value to be returned if key not found. (Optional) +	 * @return mixed +	 */ +	public function get($key, $default = null) { +		if (isset($this->data[$key])) { +			$this->recordAccess($key); +			return $this->data[$key]; +		} else { +			return $default; +		} +	} + +	/** +	 * Add something to the cache +	 * +	 * @param int|string $key   The key. Strings that are ints are cast to ints. +	 * @param mixed      $value The value to cache +	 * @return void +	 */ +	public function set($key, $value) { +		if (isset($this->data[$key])) { +			$this->data[$key] = $value; +			$this->recordAccess($key); +		} else { +			$this->data[$key] = $value; +			if ($this->size() > $this->maximumSize) { +				// remove least recently used element (front of array) +				reset($this->data); +				unset($this->data[key($this->data)]); +			} +		} +	} + +	/** +	 * Get the number of elements in the cache +	 * +	 * @return int +	 */ +	public function size() { +		return count($this->data); +	} + +	/** +	 * Does the cache contain an element with this key +	 * +	 * @param int|string $key The key +	 * @return boolean +	 */ +	public function containsKey($key) { +		return isset($this->data[$key]); +	} + +	/** +	 * Remove the element with this key. +	 * +	 * @param int|string $key The key +	 * @return mixed Value or null if not set +	 */ +	public function remove($key) { +		if (isset($this->data[$key])) { +			$value = $this->data[$key]; +			unset($this->data[$key]); +			return $value; +		} else { +			return null; +		} +	} + +	/** +	 * Clear the cache +	 *  +	 * @return void +	 */ +	public function clear() { +		$this->data = array(); +	} + +	/** +	 * Moves the element from current position to end of array +	 *  +	 * @param int|string $key The key +	 * @return void +	 */ +	protected function recordAccess($key) { +		$value = $this->data[$key]; +		unset($this->data[$key]); +		$this->data[$key] = $value; +	} + +	/** +	 * Assigns a value for the specified key +	 * +	 * @see ArrayAccess::offsetSet() +	 * +	 * @param int|string $key   The key to assign the value to. +	 * @param mixed      $value The value to set. +	 * @return void +	 */ +	public function offsetSet($key, $value) { +		$this->set($key, $value); +	} + +	/** +	 * Get the value for specified key +	 * +	 * @see ArrayAccess::offsetGet() +	 * +	 * @param int|string $key The key to retrieve. +	 * @return mixed +	 */ +	public function offsetGet($key) { +		return $this->get($key); +	} + +	/** +	 * Unsets a key. +	 * +	 * @see ArrayAccess::offsetUnset() +	 * +	 * @param int|string $key The key to unset. +	 * @return void +	 */ +	public function offsetUnset($key) { +		$this->remove($key); +	} + +	/** +	 * Does key exist? +	 * +	 * @see ArrayAccess::offsetExists() +	 * +	 * @param int|string $key A key to check for. +	 * @return boolean +	 */ +	public function offsetExists($key) { +		return $this->containsKey($key); +	} +} diff --git a/engine/classes/ElggObject.php b/engine/classes/ElggObject.php index 3cb76ffaf..d54752dca 100644 --- a/engine/classes/ElggObject.php +++ b/engine/classes/ElggObject.php @@ -107,7 +107,7 @@ class ElggObject extends ElggEntity {  		$this->attributes = $attrs;  		$this->attributes['tables_loaded'] = 2; -		cache_entity($this); +		_elgg_cache_entity($this);  		return true;  	} diff --git a/engine/classes/ElggSite.php b/engine/classes/ElggSite.php index deba5087e..dd996fe98 100644 --- a/engine/classes/ElggSite.php +++ b/engine/classes/ElggSite.php @@ -124,7 +124,7 @@ class ElggSite extends ElggEntity {  		$this->attributes = $attrs;  		$this->attributes['tables_loaded'] = 2; -		cache_entity($this); +		_elgg_cache_entity($this);  		return true;  	} diff --git a/engine/classes/ElggStaticVariableCache.php b/engine/classes/ElggStaticVariableCache.php index 17d849400..9c14fdfba 100644 --- a/engine/classes/ElggStaticVariableCache.php +++ b/engine/classes/ElggStaticVariableCache.php @@ -11,7 +11,7 @@ class ElggStaticVariableCache extends ElggSharedMemoryCache {  	/**  	 * The cache.  	 * -	 * @var unknown_type +	 * @var array  	 */  	private static $__cache; @@ -22,7 +22,7 @@ class ElggStaticVariableCache extends ElggSharedMemoryCache {  	 * memory, optionally with a given namespace (to avoid overlap).  	 *  	 * @param string $namespace The namespace for this cache to write to. -	 * @note namespaces of the same name are shared! +	 * @warning namespaces of the same name are shared!  	 */  	function __construct($namespace = 'default') {  		$this->setNamespace($namespace); @@ -80,7 +80,7 @@ class ElggStaticVariableCache extends ElggSharedMemoryCache {  	}  	/** -	 * This was probably meant to delete everything? +	 * Clears the cache for a particular namespace  	 *  	 * @return void  	 */ diff --git a/engine/classes/ElggTranslit.php b/engine/classes/ElggTranslit.php index 601965c11..4ae1d2479 100644 --- a/engine/classes/ElggTranslit.php +++ b/engine/classes/ElggTranslit.php @@ -49,10 +49,19 @@ class ElggTranslit {  		// Internationalization, AND 日本語!  		$string = self::transliterateAscii($string); -		// more translation +		// allow HTML tags in titles +		$string = preg_replace('~<([a-zA-Z][^>]*)>~', ' $1 ', $string); + +		// more substitutions +		// @todo put these somewhere else  		$string = strtr($string, array( -			// Euro/GBP -			"\xE2\x82\xAC" /* € */ => 'E', "\xC2\xA3" /* £ */ => 'GBP', +			// currency +			"\xE2\x82\xAC" /* € */ => ' E ', +			"\xC2\xA3" /* £ */ => ' GBP ', +			 +			"&" => ' and ', +			">" => ' greater than ', +			"<" => ' less than ',  		));  		// remove all ASCII except 0-9a-zA-Z, hyphen, underscore, and whitespace diff --git a/engine/classes/ElggUser.php b/engine/classes/ElggUser.php index b80065b27..6d9f10b57 100644 --- a/engine/classes/ElggUser.php +++ b/engine/classes/ElggUser.php @@ -112,7 +112,7 @@ class ElggUser extends ElggEntity  		$this->attributes = $attrs;  		$this->attributes['tables_loaded'] = 2; -		cache_entity($this); +		_elgg_cache_entity($this);  		return true;  	} diff --git a/engine/lib/actions.php b/engine/lib/actions.php index f78ca63df..56936f582 100644 --- a/engine/lib/actions.php +++ b/engine/lib/actions.php @@ -74,8 +74,7 @@ function action($action, $forwarder = "") {  	);  	if (!in_array($action, $exceptions)) { -		// All actions require a token. -		action_gatekeeper(); +		action_gatekeeper($action);  	}  	$forwarder = str_replace(elgg_get_site_url(), "", $forwarder); @@ -188,6 +187,26 @@ function elgg_unregister_action($action) {  }  /** + * Is the token timestamp within acceptable range? + *  + * @param int $ts timestamp from the CSRF token + *  + * @return bool + */ +function _elgg_validate_token_timestamp($ts) { +	$action_token_timeout = elgg_get_config('action_token_timeout'); +	// default is 2 hours +	$timeout = ($action_token_timeout !== null) ? $action_token_timeout : 2; + +	$hour = 60 * 60; +	$timeout = $timeout * $hour; +	$now = time(); + +	// Validate time to ensure its not crazy +	return ($timeout == 0 || ($ts > $now - $timeout) && ($ts < $now + $timeout)); +} + +/**   * Validate an action token.   *   * Calls to actions will automatically validate tokens. If tokens are not @@ -205,8 +224,6 @@ function elgg_unregister_action($action) {   * @access private   */  function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL) { -	global $CONFIG; -  	if (!$token) {  		$token = get_input('__elgg_token');  	} @@ -215,29 +232,18 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL)  		$ts = get_input('__elgg_ts');  	} -	if (!isset($CONFIG->action_token_timeout)) { -		// default to 2 hours -		$timeout = 2; -	} else { -		$timeout = $CONFIG->action_token_timeout; -	} -  	$session_id = session_id();  	if (($token) && ($ts) && ($session_id)) {  		// generate token, check with input and forward if invalid -		$generated_token = generate_action_token($ts); +		$required_token = generate_action_token($ts);  		// Validate token -		if ($token == $generated_token) { -			$hour = 60 * 60; -			$timeout = $timeout * $hour; -			$now = time(); - -			// Validate time to ensure its not crazy -			if ($timeout == 0 || ($ts > $now - $timeout) && ($ts < $now + $timeout)) { +		if ($token == $required_token) { +			 +			if (_elgg_validate_token_timestamp($ts)) {  				// We have already got this far, so unless anything -				// else says something to the contry we assume we're ok +				// else says something to the contrary we assume we're ok  				$returnval = true;  				$returnval = elgg_trigger_plugin_hook('action_gatekeeper:permissions:check', 'all', array( @@ -293,12 +299,33 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL)   * This function verifies form input for security features (like a generated token),   * and forwards if they are invalid.   * + * @param string $action The action being performed + *    * @return mixed True if valid or redirects.   * @access private   */ -function action_gatekeeper() { -	if (validate_action_token()) { -		return TRUE; +function action_gatekeeper($action) { +	if ($action === 'login') { +		if (validate_action_token(false)) { +			return true; +		} +		 +		$token = get_input('__elgg_token'); +		$ts = (int)get_input('__elgg_ts'); +		if ($token && _elgg_validate_token_timestamp($ts)) { +			// The tokens are present and the time looks valid: this is probably a mismatch due to the  +			// login form being on a different domain. +			register_error(elgg_echo('actiongatekeeper:crosssitelogin')); +			 +			 +			forward('login', 'csrf'); +		} +		 +		// let the validator send an appropriate msg +		validate_action_token(); +		 +	} elseif (validate_action_token()) { +		return true;  	}  	forward(REFERER, 'csrf'); diff --git a/engine/lib/database.php b/engine/lib/database.php index 2b348366d..3553d787d 100644 --- a/engine/lib/database.php +++ b/engine/lib/database.php @@ -12,17 +12,19 @@  /**   * Query cache for all queries.   * - * Each query and its results are stored in this array as: + * Each query and its results are stored in this cache as:   * <code> - * $DB_QUERY_CACHE[$query] => array(result1, result2, ... resultN) + * $DB_QUERY_CACHE[query hash] => array(result1, result2, ... resultN)   * </code> + * @see elgg_query_runner() for details on the hash.   * - * @warning be array this var may be an array or ElggStaticVariableCache depending on when called :( + * @warning Elgg used to set this as an empty array to turn off the cache   * - * @global ElggStaticVariableCache|array $DB_QUERY_CACHE + * @global ElggLRUCache|null $DB_QUERY_CACHE + * @access private   */  global $DB_QUERY_CACHE; -$DB_QUERY_CACHE = array(); +$DB_QUERY_CACHE = null;  /**   * Queries to be executed upon shutdown. @@ -40,6 +42,7 @@ $DB_QUERY_CACHE = array();   * </code>   *   * @global array $DB_DELAYED_QUERIES + * @access private   */  global $DB_DELAYED_QUERIES;  $DB_DELAYED_QUERIES = array(); @@ -51,6 +54,7 @@ $DB_DELAYED_QUERIES = array();   * $dblink as $dblink[$name] => resource.  Use get_db_link($name) to retrieve it.   *   * @global resource[] $dblink + * @access private   */  global $dblink;  $dblink = array(); @@ -61,6 +65,7 @@ $dblink = array();   * Each call to the database increments this counter.   *   * @global integer $dbcalls + * @access private   */  global $dbcalls;  $dbcalls = 0; @@ -123,9 +128,8 @@ function establish_db_link($dblinkname = "readwrite") {  	// Set up cache if global not initialized and query cache not turned off  	if ((!$DB_QUERY_CACHE) && (!$db_cache_off)) { -		// @todo everywhere else this is assigned to array(), making it dangerous to call -		// object methods on this. We should consider making this an plain array -		$DB_QUERY_CACHE = new ElggStaticVariableCache('db_query_cache'); +		// @todo if we keep this cache in 1.9, expose the size as a config parameter +		$DB_QUERY_CACHE = new ElggLRUCache(200);		  	}  } @@ -400,11 +404,9 @@ function elgg_query_runner($query, $callback = null, $single = false) {  	// Is cached?  	if ($DB_QUERY_CACHE) { -		$cached_query = $DB_QUERY_CACHE[$hash]; - -		if ($cached_query !== FALSE) { +		if (isset($DB_QUERY_CACHE[$hash])) {  			elgg_log("DB query $query results returned from cache (hash: $hash)", 'NOTICE'); -			return $cached_query; +			return $DB_QUERY_CACHE[$hash];			  		}  	} @@ -456,19 +458,12 @@ function elgg_query_runner($query, $callback = null, $single = false) {   * @access private   */  function insert_data($query) { -	global $DB_QUERY_CACHE;  	elgg_log("DB query $query", 'NOTICE');  	$dblink = get_db_link('write'); -	// Invalidate query cache -	if ($DB_QUERY_CACHE) { -		/* @var ElggStaticVariableCache $DB_QUERY_CACHE */ -		$DB_QUERY_CACHE->clear(); -	} - -	elgg_log("Query cache invalidated", 'NOTICE'); +	_elgg_invalidate_query_cache();  	if (execute_query("$query", $dblink)) {  		return mysql_insert_id($dblink); @@ -488,18 +483,12 @@ function insert_data($query) {   * @access private   */  function update_data($query) { -	global $DB_QUERY_CACHE;  	elgg_log("DB query $query", 'NOTICE');  	$dblink = get_db_link('write'); -	// Invalidate query cache -	if ($DB_QUERY_CACHE) { -		/* @var ElggStaticVariableCache $DB_QUERY_CACHE */ -		$DB_QUERY_CACHE->clear(); -		elgg_log("Query cache invalidated", 'NOTICE'); -	} +	_elgg_invalidate_query_cache();  	if (execute_query("$query", $dblink)) {  		return TRUE; @@ -519,18 +508,12 @@ function update_data($query) {   * @access private   */  function delete_data($query) { -	global $DB_QUERY_CACHE;  	elgg_log("DB query $query", 'NOTICE');  	$dblink = get_db_link('write'); -	// Invalidate query cache -	if ($DB_QUERY_CACHE) { -		/* @var ElggStaticVariableCache $DB_QUERY_CACHE */ -		$DB_QUERY_CACHE->clear(); -		elgg_log("Query cache invalidated", 'NOTICE'); -	} +	_elgg_invalidate_query_cache();  	if (execute_query("$query", $dblink)) {  		return mysql_affected_rows($dblink); @@ -539,6 +522,22 @@ function delete_data($query) {  	return FALSE;  } +/** + * Invalidate the query cache + *  + * @access private + */ +function _elgg_invalidate_query_cache() { +	global $DB_QUERY_CACHE; +	if ($DB_QUERY_CACHE instanceof ElggLRUCache) { +		$DB_QUERY_CACHE->clear(); +		elgg_log("Query cache invalidated", 'NOTICE'); +	} elseif ($DB_QUERY_CACHE) { +		// In case someone sets the cache to an array and primes it with data  +		$DB_QUERY_CACHE = array(); +		elgg_log("Query cache invalidated", 'NOTICE'); +	} +}  /**   * Return tables matching the database prefix {@link $CONFIG->dbprefix}% in the currently diff --git a/engine/lib/entities.php b/engine/lib/entities.php index 156eec040..cb972b282 100644 --- a/engine/lib/entities.php +++ b/engine/lib/entities.php @@ -30,10 +30,10 @@ $SUBTYPE_CACHE = null;   *   * @param int $guid The entity guid   * - * @return null + * @return void   * @access private   */ -function invalidate_cache_for_entity($guid) { +function _elgg_invalidate_cache_for_entity($guid) {  	global $ENTITY_CACHE;  	$guid = (int)$guid; @@ -50,13 +50,13 @@ function invalidate_cache_for_entity($guid) {   *   * @param ElggEntity $entity Entity to cache   * - * @return null - * @see retrieve_cached_entity() - * @see invalidate_cache_for_entity() + * @return void + * @see _elgg_retrieve_cached_entity() + * @see _elgg_invalidate_cache_for_entity()   * @access private - * TODO(evan): Use an ElggCache object + * @todo Use an ElggCache object   */ -function cache_entity(ElggEntity $entity) { +function _elgg_cache_entity(ElggEntity $entity) {  	global $ENTITY_CACHE;  	// Don't cache non-plugin entities while access control is off, otherwise they could be @@ -66,7 +66,7 @@ function cache_entity(ElggEntity $entity) {  	}  	// Don't store too many or we'll have memory problems -	// TODO(evan): Pick a less arbitrary limit +	// @todo Pick a less arbitrary limit  	if (count($ENTITY_CACHE) > 256) {  		$random_guid = array_rand($ENTITY_CACHE); @@ -88,11 +88,11 @@ function cache_entity(ElggEntity $entity) {   * @param int $guid The guid   *   * @return ElggEntity|bool false if entity not cached, or not fully loaded - * @see cache_entity() - * @see invalidate_cache_for_entity() + * @see _elgg_cache_entity() + * @see _elgg_invalidate_cache_for_entity()   * @access private   */ -function retrieve_cached_entity($guid) { +function _elgg_retrieve_cached_entity($guid) {  	global $ENTITY_CACHE;  	if (isset($ENTITY_CACHE[$guid])) { @@ -105,31 +105,6 @@ function retrieve_cached_entity($guid) {  }  /** - * As retrieve_cached_entity, but returns the result as a stdClass - * (compatible with load functions that expect a database row.) - * - * @param int $guid The guid - * - * @return mixed - * @todo unused - * @access private - */ -function retrieve_cached_entity_row($guid) { -	$obj = retrieve_cached_entity($guid); -	if ($obj) { -		$tmp = new stdClass; - -		foreach ($obj as $k => $v) { -			$tmp->$k = $v; -		} - -		return $tmp; -	} - -	return false; -} - -/**   * Return the id for a given subtype.   *   * ElggEntity objects have a type and a subtype.  Subtypes @@ -745,7 +720,7 @@ function get_entity($guid) {  	}  	// Check local cache first -	$new_entity = retrieve_cached_entity($guid); +	$new_entity = _elgg_retrieve_cached_entity($guid);  	if ($new_entity) {  		return $new_entity;  	} @@ -782,7 +757,7 @@ function get_entity($guid) {  	}  	if ($new_entity) { -		cache_entity($new_entity); +		_elgg_cache_entity($new_entity);  	}  	return $new_entity;  } @@ -1037,7 +1012,7 @@ function elgg_get_entities(array $options = array()) {  			foreach ($dt as $item) {  				// A custom callback could result in items that aren't ElggEntity's, so check for them  				if ($item instanceof ElggEntity) { -					cache_entity($item); +					_elgg_cache_entity($item);  					// plugins usually have only settings  					if (!$item instanceof ElggPlugin) {  						$guids[] = $item->guid; @@ -1102,7 +1077,7 @@ function _elgg_fetch_entities_from_sql($sql) {  		if (empty($row->guid) || empty($row->type)) {  			throw new LogicException('Entity row missing guid or type');  		} -		if ($entity = retrieve_cached_entity($row->guid)) { +		if ($entity = _elgg_retrieve_cached_entity($row->guid)) {  			$rows[$i] = $entity;  			continue;  		} @@ -1628,7 +1603,7 @@ function disable_entity($guid, $reason = "", $recursive = true) {  				$entity->disableMetadata();  				$entity->disableAnnotations(); -				invalidate_cache_for_entity($guid); +				_elgg_invalidate_cache_for_entity($guid);  				$res = update_data("UPDATE {$CONFIG->dbprefix}entities  					SET enabled = 'no' @@ -1726,7 +1701,7 @@ function delete_entity($guid, $recursive = true) {  				// delete cache  				if (isset($ENTITY_CACHE[$guid])) { -					invalidate_cache_for_entity($guid); +					_elgg_invalidate_cache_for_entity($guid);  				}  				// If memcache is available then delete this entry from the cache diff --git a/engine/lib/output.php b/engine/lib/output.php index da8e1ab86..c5a04989b 100644 --- a/engine/lib/output.php +++ b/engine/lib/output.php @@ -284,11 +284,9 @@ function elgg_get_friendly_title($title) {  		return $result;  	} -	// handle some special cases -	$title = str_replace('&', 'and', $title); -	// quotes and angle brackets stored in the database as html encoded -	$title = htmlspecialchars_decode($title); - +	// titles are often stored HTML encoded +	$title = html_entity_decode($title, ENT_QUOTES, 'UTF-8'); +	  	$title = ElggTranslit::urlize($title);  	return $title; diff --git a/engine/lib/river.php b/engine/lib/river.php index f2ec1e101..4926a85c4 100644 --- a/engine/lib/river.php +++ b/engine/lib/river.php @@ -380,10 +380,10 @@ function _elgg_prefetch_river_entities(array $river_items) {  	// prefetch objects and subjects  	$guids = array();  	foreach ($river_items as $item) { -		if ($item->subject_guid && !retrieve_cached_entity($item->subject_guid)) { +		if ($item->subject_guid && !_elgg_retrieve_cached_entity($item->subject_guid)) {  			$guids[$item->subject_guid] = true;  		} -		if ($item->object_guid && !retrieve_cached_entity($item->object_guid)) { +		if ($item->object_guid && !_elgg_retrieve_cached_entity($item->object_guid)) {  			$guids[$item->object_guid] = true;  		}  	} @@ -402,7 +402,7 @@ function _elgg_prefetch_river_entities(array $river_items) {  	$guids = array();  	foreach ($river_items as $item) {  		$object = $item->getObjectEntity(); -		if ($object->container_guid && !retrieve_cached_entity($object->container_guid)) { +		if ($object->container_guid && !_elgg_retrieve_cached_entity($object->container_guid)) {  			$guids[$object->container_guid] = true;  		}  	} diff --git a/engine/lib/upgrade.php b/engine/lib/upgrade.php index d684af862..0cc1e64dc 100644 --- a/engine/lib/upgrade.php +++ b/engine/lib/upgrade.php @@ -354,16 +354,12 @@ function _elgg_upgrade_unlock() {   * @access private   */  function _elgg_upgrade_is_locked() { -	global $CONFIG, $DB_QUERY_CACHE; -	 +	global $CONFIG; +  	$is_locked = count(get_data("show tables like '{$CONFIG->dbprefix}upgrade_lock'")); -	 -	// Invalidate query cache -	if ($DB_QUERY_CACHE) { -		/* @var ElggStaticVariableCache $DB_QUERY_CACHE */ -		$DB_QUERY_CACHE->clear(); -		elgg_log("Query cache invalidated", 'NOTICE'); -	} -	 + +	// @todo why? +	_elgg_invalidate_query_cache(); +  	return $is_locked;  } diff --git a/engine/lib/upgrades/2009102801.php b/engine/lib/upgrades/2009102801.php index cab9a6835..3ad113fb2 100644 --- a/engine/lib/upgrades/2009102801.php +++ b/engine/lib/upgrades/2009102801.php @@ -203,14 +203,15 @@ function user_file_matrix($guid) {  	return "$time_created/$user->guid/";  } -global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE; +global $ENTITY_CACHE, $CONFIG;  /**   * Upgrade file locations   */  $users = mysql_query("SELECT guid, username  	FROM {$CONFIG->dbprefix}users_entity WHERE username != ''");  while ($user = mysql_fetch_object($users)) { -	$DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array(); +	$ENTITY_CACHE = array(); +	_elgg_invalidate_query_cache();  	$to = $CONFIG->dataroot . user_file_matrix($user->guid);  	foreach (array('1_0', '1_1', '1_6') as $version) { diff --git a/engine/lib/upgrades/2010061501.php b/engine/lib/upgrades/2010061501.php index 9ff7d3102..744c28fd5 100644 --- a/engine/lib/upgrades/2010061501.php +++ b/engine/lib/upgrades/2010061501.php @@ -45,7 +45,7 @@ if ($dbversion < 2009100701) {  			}  		} -		global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE; +		global $ENTITY_CACHE;  		/**  			Upgrade file locations @@ -60,7 +60,9 @@ if ($dbversion < 2009100701) {  		$users = mysql_query("SELECT guid, username FROM {$CONFIG->dbprefix}users_entity  			WHERE username != ''", $link);  		while ($user = mysql_fetch_object($users)) { -			$DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array(); +			$ENTITY_CACHE = array(); +			_elgg_invalidate_query_cache(); +  			$to = $CONFIG->dataroot . user_file_matrix($user->guid);  			foreach (array('1_0', '1_1', '1_6') as $version) { diff --git a/engine/lib/upgrades/2010071001.php b/engine/lib/upgrades/2010071001.php index 1b5d379d8..5594493a8 100644 --- a/engine/lib/upgrades/2010071001.php +++ b/engine/lib/upgrades/2010071001.php @@ -30,11 +30,12 @@ function user_file_matrix_2010071001($guid) {  $sizes = array('large', 'medium', 'small', 'tiny', 'master', 'topbar'); -global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE, $CONFIG; +global $ENTITY_CACHE, $CONFIG;  $users = mysql_query("SELECT guid, username FROM {$CONFIG->dbprefix}users_entity  	WHERE username != ''");  while ($user = mysql_fetch_object($users)) { -	$DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array(); +	$ENTITY_CACHE = array(); +	_elgg_invalidate_query_cache();  	$user_directory = user_file_matrix_2010071001($user->guid);  	if (!$user_directory) { diff --git a/engine/lib/upgrades/2010071002.php b/engine/lib/upgrades/2010071002.php index 30bd6538c..52aa15ef5 100644 --- a/engine/lib/upgrades/2010071002.php +++ b/engine/lib/upgrades/2010071002.php @@ -4,12 +4,13 @@   */  // loop through all users checking collections and notifications -global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE, $CONFIG; +global $ENTITY_CACHE, $CONFIG;  global $NOTIFICATION_HANDLERS;  $users = mysql_query("SELECT guid, username FROM {$CONFIG->dbprefix}users_entity  	WHERE username != ''");  while ($user = mysql_fetch_object($users)) { -	$DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array(); +	$ENTITY_CACHE = array(); +	_elgg_invalidate_query_cache();  	$user = get_entity($user->guid);  	foreach ($NOTIFICATION_HANDLERS as $method => $foo) { diff --git a/engine/lib/upgrades/2011052801.php b/engine/lib/upgrades/2011052801.php index 8084bc06c..b5a8e1018 100644 --- a/engine/lib/upgrades/2011052801.php +++ b/engine/lib/upgrades/2011052801.php @@ -2,7 +2,7 @@  /**   * Make sure all users have the relationship member_of_site   */ -global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE, $CONFIG; +global $ENTITY_CACHE;  $db_prefix = get_config('dbprefix');  $limit = 100; @@ -17,7 +17,8 @@ $q = "SELECT e.* FROM {$db_prefix}entities e  $users = get_data($q);  while ($users) { -	$DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array(); +	$ENTITY_CACHE = array(); +	_elgg_invalidate_query_cache();  	// do manually to not trigger any events because these aren't new users.  	foreach ($users as $user) { diff --git a/engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php b/engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php index b38eb5100..8eccf05e2 100644 --- a/engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php +++ b/engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php @@ -7,8 +7,6 @@   * This script turns that back into a string.   */ -global $DB_QUERY_CACHE; -  $ia = elgg_set_ignore_access(true);  $options = array(  	'type' => 'user', @@ -17,7 +15,7 @@ $options = array(  $batch = new ElggBatch('elgg_get_entities', $options);  foreach ($batch as $entity) { -	$DB_QUERY_CACHE = array(); +	_elgg_invalidate_query_cache();  	if (is_array($entity->location)) {  		$entity->location = implode(', ', $entity->location); diff --git a/engine/lib/users.php b/engine/lib/users.php index 4a585c07f..868cd7815 100644 --- a/engine/lib/users.php +++ b/engine/lib/users.php @@ -237,7 +237,7 @@ function make_user_admin($user_guid) {  			}  			$r = update_data("UPDATE {$CONFIG->dbprefix}users_entity set admin='yes' where guid=$user_guid"); -			invalidate_cache_for_entity($user_guid); +			_elgg_invalidate_cache_for_entity($user_guid);  			return $r;  		} @@ -273,7 +273,7 @@ function remove_user_admin($user_guid) {  			}  			$r = update_data("UPDATE {$CONFIG->dbprefix}users_entity set admin='no' where guid=$user_guid"); -			invalidate_cache_for_entity($user_guid); +			_elgg_invalidate_cache_for_entity($user_guid);  			return $r;  		} @@ -558,8 +558,8 @@ function get_user_by_username($username) {  	// Caching  	if ((isset($USERNAME_TO_GUID_MAP_CACHE[$username])) -			&& (retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]))) { -		return retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]); +			&& (_elgg_retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]))) { +		return _elgg_retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]);  	}  	$query = "SELECT e.* from {$CONFIG->dbprefix}users_entity u @@ -592,9 +592,9 @@ function get_user_by_code($code) {  	// Caching  	if ((isset($CODE_TO_GUID_MAP_CACHE[$code])) -	&& (retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]))) { +	&& (_elgg_retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]))) { -		return retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]); +		return _elgg_retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]);  	}  	$query = "SELECT e.* from {$CONFIG->dbprefix}users_entity u diff --git a/engine/tests/api/access_collections.php b/engine/tests/api/access_collections.php index ebcd7d318..4acfae596 100644 --- a/engine/tests/api/access_collections.php +++ b/engine/tests/api/access_collections.php @@ -54,7 +54,6 @@ class ElggCoreAccessCollectionsTest extends ElggCoreUnitTest {  	}  	public function testCreateGetDeleteACL() { -		global $DB_QUERY_CACHE;  		$acl_name = 'test access collection';  		$acl_id = create_access_collection($acl_name); @@ -67,8 +66,6 @@ class ElggCoreAccessCollectionsTest extends ElggCoreUnitTest {  		$this->assertEqual($acl->id, $acl_id);  		if ($acl) { -			$DB_QUERY_CACHE = array(); -			  			$this->assertEqual($acl->name, $acl_name);  			$result = delete_access_collection($acl_id); diff --git a/engine/tests/regression/trac_bugs.php b/engine/tests/regression/trac_bugs.php index 691433a41..58444dd39 100644 --- a/engine/tests/regression/trac_bugs.php +++ b/engine/tests/regression/trac_bugs.php @@ -206,21 +206,23 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest {  	 */  	public function test_friendly_title() {  		$cases = array( +			// acid test +			"B&N > Amazon, OK? <bold> 'hey!' $34" +			=> "b-and-n-greater-than-amazon-ok-bold-hey-34", +  			// hyphen, underscore and ASCII whitespace replaced by separator,  			// other non-alphanumeric ASCII removed -			"a-a_a a\na\ra\ta\va!a\"a#a\$a%a&a'a(a)a*a+a,a.a/a:a;a<a=a>a?a@a[a\\a]a^a`a{a|a}a~a" -			=> "a-a-a-a-a-a-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - +			"a-a_a a\na\ra\ta\va!a\"a#a\$a%a&a'a(a)a*a+a,a.a/a:a;a=a?a@a[a\\a]a^a`a{a|a}a~a" +			=> "a-a-a-a-a-a-aaaaaaa-and-aaaaaaaaaaaaaaaaaaaaaaa", +			  			// separators trimmed -			"-_ hello _-" => "hello", +			"-_ hello _-"  +			=> "hello",  			// accents removed, lower case, other multibyte chars are URL encoded  			"I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n, AND \xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"  				// Iñtërnâtiônàlizætiøn, AND 日本語  			=> 'internationalizaetion-and-%E6%97%A5%E6%9C%AC%E8%AA%9E', - -			// some HTML entity replacements -			"Me & You" => 'me-and-you',  		);  		// where available, string is converted to NFC before transliteration diff --git a/htaccess_dist b/htaccess_dist index 898fa22fb..44d129475 100644 --- a/htaccess_dist +++ b/htaccess_dist @@ -112,6 +112,14 @@ RewriteEngine on  #  #RewriteBase / + +# If your users receive the message "Sorry, logging in from a different domain is not permitted" +# you must make sure your login form is served from the same hostname as your site pages. +# See http://docs.elgg.org/wiki/Login_token_mismatch_error for more info. +# +# If you must add RewriteRules to change hostname, add them directly below (above all the others) + +  # In for backwards compatibility  RewriteRule ^pg\/([A-Za-z0-9\_\-]+)$ engine/handlers/page_handler.php?handler=$1&%{QUERY_STRING} [L]  RewriteRule ^pg\/([A-Za-z0-9\_\-]+)\/(.*)$ engine/handlers/page_handler.php?handler=$1&page=$2&%{QUERY_STRING} [L] diff --git a/js/lib/languages.js b/js/lib/languages.js index 44ea56d2b..d218cbc4f 100644 --- a/js/lib/languages.js +++ b/js/lib/languages.js @@ -30,6 +30,9 @@ elgg.reload_all_translations = function(language) {  	var url, options;  	url = 'ajax/view/js/languages';  	options = {data: {language: lang}}; +    if (elgg.config.simplecache_enabled) { +        options.data.lc = elgg.config.lastcache; +    }  	options['success'] = function(json) {  		elgg.add_translation(lang, json); diff --git a/languages/en.php b/languages/en.php index 501855f02..be86e12e6 100644 --- a/languages/en.php +++ b/languages/en.php @@ -1193,6 +1193,7 @@ You cannot reply to this email.",  	'actiongatekeeper:timeerror' => 'The page you were using has expired. Please refresh and try again.',  	'actiongatekeeper:pluginprevents' => 'A extension has prevented this form from being submitted.',  	'actiongatekeeper:uploadexceeded' => 'The size of file(s) uploaded exceeded the limit set by your site administrator', +	'actiongatekeeper:crosssitelogin' => "Sorry, logging in from a different domain is not permitted. Please try again.",  /** diff --git a/mod/pages/actions/pages/delete.php b/mod/pages/actions/pages/delete.php index 7a314a280..fd5791e4d 100644 --- a/mod/pages/actions/pages/delete.php +++ b/mod/pages/actions/pages/delete.php @@ -21,11 +21,33 @@ if (elgg_instanceof($page, 'object', 'page') || elgg_instanceof($page, 'object',  			'metadata_value' => $page->getGUID()  		));  		if ($children) { +			$db_prefix = elgg_get_config('dbprefix'); +			$subtype_id = (int)get_subtype_id('object', 'page_top'); +			$newentity_cache = is_memcache_available() ? new ElggMemcache('new_entity_cache') : null; +  			foreach ($children as $child) { -				$child->parent_guid = $parent; +				if ($parent) { +					$child->parent_guid = $parent; +				} else { +					// If no parent, we need to transform $child to a page_top +					$child_guid = (int)$child->guid; + +					update_data("UPDATE {$db_prefix}entities +						SET subtype = $subtype_id WHERE guid = $child_guid"); + +					elgg_delete_metadata(array( +						'guid' => $child_guid, +						'metadata_name' => 'parent_guid', +					)); + +					_elgg_invalidate_cache_for_entity($child_guid); +					if ($newentity_cache) { +						$newentity_cache->delete($child_guid); +					} +				}  			}  		} -		 +  		if ($page->delete()) {  			system_message(elgg_echo('pages:delete:success'));  			if ($parent) { diff --git a/mod/pages/start.php b/mod/pages/start.php index 8debeef24..c1183c9bf 100644 --- a/mod/pages/start.php +++ b/mod/pages/start.php @@ -82,6 +82,8 @@ function pages_init() {  	// register ecml views to parse  	elgg_register_plugin_hook_handler('get_views', 'ecml', 'pages_ecml_views_hook'); +	 +	elgg_register_event_handler('upgrade', 'system', 'pages_run_upgrades');  }  /** @@ -362,3 +364,14 @@ function pages_ecml_views_hook($hook, $entity_type, $return_value, $params) {  	return $return_value;  } + +/** + * Process upgrades for the pages plugin + */ +function pages_run_upgrades() { +	$path = elgg_get_plugins_path() . 'pages/upgrades/'; +	$files = elgg_get_upgrade_files($path); +	foreach ($files as $file) { +		include "$path{$file}"; +	} +} diff --git a/mod/pages/upgrades/2012061800.php b/mod/pages/upgrades/2012061800.php new file mode 100644 index 000000000..c21ccae3b --- /dev/null +++ b/mod/pages/upgrades/2012061800.php @@ -0,0 +1,49 @@ +<?php +/** + * Restore disappeared subpages. This is caused by its parent page being deleted + * when the parent page is a top level page. We take advantage of the fact that + * the parent_guid was deleted for the subpages. + * + * This upgrade script will no longer work once we have converted all pages to + * have the same entity subtype. + */ + + +/** + * Update subtype + * + * @param ElggObject $page + */ +function pages_2012061800($page) { +	$dbprefix = elgg_get_config('dbprefix'); +	$subtype_id = (int)get_subtype_id('object', 'page_top'); +	$page_guid = (int)$page->guid; +	update_data("UPDATE {$dbprefix}entities +		SET subtype = $subtype_id WHERE guid = $page_guid"); +	error_log("called"); +	return true; +} + +$previous_access = elgg_set_ignore_access(true); + +$dbprefix = elgg_get_config('dbprefix'); +$name_metastring_id = get_metastring_id('parent_guid'); +if (!$name_metastring_id) { +	return; +} + +// Looking for pages without metadata +$options = array( +	'type' => 'object', +	'subtype' => 'page', +	'wheres' => "NOT EXISTS ( +		SELECT 1 FROM {$dbprefix}metadata md +		WHERE md.entity_guid = e.guid +		AND md.name_id = $name_metastring_id)" +); +$batch = new ElggBatch('elgg_get_entities_from_metadata', $options, 'pages_2012061800', 50, false); +elgg_set_ignore_access($previous_access); + +if ($batch->callbackResult) { +	error_log("Elgg Pages upgrade (2012061800) succeeded"); +} diff --git a/mod/twitter/graphics/thewire_speech_bubble.gif b/mod/twitter/graphics/thewire_speech_bubble.gifBinary files differ deleted file mode 100644 index d0e8606a1..000000000 --- a/mod/twitter/graphics/thewire_speech_bubble.gif +++ /dev/null diff --git a/mod/twitter/graphics/twitter16px.png b/mod/twitter/graphics/twitter16px.pngBinary files differ deleted file mode 100644 index de51c6953..000000000 --- a/mod/twitter/graphics/twitter16px.png +++ /dev/null diff --git a/mod/twitter/languages/en.php b/mod/twitter/languages/en.php deleted file mode 100644 index 11e745ba1..000000000 --- a/mod/twitter/languages/en.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -/** - * Twitter widget language file - */ - -$english = array( -	'twitter:title' => 'Twitter', -	'twitter:info' => 'Display your latest tweets', -	'twitter:username' => 'Your twitter username', -	'twitter:num' => 'Number of tweets to show*', -	'twitter:visit' => 'visit my twitter', -	'twitter:notset' => 'This widget needs to be configured. To display your latest tweets, click the customize icon and fill in your Twitter username.', -	'twitter:invalid' => 'This widget is configured with an invalid Twitter username. Click the customize icon to correct it.', -	'twitter:apibug' => "*Due to a bug in the Twitter 1.0 API, you may see fewer tweets than you ask for.", -); - -add_translation("en", $english); diff --git a/mod/twitter/manifest.xml b/mod/twitter/manifest.xml deleted file mode 100644 index 18fa8c957..000000000 --- a/mod/twitter/manifest.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<plugin_manifest xmlns="http://www.elgg.org/plugin_manifest/1.8"> -	<name>Twitter Widget</name> -	<author>Core developers</author> -	<version>1.7</version> -	<category>bundled</category> -	<category>widget</category> -	<description>Elgg simple twitter widget</description> -	<website>http://www.elgg.org/</website> -	<copyright>See COPYRIGHT.txt</copyright> -	<license>GNU General Public License version 2</license> -	<requires> -		<type>elgg_release</type> -		<version>1.8</version> -	</requires> -</plugin_manifest> diff --git a/mod/twitter/start.php b/mod/twitter/start.php deleted file mode 100644 index b793eadf0..000000000 --- a/mod/twitter/start.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php -/** - * Elgg twitter widget - * This plugin allows users to pull in their twitter feed to display on their profile - * - * @package ElggTwitter - */ - -elgg_register_event_handler('init', 'system', 'twitter_init'); - -function twitter_init() { -	elgg_extend_view('css/elgg', 'twitter/css'); -	elgg_register_widget_type('twitter', elgg_echo('twitter:title'), elgg_echo('twitter:info')); -} diff --git a/mod/twitter/views/default/twitter/css.php b/mod/twitter/views/default/twitter/css.php deleted file mode 100644 index eb0cda98a..000000000 --- a/mod/twitter/views/default/twitter/css.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php  -/** - * Elgg Twitter CSS - *  - * @package ElggTwitter - */     -?> - -#twitter_widget { -	margin:0 10px 0 10px; -} -#twitter_widget ul { -	margin:0; -	padding:0; -} -#twitter_widget li { -	list-style-image:none; -	list-style-position:outside; -	list-style-type:none; -	margin:0 0 5px 0; -	padding:0; -	overflow-x: hidden; -	border: 2px solid #dedede; -	-webkit-border-radius: 8px; -	-moz-border-radius: 8px; -	border-radius: 8px; -} -#twitter_widget li span { -	color:#666666; -	background:white; -	 -	-webkit-border-radius: 8px;  -	-moz-border-radius: 8px; -	border-radius: 8px; -	 -	padding:5px; -	display:block; -} -p.visit_twitter a { -	background:url(<?php echo elgg_get_site_url(); ?>mod/twitter/graphics/twitter16px.png) left no-repeat; -	padding:0 0 0 20px; -	margin:0; -} -p.twitter_username .input-text { -	width:200px; -} -.visit_twitter { -	background:white; -	 -	-webkit-border-radius: 8px;  -	-moz-border-radius: 8px; -	border-radius: 8px; -	 -	padding:2px; -	margin:0 0 5px 0; -} -#twitter_widget li > a { -	display:block; -	margin:0 0 0 4px; -} -#twitter_widget li span a { -	display:inline !important; -}
\ No newline at end of file diff --git a/mod/twitter/views/default/widgets/twitter/content.php b/mod/twitter/views/default/widgets/twitter/content.php deleted file mode 100644 index caefd369a..000000000 --- a/mod/twitter/views/default/widgets/twitter/content.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php - -/** - * Elgg twitter view page - * - * @package ElggTwitter - */ - -$username = $vars['entity']->twitter_username; - -if (empty($username)) { -	echo "<p>" . elgg_echo("twitter:notset") . "</p>"; -	return; -} - -$username_is_valid = preg_match('~^[a-zA-Z0-9_]{1,20}$~', $username); -if (!$username_is_valid) { -	echo "<p>" . elgg_echo("twitter:invalid") . "</p>"; -	return; -} - - -$num = $vars['entity']->twitter_num; -if (empty($num)) { -	$num = 5; -} - -// @todo upgrade to 1.1 API https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline -$script_url = "https://api.twitter.com/1/statuses/user_timeline/" . urlencode($username) . ".json" -            . "?callback=twitterCallback2&count=" . (int) $num; - -?> -<div id="twitter_widget"> -	<ul id="twitter_update_list"></ul> -	<p class="visit_twitter"><?php echo elgg_view('output/url', array( -		'text' => elgg_echo("twitter:visit"), -		'href' => 'http://twitter.com/' . urlencode($username), -		'is_trusted' => true, -	)) ?></p> -	<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script> -	<script type="text/javascript" src="<?php echo htmlspecialchars($script_url, ENT_QUOTES, 'UTF-8') ?>"></script> -</div> diff --git a/mod/twitter/views/default/widgets/twitter/edit.php b/mod/twitter/views/default/widgets/twitter/edit.php deleted file mode 100644 index c3fc6f0d5..000000000 --- a/mod/twitter/views/default/widgets/twitter/edit.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php - -/** - * Elgg twitter edit page - * - * @package ElggTwitter - */ - -?> -<div> -	<?php echo elgg_echo("twitter:username"); ?> -	<?php echo elgg_view('input/text', array( -		'name' => 'params[twitter_username]', -		'value' => $vars['entity']->twitter_username, -	)) ?> -</div> -<div> -	<?php echo elgg_echo("twitter:num"); ?> -	<?php echo elgg_view('input/text', array( -		'name' => 'params[twitter_num]', -		'value' => $vars['entity']->twitter_num, -	)) ?> -	<span class="elgg-text-help"><?php echo elgg_echo("twitter:apibug"); ?></span> -</div>
\ No newline at end of file diff --git a/views/default/js/languages.php b/views/default/js/languages.php index c51d7bcb2..fcf903d4b 100644 --- a/views/default/js/languages.php +++ b/views/default/js/languages.php @@ -1,15 +1,33 @@  <?php  /**   * @uses $vars['language'] + * @uses $vars['lc'] if present, client will be sent long expires headers   */ -global $CONFIG;  $language = $vars['language']; +$lastcache = elgg_extract('lc', $vars, 0); -$translations = $CONFIG->translations['en']; +// @todo add server-side caching +if ($lastcache) { +	// we're relying on lastcache changes to predict language changes +	$etag = '"' . md5("$language|$lastcache") .  '"'; + +	header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true); +	header("Pragma: public", true); +	header("Cache-Control: public", true); +	header("ETag: $etag"); + +	if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) === $etag) { +		header("HTTP/1.1 304 Not Modified"); +		exit; +	} +} + +$all_translations = elgg_get_config('translations'); +$translations = $all_translations['en'];  if ($language != 'en') { -	$translations = array_merge($translations, $CONFIG->translations[$language]); +	$translations = array_merge($translations, $all_translations[$language]);  }  echo json_encode($translations);
\ No newline at end of file | 
