diff options
Diffstat (limited to 'engine/lib')
-rw-r--r-- | engine/lib/actions.php | 73 | ||||
-rw-r--r-- | engine/lib/database.php | 67 | ||||
-rw-r--r-- | engine/lib/entities.php | 59 | ||||
-rw-r--r-- | engine/lib/output.php | 8 | ||||
-rw-r--r-- | engine/lib/river.php | 6 | ||||
-rw-r--r-- | engine/lib/upgrade.php | 16 | ||||
-rw-r--r-- | engine/lib/upgrades/2009102801.php | 5 | ||||
-rw-r--r-- | engine/lib/upgrades/2010061501.php | 6 | ||||
-rw-r--r-- | engine/lib/upgrades/2010071001.php | 5 | ||||
-rw-r--r-- | engine/lib/upgrades/2010071002.php | 5 | ||||
-rw-r--r-- | engine/lib/upgrades/2011052801.php | 5 | ||||
-rw-r--r-- | engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php | 4 | ||||
-rw-r--r-- | engine/lib/users.php | 12 |
13 files changed, 135 insertions, 136 deletions
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 |