diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index c7094af..98e3353 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -18,6 +18,7 @@ use Drupal\Core\Lock\DatabaseLockBackend; use Drupal\Core\Lock\LockBackendInterface; use Drupal\user\Plugin\Core\Entity\User; +use Drupal\Core\Entity\EntityBCDecorator; /** * @file @@ -2002,14 +2003,13 @@ function drupal_hash_base64($data) { * The user object. */ function drupal_anonymous_user() { - $values = array( + return (object) array( 'uid' => 0, 'hostname' => Drupal::request()->getClientIP(), 'roles' => array( DRUPAL_ANONYMOUS_RID => DRUPAL_ANONYMOUS_RID, ), ); - return new User($values, 'user'); } /** diff --git a/core/includes/common.inc b/core/includes/common.inc index 654d849..796da3b 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -5590,7 +5590,7 @@ function drupal_render_cid_parts($granularity = NULL) { // resource drag for sites with many users, so when a module is being // equivocal, we favor the less expensive 'PER_ROLE' pattern. if ($granularity & DRUPAL_CACHE_PER_ROLE) { - $cid_parts[] = 'r.' . implode(',', array_keys($user->roles)); + $cid_parts[] = 'r.' . implode(',', $user->roles); } elseif ($granularity & DRUPAL_CACHE_PER_USER) { $cid_parts[] = "u.$user->uid"; diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php index b1d8ec3..08de993 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php @@ -165,6 +165,8 @@ public function resetCache(array $ids = NULL) { } else { $this->entityCache = array(); + $this->entityFieldInfo = NULL; + $this->fieldDefinitions = array(); } } diff --git a/core/lib/Drupal/Core/Entity/EntityAccessController.php b/core/lib/Drupal/Core/Entity/EntityAccessController.php index 9b75d53..601e5c6 100644 --- a/core/lib/Drupal/Core/Entity/EntityAccessController.php +++ b/core/lib/Drupal/Core/Entity/EntityAccessController.php @@ -41,6 +41,10 @@ public function access(EntityInterface $entity, $operation, $langcode = LANGUAGE // that have checks that need to be done before the hook is invoked should // do so by overridding this method. + if ($account instanceof User) { + $account = $account->getBCEntity(); + } + // We grant access to the entity if both of these conditions are met: // - No modules say to deny access. // - At least one module says to grant access. diff --git a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php index 9697648..fed5d88 100644 --- a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php +++ b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php @@ -90,6 +90,16 @@ public function &__get($name) { return $this->decorated->values[$name]; } + // @todo: The EntityBCDecorator tries to be too intelligent and returns + // a string but we actually want an array for roles. + if ($name == 'roles') { + $roles = array(); + foreach ($this->getOriginalEntity()->roles as $role) { + $roles[] = $role->value; + } + return $roles; + } + // We access the protected 'values' and 'fields' properties of the decorated // entity via the magic getter - which returns them by reference for us. We // do so, as providing references to these arrays would make $entity->values diff --git a/core/lib/Drupal/Core/Entity/EntityNG.php b/core/lib/Drupal/Core/Entity/EntityNG.php index 9406927..e5c8476 100644 --- a/core/lib/Drupal/Core/Entity/EntityNG.php +++ b/core/lib/Drupal/Core/Entity/EntityNG.php @@ -387,7 +387,15 @@ public function updateOriginalValues() { foreach ($this->getPropertyDefinitions() as $name => $definition) { if (empty($definition['computed']) && !empty($this->fields[$name])) { foreach ($this->fields[$name] as $langcode => $field) { - $this->values[$name][$langcode] = $field->getValue(); + // If the value is array we need to filter out potential harmfull + // values like array(0 => NULL) before sending to storage mechanisms + // so that we avoid potential exceptions / empty values stored in + // the database or other storage locations. + $value = $field->getValue(); + if (is_array($value)) { + $value = array_filter($value); + } + $this->values[$name][$langcode] = $value; } } } diff --git a/core/lib/Drupal/Core/Entity/Field/Type/Field.php b/core/lib/Drupal/Core/Entity/Field/Type/Field.php index 5d0a4ff..ccff49a 100644 --- a/core/lib/Drupal/Core/Entity/Field/Type/Field.php +++ b/core/lib/Drupal/Core/Entity/Field/Type/Field.php @@ -155,7 +155,7 @@ public function __unset($property_name) { public function access($operation = 'view', User $account = NULL) { global $user; if (!isset($account) && $user->uid) { - $account = user_load($user->uid); + $account = user_load($user->uid)->getOriginalEntity(); } // Get the default access restriction that lives within this field. $access = $this->defaultAccess($operation, $account); diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 8466ce2..e7f8bc2 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -1571,7 +1571,7 @@ function comment_prepare_author(Comment $comment) { if (!$account) { $account = entity_create('user', array('uid' => 0, 'name' => $comment->name->value, 'homepage' => $comment->homepage->value)); } - return $account; + return $account->getBCEntity(); } /** diff --git a/core/modules/comment/comment.tokens.inc b/core/modules/comment/comment.tokens.inc index d938c27..213f352 100644 --- a/core/modules/comment/comment.tokens.inc +++ b/core/modules/comment/comment.tokens.inc @@ -218,7 +218,7 @@ function comment_tokens($type, $tokens, array $data = array(), array $options = } if (($author_tokens = $token_service->findwithPrefix($tokens, 'author')) && $account = $comment->uid->entity) { - $replacements += $token_service->generate('user', $author_tokens, array('user' => $account), $options); + $replacements += $token_service->generate('user', $author_tokens, array('user' => $account->getBCEntity()), $options); } } elseif ($type == 'node' & !empty($data['node'])) { diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php index 5585650..743f6d0 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php @@ -50,7 +50,8 @@ function testCommentLinks() { // Remove additional user permissions from $this->web_user added by setUp(), // since this test is limited to anonymous and authenticated roles only. - entity_delete_multiple('user_role', array(key($this->web_user->roles))); + $roles = $this->web_user->roles; + entity_delete_multiple('user_role', array(reset($roles))); // Matrix of possible environmental conditions and configuration settings. // See setEnvironment() for details. diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php b/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php index cee642e..eb257dc 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php @@ -88,7 +88,7 @@ function testConfigLocaleUserOverride() { )); $user_config_context = config_context_enter('Drupal\user\UserConfigContext'); - $user_config_context->setAccount($account); + $user_config_context->setAccount($account->getOriginalEntity()); $config = config('config_test.system'); $this->assertIdentical($config->get('foo'), 'fr bar'); // Ensure the non-overriden value is still the same. @@ -111,7 +111,7 @@ function testConfigLocaleUserOverride() { )); $config_factory = drupal_container()->get('config.factory'); - $config_factory->enterContext($user_config_context->setAccount($account)); + $config_factory->enterContext($user_config_context->setAccount($account->getOriginalEntity())); // Should not have to re-initialize the configuration object to get new // overrides as the new context will have a different uuid. $config = config('config_test.system'); @@ -127,7 +127,7 @@ function testConfigLocaleUserOverride() { )); // Create a new user config context to stack on top of the existign one. $en_user_config_context = config_context_enter('Drupal\user\UserConfigContext'); - $en_user_config_context->setAccount($account); + $en_user_config_context->setAccount($account->getOriginalEntity()); $config = config('config_test.system'); $this->assertIdentical($config->get('foo'), 'en bar'); @@ -178,7 +178,7 @@ function testConfigLocaleUserAndGlobalOverride() { )); $user_config_context = config_context_enter('Drupal\user\UserConfigContext'); - $user_config_context->setAccount($account); + $user_config_context->setAccount($account->getOriginalEntity()); $config = config('config_test.system'); $this->assertIdentical($config->get('foo'), 'fr bar'); // Ensure the value overriden from global $conf works. diff --git a/core/modules/contact/lib/Drupal/contact/MessageFormController.php b/core/modules/contact/lib/Drupal/contact/MessageFormController.php index c4352cf..b3a9ed8 100644 --- a/core/modules/contact/lib/Drupal/contact/MessageFormController.php +++ b/core/modules/contact/lib/Drupal/contact/MessageFormController.php @@ -167,7 +167,7 @@ public function save(array $form, array &$form_state) { $to = implode(', ', $category->recipients); $recipient_langcode = language_default()->langcode; } - elseif ($message->recipient instanceof User) { + elseif ($message->recipient && $message->recipient->getOriginalEntity() instanceof User) { // Send to the user in the user's preferred language. $to = $message->recipient->mail; $recipient_langcode = user_preferred_langcode($message->recipient); diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php index c8bed9a..3976f0b 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php @@ -97,5 +97,12 @@ public function testEntityReferenceItem() { $entity->field_test_taxonomy->target_id = $term2->id(); $this->assertEqual($entity->field_test_taxonomy->entity->id(), $term2->id()); $this->assertEqual($entity->field_test_taxonomy->entity->name->value, $term2->name->value); + + // Delete terms so we have nothing to reference and try again + $term->delete(); + $term2->delete(); + $entity = entity_create('entity_test', array('name' => $this->randomName())); + $entity->save(); } + } diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index de03e50..f781a6d 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -249,7 +249,7 @@ function file_field_update(EntityInterface $entity, $field, $instance, $langcode } // Compare the original field values with the ones that are being saved. - $original = $entity->original; + $original = $entity->original->getBCEntity(); $original_fids = array(); if (!empty($original->{$field['field_name']}[$langcode])) { foreach ($original->{$field['field_name']}[$langcode] as $original_item) { diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php index 8268999..14555f7 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php @@ -239,7 +239,7 @@ function testPrivateFileComment() { $user = $this->drupalCreateUser(array('access comments')); // Grant the admin user required comment permissions. - user_role_grant_permissions(key($this->admin_user->roles), array('administer comment fields')); + user_role_grant_permissions($this->admin_user->roles[1], array('administer comment fields')); // Revoke access comments permission from anon user, grant post to // authenticated. diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php index 8667a5b..11eb3e5 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php @@ -176,9 +176,7 @@ function testFormatPermissions() { */ function testFormatRoles() { // Get the role ID assigned to the regular user. - $roles = $this->web_user->roles; - unset($roles[DRUPAL_AUTHENTICATED_RID]); - $rid = key($roles); + $rid = $this->web_user->roles[0]; // Check that this role appears in the list of roles that have access to an // allowed text format, but does not appear in the list of roles that have diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php index 7f863cf..73cf876 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php @@ -111,6 +111,11 @@ public function testImageItem() { // Check that the image item can be set to the referenced file directly. $entity->image_test = $this->image; $this->assertEqual($entity->image_test->fid, $this->image->id()); + + // Delete the image and try to save the entity again. + $this->image->delete(); + $entity = entity_create('entity_test', array('mame' => $this->randomName())); + $entity->save(); } } diff --git a/core/modules/locale/lib/Drupal/locale/LocaleLookup.php b/core/modules/locale/lib/Drupal/locale/LocaleLookup.php index cc515b4..7f7d272 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleLookup.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleLookup.php @@ -46,7 +46,7 @@ public function __construct($langcode, $context, $stringStorage) { // Add the current user's role IDs to the cache key, this ensures that, for // example, strings for admin menu items and settings forms are not cached // for anonymous users. - $rids = implode(':', array_keys($GLOBALS['user']->roles)); + $rids = implode(':', $GLOBALS['user']->roles); parent::__construct("locale:$langcode:$context:$rids", 'cache', array('locale' => TRUE)); } diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php index ee2b0c3..225c708 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php @@ -62,6 +62,12 @@ function testUninstallProcess() { $language_manager->init(); // Check the UI language. + // @todo: If the global user is an EntityBCDecorator, getting the roles + // roles from it within LocaleLookup results in a loop that invokes + // LocaleLookup again. + global $user; + $user = drupal_anonymous_user(); + $this->assertEqual(language(LANGUAGE_TYPE_INTERFACE)->langcode, $this->langcode, t('Current language: %lang', array('%lang' => language(LANGUAGE_TYPE_INTERFACE)->langcode))); // Enable multilingual workflow option for articles. diff --git a/core/modules/node/lib/Drupal/node/NodeAccessController.php b/core/modules/node/lib/Drupal/node/NodeAccessController.php index cee9228..632fbfc 100644 --- a/core/modules/node/lib/Drupal/node/NodeAccessController.php +++ b/core/modules/node/lib/Drupal/node/NodeAccessController.php @@ -110,7 +110,7 @@ protected function accessGrants(EntityInterface $node, $operation, $langcode, Us $query->range(0, 1); $grants = db_or(); - foreach (node_access_grants($operation, $account) as $realm => $gids) { + foreach (node_access_grants($operation, $account instanceof User ? $account->getBCEntity() : $account) as $realm => $gids) { foreach ($gids as $gid) { $grants->condition(db_and() ->condition('gid', $gid) diff --git a/core/modules/node/node.module b/core/modules/node/node.module index f2d0ae9..12ad80f 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -2541,7 +2541,7 @@ function node_access($op, $node, $account = NULL, $langcode = NULL) { // Make sure that if an account is passed, that it is a fully loaded user // object. if ($account && !($account instanceof User)) { - $account = user_load($account->uid); + $account = entity_load('user', $account->uid); } return entity_access_controller('node')->access($node, $op, $langcode, $account); diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php index 04d78a4..fbfe050 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php @@ -125,9 +125,7 @@ function testSearchResultsComment() { function testSearchResultsCommentAccess() { $comment_body = 'Test comment body'; $this->comment_subject = 'Test comment subject'; - $this->admin_role = $this->admin_user->roles; - unset($this->admin_role[DRUPAL_AUTHENTICATED_RID]); - $this->admin_role = key($this->admin_role); + $this->admin_role = $this->admin_user->roles[0]; // Create a node. variable_set('comment_preview_article', DRUPAL_OPTIONAL); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 4b66223..432915b 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -480,7 +480,7 @@ protected function drupalCreateUser(array $permissions = array(), $name = NULL) $edit['pass'] = user_password(); $edit['status'] = 1; if ($rid) { - $edit['roles'] = array($rid => $rid); + $edit['roles'] = array($rid); } $account = entity_create('user', $edit); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityAccessTest.php index c29e4f3..e11b091 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityAccessTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityAccessTest.php @@ -82,7 +82,7 @@ function testEntityAccess() { 'update' => FALSE, 'delete' => FALSE, 'view' => FALSE, - ), $entity, $custom_user); + ), $entity, $custom_user->getOriginalEntity()); } /** diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php index 1a8947c..6269bed 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php @@ -7,7 +7,8 @@ namespace Drupal\system\Tests\Entity; -use Drupal\user\Plugin\Core\Entity\User; +use Drupal\Core\Entity\EntityInterface; + /** * Tests the basic Entity API. @@ -50,10 +51,10 @@ public function testCRUD() { * * @param string $entity_type * The entity type to run the tests with. - * @param \Drupal\user\Plugin\Core\Entity\User $user1 + * @param \Drupal\Core\Entity\EntityInterface $user1 * The user to run the tests with. */ - protected function assertCRUD($entity_type, User $user1) { + protected function assertCRUD($entity_type, EntityInterface $user1) { // Create some test entities. $entity = entity_create($entity_type, array('name' => 'test', 'user_id' => $user1->uid)); $entity->save(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php index fabbcfe..e1a36db 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php @@ -117,19 +117,19 @@ protected function assertReadWrite($entity_type) { $this->assertTrue($entity->user_id[0] instanceof FieldItemInterface, format_string('%entity_type: Field item implements interface', array('%entity_type' => $entity_type))); $this->assertEqual($this->entity_user->uid, $entity->user_id->target_id, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); // Change the assigned user by entity. $new_user = $this->createUser(); $entity->user_id->entity = $new_user; $this->assertEqual($new_user->uid, $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($new_user->name, $entity->user_id->entity->name, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user->name, $entity->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); // Change the assigned user by id. $new_user = $this->createUser(); $entity->user_id->target_id = $new_user->uid; $this->assertEqual($new_user->uid, $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($new_user->name, $entity->user_id->entity->name, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user->name, $entity->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); // Try unsetting a field. $entity->name->value = NULL; @@ -217,7 +217,7 @@ protected function assertReadWrite($entity_type) { )); $this->assertEqual($this->entity_name, $entity->name->value, format_string('%entity_type: Name value can be read.', array('%entity_type' => $entity_type))); $this->assertEqual($this->entity_user->uid, $entity->user_id->target_id, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); $this->assertEqual($this->entity_field_text, $entity->field_test_text->value, format_string('%entity_type: Text field can be read.', array('%entity_type' => $entity_type))); // Test copying field values. @@ -328,7 +328,7 @@ protected function assertSave($entity_type) { $this->assertEqual(LANGUAGE_NOT_SPECIFIED, $entity->langcode->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); $this->assertEqual(language_load(LANGUAGE_NOT_SPECIFIED), $entity->langcode->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); $this->assertEqual($this->entity_user->uid, $entity->user_id->target_id, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); $this->assertEqual($this->entity_field_text, $entity->field_test_text->value, format_string('%entity_type: Text field can be read.', array('%entity_type' => $entity_type))); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php index 41918d3..5ceeab4 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php @@ -51,7 +51,7 @@ protected function createUser($values = array(), $permissions = array()) { )); $role->save(); user_role_grant_permissions($role->id(), $permissions); - $values['roles'][$role->id()] = $role->id(); + $values['roles'][] = $role->id(); } $account = entity_create('user', $values + array( diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php index a460b6f..ba6a7b2 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php @@ -70,12 +70,12 @@ function testFieldAccess() { $values = array('name' => 'test'); $account = entity_create('user', $values); - $this->assertFalse($entity->field_test_text->access('view', $account), 'Access to the field was denied.'); + $this->assertFalse($entity->field_test_text->access('view', $account->getOriginalEntity()), 'Access to the field was denied.'); $entity->field_test_text = 'access alter value'; - $this->assertFalse($entity->field_test_text->access('view', $account), 'Access to the field was denied.'); + $this->assertFalse($entity->field_test_text->access('view', $account->getOriginalEntity()), 'Access to the field was denied.'); $entity->field_test_text = 'standard value'; - $this->assertTrue($entity->field_test_text->access('view', $account), 'Access to the field was granted.'); + $this->assertTrue($entity->field_test_text->access('view', $account->getOriginalEntity()), 'Access to the field was granted.'); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php index 882ae96..7815a8b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php @@ -99,7 +99,7 @@ function testContext() { // Set an appropriate context value appropriately and check to make sure // its methods work as expected. - $user = entity_create('user', array('name' => $name)); + $user = entity_create('user', array('name' => $name))->getOriginalEntity(); $plugin->setContextValue('user', $user); $this->assertEqual($user->label(), $plugin->getTitle()); diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUIUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUIUpgradePathTest.php index f344afb..6f44942 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUIUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUIUpgradePathTest.php @@ -63,7 +63,7 @@ function testFieldUIPermissions() { ), ); - $role_permissions = user_role_permissions(array($this->normal_role_id => $this->normal_role_name, $this->admin_role_id => $this->admin_role_name)); + $role_permissions = user_role_permissions(array($this->normal_role_id, $this->admin_role_id)); foreach ($permissions as $old_permission => $new_permissions) { $this->assertFalse(isset($role_permissions[$this->normal_role_id][$old_permission]), format_string('%role_name does not have the old %permission permission', array('%role_name' => $this->normal_role_name, '%permission' => $old_permission))); $this->assertTrue(isset($role_permissions[$this->admin_role_id][$old_permission]), format_string('%role_name still has the old %permission permission', array('%role_name' => $this->admin_role_name, '%permission' => $old_permission))); diff --git a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php index f8c585b..16b19c8 100644 --- a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php +++ b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php @@ -231,9 +231,7 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { $format = filter_format_load($edit['format']); $format_id = $format->format; $permission = filter_permission_name($format); - $roles = $this->web_user->roles; - unset($roles[DRUPAL_AUTHENTICATED_RID]); - $rid = key($roles); + $rid = $this->web_user->roles[0]; user_role_grant_permissions($rid, array($permission)); $this->drupalLogin($this->web_user); diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSettingsTest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSettingsTest.php index 41600ac..b53ab33 100644 --- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSettingsTest.php +++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSettingsTest.php @@ -87,6 +87,7 @@ function testSettingsUI() { 'settings[comment][comment_node_article][fields][comment_body]' => TRUE, ); $this->assertSettings('comment', 'comment_node_article', TRUE, $edit); + field_info_cache_clear(); $field = field_info_field('comment_body'); $this->assertTrue($field['translatable'], 'Comment body is translatable.'); diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationWorkflowsTest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationWorkflowsTest.php index 9957552..741b806 100644 --- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationWorkflowsTest.php +++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationWorkflowsTest.php @@ -7,7 +7,7 @@ namespace Drupal\translation_entity\Tests; -use Drupal\user\Plugin\Core\Entity\User; +use Drupal\Core\Entity\EntityInterface; /** * Tests entity translation workflows. @@ -113,7 +113,7 @@ function testWorkflows() { * The an associative array with the operation name as key and the expected * status as value. */ - protected function assertWorkflows(User $user, $expected_status) { + protected function assertWorkflows(EntityInterface $user, $expected_status) { $default_langcode = $this->langcodes[0]; $languages = language_list(); $args = array('@user_label' => $user->name); diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php index 8f2f0c5..44b08e2 100644 --- a/core/modules/user/lib/Drupal/user/AccountFormController.php +++ b/core/modules/user/lib/Drupal/user/AccountFormController.php @@ -146,7 +146,7 @@ public function form(array $form, array &$form_state, EntityInterface $account) $form['account']['roles'] = array( '#type' => 'checkboxes', '#title' => t('Roles'), - '#default_value' => (!$register && isset($account->roles) ? array_keys($account->roles) : array()), + '#default_value' => (!$register ? $account->roles : array()), '#options' => $roles, '#access' => $roles && user_access('administer permissions'), DRUPAL_AUTHENTICATED_RID => $checkbox_authenticated, @@ -225,6 +225,19 @@ public function form(array $form, array &$form_state, EntityInterface $account) } /** + * Overrides Drupal\Core\Entity\EntityFormController::buildEntity(). + */ + public function buildEntity(array $form, array &$form_state) { + // Change the roles array to a list of enabled roles. + // @todo: Move this to an value callback on the form element. + if (empty($this->roles_filtered)) { + $form_state['values']['roles'] = array_keys(array_filter($form_state['values']['roles'])); + $this->roles_filtered = TRUE; + } + return parent::buildEntity($form, $form_state); + } + + /** * Overrides Drupal\Core\Entity\EntityFormController::submit(). */ public function validate(array $form, array &$form_state) { diff --git a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php index 44c4562..326c952 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php @@ -7,7 +7,7 @@ namespace Drupal\user\Plugin\Core\Entity; -use Drupal\Core\Entity\Entity; +use Drupal\Core\Entity\EntityNG; use Drupal\Core\Entity\Annotation\EntityType; use Drupal\Core\Annotation\Translation; use Drupal\user\UserInterface; @@ -42,7 +42,7 @@ * } * ) */ -class User extends Entity implements UserInterface { +class User extends EntityNG implements UserInterface { /** * The user ID. @@ -63,7 +63,7 @@ class User extends Entity implements UserInterface { * * @var string */ - public $name = ''; + public $name; /** * The user's password (hashed). @@ -77,7 +77,7 @@ class User extends Entity implements UserInterface { * * @var string */ - public $mail = ''; + public $mail; /** * The user's default theme. @@ -113,7 +113,7 @@ class User extends Entity implements UserInterface { * * @var integer */ - public $access = 0; + public $access; /** * The timestamp when the user last logged in. A value of 0 means the user has @@ -121,14 +121,14 @@ class User extends Entity implements UserInterface { * * @var integer */ - public $login = 0; + public $login; /** * Whether the user is active (1) or blocked (0). * * @var integer */ - public $status = 1; + public $status; /** * The user's timezone. @@ -142,40 +142,84 @@ class User extends Entity implements UserInterface { * * @var string */ - public $langcode = LANGUAGE_NOT_SPECIFIED; + public $langcode; /** * The user's preferred langcode for receiving emails and viewing the site. * * @var string */ - public $preferred_langcode = LANGUAGE_NOT_SPECIFIED; + public $preferred_langcode; /** * The user's preferred langcode for viewing administration pages. * * @var string */ - public $preferred_admin_langcode = LANGUAGE_NOT_SPECIFIED; + public $preferred_admin_langcode; /** * The email address used for initial account creation. * * @var string */ - public $init = ''; + public $init; /** * The user's roles. * * @var array */ - public $roles = array(); + public $roles; + + /** + * The plain data values of the contained properties. + * + * Define default values. + * + * @var array + */ + protected $values = array( + 'langcode' => array(LANGUAGE_DEFAULT => array(0 => array('value' => LANGUAGE_NOT_SPECIFIED))), + 'preferred_langcode' => array(LANGUAGE_DEFAULT => array(0 => array('value' => LANGUAGE_NOT_SPECIFIED))), + 'admin_preffered_langcode' => array(LANGUAGE_DEFAULT => array(0 => array('value' => LANGUAGE_NOT_SPECIFIED))), + 'name' => array(LANGUAGE_DEFAULT => array(0 => array('value' => ''))), + 'mail' => array(LANGUAGE_DEFAULT => array(0 => array('value' => ''))), + 'init' => array(LANGUAGE_DEFAULT => array(0 => array('value' => ''))), + 'access' => array(LANGUAGE_DEFAULT => array(0 => array('value' => 0))), + 'login' => array(LANGUAGE_DEFAULT => array(0 => array('value' => 0))), + 'status' => array(LANGUAGE_DEFAULT => array(0 => array('value' => 1))), + ); /** * Implements Drupal\Core\Entity\EntityInterface::id(). */ public function id() { - return $this->uid; + return $this->get('uid')->value; + } + + protected function init() { + parent::init(); + unset($this->access); + unset($this->created); + unset($this->init); + unset($this->login); + unset($this->mail); + unset($this->name); + unset($this->pass); + unset($this->preferred_admin_langcode); + unset($this->preferred_langcode); + unset($this->roles); + unset($this->signature); + unset($this->signature_format); + unset($this->status); + unset($this->theme); + unset($this->timezone); + unset($this->uid); + unset($this->uuid); + } + + public function &__get($name) { + return parent::__get($name); } } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/filter/Name.php b/core/modules/user/lib/Drupal/user/Plugin/views/filter/Name.php index 8c5104c..6b48054 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/filter/Name.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/filter/Name.php @@ -26,8 +26,8 @@ function value_form(&$form, &$form_state) { if ($this->value) { $result = entity_load_multiple_by_properties('user', array('uid' => $this->value)); foreach ($result as $account) { - if ($account->uid) { - $values[] = $account->name; + if ($account->id()) { + $values[] = $account->name->value; } else { $values[] = 'Anonymous'; // Intentionally NOT translated. @@ -130,8 +130,8 @@ function validate_user_strings(&$form, $values) { $result = entity_load_multiple_by_properties('user', array('name' => $args)); foreach ($result as $account) { - unset($missing[strtolower($account->name)]); - $uids[] = $account->uid; + unset($missing[strtolower($account->name->value)]); + $uids[] = $account->id(); } if ($missing) { @@ -156,10 +156,10 @@ public function adminSummary() { $result = entity_load_multiple_by_properties('user', array('uid' => $this->value)); foreach ($result as $account) { if ($account->uid) { - $this->value_options[$account->uid] = $account->name; + $this->value_options[$account->id()] = $account->label(); } else { - $this->value_options[$account->uid] = 'Anonymous'; // Intentionally NOT translated. + $this->value_options[$account->id()] = 'Anonymous'; // Intentionally NOT translated. } } } diff --git a/core/modules/user/lib/Drupal/user/Tests/UserAdminTest.php b/core/modules/user/lib/Drupal/user/Tests/UserAdminTest.php index 3b83b52..0769fff 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserAdminTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserAdminTest.php @@ -60,8 +60,8 @@ function testUserAdmin() { // Filter the users by role. Grab the system-generated role name for User C. $roles = $user_c->roles; - unset($roles[DRUPAL_AUTHENTICATED_RID]); - $edit['role'] = key($roles); + unset($roles[array_search(DRUPAL_AUTHENTICATED_RID, $roles)]); + $edit['role'] = reset($roles); $this->drupalPost('admin/people', $edit, t('Refine')); // Check if the correct users show up when filtered by role. diff --git a/core/modules/user/lib/Drupal/user/Tests/UserEntityCallbacksTest.php b/core/modules/user/lib/Drupal/user/Tests/UserEntityCallbacksTest.php index 15894ad..a4bfd52 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserEntityCallbacksTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserEntityCallbacksTest.php @@ -33,7 +33,7 @@ function setUp() { parent::setUp(); $this->account = $this->drupalCreateUser(); - $this->anonymous = drupal_anonymous_user(); + $this->anonymous = entity_create('user', (array) drupal_anonymous_user()); } /** diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php index 2455b10..3fc3b4b 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php @@ -28,8 +28,8 @@ function setUp() { // Find the new role ID. $all_rids = $this->admin_user->roles; - unset($all_rids[DRUPAL_AUTHENTICATED_RID]); - $this->rid = key($all_rids); + unset($all_rids[array_search(DRUPAL_AUTHENTICATED_RID, $all_rids)]); + $this->rid = reset($all_rids); } /** diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php index 38ca376..816aaa5 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php @@ -45,7 +45,7 @@ function testRegistrationWithEmailVerification() { $this->assertText(t('A welcome message with further instructions has been sent to your e-mail address.'), 'User registered successfully.'); $accounts = entity_load_multiple_by_properties('user', array('name' => $name, 'mail' => $mail)); $new_user = reset($accounts); - $this->assertTrue($new_user->status, 'New account is active after registration.'); + $this->assertTrue($new_user->status->value, 'New account is active after registration.'); // Allow registration by site visitors, but require administrator approval. $config->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); @@ -56,7 +56,7 @@ function testRegistrationWithEmailVerification() { $this->container->get('plugin.manager.entity')->getStorageController('user')->resetCache(); $accounts = entity_load_multiple_by_properties('user', array('name' => $name, 'mail' => $mail)); $new_user = reset($accounts); - $this->assertFalse($new_user->status, 'New account is blocked until approved by an administrator.'); + $this->assertFalse($new_user->status->value, 'New account is blocked until approved by an administrator.'); } function testRegistrationWithoutEmailVerification() { @@ -114,7 +114,7 @@ function testRegistrationWithoutEmailVerification() { $edit = array( 'status' => 1, ); - $this->drupalPost('user/' . $new_user->uid . '/edit', $edit, t('Save')); + $this->drupalPost('user/' . $new_user->id() . '/edit', $edit, t('Save')); $this->drupalLogout(); // Login after administrator approval. @@ -177,16 +177,16 @@ function testRegistrationDefaultValues() { // Check user fields. $accounts = entity_load_multiple_by_properties('user', array('name' => $name, 'mail' => $mail)); $new_user = reset($accounts); - $this->assertEqual($new_user->name, $name, 'Username matches.'); - $this->assertEqual($new_user->mail, $mail, 'E-mail address matches.'); - $this->assertEqual($new_user->theme, '', 'Correct theme field.'); - $this->assertEqual($new_user->signature, '', 'Correct signature field.'); - $this->assertTrue(($new_user->created > REQUEST_TIME - 20 ), 'Correct creation time.'); - $this->assertEqual($new_user->status, $config_user_settings->get('register') == USER_REGISTER_VISITORS ? 1 : 0, 'Correct status field.'); - $this->assertEqual($new_user->timezone, $config_system_timezone->get('default'), 'Correct time zone field.'); - $this->assertEqual($new_user->langcode, language_default()->langcode, 'Correct language field.'); - $this->assertEqual($new_user->preferred_langcode, language_default()->langcode, 'Correct preferred language field.'); - $this->assertEqual($new_user->init, $mail, 'Correct init field.'); + $this->assertEqual($new_user->name->value, $name, 'Username matches.'); + $this->assertEqual($new_user->mail->value, $mail, 'E-mail address matches.'); + $this->assertEqual($new_user->theme->value, '', 'Correct theme field.'); + $this->assertEqual($new_user->signature->value, '', 'Correct signature field.'); + $this->assertTrue(($new_user->created->value > REQUEST_TIME - 20 ), 'Correct creation time.'); + $this->assertEqual($new_user->status->value, $config_user_settings->get('register') == USER_REGISTER_VISITORS ? 1 : 0, 'Correct status field.'); + $this->assertEqual($new_user->timezone->value, $config_system_timezone->get('default'), 'Correct time zone field.'); + $this->assertEqual($new_user->langcode->value, language_default()->langcode, 'Correct language field.'); + $this->assertEqual($new_user->preferred_langcode->value, language_default()->langcode, 'Correct preferred language field.'); + $this->assertEqual($new_user->init->value, $mail, 'Correct init field.'); } /** @@ -240,7 +240,7 @@ function testRegistrationWithUserFields() { // Check user fields. $accounts = entity_load_multiple_by_properties('user', array('name' => $name, 'mail' => $mail)); $new_user = reset($accounts); - $this->assertEqual($new_user->test_user_field[LANGUAGE_NOT_SPECIFIED][0]['value'], $value, 'The field value was correclty saved.'); + $this->assertEqual($new_user->test_user_field->value, $value, 'The field value was correclty saved.'); // Check that the 'add more' button works. $field['cardinality'] = FIELD_CARDINALITY_UNLIMITED; @@ -268,9 +268,9 @@ function testRegistrationWithUserFields() { // Check user fields. $accounts = entity_load_multiple_by_properties('user', array('name' => $name, 'mail' => $mail)); $new_user = reset($accounts); - $this->assertEqual($new_user->test_user_field[LANGUAGE_NOT_SPECIFIED][0]['value'], $value, format_string('@js : The field value was correclty saved.', array('@js' => $js))); - $this->assertEqual($new_user->test_user_field[LANGUAGE_NOT_SPECIFIED][1]['value'], $value + 1, format_string('@js : The field value was correclty saved.', array('@js' => $js))); - $this->assertEqual($new_user->test_user_field[LANGUAGE_NOT_SPECIFIED][2]['value'], $value + 2, format_string('@js : The field value was correclty saved.', array('@js' => $js))); + $this->assertEqual($new_user->test_user_field[0]->value, $value, format_string('@js : The field value was correclty saved.', array('@js' => $js))); + $this->assertEqual($new_user->test_user_field[1]->value, $value + 1, format_string('@js : The field value was correclty saved.', array('@js' => $js))); + $this->assertEqual($new_user->test_user_field[2]->value, $value + 2, format_string('@js : The field value was correclty saved.', array('@js' => $js))); } } } diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRolesAssignmentTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRolesAssignmentTest.php index 349b2a9..e612374 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserRolesAssignmentTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserRolesAssignmentTest.php @@ -94,10 +94,10 @@ function testCreateUserWithRole() { private function userLoadAndCheckRoleAssigned($account, $rid, $is_assigned = TRUE) { $account = user_load($account->uid, TRUE); if ($is_assigned) { - $this->assertTrue(array_key_exists($rid, $account->roles), 'The role is present in the user object.'); + $this->assertTrue(array_search($rid, $account->roles), 'The role is present in the user object.'); } else { - $this->assertFalse(array_key_exists($rid, $account->roles), 'The role is not present in the user object.'); + $this->assertFalse(array_search($rid, $account->roles), 'The role is not present in the user object.'); } } } diff --git a/core/modules/user/lib/Drupal/user/Tests/UserTranslationUITest.php b/core/modules/user/lib/Drupal/user/Tests/UserTranslationUITest.php index 171a976..fe3fa0f 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserTranslationUITest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserTranslationUITest.php @@ -39,6 +39,8 @@ function setUp() { $this->testLanguageSelector = FALSE; $this->name = $this->randomName(); parent::setUp(); + + entity_get_controller('user')->resetCache(); } /** diff --git a/core/modules/user/lib/Drupal/user/Tests/Views/AccessTestBase.php b/core/modules/user/lib/Drupal/user/Tests/Views/AccessTestBase.php index 5455eaa..33cad6e 100644 --- a/core/modules/user/lib/Drupal/user/Tests/Views/AccessTestBase.php +++ b/core/modules/user/lib/Drupal/user/Tests/Views/AccessTestBase.php @@ -54,11 +54,11 @@ protected function setUp() { $this->adminUser = $this->drupalCreateUser(array('access all views')); $this->webUser = $this->drupalCreateUser(); - $this->webRole = current($this->webUser->roles); + $this->webRole = $this->webUser->roles[0]; $this->normalRole = $this->drupalCreateRole(array()); $this->normalUser = $this->drupalCreateUser(array('views_test_data test permission')); - $this->normalUser->roles[$this->normalRole] = $this->normalRole; + $this->normalUser->getOriginalEntity()->roles[2] = $this->normalRole; // @todo when all the plugin information is cached make a reset function and // call it here. } diff --git a/core/modules/user/lib/Drupal/user/Tests/Views/HandlerFieldRoleTest.php b/core/modules/user/lib/Drupal/user/Tests/Views/HandlerFieldRoleTest.php index 55ec424..7c70baa 100644 --- a/core/modules/user/lib/Drupal/user/Tests/Views/HandlerFieldRoleTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/Views/HandlerFieldRoleTest.php @@ -41,9 +41,9 @@ public function testRole() { $this->drupalCreateRole(array('access content'), $rolename_not_assigned, $rolename_not_assigned); // Add roles to user 1. - $user = user_load(1); - $user->roles[$rid_a] = $rolename_a; - $user->roles[$rid_b] = $rolename_b; + $user = entity_load('user', 1); + $user->roles[1]->value = $rolename_a; + $user->roles[2]->value = $rolename_b; $user->save(); $view = views_get_view('test_views_handler_field_role'); diff --git a/core/modules/user/lib/Drupal/user/UserAccessController.php b/core/modules/user/lib/Drupal/user/UserAccessController.php index 4332fbc..96ce758 100644 --- a/core/modules/user/lib/Drupal/user/UserAccessController.php +++ b/core/modules/user/lib/Drupal/user/UserAccessController.php @@ -32,14 +32,14 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, U case 'update': // Users can always edit their own account. Users with the 'administer // users' permission can edit any account except the anonymous account. - return (($account->uid == $entity->uid) || user_access('administer users', $account)) && $entity->uid > 0; + return (($account->uid == $entity->uid->value) || user_access('administer users', $account)) && $entity->uid->value > 0; break; case 'delete': // Users with 'cancel account' permission can cancel their own account, // users with 'administer users' permission can cancel any account // except the anonymous account. - return ((($account->uid == $entity->uid) && user_access('cancel account', $account)) || user_access('administer users', $account)) && $entity->uid > 0; + return ((($account->uid == $entity->uid->value) && user_access('cancel account', $account)) || user_access('administer users', $account)) && $entity->uid->value > 0; break; } } @@ -51,14 +51,14 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, U */ protected function viewAccess(EntityInterface $entity, $langcode, User $account) { // Never allow access to view the anonymous user account. - if ($entity->uid) { + if ($entity->uid->value) { // Admins can view all, users can view own profiles at all times. - if ($account->uid == $entity->uid || user_access('administer users', $account)) { + if ($account->uid == $entity->uid->value || user_access('administer users', $account)) { return TRUE; } elseif (user_access('access user profiles', $account)) { // Only allow view access if the account is active. - return $entity->status; + return $entity->status->value; } } return FALSE; diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php index 3d8e981..c00937a 100644 --- a/core/modules/user/lib/Drupal/user/UserStorageController.php +++ b/core/modules/user/lib/Drupal/user/UserStorageController.php @@ -9,7 +9,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityMalformedException; -use Drupal\Core\Entity\DatabaseStorageController; +use Drupal\Core\Entity\DatabaseStorageControllerNG; /** * Controller class for users. @@ -17,7 +17,7 @@ * This extends the Drupal\Core\Entity\DatabaseStorageController class, adding * required special handling for user objects. */ -class UserStorageController extends DatabaseStorageController { +class UserStorageController extends DatabaseStorageControllerNG { /** * Overrides Drupal\Core\Entity\DatabaseStorageController::attachLoad(). @@ -26,17 +26,17 @@ function attachLoad(&$queried_users, $load_revision = FALSE) { foreach ($queried_users as $key => $record) { $queried_users[$key]->roles = array(); if ($record->uid) { - $queried_users[$record->uid]->roles[DRUPAL_AUTHENTICATED_RID] = DRUPAL_AUTHENTICATED_RID; + $queried_users[$record->uid]->roles[] = DRUPAL_AUTHENTICATED_RID; } else { - $queried_users[$record->uid]->roles[DRUPAL_ANONYMOUS_RID] = DRUPAL_ANONYMOUS_RID; + $queried_users[$record->uid]->roles[] = DRUPAL_ANONYMOUS_RID; } } // Add any additional roles from the database. $result = db_query('SELECT rid, uid FROM {users_roles} WHERE uid IN (:uids)', array(':uids' => array_keys($queried_users))); foreach ($result as $record) { - $queried_users[$record->uid]->roles[$record->rid] = $record->rid; + $queried_users[$record->uid]->roles[] = $record->rid; } // Call the default attachLoad() method. This will add fields and call @@ -52,19 +52,25 @@ public function create(array $values) { $values['created'] = REQUEST_TIME; } // Users always have the authenticated user role. - $values['roles'][DRUPAL_AUTHENTICATED_RID] = DRUPAL_AUTHENTICATED_RID; + $values['roles'][] = DRUPAL_AUTHENTICATED_RID; - return parent::create($values); + return parent::create($values)->getBCEntity(); } /** * Overrides Drupal\Core\Entity\DatabaseStorageController::save(). */ public function save(EntityInterface $entity) { - if (empty($entity->uid)) { - $entity->uid = db_next_id(db_query('SELECT MAX(uid) FROM {users}')->fetchField()); + if (!$entity->uid->value) { + $entity->uid->value = db_next_id(db_query('SELECT MAX(uid) FROM {users}')->fetchField()); $entity->enforceIsNew(); } + + // There are some cases that pre-set ->original for performance. Make sure + // original is not a BC decorator. + if ($entity->original instanceof \Drupal\Core\Entity\EntityBCDecorator) { + $entity->original = $entity->original->getOriginalEntity(); + } parent::save($entity); } @@ -73,11 +79,11 @@ public function save(EntityInterface $entity) { */ protected function preSave(EntityInterface $entity) { // Update the user password if it has changed. - if ($entity->isNew() || (!empty($entity->pass) && $entity->pass != $entity->original->pass)) { + if ($entity->isNew() || ($entity->pass->value && $entity->pass->value != $entity->original->pass->value)) { // Allow alternate password hashing schemes. - $entity->pass = drupal_container()->get('password')->hash(trim($entity->pass)); + $entity->pass->value = drupal_container()->get('password')->hash(trim($entity->pass->value)); // Abort if the hashing failed and returned FALSE. - if (!$entity->pass) { + if (!$entity->pass->value) { throw new EntityMalformedException('The entity does not have a password.'); } } @@ -85,16 +91,11 @@ protected function preSave(EntityInterface $entity) { if (!$entity->isNew()) { // If the password is empty, that means it was not changed, so use the // original password. - if (empty($entity->pass)) { - $entity->pass = $entity->original->pass; + if (empty($entity->pass->value)) { + $entity->pass->value = $entity->original->pass->value; } } - // Prepare user roles. - if (isset($entity->roles)) { - $entity->roles = array_filter($entity->roles); - } - // Store account cancellation information. foreach (array('user_cancel_method', 'user_cancel_notify') as $key) { if (isset($entity->{$key})) { @@ -111,28 +112,28 @@ protected function postSave(EntityInterface $entity, $update) { if ($update) { // If the password has been changed, delete all open sessions for the // user and recreate the current one. - if ($entity->pass != $entity->original->pass) { - drupal_session_destroy_uid($entity->uid); - if ($entity->uid == $GLOBALS['user']->uid) { + if ($entity->pass->value != $entity->original->pass->value) { + drupal_session_destroy_uid($entity->id()); + if ($entity->uid->value == $GLOBALS['user']->uid) { drupal_session_regenerate(); } } // Remove roles that are no longer enabled for the user. - $entity->roles = array_filter($entity->roles); + //$entity->roles = array_filter($entity->roles); // Reload user roles if provided. - if ($entity->roles != $entity->original->roles) { + if ($entity->roles->getValue() != $entity->original->roles->getValue()) { db_delete('users_roles') - ->condition('uid', $entity->uid) + ->condition('uid', $entity->id()) ->execute(); $query = db_insert('users_roles')->fields(array('uid', 'rid')); - foreach (array_keys($entity->roles) as $rid) { - if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { + foreach ($entity->roles as $role) { + if (!in_array($role->value, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { $query->values(array( - 'uid' => $entity->uid, - 'rid' => $rid, + 'uid' => $entity->id(), + 'rid' => $role->value, )); } } @@ -140,26 +141,26 @@ protected function postSave(EntityInterface $entity, $update) { } // If the user was blocked, delete the user's sessions to force a logout. - if ($entity->original->status != $entity->status && $entity->status == 0) { - drupal_session_destroy_uid($entity->uid); + if ($entity->original->status->value != $entity->status->value && $entity->status->value == 0) { + drupal_session_destroy_uid($entity->id()); } // Send emails after we have the new user object. - if ($entity->status != $entity->original->status) { + if ($entity->status->value != $entity->original->status->value) { // The user's status is changing; conditionally send notification email. - $op = $entity->status == 1 ? 'status_activated' : 'status_blocked'; - _user_mail_notify($op, $entity); + $op = $entity->status->value == 1 ? 'status_activated' : 'status_blocked'; + _user_mail_notify($op, $entity->getBCEntity()); } } else { // Save user roles. if (count($entity->roles) > 1) { $query = db_insert('users_roles')->fields(array('uid', 'rid')); - foreach (array_keys($entity->roles) as $rid) { - if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { + foreach ($entity->roles as $role) { + if (!in_array($role->value, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { $query->values(array( - 'uid' => $entity->uid, - 'rid' => $rid, + 'uid' => $entity->id(), + 'rid' => $role->value, )); } } @@ -177,4 +178,123 @@ protected function postDelete($entities) { ->execute(); drupal_container()->get('user.data')->delete(NULL, array_keys($entities)); } + + /** + * Overrides \Drupal\Core\Entity\DataBaseStorageControllerNG::invokeHook(). + */ + protected function invokeHook($hook, EntityInterface $entity) { + $function = 'field_attach_' . $hook; + // @todo: field_attach_delete_revision() is named the wrong way round, + // consider renaming it. + if ($function == 'field_attach_revision_delete') { + $function = 'field_attach_delete_revision'; + } + if (!empty($this->entityInfo['fieldable']) && function_exists($function)) { + $function($entity->getBCEntity()); + } + + // Invoke the hook. + module_invoke_all($this->entityType . '_' . $hook, $entity->getBCEntity()); + // Invoke the respective entity-level hook. + module_invoke_all('entity_' . $hook, $entity->getBCEntity(), $this->entityType); + } + + /** + * Overrides \Drupal\Core\Entity\DataBaseStorageControllerNG::baseFieldDefinitions(). + */ + public function baseFieldDefinitions() { + $properties['uid'] = array( + 'label' => t('User ID'), + 'description' => t('The user ID.'), + 'type' => 'integer_field', + 'read-only' => TRUE, + ); + $properties['uuid'] = array( + 'label' => t('UUID'), + 'description' => t('The user UUID.'), + 'type' => 'string_field', + 'read-only' => TRUE, + ); + $properties['langcode'] = array( + 'label' => t('Language code'), + 'description' => t('The user language code.'), + 'type' => 'language_field', + ); + $properties['preferred_langcode'] = array( + 'label' => t('Language code'), + 'description' => t("The user's preferred langcode for receiving emails and viewing the site."), + 'type' => 'language_field', + ); + $properties['preferred_admin_langcode'] = array( + 'label' => t('Language code'), + 'description' => t("The user's preferred langcode for viewing administration pages."), + 'type' => 'language_field', + ); + $properties['name'] = array( + 'label' => t('Name'), + 'description' => t('The name of this user'), + 'type' => 'string_field', + ); + $properties['pass'] = array( + 'label' => t('Name'), + 'description' => t('The password of this user (hashed)'), + 'type' => 'string_field', + ); + $properties['mail'] = array( + 'label' => t('Name'), + 'description' => t('The e-mail of this user'), + 'type' => 'string_field', + ); + $properties['signature'] = array( + 'label' => t('Name'), + 'description' => t('The signature of this user'), + 'type' => 'string_field', + ); + $properties['signature_format'] = array( + 'label' => t('Name'), + 'description' => t('The signature format of this user'), + 'type' => 'string_field', + ); + $properties['theme'] = array( + 'label' => t('Theme'), + 'description' => t('The default theme of this user'), + 'type' => 'string_field', + ); + $properties['timezone'] = array( + 'label' => t('Timeone'), + 'description' => t('The timezone of this user'), + 'type' => 'string_field', + ); + $properties['status'] = array( + 'label' => t('User status'), + 'description' => t('Whether the user is active (1) or blocked (0).'), + 'type' => 'boolean_field', + ); + $properties['created'] = array( + 'label' => t('Created'), + 'description' => t('The time that the node was created.'), + 'type' => 'integer_field', + ); + $properties['access'] = array( + 'label' => t('Last access'), + 'description' => t('The time that the user last accessed the site.'), + 'type' => 'integer_field', + ); + $properties['login'] = array( + 'label' => t('Last login'), + 'description' => t('The time that the user last logged in.'), + 'type' => 'integer_field', + ); + $properties['init'] = array( + 'label' => t('Init'), + 'description' => t('The email address used for initial account creation.'), + 'type' => 'string_field', + ); + $properties['roles'] = array( + 'label' => t('Roles'), + 'description' => t('The roles the user has.'), + 'type' => 'string_field', + ); + return $properties; + } } diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc index 768bb96..1614244 100644 --- a/core/modules/user/user.admin.inc +++ b/core/modules/user/user.admin.inc @@ -300,7 +300,7 @@ function user_admin_permissions($form, $form_state, $rid = NULL) { $role_names = array($rid => $role_names[$rid]); } // Fetch permissions for all roles or the one selected role. - $role_permissions = user_role_permissions($role_names); + $role_permissions = user_role_permissions(array_keys($role_names)); // Store $role_names for use when saving the data. $form['role_names'] = array( diff --git a/core/modules/user/user.module b/core/modules/user/user.module index d664899..e425750 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -156,7 +156,7 @@ function user_entity_bundle_info() { */ function user_uri($user) { return array( - 'path' => 'user/' . $user->uid, + 'path' => 'user/' . $user->id(), ); } @@ -177,7 +177,7 @@ function user_uri($user) { * @see user_format_name() */ function user_label($entity_type, $entity) { - return user_format_name($entity); + return user_format_name($entity->getBCEntity()); } /** @@ -293,7 +293,12 @@ function user_field_extra_fields() { * @see \Drupal\Core\Entity\Query\QueryInterface */ function user_load_multiple(array $uids = NULL, $reset = FALSE) { - return entity_load_multiple('user', $uids, $reset); + $entities = entity_load_multiple('user', $uids, $reset); + // Return BC-entities. + foreach ($entities as $id => $entity) { + $entities[$id] = $entity->getBCEntity(); + } + return $entities; } /** @@ -321,7 +326,8 @@ function user_load_multiple(array $uids = NULL, $reset = FALSE) { * @see user_load_multiple() */ function user_load($uid, $reset = FALSE) { - return entity_load('user', $uid, $reset); + $user = entity_load('user', $uid, $reset); + return $user ? $user->getBCEntity() : FALSE; } /** @@ -337,7 +343,7 @@ function user_load($uid, $reset = FALSE) { */ function user_load_by_mail($mail) { $users = entity_load_multiple_by_properties('user', array('mail' => $mail)); - return reset($users); + return $users ? reset($users)->getBCEntity() : FALSE; } /** @@ -353,7 +359,7 @@ function user_load_by_mail($mail) { */ function user_load_by_name($name) { $users = entity_load_multiple_by_properties('user', array('name' => $name)); - return reset($users); + return $users ? reset($users)->getBCEntity() : FALSE; } /** @@ -434,7 +440,7 @@ function user_role_permissions($roles) { $role_permissions = $fetch = array(); - foreach ($roles as $rid => $name) { + foreach ($roles as $rid) { if (isset($cache[$rid])) { $role_permissions[$rid] = $cache[$rid]; } @@ -485,6 +491,9 @@ function user_access($string, $account = NULL) { $account = $user; } + // Make sure we are working with the BC decorator. + $account = $account instanceof User ? $account->getBCEntity() : $account; + // User #1 has all privileges: if ($account->uid == 1) { return TRUE; @@ -623,7 +632,7 @@ function user_search_execute($keys = NULL, $conditions = NULL) { /** * Implements hook_user_view(). */ -function user_user_view(User $account, EntityDisplay $display) { +function user_user_view(EntityInterface $account, EntityDisplay $display) { if ($display->getComponent('member_for')) { $account->content['member_for'] = array( '#type' => 'item', @@ -744,6 +753,9 @@ function user_template_preprocess_default_variables_alter(&$variables) { */ function template_preprocess_username(&$variables) { $account = $variables['account']; + if ($account instanceof User) { + $account = $account->getBCEntity(); + } $variables['extra'] = ''; if (empty($account->uid)) { @@ -1740,7 +1752,7 @@ function user_mail($key, &$message, $params) { // allows the configuration objects to be localized for the user's language if // the locale module is enabled. $user_config_context = config_context_enter('Drupal\user\UserConfigContext'); - $user_config_context->setAccount($params['account']); + $user_config_context->setAccount($params['account']->getOriginalEntity()); $mail_config = config('user.mail'); // We do not sanitize the token replacement, since the output of this @@ -2096,12 +2108,11 @@ function user_multiple_role_edit($accounts, $operation, $rid) { $accounts = user_load_multiple($accounts); foreach ($accounts as $account) { // Skip adding the role to the user if they already have it. - if ($account !== FALSE && !isset($account->roles[$rid])) { - $roles = $account->roles + array($rid => $role_name); + if ($account !== FALSE && !array_search($rid, $account->roles)) { // For efficiency manually save the original account before applying // any changes. $account->original = clone $account; - $account->roles = $roles; + $account->roles[count($account->roles)] = $rid; $account->save(); } } @@ -2110,8 +2121,8 @@ function user_multiple_role_edit($accounts, $operation, $rid) { $accounts = user_load_multiple($accounts); foreach ($accounts as $account) { // Skip removing the role from the user if they already don't have it. - if ($account !== FALSE && isset($account->roles[$rid])) { - $roles = array_diff($account->roles, array($rid => $role_name)); + if ($account !== FALSE && $index = array_search($rid, $account->roles)) { + $roles = array_diff($account->roles, array($rid)); // For efficiency manually save the original account before applying // any changes. $account->original = clone $account; @@ -2340,6 +2351,7 @@ function theme_user_signature($variables) { */ function user_preferred_langcode($account, $type = NULL, $default = NULL) { $language_list = language_list(); + $account = $account->getBCEntity(); if (isset($type)) { $preferred_langcode = $account->{'preferred_' . $type . '_langcode'}; } diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc index a9f1a4e..66b377f 100644 --- a/core/modules/user/user.pages.inc +++ b/core/modules/user/user.pages.inc @@ -70,7 +70,7 @@ function user_pass_submit($form, &$form_state) { $account = $form_state['values']['account']; // Mail one time login URL and instructions using current language. - $mail = _user_mail_notify('password_reset', $account, $language_interface->langcode); + $mail = _user_mail_notify('password_reset', $account->getBCEntity(), $language_interface->langcode); if (!empty($mail)) { watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail)); drupal_set_message(t('Further instructions have been sent to your e-mail address.')); diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php index 7df986e..bd317f5 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php @@ -284,7 +284,7 @@ public function generateResultsKey() { } $key_data = array( 'build_info' => $build_info, - 'roles' => array_keys($user->roles), + 'roles' => $user->roles, 'super-user' => $user->uid == 1, // special caching for super user. 'langcode' => language(LANGUAGE_TYPE_INTERFACE)->langcode, 'base_url' => $GLOBALS['base_url'], @@ -312,7 +312,7 @@ public function generateOutputKey() { if (!isset($this->outputKey)) { $key_data = array( 'result' => $this->view->result, - 'roles' => array_keys($user->roles), + 'roles' => $user->roles, 'super-user' => $user->uid == 1, // special caching for super user. 'theme' => $GLOBALS['theme'], 'langcode' => language(LANGUAGE_TYPE_INTERFACE)->langcode, diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php index 6d262c4..4597a66 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php @@ -1367,7 +1367,7 @@ public function storeExposedInput($input, $status) { // Check if we store exposed value for current user. global $user; $allowed_rids = empty($this->options['expose']['remember_roles']) ? array() : array_filter($this->options['expose']['remember_roles']); - $intersect_rids = array_intersect_key($allowed_rids, $user->roles); + $intersect_rids = array_intersect(array_keys($allowed_rids), $user->roles); if (empty($intersect_rids)) { return; } diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/AccessTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/AccessTest.php index b4c5118..7a221e3 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/AccessTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/AccessTest.php @@ -37,11 +37,12 @@ protected function setUp() { $this->admin_user = $this->drupalCreateUser(array('access all views')); $this->web_user = $this->drupalCreateUser(); - $this->web_role = current($this->web_user->roles); + $this->web_role = $this->web_user->roles[0]; $this->normal_role = $this->drupalCreateRole(array()); $this->normal_user = $this->drupalCreateUser(array('views_test_data test permission')); - $this->normal_user->roles[$this->normal_role] = $this->normal_role; + // @todo: How to add a new item to the roles field list. + $this->normal_user->getOriginalEntity()->roles[2]->value = $this->normal_role; // @todo when all the plugin information is cached make a reset function and // call it here. } diff --git a/core/modules/views/views.module b/core/modules/views/views.module index 8e2a378..7855a60 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -756,9 +756,7 @@ function views_check_perm($perm, $account = NULL) { function views_check_roles($rids, $account = NULL) { global $user; $account = isset($account) ? $account : $user; - $roles = array_keys($account->roles); - $roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID; - return user_access('access all views', $account) || array_intersect(array_filter($rids), $roles); + return user_access('access all views', $account) || array_intersect(array_filter($rids), $account->roles); } /**