View source
<?php
function flag_flag_definitions() {
$definitions = array(
'node' => array(
'title' => t('Nodes'),
'description' => t("Nodes are a Drupal site's primary content."),
'handler' => 'flag_node',
),
'user' => array(
'title' => t('Users'),
'description' => t('Users who have created accounts on your site.'),
'handler' => 'flag_user',
),
);
if (module_exists('comment')) {
$definitions['comment'] = array(
'title' => t('Comments'),
'description' => t('Comments are responses to node content.'),
'handler' => 'flag_comment',
);
}
return $definitions;
}
function flag_fetch_definition($content_type = NULL) {
static $defintions;
if (!isset($defintions)) {
$defintions = module_invoke_all('flag_definitions');
drupal_alter('flag_definitions', $defintions);
if (!isset($defintions['node'])) {
$defintions += flag_flag_definitions();
}
}
if (isset($content_type)) {
if (isset($defintions[$content_type])) {
return $defintions[$content_type];
}
}
else {
return $defintions;
}
}
function flag_get_types() {
static $types;
if (!isset($types)) {
$types = array_keys(flag_fetch_definition());
}
return $types;
}
function flag_create_handler($content_type) {
$definition = flag_fetch_definition($content_type);
if (isset($definition) && class_exists($definition['handler'])) {
$handler = new $definition['handler']();
}
else {
$handler = new flag_broken();
}
$handler->content_type = $content_type;
$handler
->construct();
return $handler;
}
class flag_flag {
var $fid = NULL;
var $content_type = NULL;
var $name = '';
var $title = '';
var $global = FALSE;
var $types = array();
static function factory_by_row($row) {
$flag = flag_create_handler($row->content_type);
foreach ($row as $field => $value) {
$flag->{$field} = $value;
}
unset($flag->options, $flag->type);
$options = (array) unserialize($row->options);
$options += $flag
->options();
foreach ($options as $option => $value) {
$flag->{$option} = $value;
}
if (!empty($row->type)) {
$flag->types[] = $row->type;
}
return $flag;
}
static function factory_by_array($config) {
$flag = flag_create_handler($config['content_type']);
foreach ($config as $option => $value) {
$flag->{$option} = $value;
}
if (isset($config['locked']) && is_array($config['locked'])) {
$flag->locked = drupal_map_assoc($config['locked']);
}
return $flag;
}
static function factory_by_content_type($content_type) {
return flag_create_handler($content_type);
}
function options() {
$options = array(
'flag_short' => '',
'flag_long' => '',
'flag_message' => '',
'unflag_short' => '',
'unflag_long' => '',
'unflag_message' => '',
'unflag_denied_text' => '',
'link_type' => 'toggle',
'roles' => array(
'flag' => array(
DRUPAL_AUTHENTICATED_RID,
),
'unflag' => array(
DRUPAL_AUTHENTICATED_RID,
),
),
'weight' => 0,
);
$link_type = $this
->get_link_type();
$options = array_merge($options, $link_type['options']);
drupal_alter('flag_options', $options, $this);
return $options;
}
function options_form(&$form) {
}
function construct() {
$options = $this
->options();
foreach ($options as $option => $value) {
$this->{$option} = $value;
}
}
function form_input($form_values) {
foreach ($form_values as $field => $value) {
$this->{$field} = $value;
}
$this->roles['flag'] = array_values(array_filter($this->roles['flag']));
$this->roles['unflag'] = array_values(array_filter($this->roles['unflag']));
$this->types = array_values(array_filter($this->types));
$this
->get_title(NULL, TRUE);
}
function validate() {
return array_merge_recursive($this
->validate_name(), $this
->validate_access());
}
function validate_name() {
$errors = array();
if (!preg_match('/^[a-z_][a-z0-9_]*$/', $this->name)) {
$errors['name'][] = array(
'error' => 'flag_name_characters',
'message' => t('The flag name may only contain lowercase letters, underscores, and numbers.'),
);
}
$flag = flag_get_flag($this->name);
if (!empty($flag) && (!isset($this->fid) || $flag->fid != $this->fid)) {
$errors['name'][] = array(
'error' => 'flag_name_unique',
'message' => t('Flag names must be unique. This flag name is already in use.'),
);
}
return $errors;
}
function validate_access() {
$errors = array();
if (empty($this->unflag_denied_text)) {
foreach ($this->roles['flag'] as $key => $rid) {
if ($rid && empty($this->roles['unflag'][$key])) {
$errors['unflag_denied_text'][] = array(
'error' => 'flag_denied_text_required',
'message' => t('The "Unflag not allowed text" is required if any user roles are not allowed to unflag.'),
);
break;
}
}
}
foreach ($this->roles['unflag'] as $key => $rid) {
if ($rid && empty($this->roles['flag'][$key])) {
$errors['roles'][] = array(
'error' => 'flag_roles_unflag',
'message' => t('Any user role that has the ability to unflag must also have the ability to flag.'),
);
break;
}
}
return $errors;
}
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];
}
function _load_content($content_id) {
return NULL;
}
function remember_content($content_id, $object) {
$this
->fetch_content($content_id, $object);
}
function applies_to_content_object($content) {
return FALSE;
}
function applies_to_content_id($content_id) {
return $this
->applies_to_content_object($this
->fetch_content($content_id));
}
function user_access($action = 'flag', $account = NULL) {
if (!isset($account)) {
$account = $GLOBALS['user'];
}
if ($account->uid == 0 && !module_exists('session_api')) {
return FALSE;
}
$matched_roles = array_intersect($this->roles[$action], array_keys($account->roles));
return !empty($matched_roles) || $account->uid == 1;
}
function access($content_id, $action = NULL, $account = NULL) {
if (!isset($account)) {
$account = $GLOBALS['user'];
}
if (isset($content_id) && !$this
->applies_to_content_id($content_id)) {
return FALSE;
}
if (!isset($action)) {
$uid = $account->uid;
$sid = flag_get_sid($uid);
$action = $this
->is_flagged($content_id, $uid, $sid) ? 'unflag' : 'flag';
}
$access = $this
->user_access($action, $account);
$child_access = $this
->type_access($content_id, $action, $account);
if (isset($child_access)) {
$access = $child_access;
}
$access_array = module_invoke_all('flag_access', $this, $content_id, $action, $account);
foreach ($access_array as $set_access) {
if (isset($set_access)) {
$access = $set_access;
}
}
return $access;
}
function access_multiple($content_ids, $account = NULL) {
$account = isset($account) ? $account : $GLOBALS['user'];
$access = array();
foreach ($content_ids as $content_id => $action) {
$access[$content_id] = $this
->user_access($content_ids[$content_id], $account);
}
$child_access = $this
->type_access_multiple($content_ids, $account);
if (isset($child_access)) {
foreach ($child_access as $content_id => $content_access) {
if (isset($content_access)) {
$access[$content_id] = $content_access;
}
}
}
foreach (module_implements('flag_access_multiple') as $module) {
$module_access = module_invoke($module, 'flag_access_multiple', $this, $content_ids, $account);
foreach ($module_access as $content_id => $content_access) {
if (isset($content_access)) {
$access[$content_id] = $content_access;
}
}
}
return $access;
}
function type_access($content_id, $action, $account) {
return NULL;
}
function type_access_multiple($content_ids, $account) {
return array();
}
function get_content_id($content) {
return NULL;
}
function uses_hook_link($teaser) {
return FALSE;
}
function uses_anonymous_cookies() {
global $user;
return $user->uid == 0 && variable_get('cache', 0);
}
function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE) {
if (!isset($account)) {
$account = $GLOBALS['user'];
}
if (!$account) {
return FALSE;
}
if (!$skip_permission_check) {
if (!$this
->access($content_id, $action, $account)) {
return FALSE;
}
}
else {
if (!$this
->applies_to_content_id($content_id)) {
return FALSE;
}
}
flag_get_counts(NULL, NULL, TRUE);
flag_get_user_flags(NULL, NULL, NULL, NULL, TRUE);
$uid = $this->global ? 0 : $account->uid;
if ($this->global) {
$sid = 0;
}
else {
$sid = flag_get_sid($uid, TRUE);
if ($sid == 0 && $account->uid == 0) {
return FALSE;
}
}
$flagged = $this
->_is_flagged($content_id, $uid, $sid);
if ($action == 'unflag') {
if ($this
->uses_anonymous_cookies()) {
$this
->_unflag_anonymous($content_id);
}
if ($flagged) {
$fcid = $this
->_unflag($content_id, $uid, $sid);
module_invoke_all('flag', 'unflag', $this, $content_id, $account, $fcid);
}
}
elseif ($action == 'flag') {
if ($this
->uses_anonymous_cookies()) {
$this
->_flag_anonymous($content_id);
}
if (!$flagged) {
$fcid = $this
->_flag($content_id, $uid, $sid);
module_invoke_all('flag', 'flag', $this, $content_id, $account, $fcid);
}
}
return TRUE;
}
function is_flagged($content_id, $uid = NULL, $sid = NULL) {
return (bool) $this
->get_flagging_record($content_id, $uid, $sid);
}
function get_flagging_record($content_id, $uid = NULL, $sid = NULL) {
$uid = $this->global ? 0 : (!isset($uid) ? $GLOBALS['user']->uid : $uid);
$sid = $this->global ? 0 : (!isset($sid) ? flag_get_sid($uid) : $sid);
$user_flags = flag_get_user_flags($this->content_type, $content_id, $uid, $sid);
return isset($user_flags[$this->name]) ? $user_flags[$this->name] : NULL;
}
function _is_flagged($content_id, $uid, $sid) {
return db_result(db_query("SELECT fcid FROM {flag_content} WHERE fid = %d AND uid = %d AND sid = %d AND content_id = %d", $this->fid, $uid, $sid, $content_id));
}
function _flag($content_id, $uid, $sid) {
db_query("INSERT INTO {flag_content} (fid, content_type, content_id, uid, sid, timestamp) VALUES (%d, '%s', %d, %d, %d, %d)", $this->fid, $this->content_type, $content_id, $uid, $sid, time());
$fcid = db_last_insert_id('flag_content', 'fcid');
$this
->_increase_count($content_id);
return $fcid;
}
function _unflag($content_id, $uid, $sid) {
$fcid = db_result(db_query("SELECT fcid FROM {flag_content} WHERE fid = %d AND content_id = %d AND uid = %d AND sid = %d", $this->fid, $content_id, $uid, $sid));
if ($fcid) {
db_query("DELETE FROM {flag_content} WHERE fcid = %d", $fcid);
$this
->_decrease_count($content_id);
}
return $fcid;
}
function _increase_count($content_id, $number = 1) {
$time = time();
db_query("UPDATE {flag_counts} SET count = count + %d, last_updated = %d WHERE fid = %d AND content_id = %d", $number, $time, $this->fid, $content_id);
if (!db_affected_rows()) {
db_query("INSERT INTO {flag_counts} (fid, content_type, content_id, count, last_updated) VALUES (%d, '%s', %d, %d, %d)", $this->fid, $this->content_type, $content_id, $number, $time);
}
}
function _decrease_count($content_id, $number = 1) {
$time = time();
db_query("UPDATE {flag_counts} SET count = count - %d, last_updated = %d WHERE fid = %d AND content_id = %d", $number, $time, $this->fid, $content_id);
db_query("DELETE FROM {flag_counts} WHERE fid = %d and content_id = %d AND count = %d", $this->fid, $content_id, 0);
}
function _flag_anonymous($content_id) {
$storage = FlagCookieStorage::factory($this);
$storage
->flag($content_id);
}
function _unflag_anonymous($content_id) {
$storage = FlagCookieStorage::factory($this);
$storage
->unflag($content_id);
}
function get_count($content_id) {
$counts = flag_get_counts($this->content_type, $content_id);
return isset($counts[$this->name]) ? $counts[$this->name] : 0;
}
function get_user_count($uid, $sid = NULL) {
if (!isset($sid)) {
$sid = flag_get_sid($uid);
}
return db_result(db_query('SELECT COUNT(*) FROM {flag_content} WHERE fid = %d AND uid = %d AND sid = %d', $this->fid, $uid, $sid));
}
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);
}
function get_link_type() {
$link_types = flag_get_link_types();
return isset($this->link_type) && isset($link_types[$this->link_type]) ? $link_types[$this->link_type] : $link_types['normal'];
}
function replace_tokens($label, $contexts, $content_id) {
return token_replace_multiple($label, $contexts);
}
function get_labels_token_types() {
return array();
}
function get_title($content_id = NULL, $reset = FALSE) {
static $titles = array();
if ($reset) {
$titles = array();
}
$slot = intval($content_id);
if (!isset($titles[$this->fid][$slot])) {
$titles[$this->fid][$slot] = $this
->get_label('title', $content_id);
}
return $titles[$this->fid][$slot];
}
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;
}
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;
}
function get_relevant_action_objects($content_id) {
return array();
}
function rules_get_event_arguments_definition() {
return array();
}
function rules_get_element_argument_definition() {
return array();
}
function get_views_info() {
return array();
}
function save() {
if (isset($this->fid)) {
$this
->update();
$this->is_new = FALSE;
}
else {
$this
->insert();
$this->is_new = TRUE;
}
cache_clear_all('*', 'cache_page', TRUE);
}
function update() {
db_query("UPDATE {flags} SET name = '%s', title = '%s', global = %d, options = '%s' WHERE fid = %d", $this->name, $this->title, $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);
}
}
function insert() {
db_query("INSERT INTO {flags} (content_type, name, title, global, options) VALUES ('%s', '%s', '%s', %d, '%s')", $this->content_type, $this->name, $this->title, $this->global, $this
->get_serialized_options());
$this->fid = db_last_insert_id('flags', 'fid');
foreach ($this->types as $type) {
db_query("INSERT INTO {flag_types} (fid, type) VALUES (%d, '%s')", $this->fid, $type);
}
}
function get_serialized_options() {
$option_names = array_keys($this
->options());
$options = array();
foreach ($option_names as $option) {
$options[$option] = $this->{$option};
}
return serialize($options);
}
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);
module_invoke_all('flag_delete', $this);
}
function is_compatible() {
if (isset($this->fid)) {
return TRUE;
}
else {
if (!isset($this->api_version)) {
$this->api_version = 1;
}
return $this->api_version == FLAG_API_VERSION;
}
}
function find_default_flag() {
if ($this->fid) {
$default_flags = flag_get_default_flags(TRUE);
if (isset($default_flags[$this->name])) {
return $default_flags[$this->name];
}
}
}
function revert() {
if ($default_flag = $this
->find_default_flag()) {
if ($default_flag
->is_compatible()) {
$default_flag = clone $default_flag;
$default_flag->fid = $this->fid;
$default_flag
->save();
flag_get_flags(NULL, NULL, NULL, TRUE);
return TRUE;
}
else {
return FALSE;
}
}
}
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);
}
}
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);
}
}
function admin_path($action) {
if ($action == 'edit') {
return FLAG_ADMIN_PATH . '/manage/' . $this->name;
}
else {
return FLAG_ADMIN_PATH . '/manage/' . $this->name . '/' . $action;
}
}
function theme($action, $content_id, $after_flagging = FALSE) {
static $js_added = array();
global $user;
if ($user->uid == 0 && !isset($js_added['anonymous'])) {
$js_added['anonymous'] = TRUE;
drupal_add_js(array(
'flag' => array(
'anonymous' => TRUE,
),
), 'setting');
}
if ($this
->uses_anonymous_cookies() && !$after_flagging) {
if ($this->global) {
$js_action = $action == 'flag' ? 'unflag' : 'flag';
}
else {
$js_action = 'unflag';
$action = 'flag';
}
if (!isset($js_added[$this->name . '_' . $content_id])) {
$js_added[$this->name . '_' . $content_id] = TRUE;
$js_template = theme($this
->theme_suggestions(), $this, $js_action, $content_id, $after_flagging);
drupal_add_js(array(
'flag' => array(
'templates' => array(
$this->name . '_' . $content_id => $js_template,
),
),
), 'setting');
}
}
return theme($this
->theme_suggestions(), $this, $action, $content_id, $after_flagging);
}
function theme_suggestions() {
$suggestions = array();
$suggestions[] = 'flag__' . $this->name;
$suggestions[] = 'flag';
return $suggestions;
}
}
class flag_node extends flag_flag {
function options() {
$options = parent::options();
$options += array(
'show_on_page' => TRUE,
'show_on_teaser' => TRUE,
'show_on_form' => FALSE,
'access_author' => '',
'i18n' => 0,
);
return $options;
}
function options_form(&$form) {
parent::options_form($form);
$form['i18n'] = array(
'#type' => 'radios',
'#title' => t('Internationalization'),
'#options' => array(
'1' => t('Flag translations of content as a group'),
'0' => t('Flag each translation of content separately'),
),
'#default_value' => $this->i18n,
'#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will <strong>not</strong> update content that has been flagged already.'),
'#access' => module_exists('translation_helpers'),
'#weight' => 5,
);
$form['access']['access_author'] = array(
'#type' => 'radios',
'#title' => t('Flag access by content authorship'),
'#options' => array(
'' => t('No additional restrictions'),
'own' => t('Users may only flag content they own'),
'others' => t('Users may only flag content of others'),
),
'#default_value' => $this->access_author,
'#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."),
);
$form['display']['show_on_teaser'] = array(
'#type' => 'checkbox',
'#title' => t('Display link on node teaser'),
'#default_value' => $this->show_on_teaser,
'#access' => empty($this->locked['show_on_teaser']),
);
$form['display']['show_on_page'] = array(
'#type' => 'checkbox',
'#title' => t('Display link on node page'),
'#default_value' => $this->show_on_page,
'#access' => empty($this->locked['show_on_page']),
);
$form['display']['show_on_form'] = array(
'#type' => 'checkbox',
'#title' => t('Display checkbox on node edit form'),
'#default_value' => $this->show_on_form,
'#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form <a href="@content-types-url">for each content type</a>.', array(
'@content-types-url' => url('admin/content/types'),
)),
'#access' => empty($this->locked['show_on_form']),
);
}
function _load_content($content_id) {
return is_numeric($content_id) ? node_load($content_id) : NULL;
}
function applies_to_content_object($node) {
if ($node && in_array($node->type, $this->types)) {
return TRUE;
}
return FALSE;
}
function type_access_multiple($content_ids, $account) {
$access = array();
$nids = implode(',', array_map('intval', array_keys($content_ids)));
$placeholders = implode(',', array_fill(0, sizeof($this->types), "'%s'"));
$result = db_query("SELECT nid as content_id FROM {node} WHERE nid IN ({$nids}) AND type NOT IN ({$placeholders})", $this->types);
while ($row = db_fetch_object($result)) {
$access[$row->content_id] = FALSE;
}
return $access;
}
function get_content_id($node) {
return $node->nid;
}
function get_translation_id($content_id) {
if ($this->i18n) {
$node = $this
->fetch_content($content_id);
if (!empty($node->tnid)) {
$content_id = $node->tnid;
}
}
return $content_id;
}
function uses_hook_link($teaser) {
if ($teaser && $this->show_on_teaser || !$teaser && $this->show_on_page) {
return TRUE;
}
return FALSE;
}
function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE) {
$content_id = $this
->get_translation_id($content_id);
return parent::flag($action, $content_id, $account, $skip_permission_check);
}
function get_flagging_record($content_id, $uid = NULL, $sid = NULL) {
$content_id = $this
->get_translation_id($content_id);
return parent::get_flagging_record($content_id, $uid, $sid);
}
function get_labels_token_types() {
return array_merge(array(
'node',
), parent::get_labels_token_types());
}
function replace_tokens($label, $contexts, $content_id) {
if (is_numeric($content_id) && ($node = $this
->fetch_content($content_id))) {
$contexts['node'] = $node;
}
elseif (!empty($content_id) && ($type = node_get_types('type', $content_id))) {
$content_id = NULL;
$contexts['node'] = (object) array(
'nid' => NULL,
'type' => $type->type,
'title' => '',
);
}
return parent::replace_tokens($label, $contexts, $content_id);
}
function get_flag_action($content_id) {
$flag_action = parent::get_flag_action($content_id);
$node = $this
->fetch_content($content_id);
$flag_action->content_title = $node->title;
$flag_action->content_url = _flag_url('node/' . $node->nid);
return $flag_action;
}
function get_valid_actions() {
$actions = module_invoke_all('action_info');
foreach ($actions as $callback => $action) {
if ($action['type'] != 'node' && !isset($action['hooks']['nodeapi'])) {
unset($actions[$callback]);
}
}
return $actions;
}
function get_relevant_action_objects($content_id) {
return array(
'node' => $this
->fetch_content($content_id),
);
}
function rules_get_event_arguments_definition() {
return array(
'node' => array(
'type' => 'node',
'label' => t('flagged content'),
'handler' => 'flag_rules_get_event_argument',
),
'node_author' => array(
'type' => 'user',
'label' => t('flagged content author'),
'handler' => 'flag_rules_get_node_author',
),
);
}
function rules_get_element_argument_definition() {
return array(
'type' => 'node',
'label' => t('Flagged content'),
);
}
function get_views_info() {
return array(
'views table' => 'node',
'join field' => 'nid',
'title field' => 'title',
'title' => t('Node flag'),
'help' => t('Limit results to only those nodes flagged by a certain flag; Or display information about the flag set on a node.'),
'counter title' => t('Node flag counter'),
'counter help' => t('Include this to gain access to the flag counter field.'),
);
}
}
class flag_comment extends flag_flag {
function options() {
$options = parent::options();
$options += array(
'access_author' => '',
'show_on_comment' => TRUE,
);
return $options;
}
function options_form(&$form) {
parent::options_form($form);
$form['access']['access_author'] = array(
'#type' => 'radios',
'#title' => t('Flag access by content authorship'),
'#options' => array(
'' => t('No additional restrictions'),
'comment_own' => t('Users may only flag own comments'),
'comment_others' => t('Users may only flag comments by others'),
'node_own' => t('Users may only flag comments of nodes they own'),
'node_others' => t('Users may only flag comments of nodes by others'),
),
'#default_value' => $this->access_author,
'#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."),
);
$form['display']['show_on_comment'] = array(
'#type' => 'checkbox',
'#title' => t('Display link under comment'),
'#default_value' => $this->show_on_comment,
'#access' => empty($this->locked['show_on_comment']),
);
}
function _load_content($content_id) {
return _comment_load($content_id);
}
function applies_to_content_object($comment) {
if ($comment && ($node = node_load($comment->nid)) && in_array($node->type, $this->types)) {
return TRUE;
}
return FALSE;
}
function type_access_multiple($content_ids, $account) {
$access = array();
$cids = implode(',', array_map('intval', array_keys($content_ids)));
$placeholders = implode(',', array_fill(0, sizeof($this->types), "'%s'"));
$result = db_query("SELECT cid as content_id FROM {comments} c INNER JOIN {node} n ON c.nid = n.nid WHERE cid IN ({$cids}) and n.type NOT IN ({$placeholders})", $this->types);
while ($row = db_fetch_object($result)) {
$access[$row->content_id] = FALSE;
}
return $access;
}
function get_content_id($comment) {
$this
->remember_content($comment->cid, $comment);
return $comment->cid;
}
function uses_hook_link($teaser) {
return $this->show_on_comment;
}
function get_labels_token_types() {
return array_merge(array(
'comment',
'node',
), parent::get_labels_token_types());
}
function replace_tokens($label, $contexts, $content_id) {
if ($content_id) {
if (($comment = $this
->fetch_content($content_id)) && ($node = node_load($comment->nid))) {
$contexts['node'] = $node;
$contexts['comment'] = $comment;
}
}
return parent::replace_tokens($label, $contexts, $content_id);
}
function get_flag_action($content_id) {
$flag_action = parent::get_flag_action($content_id);
$comment = $this
->fetch_content($content_id);
$flag_action->content_title = $comment->subject;
$flag_action->content_url = _flag_url("node/{$comment->nid}/{$comment->cid}", "comment-{$comment->cid}");
return $flag_action;
}
function get_relevant_action_objects($content_id) {
$comment = $this
->fetch_content($content_id);
return array(
'comment' => $comment,
'node' => node_load($comment->nid),
);
}
function rules_get_event_arguments_definition() {
return array(
'comment' => array(
'type' => 'comment',
'label' => t('flagged comment'),
'handler' => 'flag_rules_get_event_argument',
),
'comment_author' => array(
'type' => 'user',
'label' => t('flagged comment author'),
'handler' => 'flag_rules_get_comment_author',
),
'node' => array(
'type' => 'node',
'label' => t("the flagged comment's content"),
'handler' => 'flag_rules_get_comment_content',
),
'node_author' => array(
'type' => 'user',
'label' => t('commented content author'),
'handler' => 'flag_rules_get_comment_node_author',
),
);
}
function rules_get_element_argument_definition() {
return array(
'type' => 'comment',
'label' => t('Flagged comment'),
);
}
function get_views_info() {
return array(
'views table' => 'comments',
'join field' => 'cid',
'title field' => 'subject',
'title' => t('Comment flag'),
'help' => t('Limit results to only those comments flagged by a certain flag; Or display information about the flag set on a comment.'),
'counter title' => t('Comment flag counter'),
'counter help' => t('Include this to gain access to the flag counter field.'),
);
}
}
class flag_user extends flag_flag {
function options() {
$options = parent::options();
$options += array(
'show_on_profile' => TRUE,
'access_uid' => '',
);
return $options;
}
function options_form(&$form) {
parent::options_form($form);
$form['access']['types'] = array(
'#type' => 'value',
'#value' => array(
0 => 0,
),
);
$form['access']['access_uid'] = array(
'#type' => 'checkbox',
'#title' => t('Users may flag themselves'),
'#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themself does not make sense.'),
'#default_value' => $this->access_uid ? 0 : 1,
);
$form['display']['show_on_profile'] = array(
'#type' => 'checkbox',
'#title' => t('Display link on user profile page'),
'#default_value' => $this->show_on_profile,
'#access' => empty($this->locked['show_on_profile']),
);
}
function form_input($form_values) {
parent::form_input($form_values);
$this->access_uid = empty($form_values['access_uid']) ? 'others' : '';
}
function _load_content($content_id) {
return user_load($content_id);
}
function applies_to_content_object($user) {
if ($user) {
return TRUE;
}
return FALSE;
}
function type_access($content_id, $action, $account) {
if ($this->access_uid == 'others' && $content_id == $account->uid) {
return FALSE;
}
}
function type_access_multiple($content_ids, $account) {
$access = array();
if (array_key_exists(0, $content_ids)) {
$access[0] = FALSE;
}
if ($this->access_uid == 'others' && array_key_exists($account->uid, $content_ids)) {
$access[$account->uid] = FALSE;
}
return $access;
}
function get_content_id($user) {
return $user->uid;
}
function uses_hook_link($teaser) {
if ($this->show_on_profile) {
return TRUE;
}
return FALSE;
}
function get_labels_token_types() {
return array_merge(array(
'user',
), parent::get_labels_token_types());
}
function replace_tokens($label, $contexts, $content_id) {
if ($content_id && ($user = $this
->fetch_content($content_id))) {
$contexts['user'] = $user;
}
return parent::replace_tokens($label, $contexts, $content_id);
}
function get_flag_action($content_id) {
$flag_action = parent::get_flag_action($content_id);
$user = $this
->fetch_content($content_id);
$flag_action->content_title = $user->name;
$flag_action->content_url = _flag_url('user/' . $user->uid);
return $flag_action;
}
function get_relevant_action_objects($content_id) {
return array(
'user' => $this
->fetch_content($content_id),
);
}
function rules_get_event_arguments_definition() {
return array(
'account' => array(
'type' => 'user',
'label' => t('flagged user'),
'handler' => 'flag_rules_get_event_argument',
),
);
}
function rules_get_element_argument_definition() {
return array(
'type' => 'user',
'label' => t('Flagged user'),
);
}
function get_views_info() {
return array(
'views table' => 'users',
'join field' => 'uid',
'title field' => 'name',
'title' => t('User flag'),
'help' => t('Limit results to only those users flagged by a certain flag; Or display information about the flag set on a user.'),
'counter title' => t('User flag counter'),
'counter help' => t('Include this to gain access to the flag counter field.'),
);
}
}
class flag_broken extends flag_flag {
function options_form(&$form) {
$form = array();
$form['error'] = array(
'#value' => '<div class="error">' . t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array(
'%type' => $this->content_type,
)) . '</div>',
);
}
}
function _flag_url($path, $fragment = NULL, $absolute = TRUE) {
return url($path, array(
'fragment' => $fragment,
'absolute' => $absolute,
));
}
abstract class FlagCookieStorage {
static function factory($flag) {
if ($flag->global) {
return new FlagGlobalCookieStorage($flag);
}
else {
return new FlagNonGlobalCookieStorage($flag);
}
}
function __construct($flag) {
$this->flag = $flag;
}
abstract function flag($content_id);
abstract function unflag($content_id);
static function drop() {
FlagGlobalCookieStorage::drop();
FlagNonGlobalCookieStorage::drop();
}
}
class FlagGlobalCookieStorage extends FlagCookieStorage {
function flag($content_id) {
$cookie_key = $this
->cookie_key($content_id);
setcookie($cookie_key, 1, time() + $this
->get_lifetime(), base_path());
$_COOKIE[$cookie_key] = 1;
}
function unflag($content_id) {
$cookie_key = $this
->cookie_key($content_id);
setcookie($cookie_key, 0, time() + $this
->get_lifetime(), base_path());
$_COOKIE[$cookie_key] = 0;
}
protected function get_lifetime() {
$cookie_lifetime = variable_get('cache', 0) ? variable_get('cache_lifetime', 0) : -1;
if ($cookie_lifetime == 0) {
$cookie_lifetime = 3600;
}
return $cookie_lifetime;
}
protected function cookie_key($content_id) {
return 'flag_global_' . $this->flag->name . '_' . $content_id;
}
static function drop() {
foreach ($_COOKIE as $key => $value) {
if (strpos($key, 'flag_global_') === 0) {
setcookie($key, FALSE, 0, base_path());
unset($_COOKIE[$key]);
}
}
}
}
class FlagNonGlobalCookieStorage extends FlagCookieStorage {
function __construct($flag) {
parent::__construct($flag);
$this->flaggings = isset($_COOKIE['flags']) ? explode(' ', $_COOKIE['flags']) : array();
}
function flag($content_id) {
if (!$this
->is_flagged($content_id)) {
$this->flaggings[] = $this
->cookie_key($content_id);
$this
->write();
}
}
function unflag($content_id) {
if (($index = $this
->index_of($content_id)) !== FALSE) {
unset($this->flaggings[$index]);
$this
->write();
}
}
protected function get_lifetime() {
return min((int) ini_get('session.cookie_lifetime'), (int) ini_get('session.gc_maxlifetime'));
}
protected function cookie_key($content_id) {
return $this->flag->name . '_' . $content_id;
}
protected function write() {
$serialized = implode(' ', array_filter($this->flaggings));
setcookie('flags', $serialized, time() + $this
->get_lifetime(), base_path());
$_COOKIE['flags'] = $serialized;
}
protected function is_flagged($content_id) {
return $this
->index_of($content_id) !== FALSE;
}
protected function index_of($content_id) {
return array_search($this
->cookie_key($content_id), $this->flaggings);
}
static function drop() {
if (isset($_COOKIE['flags'])) {
setcookie('flags', FALSE, 0, base_path());
unset($_COOKIE['flags']);
}
}
}