class flag_flag in Flag 6
Same name and namespace in other branches
- 5 flag.inc \flag_flag
- 6.2 flag.inc \flag_flag
- 7.3 includes/flag/flag_flag.inc \flag_flag
- 7.2 flag.inc \flag_flag
This abstract class represents a flag, or, in Views 2 terminology, "a handler".
This is the base class for all flag implementations. Notable derived classes are flag_node and flag_comment.
Hierarchy
- class \flag_flag
Expanded class hierarchy of flag_flag
File
- ./flag.inc, line 97 
- Implements various flags. Uses object oriented style inspired by that of Views 2.
View source
class flag_flag {
  // The database ID. Null for flags that haven't been saved to the database yet.
  var $fid = NULL;
  // The content-type this flag works with.
  var $content_type = NULL;
  // The flag's "machine readable" name.
  var $name = '';
  // Various non-serialized properties of the flag, corresponding directly to
  // database columns.
  var $title = '';
  var $roles = array(
    DRUPAL_AUTHENTICATED_RID,
  );
  var $global = FALSE;
  // The sub-types, e.g. node types, this flag applies to.
  var $types = array();
  /**
   * Creates a flag from a database row. Returns it.
   *
   * This is static method.
   *
   * The reason this isn't a non-static instance method --like Views's init()--
   * is because the class to instantiate changes according to the 'content_type'
   * database column. This design pattern is known as the "Single Table
   * Inheritance".
   *
   * @static
   */
  function factory_by_row($row) {
    $flag = flag_create_handler($row->content_type);
    // Lump all data unto the object...
    foreach ($row as $field => $value) {
      $flag->{$field} = $value;
    }
    // ...but skip the following two.
    unset($flag->options, $flag->type);
    $options = (array) unserialize($row->options);
    // Make the unserialized options accessible as normal properties.
    foreach ($options as $option => $value) {
      $flag->{$option} = $value;
    }
    if (!empty($row->type)) {
      // The loop loading from the database should further populate this property.
      $flag->types[] = $row->type;
    }
    $flag->roles = empty($row->roles) ? array() : explode(',', $row->roles);
    return $flag;
  }
  /**
   * Create a complete flag (except an FID) from an array definition.
   */
  function factory_by_array($config) {
    $flag = flag_create_handler($config['content_type']);
    foreach ($config as $option => $value) {
      $flag->{$option} = $value;
    }
    if (is_array($config['locked'])) {
      $flag->locked = drupal_map_assoc($config['locked']);
    }
    return $flag;
  }
  /**
   * Another factory method. Returns a new, "empty" flag; e.g., one suitable for
   * the "Add new flag" page.
   *
   * @static
   */
  function factory_by_content_type($content_type) {
    return flag_create_handler($content_type);
  }
  /**
   * Declares the options this flag supports, and their default values.
   *
   * Derived classes should want to override this.
   */
  function default_options() {
    return array(
      'flag_short' => '',
      'flag_long' => '',
      'flag_message' => '',
      'flag_confirmation' => '',
      'unflag_short' => '',
      'unflag_long' => '',
      'unflag_message' => '',
      'unflag_confirmation' => '',
      'link_type' => 'toggle',
    );
  }
  /**
   * Provides a form for setting options.
   *
   * Derived classes should want to override this.
   */
  function options_form(&$form) {
  }
  /**
   * Default constructor. Loads the default options.
   */
  function construct() {
    $options = $this
      ->default_options();
    foreach ($options as $option => $value) {
      $this->{$option} = $value;
    }
  }
  /**
   * Update the flag with settings entered in a form.
   */
  function form_input($form_values) {
    // Load the form fields indiscriminately unto the flag (we don't care about
    // stray FormAPI fields because we aren't touching unknown properties anyway.
    foreach ($form_values as $field => $value) {
      $this->{$field} = $value;
    }
    // But checkboxes need some massaging:
    $this->roles = array_values(array_filter($this->roles));
    $this->types = array_values(array_filter($this->types));
    // Clear internal titles cache:
    $this
      ->get_title(NULL, TRUE);
  }
  /**
   * Validates a flag settings
   */
  function validate() {
    $this
      ->validate_name();
  }
  function validate_name() {
    // Ensure a safe machine name.
    if (!preg_match('/^[a-z_][a-z0-9_]*$/', $this->name)) {
      form_set_error('name', t('The flag name may only contain lowercase letters, underscores, and numbers.'));
    }
    // Ensure the machine name is unique.
    if (!isset($this->fid)) {
      $flag = flag_get_flag($this->name);
      if (!empty($flag)) {
        form_set_error('name', t('Flag names must be unique. This flag name is already in use.'));
      }
    }
  }
  /**
   * Fetches, possibly from some cache, a content object this flag works with.
   */
  function fetch_content($content_id, $object_to_remember = NULL) {
    static $cache = array();
    if (isset($object_to_remember)) {
      $cache[$content_id] = $object_to_remember;
    }
    if (!array_key_exists($content_id, $cache)) {
      $content = $this
        ->_load_content($content_id);
      $cache[$content_id] = $content ? $content : NULL;
    }
    return $cache[$content_id];
  }
  /**
   * Loads a content object this flag works with.
   * Derived classes must implement this.
   *
   * @abstract
   * @private
   * @static
   */
  function _load_content($content_id) {
    return NULL;
  }
  /**
   * Stores some object in fetch_content()'s cache, so subsequenet calls to
   * fetch_content() return it.
   *
   * This is needed because otherwise fetch_object() loads the object from the
   * database (by calling _load_content()), whereas sometimes we want to fetch
   * an object that hasn't yet been saved to the database. See flag_nodeapi().
   */
  function remember_content($content_id, $object) {
    $this
      ->fetch_content($content_id, $object);
  }
  /**
   * Returns TRUE if the flag applies to the given content.
   * Derived classes must implement this.
   *
   * @abstract
   */
  function applies_to_content_object($content) {
    return FALSE;
  }
  /**
   * Returns TRUE if the flag applies to the content with the given ID.
   *
   * This is a convenience method that simply loads the object and calls
   * applies_to_content_object(). If you already have the object, don't call
   * this function: call applies_to_content_object() directly.
   */
  function applies_to_content_id($content_id) {
    return $this
      ->applies_to_content_object($this
      ->fetch_content($content_id));
  }
  /**
   * Given a content object, returns its ID.
   * Derived classes must implement this.
   *
   * @abstract
   */
  function get_content_id($content) {
    return NULL;
  }
  /**
   * Returns TRUE if the flag is configured to show the flag-link using hook_link.
   * Derived classes are likely to implement this.
   */
  function uses_hook_link($teaser) {
    return FALSE;
  }
  /**
   * Returns TRUE if user has access to use this flag.
   *
   * @param $account
   *   Optional. The user object. If none given, the current user will be used.
   *
   * @return
   *   Boolean TRUE if the user is allowed to flag/unflag. FALSE otherwise.
   */
  function user_access($account = NULL) {
    if (!isset($account)) {
      $account = $GLOBALS['user'];
    }
    $matched_roles = array_intersect($this->roles, array_keys($account->roles));
    return !empty($matched_roles) || empty($this->roles) || $account->uid == 1;
  }
  /**
   * Flags, on unflags, an item.
   *
   * @param $action
   *   Either 'flag' or 'unflag'.
   * @param $content_id
   *   The ID of the item to flag or unflag.
   * @param $account
   *   The user on whose behalf to flag. Leave empty for the current user.
   * @param $skip_permission_check
   *   Flag the item even if the $account user don't have permission to do so.
   * @return
   *   FALSE if some error occured (e.g., user has no permission, flag isn't
   *   applicable to the item, etc.), TRUE otherwise.
   */
  function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE) {
    if (!isset($account)) {
      $account = $GLOBALS['user'];
    }
    if (!$account) {
      return FALSE;
    }
    if (!$account->uid) {
      // Anonymous users can't flag with this system. For now.
      //
      // @todo This is legacy code. $flag->user_access() should handle this.
      // This will also make it posible to have flags that do support anonymous
      // users.
      return FALSE;
    }
    if (!$skip_permission_check && !$this
      ->user_access($account)) {
      // User has no permission to use this flag.
      return FALSE;
    }
    if (!$this
      ->applies_to_content_id($content_id)) {
      // Flag does not apply to this content.
      return FALSE;
    }
    // Clear various caches; We don't want code running after us to report
    // wrong counts or false flaggings.
    flag_get_counts(NULL, NULL, TRUE);
    flag_get_user_flags(NULL, NULL, NULL, TRUE);
    // Perform the flagging or unflagging of this flag.
    $uid = $this->global ? 0 : $account->uid;
    $flagged = $this
      ->_is_flagged($content_id, $uid);
    if ($action == 'unflag' && $flagged) {
      $this
        ->_unflag($content_id, $uid);
      // Let other modules perform actions.
      module_invoke_all('flag', 'unflag', $this, $content_id, $account);
    }
    elseif ($action == 'flag' && !$flagged) {
      $this
        ->_flag($content_id, $uid);
      // Let other modules perform actions.
      module_invoke_all('flag', 'flag', $this, $content_id, $account);
    }
    return TRUE;
  }
  /**
   * Returns TRUE if a certain user has flagged this content.
   *
   * Thanks to using a cache, inquiring several different flags about the same
   * item results in only one SQL query.
   *
   * @param $uid
   *   Optional. The user ID whose flags we're checking. If none given, the
   *   current user will be used.
   */
  function is_flagged($content_id, $uid = NULL) {
    $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid;
    // flag_get_user_flags() does caching.
    $user_flags = flag_get_user_flags($this->content_type, $content_id, $uid);
    return isset($user_flags[$this->name]);
  }
  /**
   * Returns TRUE if a certain user has flagged this content.
   *
   * You probably shouldn't call this raw private method: call the
   * is_flagged() method instead.
   *
   * This method is similar to is_flagged() except that it does direct SQL and
   * doesn't do caching. Use it when you want to not affect the cache, or to
   * bypass it.
   *
   * @private
   */
  function _is_flagged($content_id, $uid) {
    return db_result(db_query("SELECT fid FROM {flag_content} WHERE fid = %d AND uid = %d AND content_id = %d", $this->fid, $uid, $content_id));
  }
  /**
   * A low-level method to flag content.
   *
   * You probably shouldn't call this raw private method: call the flag()
   * function instead.
   *
   * @private
   */
  function _flag($content_id, $uid) {
    db_query("INSERT INTO {flag_content} (fid, content_type, content_id, uid, timestamp) VALUES (%d, '%s', %d, %d, %d)", $this->fid, $this->content_type, $content_id, $uid, time());
    $this
      ->_update_count($content_id);
  }
  /**
   * A low-level method to unflag content.
   *
   * You probably shouldn't call this raw private method: call the flag()
   * function instead.
   *
   * @private
   */
  function _unflag($content_id, $uid) {
    db_query("DELETE FROM {flag_content} WHERE fid = %d AND uid = %d AND content_id = %d", $this->fid, $uid, $content_id);
    $this
      ->_update_count($content_id);
  }
  /**
   * Updates the flag count for this content
   *
   * @private
   */
  function _update_count($content_id) {
    $count = db_result(db_query("SELECT COUNT(*) FROM {flag_content} WHERE fid = %d AND content_id = %d", $this->fid, $content_id));
    if ($count == 0) {
      db_query("DELETE FROM {flag_counts} WHERE fid = %d AND content_id = %d", $this->fid, $content_id);
    }
    else {
      db_query("UPDATE {flag_counts} SET count = %d WHERE fid = %d AND content_id = %d", $count, $this->fid, $content_id);
      if (!db_affected_rows()) {
        db_query("INSERT INTO {flag_counts} (fid, content_type, content_id, count) VALUES (%d, '%s', %d, %d)", $this->fid, $this->content_type, $content_id, $count);
      }
    }
  }
  /**
   * Returns the number of times an item is flagged.
   *
   * Thanks to using a cache, inquiring several different flags about the same
   * item results in only one SQL query.
   */
  function get_count($content_id) {
    $counts = flag_get_counts($this->content_type, $content_id);
    return isset($counts[$this->name]) ? $counts[$this->name] : 0;
  }
  /**
   * Returns the number of items a user has flagged.
   *
   * For global flags, pass '0' as the user ID.
   */
  function get_user_count($uid) {
    return db_result(db_query('SELECT COUNT(*) FROM {flag_content} WHERE fid = %d AND uid = %d', $this->fid, $uid));
  }
  /**
   * Processes a flag label for display. This means language translation and
   * token replacements.
   *
   * You should always call this function and not get at the label directly.
   * E.g., do `print $flag->get_label('title')` instead of `print
   * $flag->title`.
   *
   * @param $label
   *   The label to get, e.g. 'title', 'flag_short', 'unflag_short', etc.
   * @param $content_id
   *   The ID in whose context to interpret tokens. If not given, only global
   *   tokens will be substituted.
   * @return
   *   The processed label.
   */
  function get_label($label, $content_id = NULL) {
    if (!isset($this->{$label})) {
      return;
    }
    $label = t($this->{$label});
    if (strpos($label, '[') !== FALSE && module_exists('token')) {
      $label = $this
        ->replace_tokens($label, array(
        'global' => NULL,
      ), $content_id);
    }
    return filter_xss_admin($label);
  }
  /**
   * Replaces tokens in a label. Only the 'global' token context is regognized
   * by default, so derived classes should override this method to add all
   * token contexts they understand.
   */
  function replace_tokens($label, $contexts, $content_id) {
    return token_replace_multiple($label, $contexts);
  }
  /**
   * Returns the token types this flag understands in labels. These are used
   * for narrowing down the token list shown in the help box to only the
   * relevant ones.
   *
   * Derived classes should override this.
   */
  function get_labels_token_types() {
    return array(
      'global',
    );
  }
  /**
   * A convenience method for getting the flag title.
   *
   * `$flag->get_title()` is shorthand for `$flag->get_label('title')`.
   */
  function get_title($content_id = NULL, $reset = FALSE) {
    static $titles = array();
    if ($reset) {
      $titles = array();
    }
    $slot = intval($content_id);
    // Convert NULL to 0.
    if (!isset($titles[$this->fid][$slot])) {
      $titles[$this->fid][$slot] = $this
        ->get_label('title', $content_id);
    }
    return $titles[$this->fid][$slot];
  }
  /**
   * Returns a 'flag action' object. It exists only for the sake of its
   * informative tokens. Currently, it's utilized only for the 'mail' action.
   *
   * Derived classes should populate the 'content_title' and 'content_url'
   * slots.
   */
  function get_flag_action($content_id) {
    $flag_action = new stdClass();
    $flag_action->flag = $this->name;
    $flag_action->content_type = $this->content_type;
    $flag_action->content_id = $content_id;
    return $flag_action;
  }
  /**
   * @addtogroup actions
   * @{
   * Methods that can be overridden to support Actions.
   */
  /**
   * Returns an array of all actions that are executable with this flag.
   */
  function get_valid_actions() {
    $actions = module_invoke_all('action_info');
    foreach ($actions as $callback => $action) {
      if ($action['type'] != $this->content_type && !isset($action['hooks'][$this->content_type])) {
        unset($actions[$callback]);
      }
    }
    return $actions;
  }
  /**
   * Returns objects the action may possibly need. This method should return at
   * least the 'primary' object the action operates on.
   *
   * This method is needed because get_valid_actions() returns actions that
   * don't necessarily operate on an object of a type this flag manages. For
   * example, flagging a comment may trigger an 'Unpublish post' action on a
   * node; So the comment flag needs to tell the action about some node.
   *
   * Derived classes must implement this.
   *
   * @abstract
   */
  function get_relevant_action_objects($content_id) {
    return array();
  }
  /**
   * @} End of "addtogroup actions".
   */
  /**
   * Methods that can be overridden to support the Rules module.
   *
   * @addtogroup rules
   * @{
   */
  /**
   * Defines the Rules arguments involved in a flag event.
   */
  function rules_get_event_arguments_definition() {
    return array();
  }
  /**
   * Defines the Rules argument for flag actions or conditions
   */
  function rules_get_element_argument_definition() {
    return array();
  }
  /**
   * @} End of "addtogroup rules".
   */
  /**
   * @addtogroup views
   * @{
   * Methods that can be overridden to support the Views module.
   */
  /**
   * Returns information needed for Views integration. E.g., the Views table
   * holding the flagged content, its primary key, and various labels. See
   * derived classes for examples.
   *
   * @static
   */
  function get_views_info() {
    return array();
  }
  /**
   * Similar to applies_to_content_id() but works on a bunch of IDs. It is
   * called in the pre_render() stage of the 'Flag links' field to find out where
   * that link applies. The reason we do a separate DB query, and not lump this
   * test in the Views query, is to make 'many to one' tests possible without
   * interfering with the rows, and also to reduce the complexity of the code.
   */
  function applies_to_content_id_array($content_ids) {
    return array();
  }
  /**
   * @} End of "addtogroup views".
   */
  /**
   * Saves a flag to the database. It is a wrapper around update() and insert().
   */
  function save() {
    if (isset($this->fid)) {
      $this
        ->update();
    }
    else {
      $this
        ->insert();
    }
  }
  /**
   * Saves an existing flag to the database. Better use save().
   */
  function update() {
    db_query("UPDATE {flags} SET name = '%s', title = '%s', roles = '%s', global = %d, options = '%s' WHERE fid = %d", $this->name, $this->title, implode(',', $this->roles), $this->global, $this
      ->get_serialized_options(), $this->fid);
    db_query("DELETE FROM {flag_types} WHERE fid = %d", $this->fid);
    foreach ($this->types as $type) {
      db_query("INSERT INTO {flag_types} (fid, type) VALUES (%d, '%s')", $this->fid, $type);
    }
  }
  /**
   * Saves a new flag to the database. Better use save().
   */
  function insert() {
    if (function_exists('db_last_insert_id')) {
      // Drupal 6. We have a 'serial' primary key.
      db_query("INSERT INTO {flags} (content_type, name, title, roles, global, options) VALUES ('%s', '%s', '%s', '%s', %d, '%s')", $this->content_type, $this->name, $this->title, implode(',', $this->roles), $this->global, $this
        ->get_serialized_options());
      $this->fid = db_last_insert_id('flags', 'fid');
    }
    else {
      // Drupal 5. We have an 'integer' primary key.
      $this->fid = db_next_id('{flags}_fid');
      db_query("INSERT INTO {flags} (fid, content_type, name, title, roles, global, options) VALUES (%d, '%s', '%s', '%s', '%s', %d, '%s')", $this->fid, $this->content_type, $this->name, $this->title, implode(',', $this->roles), $this->global, $this
        ->get_serialized_options());
    }
    foreach ($this->types as $type) {
      db_query("INSERT INTO {flag_types} (fid, type) VALUES (%d, '%s')", $this->fid, $type);
    }
  }
  /**
   * Options are stored serialized in the database.
   */
  function get_serialized_options() {
    $option_names = array_keys($this
      ->default_options());
    $options = array();
    foreach ($option_names as $option) {
      $options[$option] = $this->{$option};
    }
    return serialize($options);
  }
  /**
   * Deletes a flag from the database.
   */
  function delete() {
    db_query('DELETE FROM {flags} WHERE fid = %d', $this->fid);
    db_query('DELETE FROM {flag_content} WHERE fid = %d', $this->fid);
    db_query('DELETE FROM {flag_types} WHERE fid = %d', $this->fid);
    db_query('DELETE FROM {flag_counts} WHERE fid = %d', $this->fid);
  }
  /**
   * Disable a flag provided by a module.
   */
  function disable() {
    if (isset($this->module)) {
      $flag_status = variable_get('flag_default_flag_status', array());
      $flag_status[$this->name] = FALSE;
      variable_set('flag_default_flag_status', $flag_status);
    }
  }
  /**
   * Enable a flag provided by a module.
   */
  function enable() {
    if (isset($this->module)) {
      $flag_status = variable_get('flag_default_flag_status', array());
      $flag_status[$this->name] = TRUE;
      variable_set('flag_default_flag_status', $flag_status);
    }
  }
  /**
   * Renders a flag/unflag link. This is a wrapper around theme('flag') that,
   * in Drupal 6, easily channels the call to the right template file.
   *
   * For parameters docmentation, see theme_flag().
   */
  function theme($action, $content_id, $after_flagging = FALSE) {
    if (!_flag_is_drupal_5()) {
      // We're running Drupal 6.
      return theme($this
        ->theme_suggestions(), $this, $action, $content_id, $after_flagging);
    }
    else {
      // We're running Drupal 5. Noting to do: The theme_suggestions[] are
      // handed to phptemplate in phptemplate_flag(), if the user bothered to
      // copy that function into her 'template.php'.
      return theme('flag', $this, $action, $content_id, $after_flagging);
    }
  }
  /**
   * Provides an array of possible themes to try for a given flag.
   */
  function theme_suggestions() {
    $suggestions = array();
    $suggestions[] = 'flag__' . $this->name;
    $suggestions[] = 'flag';
    return $suggestions;
  }
}Members
| Name   | Modifiers | Type | Description | Overrides | 
|---|---|---|---|---|
| flag_flag:: | property | |||
| flag_flag:: | property | |||
| flag_flag:: | property | |||
| flag_flag:: | property | |||
| flag_flag:: | property | |||
| flag_flag:: | property | |||
| flag_flag:: | property | |||
| flag_flag:: | function | Returns TRUE if the flag applies to the content with the given ID. | ||
| flag_flag:: | function | Similar to applies_to_content_id() but works on a bunch of IDs. It is called in the pre_render() stage of the 'Flag links' field to find out where that link applies. The reason we do a separate DB query, and not lump this test in the Views… | ||
| flag_flag:: | function | Returns TRUE if the flag applies to the given content. Derived classes must implement this. | ||
| flag_flag:: | function | Default constructor. Loads the default options. | ||
| flag_flag:: | function | Declares the options this flag supports, and their default values. | ||
| flag_flag:: | function | Deletes a flag from the database. | ||
| flag_flag:: | function | Disable a flag provided by a module. | ||
| flag_flag:: | function | Enable a flag provided by a module. | ||
| flag_flag:: | function | Create a complete flag (except an FID) from an array definition. | ||
| flag_flag:: | function | Another factory method. Returns a new, "empty" flag; e.g., one suitable for the "Add new flag" page. | ||
| flag_flag:: | function | Creates a flag from a database row. Returns it. | ||
| flag_flag:: | function | Fetches, possibly from some cache, a content object this flag works with. | ||
| flag_flag:: | function | Flags, on unflags, an item. | ||
| flag_flag:: | function | Update the flag with settings entered in a form. | ||
| flag_flag:: | function | Given a content object, returns its ID. Derived classes must implement this. | ||
| flag_flag:: | function | Returns the number of times an item is flagged. | ||
| flag_flag:: | function | Returns a 'flag action' object. It exists only for the sake of its informative tokens. Currently, it's utilized only for the 'mail' action. | ||
| flag_flag:: | function | Processes a flag label for display. This means language translation and token replacements. | ||
| flag_flag:: | function | Returns the token types this flag understands in labels. These are used for narrowing down the token list shown in the help box to only the relevant ones. | ||
| flag_flag:: | function | Returns objects the action may possibly need. This method should return at least the 'primary' object the action operates on. | ||
| flag_flag:: | function | Options are stored serialized in the database. | ||
| flag_flag:: | function | A convenience method for getting the flag title. | ||
| flag_flag:: | function | Returns the number of items a user has flagged. | ||
| flag_flag:: | function | Returns an array of all actions that are executable with this flag. | ||
| flag_flag:: | function | Returns information needed for Views integration. E.g., the Views table holding the flagged content, its primary key, and various labels. See derived classes for examples. | ||
| flag_flag:: | function | Saves a new flag to the database. Better use save(). | ||
| flag_flag:: | function | Returns TRUE if a certain user has flagged this content. | ||
| flag_flag:: | function | Provides a form for setting options. | ||
| flag_flag:: | function | Stores some object in fetch_content()'s cache, so subsequenet calls to fetch_content() return it. | ||
| flag_flag:: | function | Replaces tokens in a label. Only the 'global' token context is regognized by default, so derived classes should override this method to add all token contexts they understand. | ||
| flag_flag:: | function | Defines the Rules argument for flag actions or conditions | ||
| flag_flag:: | function | Defines the Rules arguments involved in a flag event. | ||
| flag_flag:: | function | Saves a flag to the database. It is a wrapper around update() and insert(). | ||
| flag_flag:: | function | Renders a flag/unflag link. This is a wrapper around theme('flag') that, in Drupal 6, easily channels the call to the right template file. | ||
| flag_flag:: | function | Provides an array of possible themes to try for a given flag. | ||
| flag_flag:: | function | Saves an existing flag to the database. Better use save(). | ||
| flag_flag:: | function | Returns TRUE if user has access to use this flag. | ||
| flag_flag:: | function | Returns TRUE if the flag is configured to show the flag-link using hook_link. Derived classes are likely to implement this. | ||
| flag_flag:: | function | Validates a flag settings | ||
| flag_flag:: | function | |||
| flag_flag:: | function | A low-level method to flag content. | ||
| flag_flag:: | function | Returns TRUE if a certain user has flagged this content. | ||
| flag_flag:: | function | Loads a content object this flag works with. Derived classes must implement this. | ||
| flag_flag:: | function | A low-level method to unflag content. | ||
| flag_flag:: | function | Updates the flag count for this content | 
