/**
  * {@inheritdoc}
  *
  * When the $operation is 'add' then the $entity is of type 'profile_type',
  * otherwise $entity is of type 'profile'.
  */
 protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account)
 {
     $account = $this->prepareUser($account);
     $user_page = \Drupal::request()->attributes->get('user');
     // Some times, operation edit is called update.
     // Use edit in any case.
     if ($operation == 'update') {
         $operation = 'edit';
     }
     // Check that if profile type has require roles, the user the profile is
     // being added to has any of the required roles.
     if ($entity->getEntityTypeId() == 'profile') {
         $profile_roles = ProfileType::load($entity->bundle())->getRoles();
         $user_roles = $entity->getOwner()->getRoles(TRUE);
         if (!empty(array_filter($profile_roles)) && !array_intersect($user_roles, $profile_roles)) {
             return AccessResult::forbidden();
         }
     } elseif ($entity->getEntityTypeId() == 'profile_type') {
         $profile_roles = $entity->getRoles();
         $user_roles = User::load($user_page->id())->getRoles(TRUE);
         if (!empty(array_filter($profile_roles)) && !array_intersect($user_roles, $profile_roles)) {
             return AccessResult::forbidden();
         }
     }
     if ($account->hasPermission('bypass profile access')) {
         return AccessResult::allowed()->cachePerPermissions();
     } elseif ($operation == 'add' && ($user_page->id() == $account->id() && $account->hasPermission($operation . ' own ' . $entity->id() . ' profile') || $account->hasPermission($operation . ' any ' . $entity->id() . ' profile')) || $operation != 'add' && ($entity->getOwnerId() == $account->id() && $account->hasPermission($operation . ' own ' . $entity->getType() . ' profile') || $account->hasPermission($operation . ' any ' . $entity->getType() . ' profile'))) {
         return AccessResult::allowed()->cachePerPermissions();
     } else {
         return AccessResult::forbidden()->cachePerPermissions();
     }
 }
  /**
   * Builds a standard list of permissions for a given profile type.
   *
   * @param \Drupal\profile\Entity\ProfileType $profile_type
   *   The machine name of the profile type.
   *
   * @return array
   *   An array of permission names and descriptions.
   */
  protected function buildPermissions(ProfileType $profile_type) {
    $type_id = $profile_type->id();
    $type_params = ['%type' => $profile_type->label()];

    return [
      "add own $type_id profile" => [
        'title' => $this->t('%type: Add own profile', $type_params),
      ],
      "add any $type_id profile" => [
        'title' => $this->t('%type: Add any profile', $type_params),
      ],
      "view own $type_id profile" => [
        'title' => $this->t('%type: View own profile', $type_params),
      ],
      "view any $type_id profile" => [
        'title' => $this->t('%type: View any profile', $type_params),
      ],
      "edit own $type_id profile" => [
        'title' => $this->t('%type: Edit own profile', $type_params),
      ],
      "edit any $type_id profile" => [
        'title' => $this->t('%type: Edit any profile', $type_params),
      ],
      "delete own $type_id profile" => [
        'title' => $this->t('%type: Delete own profile', $type_params),
      ],
      "delete any $type_id profile" => [
        'title' => $this->t('%type: Delete any profile', $type_params),
      ],
    ];
  }
 /**
  * Tests add profile form access for a profile type that requires users to
  * have one of multiple roles.
  */
 public function testProfileWithAllRoles()
 {
     // Create user with add own profile permissions.
     $web_user1 = $this->drupalCreateUser(["add own {$this->type3->id()} profile"]);
     $this->drupalLogin($web_user1);
     // Test user without role can access add profile form.
     // Expected: User cannot access form.
     $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
     $this->assertResponse(403);
     // Test user with role 1 can access add profile form.
     // Expected: User can access form.
     $web_user1->addRole($this->role1);
     $web_user1->save();
     $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
     $this->assertResponse(200);
     // Test user with both roles can access add profile form.
     // Expected: User can access form.
     $web_user1->addRole($this->role2);
     $web_user1->save();
     $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
     $this->assertResponse(200);
     // Test user with role 2 can access add profile form.
     // Expected: User can access form.
     $web_user1->removeRole($this->role1);
     $web_user1->save();
     $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
     $this->assertResponse(200);
     // Test user without role can access add profile form.
     // Expected: User cannot access form.
     $web_user1->removeRole($this->role2);
     $web_user1->save();
     $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
     $this->assertResponse(403);
 }
 /**
  * Tests tabs in profile UI.
  */
 public function testProfileTabs()
 {
     $types_data = ['profile_type_0' => ['label' => $this->randomMachineName()], 'profile_type_1' => ['label' => $this->randomMachineName()]];
     /** @var ProfileType[] $types */
     $types = [];
     foreach ($types_data as $id => $values) {
         $types[$id] = ProfileType::create(['id' => $id] + $values);
         $types[$id]->save();
     }
     $this->container->get('router.builder')->rebuild();
     $this->user1 = User::create(['name' => $this->randomMachineName(), 'mail' => $this->randomMachineName() . '@example.com']);
     $this->user1->save();
     $this->user2 = User::create(['name' => $this->randomMachineName(), 'mail' => $this->randomMachineName() . '@example.com']);
     $this->user2->save();
     // Create new profiles.
     $profile1 = Profile::create($expected = ['type' => $types['profile_type_0']->id(), 'uid' => $this->user1->id()]);
     $profile1->save();
     $profile2 = Profile::create($expected = ['type' => $types['profile_type_1']->id(), 'uid' => $this->user2->id()]);
     $profile2->save();
     $this->drupalLogin($this->adminUser);
     $this->drupalGet('admin/config');
     $this->clickLink('User profiles');
     $this->assertResponse(200);
     $this->assertUrl('admin/config/people/profiles');
     $this->assertLink($profile1->label());
     $this->assertLinkByHref($profile2->toUrl('canonical')->toString());
     $tasks = [['entity.profile.collection', []], ['entity.profile_type.collection', []]];
     $this->assertLocalTasks($tasks, 0);
 }
Example #5
0
 /**
  * Creates a profile type for tests.
  *
  * @param string $id
  *   The profile type machine name.
  * @param string $label
  *   The profile type human display name.
  * @param bool|FALSE $registration
  *   Boolean if profile type shows on registration form.
  * @param array $roles
  *   Array of user role machine names.
  *
  * @return \Drupal\profile\Entity\ProfileTypeInterface
  *   Returns a profile type entity.
  */
 protected function createProfileType($id = NULL, $label = NULL, $registration = FALSE, $roles = [])
 {
     $id = !empty($id) ? $id : $this->randomMachineName();
     $label = !empty($label) ? $label : $this->randomMachineName();
     $type = ProfileType::create(['id' => $id, 'label' => $label, 'registration' => $registration, 'roles' => $roles]);
     $type->save();
     return $type;
 }
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     parent::setUp();
     $this->drupalPlaceBlock('local_tasks_block');
     $this->drupalPlaceBlock('local_actions_block');
     $this->drupalPlaceBlock('page_title_block');
     $this->type = $this->createProfileType('test', 'Test profile', TRUE);
     $id = $this->type->id();
     $field_storage = FieldStorageConfig::create(['field_name' => 'profile_fullname', 'entity_type' => 'profile', 'type' => 'text']);
     $field_storage->save();
     $this->field = FieldConfig::create(['field_storage' => $field_storage, 'bundle' => $this->type->id(), 'label' => 'Full name']);
     $this->field->save();
     // Configure the default display.
     $this->display = EntityViewDisplay::load("profile.{$this->type->id()}.default");
     if (!$this->display) {
         $this->display = EntityViewDisplay::create(['targetEntityType' => 'profile', 'bundle' => $this->type->id(), 'mode' => 'default', 'status' => TRUE]);
         $this->display->save();
     }
     $this->display->setComponent($this->field->getName(), ['type' => 'string'])->save();
     // Configure rhe default form.
     $this->form = EntityFormDisplay::load("profile.{$this->type->id()}.default");
     if (!$this->form) {
         $this->form = EntityFormDisplay::create(['targetEntityType' => 'profile', 'bundle' => $this->type->id(), 'mode' => 'default', 'status' => TRUE]);
         $this->form->save();
     }
     $this->form->setComponent($this->field->getName(), ['type' => 'string_textfield'])->save();
     $this->checkPermissions(['administer profile types', "view own {$id} profile", "view any {$id} profile", "add own {$id} profile", "add any {$id} profile", "edit own {$id} profile", "edit any {$id} profile", "delete own {$id} profile", "delete any {$id} profile"]);
     user_role_grant_permissions(AccountInterface::AUTHENTICATED_ROLE, ['access user profiles']);
     $this->adminUser = $this->drupalCreateUser(['administer profile types', "view any {$id} profile", "add any {$id} profile", "edit any {$id} profile", "delete any {$id} profile"]);
 }
 /**
  * {@inheritdoc}
  */
 public function getRoutes(EntityTypeInterface $entity_type)
 {
     $collection = parent::getRoutes($entity_type);
     /** @var \Drupal\profile\Entity\ProfileTypeInterface $profile_type */
     foreach (ProfileType::loadMultiple() as $profile_type) {
         $route = new Route("/user/{user}/{profile_type}", ['_controller' => '\\Drupal\\profile\\Controller\\ProfileController::userProfileForm'], ['_profile_access_check' => 'add'], ['parameters' => ['user' => ['type' => 'entity:user'], 'profile_type' => ['type' => 'entity:profile_type']]]);
         $collection->add("entity.profile.type.{$profile_type->id()}.user_profile_form", $route);
         // If the profile type supports multiple, we need an additional route for
         // adding new profiles.
         if ($profile_type->getMultiple()) {
             $route = new Route("/user/{user}/{profile_type}/add", ['_controller' => '\\Drupal\\profile\\Controller\\ProfileController::addProfile'], ['_profile_access_check' => 'add'], ['parameters' => ['user' => ['type' => 'entity:user'], 'profile_type' => ['type' => 'entity:profile_type']]]);
             $collection->add("entity.profile.type.{$profile_type->id()}.user_profile_form.add", $route);
         }
     }
     return $collection;
 }
Example #8
0
 /**
  * Tests CRUD operations.
  */
 public function testCRUD()
 {
     $types_data = ['profile_type_0' => ['label' => $this->randomMachineName()], 'profile_type_1' => ['label' => $this->randomMachineName()]];
     /** @var ProfileType[] $types */
     $types = [];
     foreach ($types_data as $id => $values) {
         $types[$id] = ProfileType::create(['id' => $id] + $values);
         $types[$id]->save();
     }
     $this->user1 = User::create(['name' => $this->randomMachineName(), 'mail' => $this->randomMachineName() . '@example.com']);
     $this->user1->save();
     $this->user2 = User::create(['name' => $this->randomMachineName(), 'mail' => $this->randomMachineName() . '@example.com']);
     $this->user2->save();
     $this->profileStorage = \Drupal::entityTypeManager()->getStorage('profile');
     // Create a new profile.
     $profile = Profile::create($expected = ['type' => $types['profile_type_0']->id(), 'uid' => $this->user1->id()]);
     $this->assertIdentical($profile->id(), NULL);
     $this->assertTrue($profile->uuid());
     $this->assertIdentical($profile->getType(), $expected['type']);
     $expected_label = t('@type profile of @username (uid: @uid)', ['@type' => $types['profile_type_0']->label(), '@username' => $this->user1->getDisplayName(), '@uid' => $this->user1->id()]);
     $this->assertEqual($profile->label(), $expected_label, new FormattableMarkup('Expected "%expected" but got "%got"', ['%expected' => $expected_label, '%got' => $profile->label()]));
     $this->assertIdentical($profile->getOwnerId(), $this->user1->id());
     $this->assertIdentical($profile->getCreatedTime(), REQUEST_TIME);
     $this->assertIdentical($profile->getChangedTime(), REQUEST_TIME);
     // Save the profile.
     $status = $profile->save();
     $this->assertIdentical($status, SAVED_NEW);
     $this->assertTrue($profile->id());
     $this->assertIdentical($profile->getChangedTime(), REQUEST_TIME);
     // List profiles for the user and verify that the new profile appears.
     $list = $this->profileStorage->loadByProperties(['uid' => $this->user1->id()]);
     $list_ids = array_keys($list);
     $this->assertEqual($list_ids, [(int) $profile->id()]);
     // Reload and update the profile.
     /** @var Profile $profile */
     $profile = Profile::load($profile->id());
     $profile->setChangedTime($profile->getChangedTime() - 1000);
     $original = clone $profile;
     $status = $profile->save();
     $this->assertIdentical($status, SAVED_UPDATED);
     $this->assertIdentical($profile->id(), $original->id());
     $this->assertEqual($profile->getCreatedTime(), REQUEST_TIME);
     $this->assertEqual($original->getChangedTime(), REQUEST_TIME - 1000);
     // Changed time is only updated when saved through the UI form.
     // @see \Drupal\Core\Entity\ContentEntityForm::submitForm().
     $this->assertEqual($profile->getChangedTime(), REQUEST_TIME - 1000);
     // Create a second profile.
     $user1_profile1 = $profile;
     $profile = Profile::create(['type' => $types['profile_type_0']->id(), 'uid' => $this->user1->id()]);
     $status = $profile->save();
     $this->assertIdentical($status, SAVED_NEW);
     $user1_profile = $profile;
     // List profiles for the user and verify that both profiles appear.
     $list = $this->profileStorage->loadByProperties(['uid' => $this->user1->id()]);
     $list_ids = array_keys($list);
     $this->assertEqual($list_ids, [(int) $user1_profile1->id(), (int) $user1_profile->id()]);
     // Delete the second profile and verify that the first still exists.
     $user1_profile->delete();
     $this->assertFalse(Profile::load($user1_profile->id()));
     $list = $this->profileStorage->loadByProperties(['uid' => $this->user1->id()]);
     $list_ids = array_keys($list);
     $this->assertEqual($list_ids, [(int) $user1_profile1->id()]);
     // Create a new second profile.
     $user1_profile = Profile::create(['type' => $types['profile_type_1']->id(), 'uid' => $this->user1->id()]);
     $status = $user1_profile->save();
     $this->assertIdentical($status, SAVED_NEW);
     // Create a profile for the second user.
     $user2_profile1 = Profile::create(['type' => $types['profile_type_0']->id(), 'uid' => $this->user2->id()]);
     $status = $user2_profile1->save();
     $this->assertIdentical($status, SAVED_NEW);
     // Delete the first user and verify that all of its profiles are deleted.
     $this->user1->delete();
     $this->assertFalse(User::load($this->user1->id()));
     $list = $this->profileStorage->loadByProperties(['uid' => $this->user1->id()]);
     $list_ids = array_keys($list);
     $this->assertEqual($list_ids, []);
     // List profiles for the second user and verify that they still exist.
     $list = $this->profileStorage->loadByProperties(['uid' => $this->user2->id()]);
     $list_ids = array_keys($list);
     $this->assertEqual($list_ids, [(int) $user2_profile1->id()]);
     // @todo Rename a profile type; verify that existing profiles are updated.
 }
Example #9
0
  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $profile_type = ProfileType::load($this->entity->bundle());

    // Active profile for non administers if profile is new.
    if (!\Drupal::currentUser()->hasPermission('administer profiles') && $this->entity->isNew()) {
      $this->entity->setActive(TRUE);
    }
    switch ($this->entity->save()) {
      case SAVED_NEW:
        drupal_set_message(t('%label profile has been created.', ['%label' => $profile_type->label()]));
        break;
      case SAVED_UPDATED:
        drupal_set_message(t('%label profile has been updated.', ['%label' => $profile_type->label()]));
        break;
    }

    $form_state->setRedirect('entity.user.canonical', [
      'user' => $this->entity->getOwnerId(),
    ]);
  }
Example #10
0
 /**
  * Creates a profile type for tests.
  *
  * @param string $id
  *   The profile type machine name.
  * @param string $label
  *   The profile type human display name.
  * @param bool|FALSE $registration
  *   Boolean if profile type shows on registration form.
  *
  * @return \Drupal\profile\Entity\ProfileInterface
  *   Returns a profile type entity.
  */
 protected function createProfileType($id, $label, $registration = FALSE)
 {
     $type = ProfileType::create(['id' => $id, 'label' => $label, 'registration' => $registration]);
     $type->save();
     $this->container->get('router.builder')->rebuild();
     return $type;
 }
Example #11
0
 /**
  * Check whether the profile type exists.
  *
  * @param string $id
  *   A string representing a profile type ID.
  *
  * @return bool
  *   Returns bool if profile exists.
  */
 public function exists($id)
 {
     $profile_type = ProfileType::load($id);
     return !empty($profile_type);
 }
Example #12
0
 /**
  * {@inheritdoc}
  */
 public function label()
 {
     $profile_type = ProfileType::load($this->bundle());
     return t('@type profile of @username (uid: @uid)', ['@type' => $profile_type->label(), '@username' => $this->getOwner()->getDisplayName(), '@uid' => $this->getOwnerId()]);
 }