You are here

function flag_flag::flag in Flag 7.3

Same name and namespace in other branches
  1. 5 flag.inc \flag_flag::flag()
  2. 6.2 flag.inc \flag_flag::flag()
  3. 6 flag.inc \flag_flag::flag()
  4. 7.2 flag.inc \flag_flag::flag()

Flags, or unflags, an item.

Parameters

string $action: Either 'flag' or 'unflag'.

int $entity_id: The ID of the item to flag or unflag.

string|NULL $account: The user on whose behalf to flag. Leave empty for the current user.

bool $skip_permission_check: Flag the item even if the $account user don't have permission to do so.

$flagging: (optional) This method works in tandem with Drupal's Field subsystem. Pass in a Flagging entity if you want operate on it as well. This may be used either of the following cases:

  • to save field data on a new Flagging entity at the same time as flagging an entity. In this case, using Entity API's entity_create() is recommended, although the Flagging entity may also be created directly as a new stdClass object.
  • to update field data an existing flagging. The $action parameter should be set to 'flag'. The Flagging entity will need to be loaded first with flagging_load().

As with Drupal core API functions for saving entities, no validation of Field API fields is performed here. It is the responsibility of the caller to take care of Field API validation, using either field_attach_form_validate() or field_attach_validate().

Return value

bool FALSE if some error occured (e.g., user has no permission, flag isn't applicable to the item, etc.), TRUE otherwise.

1 call to flag_flag::flag()
flag_node::flag in includes/flag/flag_node.inc
Flags, or unflags, an item.
1 method overrides flag_flag::flag()
flag_node::flag in includes/flag/flag_node.inc
Flags, or unflags, an item.

File

includes/flag/flag_flag.inc, line 702
Contains the flag_flag class. Flag type classes use an object oriented style inspired by that of Views 2.

Class

flag_flag
This abstract class represents a flag, or, in Views 2 terminology, "a handler".

Code

function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) {

  // Get the user.
  if (!isset($account)) {
    $account = $GLOBALS['user'];
  }

  // Check access and applicability.
  if (!$skip_permission_check) {
    if (!$this
      ->access($entity_id, $action, $account)) {
      $this->errors['access-denied'] = t('You are not allowed to flag, or unflag, this content.');

      // User has no permission to flag/unflag this object.
      return FALSE;
    }
  }
  else {

    // We are skipping permission checks. However, at a minimum we must make
    // sure the flag applies to this entity type:
    if (!$this
      ->applies_to_entity_id($entity_id)) {
      $this->errors['entity-type'] = t('This flag does not apply to this entity type.');
      return FALSE;
    }
  }
  if ($this->errors = module_invoke_all('flag_validate', $action, $this, $entity_id, $account, $skip_permission_check, $flagging)) {
    return FALSE;
  }

  // Find out which user id to use.
  $uid = $this->global ? 0 : $account->uid;

  // Find out which session id to use.
  if ($this->global) {
    $sid = 0;
  }
  else {
    $sid = flag_get_sid($uid, TRUE);

    // Anonymous users must always have a session id.
    if ($sid == 0 && $account->uid == 0) {
      $this->errors['session'] = t('Internal error: You are anonymous but you have no session ID.');
      return FALSE;
    }
  }

  // @todo: Discuss: Core wraps everything in a try { }, should we?
  $existing_flagging_id = $this
    ->_is_flagged($entity_id, $uid, $sid);
  $flagged = (bool) $existing_flagging_id;

  // Ensure we have a Flagging entity and it is correctly formed.
  if (isset($flagging)) {

    // We were given a Flagging entity.
    // Ensure that it has the uid and sid that we were also given.
    $flagging->uid = $uid;
    $flagging->sid = $sid;

    // This is an ugly hack to preserve previous behaviour.
    $flagging->given_as_parameter = TRUE;
  }
  else {

    // We were not given a Flagging entity.
    if ($flagged) {

      // Load the existing Flagging entity.
      $flagging = flagging_load($existing_flagging_id);
    }
    else {

      // Construct a new Flagging entity to flag with.
      $flagging = $this
        ->new_flagging($entity_id, $uid, $sid);
    }
  }

  // Perform the flagging or unflagging of this flag
  // along with a transaction mechanism.
  $transaction = db_transaction();
  try {
    if ($action == 'unflag') {
      if ($flagged) {
        $this
          ->flagging_delete($flagging, $entity_id, $account);
      }

      // We do nothing in the case of an attempt to unflag something that isn't
      // actually flagged.
    }
    elseif ($action == 'flag') {
      if (!$flagged) {
        $this
          ->flagging_insert($flagging, $entity_id, $account);
      }
      else {
        $this
          ->flagging_update($flagging, $entity_id, $account);
      }
    }
  } catch (Exception $e) {
    $transaction
      ->rollback();
    watchdog_exception('flag', $e);
    throw $e;
  }
  return TRUE;
}