diff options
-rw-r--r-- | actions/profile/edit.php | 5 | ||||
-rw-r--r-- | engine/classes/ElggEntity.php | 12 | ||||
-rw-r--r-- | engine/classes/ElggGroup.php | 7 | ||||
-rw-r--r-- | engine/classes/ElggObject.php | 8 | ||||
-rw-r--r-- | engine/classes/ElggUser.php | 6 | ||||
-rw-r--r-- | engine/lib/entities.php | 46 | ||||
-rw-r--r-- | engine/lib/metadata.php | 10 | ||||
-rw-r--r-- | engine/tests/api/metadata_cache.php | 7 | ||||
-rw-r--r-- | views/default/forms/profile/edit.php | 13 |
9 files changed, 100 insertions, 14 deletions
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/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/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/ElggUser.php b/engine/classes/ElggUser.php index b2cada8ef..6163f9b62 100644 --- a/engine/classes/ElggUser.php +++ b/engine/classes/ElggUser.php @@ -132,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/lib/entities.php b/engine/lib/entities.php index 5cfeca6f8..d0d97aa95 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; } /** diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php index 43f7d5d6e..046b85124 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); 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/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 |