diff options
77 files changed, 701 insertions, 217 deletions
diff --git a/.gitignore b/.gitignore index c0bba2c6c..a1c78c400 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,7 @@ !/mod/uservalidationbyemail/ !/mod/zaudio/ -# ignore IDE/hidden/OS cache files +# ignore IDE/hidden/testing/OS cache files .* *~ /nbproject @@ -49,6 +49,7 @@ Session.vim tmtags Thumbs.db Desktop.ini +/JsTestDriver-*.jar # don't ignore travis config !/.travis.yml diff --git a/CHANGES.txt b/CHANGES.txt index 9b79735b3..187dc7e25 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,26 @@ +Version 1.8.16 +(June 25, 2013 from https://github.com/Elgg/Elgg/tree/1.8) + Contributing Developers: + * Brett Profitt + * Cash Costello + * Jeff Tilson + * Jerome Bakker + * Paweł Sroka + * Steve Clay + + Security Fixes: + * Fixed avatar removal bug (thanks to Jerome Bakker for the first report of this) + + Bugfixes: + * Fixed infinite loop when deleting/disabling an entity with > 50 annotations + * Fixed deleting log tables in log rotate plugin + * Added full text index for groups if missing + * Added workaround for IE8 and jumping user avatar + * Fixed pagination for members pages + * Fixed several internal cache issues + * Plus many more bug fixes + + Version 1.8.15 (April 23, 2013 from https://github.com/Elgg/Elgg/tree/1.8) Contributing Developers: diff --git a/actions/avatar/remove.php b/actions/avatar/remove.php index cd38e456a..9cb40a760 100644 --- a/actions/avatar/remove.php +++ b/actions/avatar/remove.php @@ -3,32 +3,34 @@ * Avatar remove action */ -$guid = get_input('guid'); -$user = get_entity($guid); -if ($user) { - // Delete all icons from diskspace - $icon_sizes = elgg_get_config('icon_sizes'); - foreach ($icon_sizes as $name => $size_info) { - $file = new ElggFile(); - $file->owner_guid = $guid; - $file->setFilename("profile/{$guid}{$name}.jpg"); - $filepath = $file->getFilenameOnFilestore(); - if (!$file->delete()) { - elgg_log("Avatar file remove failed. Remove $filepath manually, please.", 'WARNING'); - } - } - - // Remove crop coords - unset($user->x1); - unset($user->x2); - unset($user->y1); - unset($user->y2); - - // Remove icon - unset($user->icontime); - system_message(elgg_echo('avatar:remove:success')); -} else { +$user_guid = get_input('guid'); +$user = get_user($user_guid); + +if (!$user || !$user->canEdit()) { register_error(elgg_echo('avatar:remove:fail')); + forward(REFERER); } +// Delete all icons from diskspace +$icon_sizes = elgg_get_config('icon_sizes'); +foreach ($icon_sizes as $name => $size_info) { + $file = new ElggFile(); + $file->owner_guid = $user_guid; + $file->setFilename("profile/{$user_guid}{$name}.jpg"); + $filepath = $file->getFilenameOnFilestore(); + if (!$file->delete()) { + elgg_log("Avatar file remove failed. Remove $filepath manually, please.", 'WARNING'); + } +} + +// Remove crop coords +unset($user->x1); +unset($user->x2); +unset($user->y1); +unset($user->y2); + +// Remove icon +unset($user->icontime); + +system_message(elgg_echo('avatar:remove:success')); forward(REFERER); diff --git a/actions/login.php b/actions/login.php index 1e5e92ede..bd7f91299 100644 --- a/actions/login.php +++ b/actions/login.php @@ -9,7 +9,6 @@ // set forward url if (!empty($_SESSION['last_forward_from'])) { $forward_url = $_SESSION['last_forward_from']; - unset($_SESSION['last_forward_from']); } elseif (get_input('returntoreferer')) { $forward_url = REFERER; } else { @@ -62,5 +61,9 @@ if ($user->language) { $message = elgg_echo('loginok'); } +if (isset($_SESSION['last_forward_from'])) { + unset($_SESSION['last_forward_from']); +} + system_message($message); forward($forward_url); diff --git a/actions/profile/edit.php b/actions/profile/edit.php index b817463ac..e1f066e82 100644 --- a/actions/profile/edit.php +++ b/actions/profile/edit.php @@ -4,6 +4,8 @@ * */ +elgg_make_sticky_form('profile:edit'); + $guid = get_input('guid'); $owner = get_entity($guid); @@ -80,7 +82,7 @@ if (sizeof($input) > 0) { ); elgg_delete_metadata($options); - if(!is_null($value) && ($value !== '')){ + if (!is_null($value) && ($value !== '')) { // only create metadata for non empty values (0 is allowed) to prevent metadata records with empty string values #4858 if (isset($accesslevel[$shortname])) { @@ -107,6 +109,7 @@ if (sizeof($input) > 0) { // Notify of profile update elgg_trigger_event('profileupdate', $owner->type, $owner); + elgg_clear_sticky_form('profile:edit'); system_message(elgg_echo("profile:saved")); } diff --git a/engine/classes/ElggAttributeLoader.php b/engine/classes/ElggAttributeLoader.php index b91e4b88a..0b770da75 100644 --- a/engine/classes/ElggAttributeLoader.php +++ b/engine/classes/ElggAttributeLoader.php @@ -24,7 +24,7 @@ class ElggAttributeLoader { 'time_created', 'time_updated', 'last_action', - 'enabled' + 'enabled', ); /** @@ -200,6 +200,8 @@ class ElggAttributeLoader { // saved, these are stored w/ type "site", but with no sites_entity row. These // are probably only created in the unit tests. // @todo Don't save vanilla ElggEntities with type "site" + + $row = $this->filterAddedColumns($row); $row['guid'] = (int) $row['guid']; return $row; } @@ -209,6 +211,8 @@ class ElggAttributeLoader { } } + $row = $this->filterAddedColumns($row); + // Note: If there are still missing attributes, we're running on a 1.7 or earlier schema. We let // this pass so the upgrades can run. @@ -217,4 +221,28 @@ class ElggAttributeLoader { return $row; } + + /** + * Filter out keys returned by the query which should not appear in the entity's attributes + * + * @param array $row All columns from the query + * @return array Columns acceptable for the entity's attributes + */ + protected function filterAddedColumns($row) { + // make an array with keys as acceptable attribute names + $acceptable_attrs = self::$primary_attr_names; + array_splice($acceptable_attrs, count($acceptable_attrs), 0, $this->secondary_attr_names); + $acceptable_attrs = array_combine($acceptable_attrs, $acceptable_attrs); + + // @todo remove these when #4584 is in place + $acceptable_attrs['tables_split'] = true; + $acceptable_attrs['tables_loaded'] = true; + + foreach ($row as $key => $val) { + if (!isset($acceptable_attrs[$key])) { + unset($row[$key]); + } + } + return $row; + } } diff --git a/engine/classes/ElggBatch.php b/engine/classes/ElggBatch.php index eb93b0f5d..d810ea066 100644 --- a/engine/classes/ElggBatch.php +++ b/engine/classes/ElggBatch.php @@ -150,6 +150,20 @@ class ElggBatch private $incrementOffset = true; /** + * Entities that could not be instantiated during a fetch + * + * @var stdClass[] + */ + private $incompleteEntities = array(); + + /** + * Total number of incomplete entities fetched + * + * @var int + */ + private $totalIncompletes = 0; + + /** * Batches operations on any elgg_get_*() or compatible function that supports * an options array. * @@ -222,6 +236,17 @@ class ElggBatch } /** + * Tell the process that an entity was incomplete during a fetch + * + * @param stdClass $row + * + * @access private + */ + public function reportIncompleteEntity(stdClass $row) { + $this->incompleteEntities[] = $row; + } + + /** * Fetches the next chunk of results * * @return bool @@ -260,27 +285,47 @@ class ElggBatch if ($this->incrementOffset) { $offset = $this->offset + $this->retrievedResults; } else { - $offset = $this->offset; + $offset = $this->offset + $this->totalIncompletes; } $current_options = array( 'limit' => $limit, - 'offset' => $offset + 'offset' => $offset, + '__ElggBatch' => $this, ); $options = array_merge($this->options, $current_options); - $getter = $this->getter; - if (is_string($getter)) { - $this->results = $getter($options); - } else { - $this->results = call_user_func_array($getter, array($options)); + $this->incompleteEntities = array(); + $this->results = call_user_func_array($this->getter, array($options)); + + $num_results = count($this->results); + $num_incomplete = count($this->incompleteEntities); + + $this->totalIncompletes += $num_incomplete; + + if ($this->incompleteEntities) { + // pad the front of the results with nulls representing the incompletes + array_splice($this->results, 0, 0, array_pad(array(), $num_incomplete, null)); + // ...and skip past them + reset($this->results); + for ($i = 0; $i < $num_incomplete; $i++) { + next($this->results); + } } if ($this->results) { $this->chunkIndex++; - $this->resultIndex = 0; - $this->retrievedResults += count($this->results); + + // let the system know we've jumped past the nulls + $this->resultIndex = $num_incomplete; + + $this->retrievedResults += ($num_results + $num_incomplete); + if ($num_results == 0) { + // This fetch was *all* incompletes! We need to fetch until we can either + // offer at least one row to iterate over, or give up. + return $this->getNextResultsChunk(); + } return true; } else { return false; diff --git a/engine/classes/ElggEntity.php b/engine/classes/ElggEntity.php index 8b3ceb551..dd1c7c114 100644 --- a/engine/classes/ElggEntity.php +++ b/engine/classes/ElggEntity.php @@ -1270,15 +1270,23 @@ abstract class ElggEntity extends ElggData implements public function save() { $guid = $this->getGUID(); if ($guid > 0) { - _elgg_cache_entity($this); - return update_entity( + // See #5600. This ensures the lower level can_edit_entity() check will use a + // fresh entity from the DB so it sees the persisted owner_guid + _elgg_disable_caching_for_entity($guid); + + $ret = update_entity( $guid, $this->get('owner_guid'), $this->get('access_id'), $this->get('container_guid'), $this->get('time_created') ); + + _elgg_enable_caching_for_entity($guid); + _elgg_cache_entity($this); + + return $ret; } else { // Create a new entity (nb: using attribute array directly // 'cos set function does something special!) diff --git a/engine/classes/ElggFile.php b/engine/classes/ElggFile.php index 3e9c24c17..23080834b 100644 --- a/engine/classes/ElggFile.php +++ b/engine/classes/ElggFile.php @@ -275,9 +275,14 @@ class ElggFile extends ElggObject { */ public function delete() { $fs = $this->getFilestore(); - if ($fs->delete($this)) { - return parent::delete(); + + $result = $fs->delete($this); + + if ($this->getGUID() && $result) { + $result = parent::delete(); } + + return $result; } /** diff --git a/engine/classes/ElggGroup.php b/engine/classes/ElggGroup.php index 61f9163d5..7e69b7a84 100644 --- a/engine/classes/ElggGroup.php +++ b/engine/classes/ElggGroup.php @@ -352,7 +352,12 @@ class ElggGroup extends ElggEntity } // Now save specific stuff - return create_group_entity($this->get('guid'), $this->get('name'), $this->get('description')); + + _elgg_disable_caching_for_entity($this->guid); + $ret = create_group_entity($this->get('guid'), $this->get('name'), $this->get('description')); + _elgg_enable_caching_for_entity($this->guid); + + return $ret; } // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// diff --git a/engine/classes/ElggObject.php b/engine/classes/ElggObject.php index d54752dca..aeaa3ba5c 100644 --- a/engine/classes/ElggObject.php +++ b/engine/classes/ElggObject.php @@ -126,8 +126,12 @@ class ElggObject extends ElggEntity { } // Save ElggObject-specific attributes - return create_object_entity($this->get('guid'), $this->get('title'), - $this->get('description')); + + _elgg_disable_caching_for_entity($this->guid); + $ret = create_object_entity($this->get('guid'), $this->get('title'), $this->get('description')); + _elgg_enable_caching_for_entity($this->guid); + + return $ret; } /** diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php index c1c46f272..7bf6eb1df 100644 --- a/engine/classes/ElggPlugin.php +++ b/engine/classes/ElggPlugin.php @@ -350,11 +350,14 @@ class ElggPlugin extends ElggObject { */ public function unsetAllSettings() { $db_prefix = get_config('dbprefix'); - $ps_prefix = elgg_namespace_plugin_private_setting('setting', ''); + + $us_prefix = elgg_namespace_plugin_private_setting('user_setting', '', $this->getID()); + $is_prefix = elgg_namespace_plugin_private_setting('internal', '', $this->getID()); $q = "DELETE FROM {$db_prefix}private_settings WHERE entity_guid = $this->guid - AND name NOT LIKE '$ps_prefix%'"; + AND name NOT LIKE '$us_prefix%' + AND name NOT LIKE '$is_prefix%'"; return delete_data($q); } @@ -546,7 +549,7 @@ class ElggPlugin extends ElggObject { * Returns if the plugin is complete, meaning has all required files * and Elgg can read them and they make sense. * - * @todo bad name? This could be confused with isValid() from ElggPackage. + * @todo bad name? This could be confused with isValid() from ElggPluginPackage. * * @return bool */ diff --git a/engine/classes/ElggPluginPackage.php b/engine/classes/ElggPluginPackage.php index 209242288..37eb4bf4d 100644 --- a/engine/classes/ElggPluginPackage.php +++ b/engine/classes/ElggPluginPackage.php @@ -294,6 +294,7 @@ class ElggPluginPackage { return true; } + $this->errorMsg = elgg_echo('unknown_error'); return false; } diff --git a/engine/classes/ElggUser.php b/engine/classes/ElggUser.php index 6d9f10b57..6163f9b62 100644 --- a/engine/classes/ElggUser.php +++ b/engine/classes/ElggUser.php @@ -40,6 +40,9 @@ class ElggUser extends ElggEntity $this->attributes['code'] = NULL; $this->attributes['banned'] = "no"; $this->attributes['admin'] = 'no'; + $this->attributes['prev_last_action'] = NULL; + $this->attributes['last_login'] = NULL; + $this->attributes['prev_last_login'] = NULL; $this->attributes['tables_split'] = 2; } @@ -129,9 +132,13 @@ class ElggUser extends ElggEntity } // Now save specific stuff - return create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'), + _elgg_disable_caching_for_entity($this->guid); + $ret = create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'), $this->get('password'), $this->get('salt'), $this->get('email'), $this->get('language'), $this->get('code')); + _elgg_enable_caching_for_entity($this->guid); + + return $ret; } /** diff --git a/engine/handlers/cache_handler.php b/engine/handlers/cache_handler.php index 9848d3531..36fc665bb 100644 --- a/engine/handlers/cache_handler.php +++ b/engine/handlers/cache_handler.php @@ -88,20 +88,18 @@ header("ETag: \"$etag\""); $filename = $dataroot . 'views_simplecache/' . md5($viewtype . $view); if (file_exists($filename)) { - $contents = file_get_contents($filename); + readfile($filename); } else { // someone trying to access a non-cached file or a race condition with cache flushing mysql_close($mysql_dblink); require_once(dirname(dirname(__FILE__)) . "/start.php"); global $CONFIG; - if (!isset($CONFIG->views->simplecache[$view])) { + if (!in_array($view, $CONFIG->views->simplecache)) { header("HTTP/1.1 404 Not Found"); exit; } elgg_set_viewtype($viewtype); - $contents = elgg_view($view); + echo elgg_view($view); } - -echo $contents; diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php index 81755f169..124e67e0f 100644 --- a/engine/lib/annotations.php +++ b/engine/lib/annotations.php @@ -419,8 +419,8 @@ function elgg_list_entities_from_annotations($options = array()) { function elgg_get_entities_from_annotation_calculation($options) { $db_prefix = elgg_get_config('dbprefix'); $defaults = array( - 'calculation' => 'sum', - 'order_by' => 'annotation_calculation desc' + 'calculation' => 'sum', + 'order_by' => 'annotation_calculation desc' ); $options = array_merge($defaults, $options); @@ -457,6 +457,12 @@ function elgg_get_entities_from_annotation_calculation($options) { * @return string */ function elgg_list_entities_from_annotation_calculation($options) { + $defaults = array( + 'calculation' => 'sum', + 'order_by' => 'annotation_calculation desc' + ); + $options = array_merge($defaults, $options); + return elgg_list_entities($options, 'elgg_get_entities_from_annotation_calculation'); } diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php index fb652a141..b5ef7e572 100644 --- a/engine/lib/elgglib.php +++ b/engine/lib/elgglib.php @@ -2247,6 +2247,9 @@ function elgg_api_test($hook, $type, $value, $params) { /**#@+ * Controls access levels on ElggEntity entities, metadata, and annotations. * + * @warning ACCESS_DEFAULT is a place holder for the input/access view. Do not + * use it when saving an entity. + * * @var int */ define('ACCESS_DEFAULT', -1); diff --git a/engine/lib/entities.php b/engine/lib/entities.php index 15ab1170e..997db79d2 100644 --- a/engine/lib/entities.php +++ b/engine/lib/entities.php @@ -17,6 +17,15 @@ global $ENTITY_CACHE; $ENTITY_CACHE = array(); /** + * GUIDs of entities banned from the entity cache (during this request) + * + * @global array $ENTITY_CACHE_DISABLED_GUIDS + * @access private + */ +global $ENTITY_CACHE_DISABLED_GUIDS; +$ENTITY_CACHE_DISABLED_GUIDS = array(); + +/** * Cache subtypes and related class names. * * @global array|null $SUBTYPE_CACHE array once populated from DB, initially null @@ -26,6 +35,34 @@ global $SUBTYPE_CACHE; $SUBTYPE_CACHE = null; /** + * Remove this entity from the entity cache and make sure it is not re-added + * + * @param int $guid The entity guid + * + * @access private + * @todo this is a workaround until #5604 can be implemented + */ +function _elgg_disable_caching_for_entity($guid) { + global $ENTITY_CACHE_DISABLED_GUIDS; + + _elgg_invalidate_cache_for_entity($guid); + $ENTITY_CACHE_DISABLED_GUIDS[$guid] = true; +} + +/** + * Allow this entity to be stored in the entity cache + * + * @param int $guid The entity guid + * + * @access private + */ +function _elgg_enable_caching_for_entity($guid) { + global $ENTITY_CACHE_DISABLED_GUIDS; + + unset($ENTITY_CACHE_DISABLED_GUIDS[$guid]); +} + +/** * Invalidate this class's entry in the cache. * * @param int $guid The entity guid @@ -57,7 +94,7 @@ function _elgg_invalidate_cache_for_entity($guid) { * @todo Use an ElggCache object */ function _elgg_cache_entity(ElggEntity $entity) { - global $ENTITY_CACHE; + global $ENTITY_CACHE, $ENTITY_CACHE_DISABLED_GUIDS; // Don't cache non-plugin entities while access control is off, otherwise they could be // exposed to users who shouldn't see them when control is re-enabled. @@ -65,6 +102,11 @@ function _elgg_cache_entity(ElggEntity $entity) { return; } + $guid = $entity->getGUID(); + if (isset($ENTITY_CACHE_DISABLED_GUIDS[$guid])) { + return; + } + // Don't store too many or we'll have memory problems // @todo Pick a less arbitrary limit if (count($ENTITY_CACHE) > 256) { @@ -79,7 +121,7 @@ function _elgg_cache_entity(ElggEntity $entity) { elgg_get_metadata_cache()->clear($random_guid); } - $ENTITY_CACHE[$entity->guid] = $entity; + $ENTITY_CACHE[$guid] = $entity; } /** @@ -407,7 +449,7 @@ function update_subtype($type, $subtype, $class = '') { * @param int $time_created The time creation timestamp * * @return bool - * @link http://docs.elgg.org/DataModel/Entities + * @throws InvalidParameterException * @access private */ function update_entity($guid, $owner_guid, $access_id, $container_guid = null, $time_created = null) { @@ -430,6 +472,10 @@ function update_entity($guid, $owner_guid, $access_id, $container_guid = null, $ $time_created = (int) $time_created; } + if ($access_id == ACCESS_DEFAULT) { + throw new InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in elgglib.h'); + } + if ($entity && $entity->canEdit()) { if (elgg_trigger_event('update', $entity->type, $entity)) { $ret = update_data("UPDATE {$CONFIG->dbprefix}entities @@ -556,7 +602,6 @@ $container_guid = 0) { $type = sanitise_string($type); $subtype_id = add_subtype($type, $subtype); $owner_guid = (int)$owner_guid; - $access_id = (int)$access_id; $time = time(); if ($site_guid == 0) { $site_guid = $CONFIG->site_guid; @@ -565,6 +610,10 @@ $container_guid = 0) { if ($container_guid == 0) { $container_guid = $owner_guid; } + $access_id = (int)$access_id; + if ($access_id == ACCESS_DEFAULT) { + throw new InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in elgglib.h'); + } $user_guid = elgg_get_logged_in_user_guid(); if (!can_write_to_container($user_guid, $owner_guid, $type, $subtype)) { @@ -712,7 +761,7 @@ function get_entity($guid) { // @todo We need a single Memcache instance with a shared pool of namespace wrappers. This function would pull an instance from the pool. static $shared_cache; - // We could also use: if (!(int) $guid) { return FALSE }, + // We could also use: if (!(int) $guid) { return FALSE }, // but that evaluates to a false positive for $guid = TRUE. // This is a bit slower, but more thorough. if (!is_numeric($guid) || $guid === 0 || $guid === '0') { @@ -884,6 +933,8 @@ function elgg_get_entities(array $options = array()) { 'joins' => array(), 'callback' => 'entity_row_to_elggstar', + + '__ElggBatch' => null, ); $options = array_merge($defaults, $options); @@ -1001,7 +1052,7 @@ function elgg_get_entities(array $options = array()) { } if ($options['callback'] === 'entity_row_to_elggstar') { - $dt = _elgg_fetch_entities_from_sql($query); + $dt = _elgg_fetch_entities_from_sql($query, $options['__ElggBatch']); } else { $dt = get_data($query, $options['callback']); } @@ -1036,13 +1087,14 @@ function elgg_get_entities(array $options = array()) { /** * Return entities from an SQL query generated by elgg_get_entities. * - * @param string $sql + * @param string $sql + * @param ElggBatch $batch * @return ElggEntity[] * * @access private * @throws LogicException */ -function _elgg_fetch_entities_from_sql($sql) { +function _elgg_fetch_entities_from_sql($sql, ElggBatch $batch = null) { static $plugin_subtype; if (null === $plugin_subtype) { $plugin_subtype = get_subtype_id('object', 'plugin'); @@ -1119,6 +1171,11 @@ function _elgg_fetch_entities_from_sql($sql) { } catch (IncompleteEntityException $e) { // don't let incomplete entities throw fatal errors unset($rows[$i]); + + // report incompletes to the batch process that spawned this query + if ($batch) { + $batch->reportIncompleteEntity($row); + } } } } @@ -1416,8 +1473,10 @@ function elgg_list_entities(array $options = array(), $getter = 'elgg_get_entiti global $autofeed; $autofeed = true; + $offset_key = isset($options['offset_key']) ? $options['offset_key'] : 'offset'; + $defaults = array( - 'offset' => (int) max(get_input('offset', 0), 0), + 'offset' => (int) max(get_input($offset_key, 0), 0), 'limit' => (int) max(get_input('limit', 10), 0), 'full_view' => TRUE, 'list_type_toggle' => FALSE, @@ -2069,7 +2128,7 @@ function can_edit_entity_metadata($entity_guid, $user_guid = 0, $metadata = null $return = null; - if ($metadata->owner_guid == 0) { + if ($metadata && ($metadata->owner_guid == 0)) { $return = true; } if (is_null($return)) { @@ -2470,11 +2529,18 @@ function update_entity_last_action($guid, $posted = NULL) { function entities_gc() { global $CONFIG; - $tables = array ('sites_entity', 'objects_entity', 'groups_entity', 'users_entity'); + $tables = array( + 'site' => 'sites_entity', + 'object' => 'objects_entity', + 'group' => 'groups_entity', + 'user' => 'users_entity' + ); - foreach ($tables as $table) { - delete_data("DELETE from {$CONFIG->dbprefix}{$table} - where guid NOT IN (SELECT guid from {$CONFIG->dbprefix}entities)"); + foreach ($tables as $type => $table) { + delete_data("DELETE FROM {$CONFIG->dbprefix}{$table} + WHERE guid NOT IN (SELECT guid FROM {$CONFIG->dbprefix}entities)"); + delete_data("DELETE FROM {$CONFIG->dbprefix}entities + WHERE type = '$type' AND guid NOT IN (SELECT guid FROM {$CONFIG->dbprefix}{$table})"); } } diff --git a/engine/lib/group.php b/engine/lib/group.php index 359bc59c2..6ded8a825 100644 --- a/engine/lib/group.php +++ b/engine/lib/group.php @@ -240,6 +240,7 @@ function leave_group($group_guid, $user_guid) { */ function get_users_membership($user_guid) { $options = array( + 'type' => 'group', 'relationship' => 'member', 'relationship_guid' => $user_guid, 'inverse_relationship' => false, diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php index 43f7d5d6e..d2f8d4cd4 100644 --- a/engine/lib/metadata.php +++ b/engine/lib/metadata.php @@ -191,19 +191,19 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i } // Add the metastring - $value = add_metastring($value); - if (!$value) { + $value_id = add_metastring($value); + if (!$value_id) { return false; } - $name = add_metastring($name); - if (!$name) { + $name_id = add_metastring($name); + if (!$name_id) { return false; } // If ok then add it $query = "UPDATE {$CONFIG->dbprefix}metadata" - . " set name_id='$name', value_id='$value', value_type='$value_type', access_id=$access_id," + . " set name_id='$name_id', value_id='$value_id', value_type='$value_type', access_id=$access_id," . " owner_guid=$owner_guid where id=$id"; $result = update_data($query); @@ -402,9 +402,11 @@ function elgg_enable_metadata(array $options) { * 'operand' => '=', * 'case_sensitive' => TRUE * ) - * Currently if multiple values are sent via + * Currently if multiple values are sent via * an array (value => array('value1', 'value2') * the pair's operand will be forced to "IN". + * If passing "IN" as the operand and a string as the value, + * the value must be a properly quoted and escaped string. * * metadata_name_value_pairs_operator => NULL|STR The operator to use for combining * (name = value) OPERATOR (name = value); default AND diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php index 39a81c6d0..57d876c06 100644 --- a/engine/lib/metastrings.php +++ b/engine/lib/metastrings.php @@ -425,7 +425,7 @@ function elgg_get_metastring_based_objects($options) { $wheres[] = get_access_sql_suffix('n_table'); } - if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) { + if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) { $selects = array_unique($selects); // evalutate selects $select_str = ''; @@ -436,6 +436,9 @@ function elgg_get_metastring_based_objects($options) { } $query = "SELECT DISTINCT n_table.*{$select_str} FROM {$db_prefix}$type n_table"; + } elseif ($options['count']) { + // count is over the entities + $query = "SELECT count(DISTINCT e.guid) as calculation FROM {$db_prefix}$type n_table"; } else { $query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table"; } @@ -464,7 +467,7 @@ function elgg_get_metastring_based_objects($options) { $defaults['order_by']); } - if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) { + if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) { if (isset($options['group_by'])) { $options['group_by'] = sanitise_string($options['group_by']); $query .= " GROUP BY {$options['group_by']}"; diff --git a/engine/lib/navigation.php b/engine/lib/navigation.php index 118a7214c..ab9cc05e8 100644 --- a/engine/lib/navigation.php +++ b/engine/lib/navigation.php @@ -218,7 +218,7 @@ function elgg_push_breadcrumb($title, $link = NULL) { } // avoid key collisions. - $CONFIG->breadcrumbs[] = array('title' => $title, 'link' => $link); + $CONFIG->breadcrumbs[] = array('title' => elgg_get_excerpt($title, 100), 'link' => $link); } /** @@ -323,7 +323,8 @@ function elgg_site_menu_setup($hook, $type, $return, $params) { } if (!$selected) { - // nothing selected, match name to context + // nothing selected, match name to context or match url + $current_url = current_page_url(); foreach ($return as $section_name => $section) { foreach ($section as $key => $item) { // only highlight internal links @@ -332,6 +333,10 @@ function elgg_site_menu_setup($hook, $type, $return, $params) { $return[$section_name][$key]->setSelected(true); break 2; } + if ($item->getHref() == $current_url) { + $return[$section_name][$key]->setSelected(true); + break 2; + } } } } diff --git a/engine/lib/output.php b/engine/lib/output.php index 5adc01053..6172a5c8d 100644 --- a/engine/lib/output.php +++ b/engine/lib/output.php @@ -27,16 +27,16 @@ function parse_urls($text) { // By default htmlawed rewrites tags to this format. // if PHP supported conditional negative lookbehinds we could use this: // $r = preg_replace_callback('/(?<!=)(?<![ ])?(?<!["\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\!\(\),]+)/i', - $r = preg_replace_callback('/(?<![=\/"\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\(\)]+)/i', + $r = preg_replace_callback('/(?<![=\/"\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\']+)/i', create_function( '$matches', ' $url = $matches[1]; - $punc = \'\'; + $punc = ""; $last = substr($url, -1, 1); - if (in_array($last, array(".", "!", ","))) { + if (in_array($last, array(".", "!", ",", "(", ")"))) { $punc = $last; - $url = rtrim($url, ".!,"); + $url = rtrim($url, ".!,()"); } $urltext = str_replace("/", "/<wbr />", $url); return "<a href=\"$url\" rel=\"nofollow\">$urltext</a>$punc"; diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php index a34c2045b..fb28e1e9a 100644 --- a/engine/lib/sessions.php +++ b/engine/lib/sessions.php @@ -87,6 +87,9 @@ function elgg_is_admin_logged_in() { */ function elgg_is_admin_user($user_guid) { global $CONFIG; + + $user_guid = (int)$user_guid; + // cannot use magic metadata here because of recursion // must support the old way of getting admin from metadata diff --git a/engine/lib/statistics.php b/engine/lib/statistics.php index 0c9a3c945..4cb0bb0b8 100644 --- a/engine/lib/statistics.php +++ b/engine/lib/statistics.php @@ -95,13 +95,17 @@ function get_number_users($show_deactivated = false) { * @return string */ function get_online_users() { - $count = find_active_users(600, 10, 0, true); - $objects = find_active_users(600, 10); + $limit = max(0, (int) get_input("limit", 10)); + $offset = max(0, (int) get_input("offset", 0)); + + $count = find_active_users(600, $limit, $offset, true); + $objects = find_active_users(600, $limit, $offset); if ($objects) { return elgg_view_entity_list($objects, array( 'count' => $count, - 'limit' => 10, + 'limit' => $limit, + 'offset' => $offset )); } return ''; diff --git a/engine/lib/views.php b/engine/lib/views.php index c4b349fc6..65ba20204 100644 --- a/engine/lib/views.php +++ b/engine/lib/views.php @@ -1638,7 +1638,7 @@ function elgg_views_boot() { } // set default icon sizes - can be overridden in settings.php or with plugin - if (!$CONFIG->icon_sizes) { + if (!isset($CONFIG->icon_sizes)) { $icon_sizes = array( 'topbar' => array('w' => 16, 'h' => 16, 'square' => TRUE, 'upscale' => TRUE), 'tiny' => array('w' => 25, 'h' => 25, 'square' => TRUE, 'upscale' => TRUE), diff --git a/engine/tests/api/entity_getter_functions.php b/engine/tests/api/entity_getter_functions.php index 7bf8ef04a..0492b1fb0 100644 --- a/engine/tests/api/entity_getter_functions.php +++ b/engine/tests/api/entity_getter_functions.php @@ -2755,7 +2755,7 @@ class ElggCoreEntityGetterFunctionsTest extends ElggCoreUnitTest { 'calculation' => 'count', 'count' => true, ); - $count = (int)elgg_get_entities_from_annotation_calculation($options); + $count = elgg_get_entities_from_annotation_calculation($options); $this->assertEqual(1, $count); } diff --git a/engine/tests/api/helpers.php b/engine/tests/api/helpers.php index 62e4471e0..10216140f 100644 --- a/engine/tests/api/helpers.php +++ b/engine/tests/api/helpers.php @@ -578,6 +578,107 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest { $this->assertEqual(11, $j); } + public function testElggBatchReadHandlesBrokenEntities() { + $num_test_entities = 8; + $guids = array(); + for ($i = $num_test_entities; $i > 0; $i--) { + $entity = new ElggObject(); + $entity->type = 'object'; + $entity->subtype = 'test_5357_subtype'; + $entity->access_id = ACCESS_PUBLIC; + $entity->save(); + $guids[] = $entity->guid; + _elgg_invalidate_cache_for_entity($entity->guid); + } + + // break entities such that the first fetch has one incomplete + // and the second and third fetches have only incompletes! + $db_prefix = elgg_get_config('dbprefix'); + delete_data(" + DELETE FROM {$db_prefix}objects_entity + WHERE guid IN ({$guids[1]}, {$guids[2]}, {$guids[3]}, {$guids[4]}, {$guids[5]}) + "); + + $options = array( + 'type' => 'object', + 'subtype' => 'test_5357_subtype', + 'order_by' => 'e.guid', + ); + + $entities_visited = array(); + $batch = new ElggBatch('elgg_get_entities', $options, null, 2); + /* @var ElggEntity[] $batch */ + foreach ($batch as $entity) { + $entities_visited[] = $entity->guid; + } + + // The broken entities should not have been visited + $this->assertEqual($entities_visited, array($guids[0], $guids[6], $guids[7])); + + // cleanup (including leftovers from previous tests) + $entity_rows = elgg_get_entities(array_merge($options, array( + 'callback' => '', + 'limit' => false, + ))); + $guids = array(); + foreach ($entity_rows as $row) { + $guids[] = $row->guid; + } + delete_data("DELETE FROM {$db_prefix}entities WHERE guid IN (" . implode(',', $guids) . ")"); + delete_data("DELETE FROM {$db_prefix}objects_entity WHERE guid IN (" . implode(',', $guids) . ")"); + } + + public function testElggBatchDeleteHandlesBrokenEntities() { + $num_test_entities = 8; + $guids = array(); + for ($i = $num_test_entities; $i > 0; $i--) { + $entity = new ElggObject(); + $entity->type = 'object'; + $entity->subtype = 'test_5357_subtype'; + $entity->access_id = ACCESS_PUBLIC; + $entity->save(); + $guids[] = $entity->guid; + _elgg_invalidate_cache_for_entity($entity->guid); + } + + // break entities such that the first fetch has one incomplete + // and the second and third fetches have only incompletes! + $db_prefix = elgg_get_config('dbprefix'); + delete_data(" + DELETE FROM {$db_prefix}objects_entity + WHERE guid IN ({$guids[1]}, {$guids[2]}, {$guids[3]}, {$guids[4]}, {$guids[5]}) + "); + + $options = array( + 'type' => 'object', + 'subtype' => 'test_5357_subtype', + 'order_by' => 'e.guid', + ); + + $entities_visited = array(); + $batch = new ElggBatch('elgg_get_entities', $options, null, 2, false); + /* @var ElggEntity[] $batch */ + foreach ($batch as $entity) { + $entities_visited[] = $entity->guid; + $entity->delete(); + } + + // The broken entities should not have been visited + $this->assertEqual($entities_visited, array($guids[0], $guids[6], $guids[7])); + + // cleanup (including leftovers from previous tests) + $entity_rows = elgg_get_entities(array_merge($options, array( + 'callback' => '', + 'limit' => false, + ))); + $guids = array(); + foreach ($entity_rows as $row) { + $guids[] = $row->guid; + } + delete_data("DELETE FROM {$db_prefix}entities WHERE guid IN (" . implode(',', $guids) . ")"); + delete_data("DELETE FROM {$db_prefix}objects_entity WHERE guid IN (" . implode(',', $guids) . ")"); + } + static function elgg_batch_callback_test($options, $reset = false) { static $count = 1; diff --git a/engine/tests/api/metadata_cache.php b/engine/tests/api/metadata_cache.php index 846116a7b..7fb328169 100644 --- a/engine/tests/api/metadata_cache.php +++ b/engine/tests/api/metadata_cache.php @@ -166,4 +166,11 @@ class ElggCoreMetadataCacheTest extends ElggCoreUnitTest { $actual = $this->cache->filterMetadataHeavyEntities($guids, 6000); $this->assertIdentical($actual, $expected); } + + public function testCreateMetadataInvalidates() { + $this->obj1->foo = 1; + create_metadata($this->guid1, 'foo', 2, '', elgg_get_logged_in_user_guid(), ACCESS_FRIENDS); + + $this->assertEqual($this->obj1->foo, 2); + } } diff --git a/engine/tests/objects/users.php b/engine/tests/objects/users.php index a3573acb6..dc9129326 100644 --- a/engine/tests/objects/users.php +++ b/engine/tests/objects/users.php @@ -65,6 +65,9 @@ class ElggCoreUserTest extends ElggCoreUnitTest { $attributes['code'] = NULL; $attributes['banned'] = 'no'; $attributes['admin'] = 'no'; + $attributes['prev_last_action'] = NULL; + $attributes['last_login'] = NULL; + $attributes['prev_last_login'] = NULL; ksort($attributes); $entity_attributes = $this->user->expose_attributes(); diff --git a/engine/tests/regression/trac_bugs.php b/engine/tests/regression/trac_bugs.php index 051aa8d1b..f173b5b9f 100644 --- a/engine/tests/regression/trac_bugs.php +++ b/engine/tests/regression/trac_bugs.php @@ -291,9 +291,45 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest { 'unquoted already anchor <a href=http://www.yahoo.com>yahoo</a>' => 'unquoted already anchor <a href=http://www.yahoo.com>yahoo</a>', + + 'parens in uri http://thedailywtf.com/Articles/A-(Long-Overdue)-BuildMaster-Introduction.aspx' => + 'parens in uri <a href="http://thedailywtf.com/Articles/A-(Long-Overdue)-BuildMaster-Introduction.aspx" rel="nofollow">http:/<wbr />/<wbr />thedailywtf.com/<wbr />Articles/<wbr />A-(Long-Overdue)-BuildMaster-Introduction.aspx</a>' ); foreach ($cases as $input => $output) { $this->assertEqual($output, parse_urls($input)); } } + + /** + * Ensure additional select columns do not end up in entity attributes. + * + * https://github.com/Elgg/Elgg/issues/5538 + */ + public function test_extra_columns_dont_appear_in_attributes() { + global $ENTITY_CACHE; + + // may not have groups in DB - let's create one + $group = new ElggGroup(); + $group->name = 'test_group'; + $group->access_id = ACCESS_PUBLIC; + $this->assertTrue($group->save() !== false); + + // entity cache interferes with our test + $ENTITY_CACHE = array(); + + foreach (array('site', 'user', 'group', 'object') as $type) { + $entities = elgg_get_entities(array( + 'type' => $type, + 'selects' => array('1 as _nonexistent_test_column'), + 'limit' => 1, + )); + if (!$this->assertTrue($entities, "Query for '$type' did not return an entity.")) { + continue; + } + $entity = $entities[0]; + $this->assertNull($entity->_nonexistent_test_column, "Additional select columns are leaking to attributes for '$type'"); + } + + $group->delete(); + } } diff --git a/install/cli/sample_installer.php b/install/cli/sample_installer.php index 0bae0cd23..a51f9aae4 100644 --- a/install/cli/sample_installer.php +++ b/install/cli/sample_installer.php @@ -1,28 +1,12 @@ <?php + /** * Sample cli installer script */ +// change to true to run this script. Change back to false when done. $enabled = false; -// Do not edit below this line. ////////////////////////////// - - -if (!$enabled) { - echo "To enable this script, change \$enabled to true.\n"; - echo "You *must* disable this script after a successful installation.\n"; - exit; -} - -if (PHP_SAPI !== 'cli') { - echo "You must use the command line to run this script."; - exit; -} - -require_once(dirname(dirname(__FILE__)) . "/ElggInstaller.php"); - -$installer = new ElggInstaller(); - // none of the following may be empty $params = array( // database parameters @@ -43,11 +27,29 @@ $params = array( 'password' => '', ); + +// Do not edit below this line. ////////////////////////////// + + +if (!$enabled) { + echo "To enable this script, change \$enabled to true.\n"; + echo "You *must* disable this script after a successful installation.\n"; + exit; +} + +if (PHP_SAPI !== 'cli') { + echo "You must use the command line to run this script."; + exit; +} + +require_once(dirname(dirname(__FILE__)) . "/ElggInstaller.php"); + +$installer = new ElggInstaller(); + // install and create the .htaccess file $installer->batchInstall($params, TRUE); // at this point installation has completed (otherwise an exception halted execution). - // try to rewrite the script to disable it. if (is_writable(__FILE__)) { $code = file_get_contents(__FILE__); diff --git a/js/lib/elgglib.js b/js/lib/elgglib.js index af2c94000..a8e187f1d 100644 --- a/js/lib/elgglib.js +++ b/js/lib/elgglib.js @@ -474,8 +474,8 @@ elgg.parse_str = function(string) { re = /([^&=]+)=?([^&]*)/g; while (result = re.exec(string)) { - key = decodeURIComponent(result[1]) - value = decodeURIComponent(result[2]) + key = decodeURIComponent(result[1].replace(/\+/g, ' ')); + value = decodeURIComponent(result[2].replace(/\+/g, ' ')); params[key] = value; } diff --git a/js/lib/session.js b/js/lib/session.js index fa3d60aa9..a8d52733c 100644 --- a/js/lib/session.js +++ b/js/lib/session.js @@ -14,9 +14,9 @@ elgg.provide('elgg.session'); * {string} options[domain] * {boolean} options[secure] * - * @return {string} The value of the cookie, if only name is specified + * @return {string|undefined} The value of the cookie, if only name is specified. Undefined if no value set */ -elgg.session.cookie = function (name, value, options) { +elgg.session.cookie = function(name, value, options) { var cookies = [], cookie = [], i = 0, date, valid = true; //elgg.session.cookie() @@ -47,21 +47,19 @@ elgg.session.cookie = function (name, value, options) { } cookies.push(name + '=' + value); - - if (elgg.isNumber(options.expires)) { - if (elgg.isNumber(options.expires)) { - date = new Date(); - date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); - } else if (options.expires.toUTCString) { - date = options.expires; - } else { - valid = false; - } - - if (valid) { - cookies.push('expires=' + date.toUTCString()); - } - } + + if (options.expires) { + if (elgg.isNumber(options.expires)) { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else if (options.expires.toUTCString) { + date = options.expires; + } + + if (date) { + cookies.push('expires=' + date.toUTCString()); + } + } // CAUTION: Needed to parenthesize options.path and options.domain // in the following expressions, otherwise they evaluate to undefined diff --git a/js/lib/ui.userpicker.js b/js/lib/ui.userpicker.js index 7298da114..669b84cdb 100644 --- a/js/lib/ui.userpicker.js +++ b/js/lib/ui.userpicker.js @@ -107,11 +107,11 @@ elgg.userpicker.viewUser = function(info) { * @return Object */ elgg.userpicker.getSearchParams = function(obj) { - if (obj.element.siblings('[name=match_on]').attr('checked')) { + if (obj.element.parent('.elgg-user-picker').find('input[name=match_on]').attr('checked')) { return {'match_on[]': 'friends', 'term' : obj.term}; } else { return {'match_on[]': 'users', 'term' : obj.term}; } }; -elgg.register_hook_handler('init', 'system', elgg.userpicker.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.userpicker.init); diff --git a/js/tests/ElggLibTest.js b/js/tests/ElggLibTest.js index 31b561923..bd39e7fb3 100644 --- a/js/tests/ElggLibTest.js +++ b/js/tests/ElggLibTest.js @@ -128,3 +128,13 @@ ElggLibTest.prototype.testParseUrl = function() { }); }; +ElggLibTest.prototype.testParseStr = function() { + + [ + ["A+%2B+B=A+%2B+B", {"A + B": "A + B"}] + + ].forEach(function(args) { + assertEquals(args[1], elgg.parse_str(args[0])); + }); +}; + diff --git a/js/tests/README b/js/tests/README index 4f86b27c6..f43c0c89d 100644 --- a/js/tests/README +++ b/js/tests/README @@ -12,9 +12,10 @@ based debuggers. Visit its wiki at the Google Code site for more information. Sample Usage ============ 1. Put jar file in the base directory of Elgg - 2. Run the server: java -jar JsTestDriver-1.3.3d.jar --port 4224 + 2. Run the server: java -jar JsTestDriver-1.3.5.jar --port 4224 3. Point a web browser at http://localhost:4224 - 4. Run the tests: java -jar JsTestDriver-1.3.3d.jar --config js/tests/jsTestDriver.conf --basePath . --tests all + 4. Click "Capture this browser" + 5. Run the tests: java -jar JsTestDriver-1.3.5.jar --config js/tests/jsTestDriver.conf --basePath . --tests all Configuration Hints diff --git a/languages/en.php b/languages/en.php index be86e12e6..1721865f7 100644 --- a/languages/en.php +++ b/languages/en.php @@ -359,6 +359,7 @@ $english = array( 'friendspicker:chararray' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'avatar' => 'Avatar', + 'avatar:noaccess' => "You're not allowed to edit this user's avatar", 'avatar:create' => 'Create your avatar', 'avatar:edit' => 'Edit avatar', 'avatar:preview' => 'Preview', @@ -902,6 +903,7 @@ $english = array( 'total' => 'Total', 'learnmore' => "Click here to learn more.", + 'unknown_error' => 'Unknown error', 'content' => "content", 'content:latest' => 'Latest activity', diff --git a/mod/blog/actions/blog/save.php b/mod/blog/actions/blog/save.php index 9256610cc..82a9e6c51 100644 --- a/mod/blog/actions/blog/save.php +++ b/mod/blog/actions/blog/save.php @@ -79,11 +79,7 @@ foreach ($values as $name => $default) { switch ($name) { case 'tags': - if ($value) { - $values[$name] = string_to_tag_array($value); - } else { - unset ($values[$name]); - } + $values[$name] = string_to_tag_array($value); break; case 'excerpt': @@ -125,10 +121,7 @@ if ($values['status'] == 'draft') { // assign values to the entity, stopping on error. if (!$error) { foreach ($values as $name => $value) { - if (FALSE === ($blog->$name = $value)) { - $error = elgg_echo('blog:error:cannot_save' . "$name=$value"); - break; - } + $blog->$name = $value; } } diff --git a/mod/blog/start.php b/mod/blog/start.php index 25cd81935..91525acee 100644 --- a/mod/blog/start.php +++ b/mod/blog/start.php @@ -113,14 +113,23 @@ function blog_page_handler($page) { switch ($page_type) { case 'owner': $user = get_user_by_username($page[1]); + if (!$user) { + forward('', '404'); + } $params = blog_get_page_content_list($user->guid); break; case 'friends': $user = get_user_by_username($page[1]); + if (!$user) { + forward('', '404'); + } $params = blog_get_page_content_friends($user->guid); break; case 'archive': $user = get_user_by_username($page[1]); + if (!$user) { + forward('', '404'); + } $params = blog_get_page_content_archive($user->guid, $page[2], $page[3]); break; case 'view': @@ -139,6 +148,10 @@ function blog_page_handler($page) { $params = blog_get_page_content_edit($page_type, $page[1], $page[2]); break; case 'group': + $group = get_entity($page[1]); + if (!elgg_instanceof($group, 'group')) { + forward('', '404'); + } if ($page[2] == 'all') { $params = blog_get_page_content_list($page[1]); } else { diff --git a/mod/blog/views/default/blog/sidebar/archives.php b/mod/blog/views/default/blog/sidebar/archives.php index 3d8f28ca4..5098e6e3e 100644 --- a/mod/blog/views/default/blog/sidebar/archives.php +++ b/mod/blog/views/default/blog/sidebar/archives.php @@ -14,7 +14,7 @@ if (elgg_instanceof($page_owner, 'user')) { // This is a limitation of the URL schema. if ($page_owner && $vars['page'] != 'friends') { - $dates = get_entity_dates('object', 'blog', $page_owner->getGUID()); + $dates = array_reverse(get_entity_dates('object', 'blog', $page_owner->getGUID())); if ($dates) { $title = elgg_echo('blog:archives'); diff --git a/mod/bookmarks/pages/bookmarks/all.php b/mod/bookmarks/pages/bookmarks/all.php index bdb8fc793..5c6011ad9 100644 --- a/mod/bookmarks/pages/bookmarks/all.php +++ b/mod/bookmarks/pages/bookmarks/all.php @@ -13,9 +13,8 @@ elgg_register_title_button(); $content = elgg_list_entities(array( 'type' => 'object', 'subtype' => 'bookmarks', - 'limit' => 10, 'full_view' => false, - 'view_toggle_type' => false + 'view_toggle_type' => false, )); if (!$content) { diff --git a/mod/bookmarks/pages/bookmarks/friends.php b/mod/bookmarks/pages/bookmarks/friends.php index 15b1da098..173996346 100644 --- a/mod/bookmarks/pages/bookmarks/friends.php +++ b/mod/bookmarks/pages/bookmarks/friends.php @@ -7,7 +7,7 @@ $page_owner = elgg_get_page_owner_entity(); if (!$page_owner) { - forward('bookmarks/all'); + forward('', '404'); } elgg_push_breadcrumb($page_owner->name, "bookmarks/owner/$page_owner->username"); diff --git a/mod/bookmarks/pages/bookmarks/owner.php b/mod/bookmarks/pages/bookmarks/owner.php index a024ff352..b7b907916 100644 --- a/mod/bookmarks/pages/bookmarks/owner.php +++ b/mod/bookmarks/pages/bookmarks/owner.php @@ -7,7 +7,7 @@ $page_owner = elgg_get_page_owner_entity(); if (!$page_owner) { - forward('bookmarks/all'); + forward('', '404'); } elgg_push_breadcrumb($page_owner->name); @@ -18,7 +18,6 @@ $content .= elgg_list_entities(array( 'type' => 'object', 'subtype' => 'bookmarks', 'container_guid' => $page_owner->guid, - 'limit' => 10, 'full_view' => false, 'view_toggle_type' => false )); diff --git a/mod/embed/start.php b/mod/embed/start.php index e14e0efd4..1da35aa46 100644 --- a/mod/embed/start.php +++ b/mod/embed/start.php @@ -14,8 +14,10 @@ elgg_register_event_handler('init', 'system', 'embed_init'); function embed_init() { elgg_extend_view('css/elgg', 'embed/css'); elgg_extend_view('css/admin', 'embed/css'); - - elgg_register_plugin_hook_handler('register', 'menu:longtext', 'embed_longtext_menu'); + + if (elgg_is_logged_in()) { + elgg_register_plugin_hook_handler('register', 'menu:longtext', 'embed_longtext_menu'); + } elgg_register_plugin_hook_handler('register', 'menu:embed', 'embed_select_tab', 1000); // Page handler for the modal media embed diff --git a/mod/file/pages/file/friends.php b/mod/file/pages/file/friends.php index f504bdc1f..d55c1e62b 100644 --- a/mod/file/pages/file/friends.php +++ b/mod/file/pages/file/friends.php @@ -7,7 +7,7 @@ $owner = elgg_get_page_owner_entity(); if (!$owner) { - forward('file/all'); + forward('', '404'); } elgg_push_breadcrumb(elgg_echo('file'), "file/all"); diff --git a/mod/file/pages/file/owner.php b/mod/file/pages/file/owner.php index d7f057f2a..99cf62714 100644 --- a/mod/file/pages/file/owner.php +++ b/mod/file/pages/file/owner.php @@ -10,7 +10,7 @@ group_gatekeeper(); $owner = elgg_get_page_owner_entity(); if (!$owner) { - forward('file/all'); + forward('', '404'); } elgg_push_breadcrumb(elgg_echo('file'), "file/all"); @@ -39,7 +39,6 @@ $content = elgg_list_entities(array( 'type' => 'object', 'subtype' => 'file', 'container_guid' => $owner->guid, - 'limit' => 10, 'full_view' => FALSE, )); if (!$content) { diff --git a/mod/file/pages/file/world.php b/mod/file/pages/file/world.php index 8e6c87f26..96c8de785 100644 --- a/mod/file/pages/file/world.php +++ b/mod/file/pages/file/world.php @@ -9,14 +9,11 @@ elgg_push_breadcrumb(elgg_echo('file')); elgg_register_title_button(); -$limit = get_input("limit", 10); - $title = elgg_echo('file:all'); $content = elgg_list_entities(array( 'type' => 'object', 'subtype' => 'file', - 'limit' => $limit, 'full_view' => FALSE )); if (!$content) { diff --git a/mod/groups/lib/discussion.php b/mod/groups/lib/discussion.php index ab2fe4849..874e21b2d 100644 --- a/mod/groups/lib/discussion.php +++ b/mod/groups/lib/discussion.php @@ -39,9 +39,8 @@ function discussion_handle_list_page($guid) { elgg_set_page_owner_guid($guid); $group = get_entity($guid); - if (!$group) { - register_error(elgg_echo('group:notfound')); - forward(); + if (!elgg_instanceof($group, 'group')) { + forward('', '404'); } elgg_push_breadcrumb($group->name); diff --git a/mod/groups/lib/groups.php b/mod/groups/lib/groups.php index 0557d41eb..77d7c09cc 100644 --- a/mod/groups/lib/groups.php +++ b/mod/groups/lib/groups.php @@ -255,8 +255,8 @@ function groups_handle_profile_page($guid) { elgg_push_context('group_profile'); $group = get_entity($guid); - if (!$group) { - forward('groups/all'); + if (!elgg_instanceof($group, 'group')) { + forward('', '404'); } elgg_push_breadcrumb($group->name); @@ -366,12 +366,15 @@ function groups_handle_members_page($guid) { elgg_push_breadcrumb($group->name, $group->getURL()); elgg_push_breadcrumb(elgg_echo('groups:members')); + $db_prefix = elgg_get_config('dbprefix'); $content = elgg_list_entities_from_relationship(array( 'relationship' => 'member', 'relationship_guid' => $group->guid, 'inverse_relationship' => true, 'type' => 'user', 'limit' => 20, + 'joins' => array("JOIN {$db_prefix}users_entity u ON e.guid=u.guid"), + 'order_by' => 'u.name ASC', )); $params = array( diff --git a/mod/groups/start.php b/mod/groups/start.php index 46ab0e636..6002a535c 100644 --- a/mod/groups/start.php +++ b/mod/groups/start.php @@ -142,6 +142,10 @@ function groups_setup_sidebar_menus() { $page_owner = elgg_get_page_owner_entity(); if (elgg_in_context('group_profile')) { + if (!elgg_instanceof($page_owner, 'group')) { + forward('', '404'); + } + if (elgg_is_logged_in() && $page_owner->canEdit() && !$page_owner->isPublicMembership()) { $url = elgg_get_site_url() . "groups/requests/{$page_owner->getGUID()}"; diff --git a/mod/groups/views/default/object/groupforumtopic.php b/mod/groups/views/default/object/groupforumtopic.php index 34e0ee3cc..e6988d16e 100644 --- a/mod/groups/views/default/object/groupforumtopic.php +++ b/mod/groups/views/default/object/groupforumtopic.php @@ -73,7 +73,10 @@ if ($full) { $info = elgg_view_image_block($poster_icon, $list_body); - $body = elgg_view('output/longtext', array('value' => $topic->description)); + $body = elgg_view('output/longtext', array( + 'value' => $topic->description, + 'class' => 'clearfix', + )); echo <<<HTML $info diff --git a/mod/messageboard/pages/messageboard/owner.php b/mod/messageboard/pages/messageboard/owner.php index 2c854d4f3..b3e9f45b0 100644 --- a/mod/messageboard/pages/messageboard/owner.php +++ b/mod/messageboard/pages/messageboard/owner.php @@ -16,7 +16,6 @@ elgg_push_breadcrumb($page_owner->name, $page_owner->getURL()); $options = array( 'annotations_name' => 'messageboard', 'guid' => $page_owner_guid, - 'limit' => 10, 'reverse_order_by' => true, ); diff --git a/mod/pages/pages/pages/friends.php b/mod/pages/pages/pages/friends.php index 87ac631c2..cecc4053b 100644 --- a/mod/pages/pages/pages/friends.php +++ b/mod/pages/pages/pages/friends.php @@ -7,7 +7,7 @@ $owner = elgg_get_page_owner_entity(); if (!$owner) { - forward('pages/all'); + forward('', '404'); } elgg_push_breadcrumb($owner->name, "pages/owner/$owner->username"); diff --git a/mod/pages/pages/pages/owner.php b/mod/pages/pages/pages/owner.php index 48199368c..7de74a3b4 100644 --- a/mod/pages/pages/pages/owner.php +++ b/mod/pages/pages/pages/owner.php @@ -7,7 +7,7 @@ $owner = elgg_get_page_owner_entity(); if (!$owner) { - forward('pages/all'); + forward('', '404'); } // access check for closed groups diff --git a/mod/search/search_hooks.php b/mod/search/search_hooks.php index c92003c7e..923cf0aa8 100644 --- a/mod/search/search_hooks.php +++ b/mod/search/search_hooks.php @@ -405,14 +405,19 @@ function search_comments_hook($hook, $type, $value, $params) { // don't continue if nothing there... if (!$count) { - return array ('entities' => array(), 'count' => 0); + return array('entities' => array(), 'count' => 0); } - - $order_by = search_get_order_by_sql('e', null, $params['sort'], $params['order']); + + // no full text index on metastrings table + if ($params['sort'] == 'relevance') { + $params['sort'] = 'created'; + } + + $order_by = search_get_order_by_sql('a', null, $params['sort'], $params['order']); if ($order_by) { $order_by = "ORDER BY $order_by"; } - + $q = "SELECT DISTINCT a.*, msv.string as comment FROM {$db_prefix}annotations a JOIN {$db_prefix}metastrings msn ON a.name_id = msn.id JOIN {$db_prefix}metastrings msv ON a.value_id = msv.id @@ -450,10 +455,17 @@ function search_comments_hook($hook, $type, $value, $params) { } $comment_str = search_get_highlighted_relevant_substrings($comment->comment, $query); - $entity->setVolatileData('search_match_annotation_id', $comment->id); - $entity->setVolatileData('search_matched_comment', $comment_str); - $entity->setVolatileData('search_matched_comment_owner_guid', $comment->owner_guid); - $entity->setVolatileData('search_matched_comment_time_created', $comment->time_created); + $comments_data = $entity->getVolatileData('search_comments_data'); + if (!$comments_data) { + $comments_data = array(); + } + $comments_data[] = array( + 'annotation_id' => $comment->id, + 'text' => $comment_str, + 'owner_guid' => $comment->owner_guid, + 'time_created' => $comment->time_created, + ); + $entity->setVolatileData('search_comments_data', $comments_data); $entities[] = $entity; } diff --git a/mod/search/views/default/search/comments/entity.php b/mod/search/views/default/search/comments/entity.php index 005bb270c..77e950843 100644 --- a/mod/search/views/default/search/comments/entity.php +++ b/mod/search/views/default/search/comments/entity.php @@ -6,8 +6,11 @@ */ $entity = $vars['entity']; +$comments_data = $entity->getVolatileData('search_comments_data'); +$comment_data = array_shift($comments_data); +$entity->setVolatileData('search_comments_data', $comments_data); -$owner = get_entity($entity->getVolatileData('search_matched_comment_owner_guid')); +$owner = get_entity($comment_data['owner_guid']); if ($owner instanceof ElggUser) { $icon = elgg_view_entity_icon($owner, 'tiny'); @@ -38,12 +41,12 @@ if ($entity->getVolatileData('search_unavailable_entity')) { $title = elgg_echo('search:comment_on', array($title)); // @todo this should use something like $comment->getURL() - $url = $entity->getURL() . '#comment_' . $entity->getVolatileData('search_match_annotation_id'); + $url = $entity->getURL() . '#comment_' . $comment_data['annotation_id']; $title = "<a href=\"$url\">$title</a>"; } -$description = $entity->getVolatileData('search_matched_comment'); -$tc = $entity->getVolatileData('search_matched_comment_time_created');; +$description = $comment_data['text']; +$tc = $comment_data['time_created']; $time = elgg_view_friendly_time($tc); $body = "<p class=\"mbn\">$title</p>$description"; diff --git a/mod/search/views/rss/search/comments/entity.php b/mod/search/views/rss/search/comments/entity.php index 869779f35..e47afec4a 100644 --- a/mod/search/views/rss/search/comments/entity.php +++ b/mod/search/views/rss/search/comments/entity.php @@ -6,9 +6,12 @@ */ $entity = $vars['entity']; +$comments_data = $entity->getVolatileData('search_comments_data'); +$comment_data = array_shift($comments_data); +$entity->setVolatileData('search_comments_data', $comments_data); $author_name = ''; -$comment_author_guid = $entity->getVolatileData('search_matched_comment_owner_guid'); +$comment_author_guid = $comment_data['owner_guid']; $author = get_user($comment_author_guid); if ($author) { $author_name = $author->name; @@ -34,11 +37,11 @@ if ($entity->getVolatileData('search_unavailable_entity')) { $title = elgg_echo('search:comment_on', array($title)); $title .= ' ' . elgg_echo('search:comment_by') . ' ' . $author_name; - $url = $entity->getURL() . '#annotation-' . $entity->getVolatileData('search_match_annotation_id'); + $url = $entity->getURL() . '#annotation-' . $comment_data['annotation_id']; } -$description = $entity->getVolatileData('search_matched_comment'); -$tc = $entity->getVolatileData('search_matched_comment_time_created');; +$description = $comment_data['text']; +$tc = $comment_data['time_created']; ?> diff --git a/mod/thewire/pages/thewire/everyone.php b/mod/thewire/pages/thewire/everyone.php index 909f0caf2..c7438747e 100644 --- a/mod/thewire/pages/thewire/everyone.php +++ b/mod/thewire/pages/thewire/everyone.php @@ -18,7 +18,7 @@ if (elgg_is_logged_in()) { $content .= elgg_list_entities(array( 'type' => 'object', 'subtype' => 'thewire', - 'limit' => 15, + 'limit' => get_input('limit', 15), )); $body = elgg_view_layout('content', array( diff --git a/mod/thewire/pages/thewire/friends.php b/mod/thewire/pages/thewire/friends.php index e7f5eed59..efa7e7a56 100644 --- a/mod/thewire/pages/thewire/friends.php +++ b/mod/thewire/pages/thewire/friends.php @@ -5,7 +5,7 @@ $owner = elgg_get_page_owner_entity(); if (!$owner) { - forward('thewire/all'); + forward('', '404'); } $title = elgg_echo('thewire:friends'); diff --git a/mod/thewire/pages/thewire/owner.php b/mod/thewire/pages/thewire/owner.php index 6246c1770..dc25940e1 100644 --- a/mod/thewire/pages/thewire/owner.php +++ b/mod/thewire/pages/thewire/owner.php @@ -6,7 +6,7 @@ $owner = elgg_get_page_owner_entity(); if (!$owner) { - forward('thewire/all'); + forward('', '404'); } $title = elgg_echo('thewire:user', array($owner->name)); @@ -26,7 +26,7 @@ $content .= elgg_list_entities(array( 'type' => 'object', 'subtype' => 'thewire', 'owner_guid' => $owner->guid, - 'limit' => 15, + 'limit' => get_input('limit', 15), )); $body = elgg_view_layout('content', array( diff --git a/pages/account/forgotten_password.php b/pages/account/forgotten_password.php index bf6ef87e0..f464f98c9 100644 --- a/pages/account/forgotten_password.php +++ b/pages/account/forgotten_password.php @@ -17,6 +17,11 @@ $content .= elgg_view_form('user/requestnewpassword', array( 'class' => 'elgg-form-account', )); -$body = elgg_view_layout("one_column", array('content' => $content)); - -echo elgg_view_page($title, $body); +if (elgg_get_config('walled_garden')) { + elgg_load_css('elgg.walled_garden'); + $body = elgg_view_layout('walled_garden', array('content' => $content)); + echo elgg_view_page($title, $body, 'walled_garden'); +} else { + $body = elgg_view_layout('one_column', array('content' => $content)); + echo elgg_view_page($title, $body); +} diff --git a/pages/account/login.php b/pages/account/login.php index 14f65cc3f..6aa3752d0 100644 --- a/pages/account/login.php +++ b/pages/account/login.php @@ -15,6 +15,14 @@ if (elgg_is_logged_in()) { forward(''); } -$login_box = elgg_view('core/account/login_box'); -$content = elgg_view_layout('one_column', array('content' => $login_box)); -echo elgg_view_page(elgg_echo('login'), $content); +$title = elgg_echo('login'); +$content = elgg_view('core/account/login_box'); + +if (elgg_get_config('walled_garden')) { + elgg_load_css('elgg.walled_garden'); + $body = elgg_view_layout('walled_garden', array('content' => $content)); + echo elgg_view_page($title, $body, 'walled_garden'); +} else { + $body = elgg_view_layout('one_column', array('content' => $content)); + echo elgg_view_page($title, $body); +} diff --git a/pages/account/register.php b/pages/account/register.php index cf18a635b..2fe8b74c0 100644 --- a/pages/account/register.php +++ b/pages/account/register.php @@ -48,6 +48,11 @@ $content .= elgg_view_form('register', $form_params, $body_params); $content .= elgg_view('help/register'); -$body = elgg_view_layout("one_column", array('content' => $content)); - -echo elgg_view_page($title, $body); +if (elgg_get_config('walled_garden')) { + elgg_load_css('elgg.walled_garden'); + $body = elgg_view_layout('walled_garden', array('content' => $content)); + echo elgg_view_page($title, $body, 'walled_garden'); +} else { + $body = elgg_view_layout('one_column', array('content' => $content)); + echo elgg_view_page($title, $body); +} diff --git a/pages/account/reset_password.php b/pages/account/reset_password.php index 6515bfc5d..3ab8ccf3e 100644 --- a/pages/account/reset_password.php +++ b/pages/account/reset_password.php @@ -30,6 +30,11 @@ $form = elgg_view_form('user/passwordreset', array('class' => 'elgg-form-account $title = elgg_echo('resetpassword'); $content = elgg_view_title(elgg_echo('resetpassword')) . $form; -$body = elgg_view_layout('one_column', array('content' => $content)); - -echo elgg_view_page($title, $body); +if (elgg_get_config('walled_garden')) { + elgg_load_css('elgg.walled_garden'); + $body = elgg_view_layout('walled_garden', array('content' => $content)); + echo elgg_view_page($title, $body, 'walled_garden'); +} else { + $body = elgg_view_layout('one_column', array('content' => $content)); + echo elgg_view_page($title, $body); +} diff --git a/pages/avatar/edit.php b/pages/avatar/edit.php index c71633b8b..56aede887 100644 --- a/pages/avatar/edit.php +++ b/pages/avatar/edit.php @@ -11,6 +11,11 @@ elgg_set_context('profile_edit'); $title = elgg_echo('avatar:edit'); $entity = elgg_get_page_owner_entity(); +if (!elgg_instanceof($entity, 'user') || !$entity->canEdit()) { + register_error(elgg_echo('avatar:noaccess')); + forward(REFERER); +} + $content = elgg_view('core/avatar/upload', array('entity' => $entity)); // only offer the crop view if an avatar has been uploaded diff --git a/pages/river.php b/pages/river.php index 0e1511334..801d9f664 100644 --- a/pages/river.php +++ b/pages/river.php @@ -49,6 +49,7 @@ $content = elgg_view('core/river/filter', array('selector' => $selector)); $sidebar = elgg_view('core/river/sidebar'); $params = array( + 'title' => $title, 'content' => $content . $activity, 'sidebar' => $sidebar, 'filter_context' => $page_filter, diff --git a/version.php b/version.php index a006fe7b6..a94bf9d31 100644 --- a/version.php +++ b/version.php @@ -14,4 +14,4 @@ $version = 2013052900; // Human-friendly version name -$release = '1.8.15'; +$release = '1.8.16'; diff --git a/views/default/forms/plugins/settings/save.php b/views/default/forms/plugins/settings/save.php index dc7b2fef7..116529905 100644 --- a/views/default/forms/plugins/settings/save.php +++ b/views/default/forms/plugins/settings/save.php @@ -17,11 +17,11 @@ if ($type != 'user') { $type = ''; } -if (elgg_view_exists("{$type}settings/$plugin_id/edit")) { +if (elgg_view_exists("plugins/$plugin_id/{$type}settings")) { + echo elgg_view("plugins/$plugin_id/{$type}settings", $vars); +} elseif (elgg_view_exists("{$type}settings/$plugin_id/edit")) { elgg_deprecated_notice("{$type}settings/$plugin_id/edit was deprecated in favor of plugins/$plugin_id/{$type}settings", 1.8); echo elgg_view("{$type}settings/$plugin_id/edit", $vars); -} else { - echo elgg_view("plugins/$plugin_id/{$type}settings", $vars); } echo '<div class="elgg-foot">'; diff --git a/views/default/forms/profile/edit.php b/views/default/forms/profile/edit.php index 9538b779e..cb0a37ca4 100644 --- a/views/default/forms/profile/edit.php +++ b/views/default/forms/profile/edit.php @@ -13,6 +13,8 @@ </div> <?php +$sticky_values = elgg_get_sticky_values('profile:edit'); + $profile_fields = elgg_get_config('profile_fields'); if (is_array($profile_fields) && count($profile_fields) > 0) { foreach ($profile_fields as $shortname => $valtype) { @@ -40,6 +42,14 @@ if (is_array($profile_fields) && count($profile_fields) > 0) { $access_id = ACCESS_DEFAULT; } + // sticky form values take precedence over saved ones + if (isset($sticky_values[$shortname])) { + $value = $sticky_values[$shortname]; + } + if (isset($sticky_values['accesslevel'][$shortname])) { + $access_id = $sticky_values['accesslevel'][$shortname]; + } + ?> <div> <label><?php echo elgg_echo("profile:{$shortname}") ?></label> @@ -59,6 +69,9 @@ if (is_array($profile_fields) && count($profile_fields) > 0) { <?php } } + +elgg_clear_sticky_form('profile:edit'); + ?> <div class="elgg-foot"> <?php diff --git a/views/default/input/userpicker.php b/views/default/input/userpicker.php index 91a397e37..8b64d7df5 100644 --- a/views/default/input/userpicker.php +++ b/views/default/input/userpicker.php @@ -63,11 +63,13 @@ foreach ($vars['value'] as $user_id) { ?> <div class="elgg-user-picker"> <input type="text" class="elgg-input-user-picker" size="30"/> - <input type="checkbox" name="match_on" value="true" /> - <label><?php echo elgg_echo('userpicker:only_friends'); ?></label> + <label> + <input type="checkbox" name="match_on" value="true" /> + <?php echo elgg_echo('userpicker:only_friends'); ?> + </label> <ul class="elgg-user-picker-list"><?php echo $user_list; ?></ul> </div> <script type="text/javascript"> // @todo grab the values in the init function rather than using inline JS elgg.userpicker.userList = <?php echo $json_values ?>; -</script>
\ No newline at end of file +</script> diff --git a/views/default/js/walled_garden.php b/views/default/js/walled_garden.php index 7a482fe23..e228df507 100644 --- a/views/default/js/walled_garden.php +++ b/views/default/js/walled_garden.php @@ -5,12 +5,11 @@ * @since 1.8 */ -// note that this assumes the button view is not using single quotes $cancel_button = elgg_view('input/button', array( 'value' => elgg_echo('cancel'), 'class' => 'elgg-button-cancel mlm', )); -$cancel_button = trim($cancel_button); +$cancel_button = json_encode($cancel_button); if (0) { ?><script><?php } ?> @@ -23,10 +22,11 @@ elgg.walled_garden.init = function () { $('.registration_link').click(elgg.walled_garden.load('register')); $('input.elgg-button-cancel').live('click', function(event) { - if ($('.elgg-walledgarden-single').is(':visible')) { + var $wgs = $('.elgg-walledgarden-single'); + if ($wgs.is(':visible')) { $('.elgg-walledgarden-double').fadeToggle(); - $('.elgg-walledgarden-single').fadeToggle(); - $('.elgg-walledgarden-single').remove(); + $wgs.fadeToggle(); + $wgs.remove(); } event.preventDefault(); }); @@ -42,12 +42,22 @@ elgg.walled_garden.load = function(view) { return function(event) { var id = '#elgg-walledgarden-' + view; id = id.replace('_', '-'); + //@todo display some visual element that indicates that loading of content is running elgg.get('walled_garden/' + view, { 'success' : function(data) { - $('.elgg-body-walledgarden').append(data); - $(id).find('input.elgg-button-submit').after('<?php echo $cancel_button; ?>'); - $('#elgg-walledgarden-login').fadeToggle(); - $(id).fadeToggle(); + var $wg = $('.elgg-body-walledgarden'); + $wg.append(data); + $(id).find('input.elgg-button-submit').after(<?php echo $cancel_button; ?>); + + if (view == 'register' && $wg.hasClass('hidden')) { + // this was a failed register, display the register form ASAP + $('#elgg-walledgarden-login').toggle(false); + $(id).toggle(); + $wg.removeClass('hidden'); + } else { + $('#elgg-walledgarden-login').fadeToggle(); + $(id).fadeToggle(); + } } }); event.preventDefault(); diff --git a/views/default/object/default.php b/views/default/object/default.php index 110648304..70e098742 100644 --- a/views/default/object/default.php +++ b/views/default/object/default.php @@ -41,7 +41,6 @@ $params = array( 'title' => $title, 'metadata' => $metadata, 'subtitle' => $subtitle, - 'tags' => $vars['entity']->tags, ); $params = $params + $vars; $body = elgg_view('object/elements/summary', $params); diff --git a/views/default/object/elements/full.php b/views/default/object/elements/full.php index 9b89f9706..b4634fe7e 100644 --- a/views/default/object/elements/full.php +++ b/views/default/object/elements/full.php @@ -22,9 +22,9 @@ $summary = elgg_extract('summary', $vars); $body = elgg_extract('body', $vars); $class = elgg_extract('class', $vars); if ($class) { - $class = "elgg-content $class"; + $class = "elgg-content clearfix $class"; } else { - $class = "elgg-content"; + $class = "elgg-content clearfix"; } $header = elgg_view_image_block($icon, $summary); diff --git a/views/default/object/elements/summary.php b/views/default/object/elements/summary.php index c0f3ad340..63ab8f816 100644 --- a/views/default/object/elements/summary.php +++ b/views/default/object/elements/summary.php @@ -27,7 +27,7 @@ if ($title_link === '') { $text = $entity->name; } $params = array( - 'text' => $text, + 'text' => elgg_get_excerpt($text, 100), 'href' => $entity->getURL(), 'is_trusted' => true, ); diff --git a/views/default/page/walled_garden.php b/views/default/page/walled_garden.php index ff8e317c7..b280cf6b2 100644 --- a/views/default/page/walled_garden.php +++ b/views/default/page/walled_garden.php @@ -5,6 +5,12 @@ * Used for the walled garden index page */ +$is_sticky_register = elgg_is_sticky_form('register'); +$wg_body_class = 'elgg-body-walledgarden'; +if ($is_sticky_register) { + $wg_body_class .= ' hidden'; +} + // Set the content type header("Content-type: text/html; charset=UTF-8"); ?> @@ -18,10 +24,17 @@ header("Content-type: text/html; charset=UTF-8"); <div class="elgg-page-messages"> <?php echo elgg_view('page/elements/messages', array('object' => $vars['sysmessages'])); ?> </div> - <div class="elgg-body-walledgarden"> + <div class="<?php echo $wg_body_class; ?>"> <?php echo $vars['body']; ?> </div> </div> +<?php if ($is_sticky_register): ?> +<script type="text/javascript"> +elgg.register_hook_handler('init', 'system', function() { + $('.registration_link').trigger('click'); +}); +</script> +<?php endif; ?> <?php echo elgg_view('page/elements/foot'); ?> </body> </html>
\ No newline at end of file diff --git a/views/default/river/elements/summary.php b/views/default/river/elements/summary.php index 416bc708b..d7bde51dd 100644 --- a/views/default/river/elements/summary.php +++ b/views/default/river/elements/summary.php @@ -18,9 +18,10 @@ $subject_link = elgg_view('output/url', array( 'is_trusted' => true, )); +$object_text = $object->title ? $object->title : $object->name; $object_link = elgg_view('output/url', array( 'href' => $object->getURL(), - 'text' => $object->title ? $object->title : $object->name, + 'text' => elgg_get_excerpt($object_text, 100), 'class' => 'elgg-river-object', 'is_trusted' => true, )); |