/**
   * Performs a flagging when called via a route.
   *
   * @param \Drupal\flag\FlagInterface $flag
   *   The flag entity.
   * @param int $entity_id
   *   The flaggable ID.
   *
   * @return AjaxResponse
   *   The response object.
   *
   * @see \Drupal\flag\Plugin\ActionLink\AJAXactionLink
   */
  public function flag(FlagInterface $flag, $entity_id) {
    $flag_id = $flag->id();

    $account = $this->currentUser();

    $flagging = $this->entityTypeManager()->getStorage('flagging')->create([
      'flag_id' => $flag->id(),
      'entity_type' => $flag->getFlaggableEntityTypeId(),
      'entity_id' => $entity_id,
      'uid' => $account->id(),
    ]);

    return $this->getForm($flagging, 'add');
  }
  /**
   * {@inheritdoc}
   */
  public function getLinkURL($action, FlagInterface $flag, EntityInterface $entity) {
    $parameters = [
      'flag' => $flag->id(),
      'entity_id' => $entity->id(),
    ];

    return new Url($this->routeName($action), $parameters);
  }
  /**
   * Assert editing an invalid flagging throws an exception.
   */
  public function doBadEditFlagField() {
    $flag_id = $this->flag->id();

    // Test a good flag ID param, but a bad flaggable ID param.
    $this->drupalGet('flag/details/edit/' . $flag_id . '/-9999');
    $this->assertResponse('404', 'Editing an invalid flagging path: good flag, bad entity.');

    // Test a bad flag ID param, but a good flaggable ID param.
    $this->drupalGet('flag/details/edit/jibberish/' . $this->nodeId);
    $this->assertResponse('404', 'Editing an invalid flagging path: bad flag, good entity');

    // Test editing a unflagged entity.
    $unlinked_node = $this->drupalCreateNode(['type' => $this->nodeType]);
    $this->drupalGet('flag/details/edit/' . $flag_id . '/' . $unlinked_node->id());
    $this->assertResponse('404', 'Editing an invalid flagging path: good flag, good entity, but not flagged');
  }
Пример #4
0
  /**
   * Delete the flag.
   */
  public function doFlagDelete() {
    // Flag node.
    $this->drupalGet('node/' . $this->nodeId);
    $this->assertLink($this->flagShortText);
    // Go to the delete form for the flag.
    $this->drupalGet('admin/structure/flags/manage/' . $this->flag->id() . '/delete');

    $this->assertText($this->t('Are you sure you want to delete the flag @this_label?', ['@this_label' => $this->label]));

    $this->drupalPostForm(NULL, [], $this->t('Delete'));

    // Check the flag has been deleted.
    $result = $this->flagService->getFlagById($this->flagId);

    $this->assertNull($result, 'The flag was deleted.');
    $this->drupalGet('node/' . $this->nodeId);
    $this->assertText($this->node->label());
    $this->assertNoLink($this->flagShortText);
  }
Пример #5
0
  /**
   * {@inheritdoc}
   */
  public function reset(FlagInterface $flag, EntityInterface $entity = NULL) {
    $query = $this->entityQueryManager->get('flagging')
      ->condition('flag_id', $flag->id());

    if (!empty($entity)) {
      $query->condition('entity_id', $entity->id());
    }

    // Count the number of flaggings to delete.
    $count = $query->count()
      ->execute();

    $this->eventDispatcher->dispatch(FlagEvents::FLAG_RESET, new FlagResetEvent($flag, $count));

    $flaggings = $this->flagService->getFlaggings($flag, $entity);
    foreach ($flaggings as $flagging) {
      $flagging->delete();
    }

    return $count;
  }
Пример #6
0
  /**
   * Tests flaggings and counts are deleted when its user is deleted.
   */
  public function testUserDeletion() {
    $auth_user = $this->createUser();

    // Create a flag.
    $user_flag = Flag::create([
      'id' => strtolower($this->randomMachineName()),
      'label' => $this->randomString(),
      'entity_type' => 'user',
      'flag_type' => 'entity:user',
      'link_type' => 'reload',
      'flagTypeConfig' => [],
      'linkTypeConfig' => [],
    ]);
    $user_flag->save();

    $article = Node::create([
      'type' => 'article',
      'title' => $this->randomMachineName(8),
    ]);
    $article->save();

    $this->flagService->flag($user_flag, $auth_user, $this->adminUser);
    $this->flagService->flag($this->flag, $article, $auth_user);

    $user_before_count = $this->flagCountService->getEntityFlagCounts($auth_user);
    $this->assertEqual($user_before_count[$user_flag->id()], 1, 'The user has been flagged.');

    $article_count_before = $this->flagCountService->getEntityFlagCounts($article);
    $this->assertEqual($article_count_before[$this->flag->id()], 1, 'The article has been flagged by the user.');

    $auth_user->delete();

    $flaggings_after = $this->flagService->getFlaggings($user_flag);
    $this->assertEmpty($flaggings_after, 'The user flaggings were removed when the user was deleted.');

    $flaggings_after = $this->flagService->getFlaggings($this->flag);
    $this->assert(empty($flaggings_after), 'The node flaggings were removed when the user was deleted');
  }
  /**
   * Create a node, flag it and unflag it.
   */
  public function doFlagUnflagNode() {
    $node = $this->drupalCreateNode(['type' => $this->nodeType]);
    $node_id = $node->id();
    $flag_id = $this->flag->id();

    // Grant the flag permissions to the authenticated role, so that both
    // users have the same roles and share the render cache.
    $this->grantFlagPermissions($this->flag);

    // Create and login a new user.
    $user_1 = $this->drupalCreateUser();
    $this->drupalLogin($user_1);

    // Get the flag count before the flagging, querying the database directly.
    $flag_count_pre = db_query('SELECT count FROM {flag_counts}
      WHERE flag_id = :flag_id AND entity_type = :entity_type AND entity_id = :entity_id', [
      ':flag_id' => $flag_id,
      ':entity_type' => 'node',
      ':entity_id' => $node_id,
    ])->fetchField();

    // Click the flag link.
    $this->drupalGet('node/' . $node_id);
    $this->clickLink($this->flag->getFlagShortText());

    // Check if we have the confirm form message displayed.
    $this->assertText($this->flagConfirmMessage);

    // Submit the confirm form.
    $this->drupalPostForm('flag/confirm/flag/' . $flag_id . '/' . $node_id, [], t('Flag'));
    $this->assertResponse(200);

    // Check that the node is flagged.
    $this->drupalGet('node/' . $node_id);
    $this->assertLink($this->flag->getUnflagShortText());

    // Check the flag count was incremented.
    $flag_count_flagged = db_query('SELECT count FROM {flag_counts}
      WHERE flag_id = :flag_id AND entity_type = :entity_type AND entity_id = :entity_id', [
      ':flag_id' => $flag_id,
      ':entity_type' => 'node',
      ':entity_id' => $node_id,
    ])->fetchField();
    $this->assertEqual($flag_count_flagged, $flag_count_pre + 1, "The flag count was incremented.");

    // Unflag the node.
    $this->clickLink($this->flag->getUnflagShortText());

    // Check if we have the confirm form message displayed.
    $this->assertText($this->unflagConfirmMessage);

    // Submit the confirm form.
    $this->drupalPostForm(NULL, [], t('Unflag'));
    $this->assertResponse(200);

    // Check that the node is no longer flagged.
    $this->drupalGet('node/' . $node_id);
    $this->assertLink($this->flag->getFlagShortText());

    // Check the flag count was decremented.
    $flag_count_unflagged = db_query('SELECT count FROM {flag_counts}
      WHERE flag_id = :flag_id AND entity_type = :entity_type AND entity_id = :entity_id', [
      ':flag_id' => $flag_id,
      ':entity_type' => 'node',
      ':entity_id' => $node_id,
    ])->fetchField();
    $this->assertEqual($flag_count_unflagged, $flag_count_flagged - 1, "The flag count was decremented.");
  }
Пример #8
0
  /**
   * {@inheritdoc}
   */
  public function getFlaggingUsers(EntityInterface $entity, FlagInterface $flag = NULL) {
    $query = $this->entityQueryManager->get('flagging')
      ->condition('entity_type', $entity->getEntityTypeId())
      ->condition('entity_id', $entity->id());

    if (!empty($flag)) {
      $query->condition('flag_id', $flag->id());
    }

    $ids = $query->execute();
    // Load the flaggings.
    $flaggings = $this->getFlaggingsByIds($ids);

    $user_ids = array();
    foreach ($flaggings as $flagging) {
      $user_ids[] = $flagging->get('uid')->first()->getValue()['target_id'];
    }

    return $this->entityTypeManager->getStorage('user')->loadMultiple($user_ids);
  }
Пример #9
0
  /**
   * Flags a node using different user accounts and checks flag counts.
   */
  public function doTestFlagCounts() {
    /** \Drupal\Core\Database\Connection $connection */
    $connection = \Drupal::database();

    $node = $this->drupalCreateNode(['type' => $this->nodeType]);
    $node_id = $node->id();

    // Grant the flag permissions to the authenticated role, so that both
    // users have the same roles and share the render cache.
    $this->grantFlagPermissions($this->flag);

    // Create and login user 1.
    $user_1 = $this->drupalCreateUser();
    $this->drupalLogin($user_1);

    // Flag node (first count).
    $this->drupalGet('node/' . $node_id);
    $this->clickLink($this->flag->getFlagShortText());
    $this->assertResponse(200);
    $this->assertLink($this->flag->getUnflagShortText());

    // Check for 1 flag count.
    $count_flags_before = $connection->select('flag_counts')
      ->condition('flag_id', $this->flag->id())
      ->condition('entity_type', $node->getEntityTypeId())
      ->condition('entity_id', $node_id)
      ->countQuery()
      ->execute()
      ->fetchField();
    $this->assertTrue(1, $count_flags_before);

    // Logout user 1, create and login user 2.
    $user_2 = $this->drupalCreateUser();
    $this->drupalLogin($user_2);

    // Flag node (second count).
    $this->drupalGet('node/' . $node_id);
    $this->clickLink($this->flag->getFlagShortText());
    $this->assertResponse(200);
    $this->assertLink($this->flag->getUnflagShortText());

    // Check for 2 flag counts.
    $count_flags_after = $connection->select('flag_counts')
      ->condition('flag_id', $this->flag->id())
      ->condition('entity_type', $node->getEntityTypeId())
      ->condition('entity_id', $node_id)
      ->countQuery()
      ->execute()
      ->fetchField();
    $this->assertTrue(2, $count_flags_after);

    // Unflag the node again.
    $this->drupalGet('node/' . $node_id);
    $this->clickLink($this->flag->getUnflagShortText());
    $this->assertResponse(200);
    $this->assertLink($this->flag->getFlagShortText());

    // Check for 1 flag count.
    $count_flags_before = $connection->select('flag_counts')
      ->condition('flag_id', $this->flag->id())
      ->condition('entity_type', $node->getEntityTypeId())
      ->condition('entity_id', $node_id)
      ->countQuery()
      ->execute()
      ->fetchField();
    $this->assertEqual(1, $count_flags_before);

    // Delete  user 1.
    $user_1->delete();

    // Check for 0 flag counts, user deletion should lead to count decrement
    // or row deletion.
    $count_flags_before = $connection->select('flag_counts')
      ->condition('flag_id', $this->flag->id())
      ->condition('entity_type', $node->getEntityTypeId())
      ->condition('entity_id', $node_id)
      ->countQuery()
      ->execute()
      ->fetchField();

    $this->assertEqual(0, $count_flags_before);
  }
 /**
  * Helper for assertPseudofield() and assertNoPseudofield().
  *
  * It is not recommended to call this function directly.
  *
  * @param \Drupal\flag\FlagInterface $flag
  *   The flag to look for.
  * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The flaggable entity the flag is on.
  * @param string $message
  *   Message to display.
  * @param bool $exists
  *   TRUE if the flag link should exist, FALSE if it should not exist.
  */
 protected function assertPseudofieldHelper(FlagInterface $flag, EntityInterface $entity, $message, $exists) {
   $xpath = $this->xpath("//*[contains(@class, 'node__content')]/a[@id = :id]", [
     ':id' => 'flag-' . $flag->id() . '-id-' . $entity->id(),
   ]);
   $this->assert(count($xpath) == ($exists ? 1 : 0), $message);
 }
Пример #11
0
  /**
   * Grants flag and unflag permission to the given flag.
   *
   * @param \Drupal\flag\FlagInterface $flag
   *   The flag on which to grant permissions.
   * @param array|string $role_id
   *   (optional) The ID of the role to grant permissions. If omitted, the
   *   authenticated role is assumed.
   * @param bool $can_flag
   *   (optional) TRUE to grant the role flagging permission, FALSE to not grant
   *   flagging permission to the role. If omitted, TRUE is assumed.
   * @param bool $can_unflag
   *   Optional TRUE to grant the role unflagging permission, FALSE to not grant
   *   unflagging permission to the role. If omitted, TRUE is assumed.
   */
  protected function grantFlagPermissions(FlagInterface $flag,
                                      $role_id = RoleInterface::AUTHENTICATED_ID,
                                      $can_flag = TRUE, $can_unflag = TRUE) {

    // Grant the flag permissions to the authenticated role, so that both
    // users have the same roles and share the render cache.
    $role = Role::load($role_id);
    if ($can_flag) {
      $role->grantPermission('flag ' . $flag->id());
    }

    if ($can_unflag) {
      $role->grantPermission('unflag ' . $flag->id());
    }

    $role->save();
  }
  /**
   * Flag a node.
   */
  public function doFlagNode() {
    $node = $this->drupalCreateNode(['type' => $this->nodeType]);
    $node_id = $node->id();
    $flag_id = $this->flag->id();

    // Grant the flag permissions to the authenticated role, so that both
    // users have the same roles and share the render cache. ???? TODO
    $this->grantFlagPermissions($this->flag);

    // Create and login a new user.
    $user_1 = $this->drupalCreateUser();
    $this->drupalLogin($user_1);

    // Get the flag count before the flagging, querying the database directly.
    $flag_count_pre = db_query('SELECT count FROM {flag_counts}
      WHERE flag_id = :flag_id AND entity_type = :entity_type AND entity_id = :entity_id', [
      ':flag_id' => $flag_id,
      ':entity_type' => 'node',
      ':entity_id' => $node_id,
    ])->fetchField();

    // Attempt to load the reload link URL without the token.
    // We (probably) can't obtain the URL from the route rather than hardcoding
    // it, as that would probably give us the token too.
    $this->drupalGet("flag/flag/$flag_id/$node_id");
    $this->assertResponse(403, "Access to the flag reload link is denied when no token is supplied.");

    // Click the flag link.
    $this->drupalGet('node/' . $node_id);
    $this->clickLink($this->flag->getFlagShortText());

    // Check that the node is flagged.
    $this->drupalGet('node/' . $node_id);
    $this->assertLink($this->flag->getUnflagShortText());

    // Check the flag count was incremented.
    $flag_count_flagged = db_query('SELECT count FROM {flag_counts}
      WHERE flag_id = :flag_id AND entity_type = :entity_type AND entity_id = :entity_id', [
      ':flag_id' => $flag_id,
      ':entity_type' => 'node',
      ':entity_id' => $node_id,
    ])->fetchField();
    $this->assertEqual($flag_count_flagged, $flag_count_pre + 1, "The flag count was incremented.");

    // Attempt to load the reload link URL without the token.
    $this->drupalGet("flag/unflag/$flag_id/$node_id");
    $this->assertResponse(403, "Access to the unflag reload link is denied when no token is supplied.");

    // Unflag the node.
    $this->drupalGet('node/' . $node_id);
    $this->clickLink($this->flag->getUnflagShortText());

    // Check that the node is no longer flagged.
    $this->drupalGet('node/' . $node_id);
    $this->assertLink($this->flag->getFlagShortText());

    // Check the flag count was decremented.
    $flag_count_unflagged = db_query('SELECT count FROM {flag_counts}
      WHERE flag_id = :flag_id AND entity_type = :entity_type AND entity_id = :entity_id', [
      ':flag_id' => $flag_id,
      ':entity_type' => 'node',
      ':entity_id' => $node_id,
    ])->fetchField();
    $this->assertEqual($flag_count_unflagged, $flag_count_flagged - 1, "The flag count was decremented.");
  }
Пример #13
0
 /**
  * Resets loaded flag counts.
  *
  * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The flagged entity.
  * @param \Drupal\flag\FlagInterface $flag
  *   The flag.
  */
 protected function resetLoadedCounts(EntityInterface $entity, FlagInterface $flag) {
   // @todo Consider updating them instead of just clearing it.
   unset($this->entityCounts[$entity->getEntityTypeId()][$entity->id()]);
   unset($this->flagCounts[$flag->id()]);
   unset($this->flagEntityCounts[$flag->id()]);
   unset($this->userFlagCounts[$flag->id()]);
 }