aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/classes/ElggBatch.php5
-rw-r--r--engine/classes/ElggEntity.php6
-rw-r--r--engine/classes/ElggGroup.php2
-rw-r--r--engine/classes/ElggLRUCache.php181
-rw-r--r--engine/classes/ElggObject.php2
-rw-r--r--engine/classes/ElggSite.php2
-rw-r--r--engine/classes/ElggStaticVariableCache.php6
-rw-r--r--engine/classes/ElggTranslit.php15
-rw-r--r--engine/classes/ElggUser.php2
-rw-r--r--engine/lib/actions.php73
-rw-r--r--engine/lib/database.php67
-rw-r--r--engine/lib/entities.php59
-rw-r--r--engine/lib/output.php8
-rw-r--r--engine/lib/river.php6
-rw-r--r--engine/lib/upgrade.php16
-rw-r--r--engine/lib/upgrades/2009102801.php5
-rw-r--r--engine/lib/upgrades/2010061501.php6
-rw-r--r--engine/lib/upgrades/2010071001.php5
-rw-r--r--engine/lib/upgrades/2010071002.php5
-rw-r--r--engine/lib/upgrades/2011052801.php5
-rw-r--r--engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php4
-rw-r--r--engine/lib/users.php12
-rw-r--r--engine/tests/api/access_collections.php3
-rw-r--r--engine/tests/regression/trac_bugs.php16
-rw-r--r--htaccess_dist8
-rw-r--r--js/lib/languages.js3
-rw-r--r--js/tests/ElggLibTest.js1
-rw-r--r--languages/en.php1
-rw-r--r--mod/bookmarks/start.php16
-rw-r--r--mod/pages/actions/pages/delete.php26
-rw-r--r--mod/pages/start.php13
-rw-r--r--mod/pages/upgrades/2012061800.php49
-rw-r--r--mod/twitter/graphics/thewire_speech_bubble.gifbin560 -> 0 bytes
-rw-r--r--mod/twitter/graphics/twitter16px.pngbin724 -> 0 bytes
-rw-r--r--mod/twitter/languages/en.php17
-rw-r--r--mod/twitter/manifest.xml16
-rw-r--r--mod/twitter/start.php14
-rw-r--r--mod/twitter/views/default/twitter/css.php63
-rw-r--r--mod/twitter/views/default/widgets/twitter/content.php42
-rw-r--r--mod/twitter/views/default/widgets/twitter/edit.php24
-rw-r--r--mod/twitter_api/languages/en.php2
-rw-r--r--views/default/js/languages.php24
42 files changed, 484 insertions, 346 deletions
diff --git a/engine/classes/ElggBatch.php b/engine/classes/ElggBatch.php
index 5d59425d0..eb93b0f5d 100644
--- a/engine/classes/ElggBatch.php
+++ b/engine/classes/ElggBatch.php
@@ -227,11 +227,6 @@ class ElggBatch
* @return bool
*/
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();
- }
// always reset results.
$this->results = array();
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('&amp;', '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 &amp; 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/js/tests/ElggLibTest.js b/js/tests/ElggLibTest.js
index 2a676e22a..31b561923 100644
--- a/js/tests/ElggLibTest.js
+++ b/js/tests/ElggLibTest.js
@@ -78,6 +78,7 @@ ElggLibTest.prototype.testNormalizeUrl = function() {
['https://example.com', 'https://example.com'],
['http://example-time.com', 'http://example-time.com'],
['//example.com', '//example.com'],
+ ['mod/my_plugin/graphics/image.jpg', elgg.config.wwwroot + 'mod/my_plugin/graphics/image.jpg'],
['ftp://example.com/file', 'ftp://example.com/file'],
['mailto:brett@elgg.org', 'mailto:brett@elgg.org'],
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/bookmarks/start.php b/mod/bookmarks/start.php
index 3846f5165..a5685388b 100644
--- a/mod/bookmarks/start.php
+++ b/mod/bookmarks/start.php
@@ -56,6 +56,9 @@ function bookmarks_init() {
// Listen to notification events and supply a more useful message
elgg_register_plugin_hook_handler('notify:entity:message', 'object', 'bookmarks_notify_message');
+ // Register bookmarks view for ecml parsing
+ elgg_register_plugin_hook_handler('get_views', 'ecml', 'bookmarks_ecml_views_hook');
+
// Register a URL handler for bookmarks
elgg_register_entity_url_handler('object', 'bookmarks', 'bookmark_url');
@@ -295,3 +298,16 @@ function bookmarks_page_menu($hook, $type, $return, $params) {
return $return;
}
+
+/**
+ * Return bookmarks views to parse for ecml
+ *
+ * @param string $hook
+ * @param string $type
+ * @param array $return
+ * @param array $params
+ */
+function bookmarks_ecml_views_hook($hook, $type, $return, $params) {
+ $return['object/bookmarks'] = elgg_echo('item:object:bookmarks');
+ return $return;
+}
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.gif
deleted file mode 100644
index d0e8606a1..000000000
--- a/mod/twitter/graphics/thewire_speech_bubble.gif
+++ /dev/null
Binary files differ
diff --git a/mod/twitter/graphics/twitter16px.png b/mod/twitter/graphics/twitter16px.png
deleted file mode 100644
index de51c6953..000000000
--- a/mod/twitter/graphics/twitter16px.png
+++ /dev/null
Binary files differ
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/mod/twitter_api/languages/en.php b/mod/twitter_api/languages/en.php
index f4b3c7f94..c19a058aa 100644
--- a/mod/twitter_api/languages/en.php
+++ b/mod/twitter_api/languages/en.php
@@ -25,7 +25,7 @@ $english = array(
'twitter_api:revoke:success' => 'Twitter access has been revoked.',
- 'twitter_api:login' => 'Allow existing users who have connected their Twitter account to sign in with Twitter?',
+ 'twitter_api:login' => 'Allow users to sign in with Twitter?',
'twitter_api:new_users' => 'Allow new users to sign up using their Twitter account even if user registration is disabled?',
'twitter_api:login:success' => 'You have been logged in.',
'twitter_api:login:error' => 'Unable to login with Twitter.',
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