- <?php
-
- * @file
- * The Flag module.
- */
-
- define('FLAG_API_VERSION', 3);
-
- define('FLAG_ADMIN_PATH', 'admin/structure/flags');
- define('FLAG_ADMIN_PATH_START', 3);
-
- * Implements hook_entity_info().
- */
- function flag_entity_info() {
- $return = array(
- 'flagging' => array(
- 'label' => t('Flagging'),
- 'controller class' => 'FlaggingController',
- 'base table' => 'flagging',
- 'fieldable' => TRUE,
- 'entity keys' => array(
- 'id' => 'flagging_id',
- 'bundle' => 'flag_name',
- ),
-
-
- 'bundle keys' => array(
- 'bundle' => 'name',
- ),
- 'bundles' => array(),
- ),
- );
-
-
-
- $result = db_query("SELECT name, title FROM {flag}");
- $flag_names = $result->fetchAllKeyed();
- foreach ($flag_names as $flag_name => $flag_title) {
- $return['flagging']['bundles'][$flag_name] = array(
- 'label' => $flag_title,
- 'admin' => array(
- 'path' => FLAG_ADMIN_PATH . '/manage/%flag',
- 'real path' => FLAG_ADMIN_PATH . '/manage/' . $flag_name,
- 'bundle argument' => FLAG_ADMIN_PATH_START + 1,
- 'access arguments' => array('administer flags'),
- ),
- );
- }
-
- return $return;
- }
-
- * Loads a flagging entity.
- *
- * @param $flagging_id
- * The 'flagging_id' database serial column.
- * @param $reset
- * Whether to reset the DrupalDefaultEntityController cache.
- *
- * @return
- * The entity object, or FALSE if it can't be found.
- */
- function flagging_load($flagging_id, $reset = FALSE) {
-
- $result = entity_load('flagging', array($flagging_id), array(), $reset);
- return reset($result);
- }
-
-
-
-
-
-
-
-
-
- * Implements hook_entity_query_alter().
- *
- * Converts EntityFieldQuery instances on flaggings that have an entity
- * condition on bundles (flag machine names).
- *
- * Based on taxonomy_entity_query_alter().
- */
- function flag_entity_query_alter($query) {
- $conditions = &$query->entityConditions;
-
-
- if (isset($conditions['entity_type']) && $conditions['entity_type']['value'] == 'flagging' && isset($conditions['bundle'])) {
-
- $flags = flag_get_flags();
- $fids = array();
- if (is_array($conditions['bundle']['value'])) {
- foreach ($conditions['bundle']['value'] as $flag_name) {
- $fids[] = $flags[$flag_name]->fid;
- }
- }
- else {
- $flag_name = $conditions['bundle']['value'];
- $fids = $flags[$flag_name]->fid;
- }
-
- $query->propertyCondition('fid', $fids, $conditions['bundle']['operator']);
- unset($conditions['bundle']);
- }
- }
-
- * Implements hook_menu().
- */
- function flag_menu() {
- $items[FLAG_ADMIN_PATH] = array(
- 'title' => 'Flags',
- 'page callback' => 'flag_admin_page',
- 'access callback' => 'user_access',
- 'access arguments' => array('administer flags'),
- 'description' => 'Configure flags for marking content with arbitrary information (such as <em>offensive</em> or <em>bookmarked</em>).',
- 'file' => 'includes/flag.admin.inc',
- 'type' => MENU_NORMAL_ITEM,
- );
- $items[FLAG_ADMIN_PATH . '/list'] = array(
- 'title' => 'List',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
- $items[FLAG_ADMIN_PATH . '/add'] = array(
- 'title' => 'Add flag',
- 'page callback' => 'flag_add_page',
- 'access callback' => 'user_access',
- 'access arguments' => array('administer flags'),
- 'file' => 'includes/flag.admin.inc',
- 'type' => MENU_LOCAL_ACTION,
- 'weight' => 1,
- );
- $items[FLAG_ADMIN_PATH . '/import'] = array(
- 'title' => 'Import',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('flag_import_form'),
- 'access arguments' => array('use flag import'),
- 'file' => 'includes/flag.export.inc',
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 2,
- );
- $items[FLAG_ADMIN_PATH . '/export'] = array(
- 'title' => 'Export',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('flag_export_form'),
- 'access arguments' => array('administer flags'),
- 'file' => 'includes/flag.export.inc',
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 3,
- );
-
- $items[FLAG_ADMIN_PATH . '/manage/%flag'] = array(
- 'load arguments' => array(TRUE),
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('flag_form', FLAG_ADMIN_PATH_START + 1),
- 'access callback' => 'user_access',
- 'access arguments' => array('administer flags'),
- 'file' => 'includes/flag.admin.inc',
- 'type' => MENU_CALLBACK,
-
- 'title callback' => '_flag_menu_title',
- 'title arguments' => array(FLAG_ADMIN_PATH_START + 1),
- );
- $items[FLAG_ADMIN_PATH . '/manage/%flag/edit'] = array(
- 'load arguments' => array(TRUE),
- 'title' => 'Edit flag',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
- $items[FLAG_ADMIN_PATH . '/manage/%flag/export'] = array(
- 'title' => 'Export',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('flag_export_form', FLAG_ADMIN_PATH_START + 1),
- 'access arguments' => array('administer flags'),
- 'file' => 'includes/flag.export.inc',
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 20,
- );
- $items[FLAG_ADMIN_PATH . '/manage/%flag/delete'] = array(
- 'title' => 'Delete flag',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('flag_delete_confirm', FLAG_ADMIN_PATH_START + 1),
- 'access callback' => 'user_access',
- 'access arguments' => array('administer flags'),
- 'file' => 'includes/flag.admin.inc',
- 'type' => MENU_CALLBACK,
- );
- $items[FLAG_ADMIN_PATH . '/manage/%flag/update'] = array(
- 'load arguments' => array(TRUE),
- 'title' => 'Update',
- 'page callback' => 'flag_update_page',
- 'page arguments' => array(FLAG_ADMIN_PATH_START + 1),
- 'access arguments' => array('administer flags'),
- 'file' => 'includes/flag.export.inc',
- 'type' => MENU_CALLBACK,
- );
-
- $items['flag/%/%flag/%'] = array(
- 'title' => 'Flag',
- 'page callback' => 'flag_page',
- 'page arguments' => array(1, 2, 3),
- 'access callback' => 'user_access',
- 'access arguments' => array('access content'),
- 'file' => 'includes/flag.pages.inc',
- 'type' => MENU_CALLBACK,
- );
- $items['flag/confirm/%/%flag/%'] = array(
- 'title' => 'Flag confirm',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('flag_confirm', 2, 3, 4),
- 'access callback' => 'user_access',
- 'access arguments' => array('access content'),
- 'file' => 'includes/flag.pages.inc',
- 'type' => MENU_CALLBACK,
- );
-
- return $items;
- }
-
- * Implements hook_admin_menu_map().
- */
- function flag_admin_menu_map() {
- if (!user_access('administer flags')) {
- return;
- }
-
- $map = array();
- $map[FLAG_ADMIN_PATH . '/manage/%flag'] = array(
- 'parent' => FLAG_ADMIN_PATH,
- 'arguments' => array(
- array(
- '%flag' => array_keys(flag_get_flags()),
- ),
- ),
- );
-
- if (module_exists('field_ui')) {
- foreach (entity_get_info() as $obj_type => $info) {
- if ($obj_type == 'flagging') {
- foreach ($info['bundles'] as $bundle_name => $bundle_info) {
- if (isset($bundle_info['admin'])) {
- $fields = array();
-
- foreach (field_info_instances($obj_type, $bundle_name) as $field) {
- $fields[] = $field['field_name'];
- }
-
- $arguments = array(
- '%flag' => array($bundle_name),
- '%field_ui_menu' => $fields,
- );
-
- $path = $bundle_info['admin']['path'];
- $map["$path/fields/%field_ui_menu"]['parent'] = "$path/fields";
- $map["$path/fields/%field_ui_menu"]['arguments'][] = $arguments;
- }
- }
- }
- }
- }
-
- return $map;
- }
-
- * Menu loader for '%flag' arguments.
- *
- * @param $include_disabled
- * Whether to return a disabled flag too. Normally only enabled flags are
- * returned. Some menu items operate on disabled flags and in this case
- * you need to turn on this switch by doing
- * <code>'load arguments' => array(TRUE)</code> in your menu router.
- *
- * @return
- * Either the flag object, or FALSE if none was found.
- */
- function flag_load($flag_name, $include_disabled = FALSE) {
- if (($flag = flag_get_flag($flag_name))) {
- return $flag;
- }
- else {
-
- if ($include_disabled) {
- $default_flags = flag_get_default_flags(TRUE);
- if (isset($default_flags[$flag_name])) {
- return $default_flags[$flag_name];
- }
- }
- }
-
- return FALSE;
- }
-
- * Menu title callback.
- */
- function _flag_menu_title($flag) {
-
- return $flag ? $flag->get_title() : '';
- }
-
- * Implements hook_help().
- */
- function flag_help($path, $arg) {
- switch ($path) {
- case FLAG_ADMIN_PATH:
- $output = '<p>' . t('This page lists all the <em>flags</em> that are currently defined on this system.') . '</p>';
- return $output;
- case FLAG_ADMIN_PATH . '/add':
- $output = '<p>' . t('Select the type of flag to create. An individual flag can only affect one type of object. This cannot be changed once the flag is created.') . '</p>';
- return $output;
- case FLAG_ADMIN_PATH . '/manage/%/fields':
-
- $link_types = flag_get_link_types();
- $form_link_types = array();
- foreach (flag_get_link_types() as $link_type) {
- if ($link_type['provides form']) {
- $form_link_types[] = '<em>' . $link_type['title'] . '</em>';
- }
- }
-
-
- $flag = menu_get_object('flag', FLAG_ADMIN_PATH_START + 1);
-
-
- $output = '<p>' . t('Flags can have fields added to them. For example, a "Spam" flag could have a <em>Reason</em> field where a user could type in why he believes the item flagged is spam. A "Bookmarks" flag could have a <em>Folder</em> field into which a user could arrange her bookmarks.') . '</p>';
- $output .= '<p>' . t('On this page you can add fields to flags, delete them, and otherwise manage them.') . '</p>';
-
-
- if ($flag->link_type == 'form') {
-
-
- }
- elseif ($link_types[$flag->link_type]['provides form']) {
-
-
-
- $output .= t("Field values may be edited when flaggings are created because this flag's link type shows a form for the flagging. However, to edit field values on existing flaggings, you will need to set your flag to use the <em>Flagging form</em> link type. This is provided by the <em><a href='!flagging-form-url'>Flagging Form</a></em> module.", array(
- '!flagging-form-url' => 'http://drupal.org/project/flagging_form',
- ));
- if (!module_exists('flagging_form')) {
- $output .= ' <span class="warning">'
- . t("You do not currently have this module enabled.")
- . '</span>';
- }
- $output .= '</p>';
- }
- else {
-
-
- $output .= '<p class="warning">' . t("To allow users to enter values for fields you will need to <a href='!form-link-type-url'>set your flag</a> to use one of the following link types which allow users to access the flagging form: !link-types-list. (In case a form isn't used, the fields are assigned their default values.)", array(
- '!form-link-type-url' => url('admin/structure/flags/manage/' . $flag->name, array('fragment' => 'edit-link-type')),
-
-
- '!link-types-list' => implode(', ', $form_link_types),
- )) . '</p>';
- $output .= '<p>' . t("Additionally, to edit field values on existing flaggings, you will need to set your flag to use the Flagging form link type. This is provided by the <em><a href='!flagging-form-url'>Flagging Form</a></em> module.", array(
- '!flagging-form-url' => 'http://drupal.org/project/flagging_form',
- ));
- if (!module_exists('flagging_form')) {
- $output .= ' <span class="warning">'
- . t("You do not currently have this module enabled.")
- . '</span>';
- }
- $output .= '</p>';
- }
-
- return $output;
- }
- }
-
- * Implements hook_init().
- */
- function flag_init() {
- $path = drupal_get_path('module', 'flag');
- include_once $path . '/includes/flag.actions.inc';
- }
-
- * Implements hook_hook_info().
- */
- function flag_hook_info() {
- $hooks['flag_type_info'] = array(
- 'group' => 'flag',
- );
- $hooks['flag_type_info_alter'] = array(
- 'group' => 'flag',
- );
- $hooks['flag_link_type_info'] = array(
- 'group' => 'flag',
- );
- $hooks['flag_link_type_info_alter'] = array(
- 'group' => 'flag',
- );
- return $hooks;
- }
-
- * Returns a flag definition.
- */
- function flag_fetch_definition($entity_type = NULL) {
- $definitions = &drupal_static(__FUNCTION__);
- if (!isset($definitions)) {
- if ($cache = cache_get('flag_type_info')) {
- $definitions = $cache->data;
- }
- else {
- $definitions = module_invoke_all('flag_type_info');
- drupal_alter('flag_type_info', $definitions);
-
- cache_set('flag_type_info', $definitions);
- }
- }
-
- if (isset($entity_type)) {
- if (isset($definitions[$entity_type])) {
- return $definitions[$entity_type];
- }
- }
- else {
- return $definitions;
- }
- }
-
- * Returns all flag types defined on the system.
- */
- function flag_get_types() {
- $types = &drupal_static(__FUNCTION__);
- if (!isset($types)) {
- $types = array_keys(flag_fetch_definition());
- }
- return $types;
- }
-
- * Instantiates a new flag handler.
- *
- * A flag handler is more commonly know as "a flag". A factory method usually
- * populates this empty flag with settings loaded from the database.
- *
- * @param $entity_type
- * The entity type to create a flag handler for. This may be FALSE if the
- * entity type property could not be found in the flag configuration data.
- *
- * @return
- * A flag handler object. This may be the special class flag_broken is there is
- * a problem with the flag.
- */
- function flag_create_handler($entity_type) {
- $definition = flag_fetch_definition($entity_type);
- if (isset($definition) && class_exists($definition['handler'])) {
- $handler = new $definition['handler'];
- }
- else {
- $handler = new flag_broken;
- }
- $handler->entity_type = $entity_type;
- $handler->construct();
- return $handler;
- }
-
- * A shortcut function to output the link URL.
- */
- function _flag_url($path, $fragment = NULL, $absolute = TRUE) {
- return url($path, array('fragment' => $fragment, 'absolute' => $absolute));
- }
-
- * Implements hook_views_api().
- */
- function flag_views_api() {
- return array(
- 'api' => 3.0,
- 'path' => drupal_get_path('module', 'flag') . '/includes/views',
- );
- }
-
- * Implements hook_features_api().
- */
- function flag_features_api() {
- return array(
- 'flag' => array(
- 'name' => t('Flag'),
- 'feature_source' => TRUE,
- 'default_hook' => 'flag_default_flags',
- 'file' => drupal_get_path('module', 'flag') . '/includes/flag.features.inc',
- ),
- );
- }
-
- * Implements hook_permission().
- */
- function flag_permission() {
- $permissions = array(
- 'administer flags' => array(
- 'title' => t('Administer flags'),
- 'description' => t('Create and edit site-wide flags.'),
- ),
- 'use flag import' => array(
- 'title' => t('Use flag importer'),
- 'description' => t('Access the flag import functionality.'),
- 'restrict access' => TRUE,
- ),
- );
-
- $flags = flag_get_flags();
-
- foreach ($flags as $flag_name => $flag) {
- $permissions += $flag->get_permissions();
- }
-
- return $permissions;
- }
-
- * Implements hook_form_FORM_ID_alter(): user_admin_permissions.
- *
- * Disable permission on the permissions form that don't make sense for
- * anonymous users when Session API module is not enabled.
- */
- function flag_form_user_admin_permissions_alter(&$form, &$form_state, $form_id) {
- if (!module_exists('session_api')) {
- $flags = flag_get_flags();
-
- foreach ($flags as $flag_name => $flag) {
- $form['checkboxes'][DRUPAL_ANONYMOUS_RID]["flag $flag_name"]['#disabled'] = TRUE;
- $form['checkboxes'][DRUPAL_ANONYMOUS_RID]["unflag $flag_name"]['#disabled'] = TRUE;
- }
- }
- }
-
- * Implements hook_link().
- *
- * This hook does not exist in Drupal 7, it is called from flag_entity_view().
- */
- function flag_link($type, $object = NULL, $teaser = FALSE) {
- if (!isset($object) || !flag_fetch_definition($type)) {
- return;
- }
- global $user;
-
-
- $flags = flag_get_flags($type);
-
- foreach ($flags as $flag) {
- $entity_id = $flag->get_entity_id($object);
-
- if (!$flag->uses_hook_link($teaser)) {
-
- continue;
- }
- if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) {
-
-
-
- continue;
- }
-
-
-
- $links['flag-' . $flag->name] = array(
- 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id),
- 'html' => TRUE,
- );
- }
-
- if (isset($links)) {
- return $links;
- }
- }
-
- * Implements hook_flag_link().
- */
- function flag_flag_link($flag, $action, $entity_id) {
- $token = flag_get_token($entity_id);
- return array(
- 'href' => 'flag/' . ($flag->link_type == 'confirm' ? 'confirm/' : '') . "$action/$flag->name/$entity_id",
- 'query' => drupal_get_destination() + ($flag->link_type == 'confirm' ? array() : array('token' => $token)),
- );
- }
-
- * Implements hook_field_extra_fields().
- */
- function flag_field_extra_fields() {
- $extra = array();
-
- $flags = flag_get_flags();
- foreach ($flags as $name => $flag) {
-
- if (!is_subclass_of($flag, 'flag_entity')) {
- continue;
- }
-
- foreach ($flag->types as $bundle_name) {
- if ($flag->show_on_form) {
- $extra[$flag->entity_type][$bundle_name]['form']['flag'] = array(
- 'label' => t('Flags'),
- 'description' => t('Checkboxes for toggling flags'),
- 'weight' => 10
- );
- }
- }
- }
-
- return $extra;
- }
-
- * Implements hook_form_FORM_ID_alter(): node_type_form.
- */
- function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) {
- global $user;
- $flags = flag_get_flags('node', $form['#node_type']->type, $user);
- foreach ($flags as $flag) {
- if ($flag->show_on_form) {
- $var = 'flag_' . $flag->name . '_default';
- $form['workflow']['flag'][$var] = array(
- '#type' => 'checkbox',
- '#title' => $flag->get_label('flag_short', $form['#node_type']->type),
- '#default_value' => variable_get($var . '_' . $form['#node_type']->type, 0),
- '#return_value' => 1,
- );
- }
- }
-
- if (isset($form['workflow']['flag'])) {
- $form['workflow']['flag'] += array(
- '#type' => 'item',
- '#title' => t('Default flags'),
- '#description' => t('Above are the <a href="@flag-url">flags</a> you elected to show on the node editing form. You may specify their initial state here.', array('@flag-url' => url(FLAG_ADMIN_PATH))),
-
- '#prefix' => '<div class="form-checkboxes">',
- '#suffix' => '</div>',
- );
- }
- }
-
- * Implements hook_field_attach_form().
- *
- * Handles the 'show_on_form' flag option.
- *
- * Warning: will not work on entity types that are not fieldable, as this relies
- * on a field module hook.
- *
- * @see flag_field_attach_submit().
- */
- function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
-
- if ($entity_type == 'node') {
- return;
- }
-
- list($id) = entity_extract_ids($entity_type, $entity);
-
- if (empty($id)) {
- $id = NULL;
- }
-
-
- $flags = flag_get_flags($entity_type);
-
-
- $flags_in_form = 0;
- $flags_visible = 0;
- foreach ($flags as $flag) {
- if (!$flag->show_on_form) {
- continue;
- }
-
-
-
- $flag_status = $id ? $flag->is_flagged($id) : FALSE;
-
-
-
-
-
- global $user;
- $access = $flag->access($id, $flag_status ? 'unflag' : 'flag');
- if (!$access && !$flag->global) {
- continue;
- }
-
- $form['flag'][$flag->name] = array(
- '#type' => 'checkbox',
- '#title' => $flag->get_label('flag_short', $id),
- '#description' => $flag->get_label('flag_long', $id),
- '#default_value' => $flag_status,
- '#return_value' => 1,
- );
-
-
- if (!$access) {
- $form['flag'][$flag->name]['#type'] = 'value';
- $form['flag'][$flag->name]['#value'] = $flag_status;
- }
- else {
- $flags_visible++;
- }
- $flags_in_form++;
- }
-
- if ($flags_in_form) {
- $form['flag'] += array(
- '#weight' => 1,
- '#tree' => TRUE,
- );
- }
- if ($flags_visible) {
- $form['flag'] += array(
- '#type' => 'fieldset',
- '#title' => t('Flags'),
- '#collapsible' => TRUE,
- );
- }
- }
-
- * Implements hook_field_attach_submit().
- *
- * @see flag_field_attach_form().
- */
- function flag_field_attach_submit($entity_type, $entity, $form, &$form_state) {
-
-
-
-
- if (isset($form['flag'])) {
- $parents = $form['flag']['#parents'];
- $flag_values = drupal_array_get_nested_value($form_state['values'], $parents);
-
-
-
- $entity->flag = $flag_values;
- }
- }
-
- * Implements hook_field_attach_insert().
- */
- function flag_field_attach_insert($entity_type, $entity) {
- if (isset($entity->flag)) {
- flag_field_attach_save($entity_type, $entity);
- }
- }
-
- * Implements hook_field_attach_update().
- */
- function flag_field_attach_update($entity_type, $entity) {
- if (isset($entity->flag)) {
- flag_field_attach_save($entity_type, $entity);
- }
- }
-
- * Shared saving routine between flag_field_attach_insert/update().
- *
- * @see flag_field_attach_form().
- */
- function flag_field_attach_save($entity_type, $entity) {
- list($id) = entity_extract_ids($entity_type, $entity);
-
- foreach ($entity->flag as $flag_name => $state) {
- flag($state ? 'flag' : 'unflag', $flag_name, $id);
- }
- }
-
- * Implements hook_form_alter().
- */
- function flag_form_alter(&$form, &$form_state, $form_id) {
-
- if (isset($form['type']) && isset($form['#node']) && ($form_id == $form['type']['#value'] . '_node_form')) {
- global $user;
- $nid = !empty($form['nid']['#value']) ? $form['nid']['#value'] : NULL;
- $flags = flag_get_flags('node', $form['type']['#value'], $user);
-
-
- $flags_in_form = 0;
- $flags_visible = 0;
- foreach ($flags as $name => $flag) {
- if (!$flag->show_on_form) {
- continue;
- }
-
- if (isset($form['#node']->flag[$flag->name])) {
- $flag_status = $form['#node']->flag[$flag->name];
- }
- else {
- $flag_status_default = variable_get('flag_' . $flag->name . '_default_' . $form['type']['#value'], 0);
- $flag_status = $nid ? $flag->is_flagged($nid) : $flag_status_default;
- }
-
-
-
-
-
- $access = $flag->access($nid, $flag_status ? 'unflag' : 'flag', $user);
- if (!$access && !$flag->global) {
- continue;
- }
-
-
- $form['flag'][$flag->name] = array(
- '#type' => 'checkbox',
- '#title' => $flag->get_label('flag_short', $nid ? $nid : $form['type']['#value']),
- '#description' => $flag->get_label('flag_long', $nid ? $nid : $form['type']['#value']),
- '#default_value' => $flag_status,
- '#return_value' => 1,
- '#attributes' => array('title' => $flag->get_title()),
- );
-
- if (!$access) {
- $form['flag'][$flag->name]['#type'] = 'value';
- $form['flag'][$flag->name]['#value'] = $flag_status;
- }
- else {
- $flags_visible++;
- }
- $flags_in_form++;
- }
- if ($flags_in_form) {
- $form['flag'] += array(
- '#weight' => 1,
- '#tree' => TRUE,
- );
- }
- if ($flags_visible) {
- $form['flag'] += array(
- '#type' => 'fieldset',
- '#title' => t('Flags'),
- '#collapsible' => TRUE,
-
- '#group' => 'additional_settings',
- '#attributes' => array('class' => array('flag-fieldset')),
- '#attached' => array(
- 'js' => array(
- 'vertical-tabs' => drupal_get_path('module', 'flag') . '/theme/flag-admin.js',
- ),
- ),
- );
- }
-
- }
- }
-
- * Implements hook_contextual_links_view_alter().
- */
- function flag_contextual_links_view_alter(&$element, $items) {
- if (isset($element['#element']['#entity_type'])) {
- $entity_type = $element['#element']['#entity_type'];
-
-
- if (isset($element['#element']['#entity'])) {
-
- $entity = $element['#element']['#entity'];
- }
- elseif (isset($element['#element']['#' . $entity_type])) {
-
- $entity = $element['#element']['#' . $entity_type];
- }
- else {
-
- return;
- }
-
-
- $flags = flag_get_flags($entity_type);
-
- foreach ($flags as $name => $flag) {
- if (!$flag->show_contextual_link) {
- continue;
- }
-
- list($entity_id) = entity_extract_ids($entity_type, $entity);
- if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) {
-
-
-
- continue;
- }
-
- $element['#links']['flag-'. $name] = array(
- 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id),
- 'html' => TRUE,
- );
- }
- }
- }
-
- * Implements hook_entity_view().
- *
- * Handles the 'show_on_entity' flag option.
- *
- * Note this is broken for taxonomy terms. @see http://drupal.org/node/1067120
- */
- function flag_entity_view($entity, $type, $view_mode, $langcode) {
- $links = flag_link($type, $entity, $view_mode == 'teaser');
- if (isset($links)) {
- $entity->content['links']['flag'] = array(
- '#theme' => 'links',
- '#links' => $links,
- '#attributes' => array('class' => array('links', 'inline')),
- );
- }
- }
-
- * Implements hook_node_insert().
- */
- function flag_node_insert($node) {
- flag_node_save($node);
- }
-
- * Implements hook_node_update().
- */
- function flag_node_update($node) {
- flag_node_save($node);
- }
-
- * Shared saving routine between flag_node_insert() and flag_node_update().
- */
- function flag_node_save($node) {
- global $user;
-
-
- $remembered = FALSE;
- if (isset($node->flag)) {
- foreach ($node->flag as $name => $state) {
- $flag = flag_get_flag($name);
-
-
- if (!$remembered) {
- $flag->remember_entity($node->nid, $node);
-
-
- $remembered = TRUE;
- }
- flag($state ? 'flag' : 'unflag', $name, $node->nid, $user);
- }
- }
- }
-
- * Implements hook_entity_delete().
- */
- function flag_entity_delete($entity, $type) {
-
-
- if ($type == 'node' || $type == 'user') {
- return;
- }
-
- list($id) = entity_extract_ids($type, $entity);
- _flag_entity_delete($type, $id);
- }
-
- * Implements hook_node_delete().
- */
- function flag_node_delete($node) {
- foreach (flag_get_flags('node') as $flag) {
-
-
-
- if (!$flag->i18n || empty($node->tnid)) {
- _flag_entity_delete('node', $node->nid, $flag->fid);
- }
- }
- }
-
- * Implements hook_node_translation_change().
- *
- * (Hook provided by translation_helpers module.)
- */
- function flag_node_translation_change($node) {
- if (isset($node->translation_change)) {
-
-
- $entity_id = $node->translation_change['new_tnid'] == 0 ? $node->translation_change['remaining_nid'] : $node->translation_change['new_tnid'];
- foreach (flag_get_flags('node') as $flag) {
- if ($flag->i18n) {
- db_update('flagging')->fields(array('entity_id' => $entity_id))
- ->condition('fid', $flag->fid)
- ->condition('entity_id', $node->translation_change['old_tnid'])
- ->execute();
- db_update('flag_counts')->fields(array('entity_id' => $entity_id))
- ->condition('fid', $flag->fid)
- ->condition('entity_id', $node->translation_change['old_tnid'])
- ->execute();
- }
- }
- }
- }
-
- * Deletes flagging records for the entity.
- *
- * @param $entity_type
- * The type of the entity being deleted; e.g. 'node' or 'comment'.
- * @param $entity_id
- * The ID of the entity being deleted.
- * @param $fid
- * The flag id
- */
- function _flag_entity_delete($entity_type, $entity_id, $fid = NULL) {
- $query_content = db_delete('flagging')
- ->condition('entity_type', $entity_type)
- ->condition('entity_id', $entity_id);
- $query_counts = db_delete('flag_counts')
- ->condition('entity_type', $entity_type)
- ->condition('entity_id', $entity_id);
- if (isset($fid)) {
- $query_content->condition('fid', $fid);
- $query_counts->condition('fid', $fid);
- }
- $query_content->execute();
- $query_counts->execute();
- }
-
- * Implements hook_user_login().
- */
- function flag_user_login(&$edit, &$account) {
-
- if (module_exists('session_api') && ($sid = flag_get_sid(0))) {
-
- $duplicate_flaggings = array();
- $flaggings = db_select('flagging', 'fc')
- ->fields('fc', array('flagging_id', 'fid', 'entity_id'))
- ->condition('uid', 0)
- ->condition('sid', $sid)
- ->execute()
- ->fetchAllAssoc('flagging_id', PDO::FETCH_ASSOC);
-
-
- foreach ($flaggings as $flagging_id => $flagging) {
-
-
-
- try {
- db_update('flagging')
- ->fields(array(
- 'uid' => $account->uid,
- 'sid' => 0,
- ))
- ->condition('flagging_id', $flagging_id)
- ->execute();
- }
- catch (Exception $e) {
- $duplicate_flaggings[$flagging_id] = $flagging;
- }
- }
-
-
-
-
- $anonymous_user = drupal_anonymous_user();
- foreach ($duplicate_flaggings as $flagging_id => $flagging) {
- $flag = flag_get_flag(NULL, $flagging['fid']);
- $flag->flag('unflag', $flagging['entity_id'], $anonymous_user, TRUE);
- }
-
-
- FlagCookieStorage::drop();
- }
- }
-
- * Implements hook_user_cancel().
- */
- function flag_user_cancel($edit, $account, $method) {
- flag_user_account_removal($account);
- }
-
- * Implements hook_user_delete().
- */
- function flag_user_delete($account) {
- flag_user_account_removal($account);
- }
-
- * Callback function for user account cancellation or deletion.
- */
- function flag_user_account_removal($account) {
-
- $query = db_select('flagging', 'fc');
- $query->leftJoin('flag_counts', 'c', 'fc.entity_id = c.entity_id AND fc.entity_type = c.entity_type');
- $result = $query
- ->fields('fc', array('fid', 'entity_id'))
- ->fields('c', array('count'))
- ->condition('fc.uid', $account->uid)
- ->execute();
-
- foreach ($result as $flag_data) {
-
- if ($flag_data->count > 0) {
- $flag_data->count--;
- db_update('flag_counts')
- ->fields(array(
- 'count' => $flag_data->count,
- ))
- ->condition('fid', $flag_data->fid)
- ->condition('entity_id', $flag_data->entity_id)
- ->execute();
- }
- elseif ($flag_data->count == 0) {
- db_delete('flag_counts')
- ->condition('fid', $flag_data->fid)
- ->condition('entity_id', $flag_data->entity_id)
- ->execute();
- }
- }
- db_delete('flagging')
- ->condition('uid', $account->uid)
- ->execute();
-
-
- _flag_entity_delete('user', $account->uid);
- }
-
- * Implements hook_user_view().
- */
- function flag_user_view($account, $view_mode) {
- $flags = flag_get_flags('user');
- $flag_items = array();
- foreach ($flags as $flag) {
- if (!$flag->access($account->uid)) {
-
- continue;
- }
- if (!$flag->uses_hook_link(array())) {
-
- continue;
- }
- $flag_items[$flag->name] = array(
- '#type' => 'user_profile_item',
- '#title' => $flag->get_title($account->uid),
- '#markup' => $flag->theme($flag->is_flagged($account->uid) ? 'unflag' : 'flag', $account->uid),
- '#attributes' => array('class' => array('flag-profile-' . $flag->name)),
- );
- }
- if (!empty($flag_items)) {
- $account->content['flags'] = $flag_items;
- $account->content['flags'] += array(
- '#type' => 'user_profile_category',
- '#title' => t('Actions'),
- '#attributes' => array('class' => array('flag-profile')),
- );
- }
- }
-
- * Implements hook_session_api_cleanup().
- *
- * Clear out anonymous user flaggings during Session API cleanup.
- */
- function flag_session_api_cleanup($arg = 'run') {
-
- if ($arg == 'run') {
- $query = db_select('flagging', 'fc');
- $query->leftJoin('session_api', 's', 'fc.sid = s.sid');
- $result = $query
- ->fields('fc', array('sid'))
- ->condition('fc.sid', 0, '<>')
- ->isNull('s.sid')
- ->execute();
- foreach ($result as $row) {
- db_delete('flagging')
- ->condition('sid', $row->sid)
- ->execute();
- }
- }
-
- elseif (is_array($arg)) {
- $outdated_sids = $arg;
- db_delete('flagging')->condition('sid', $outdated_sids, 'IN')->execute();
- }
- }
-
- * Implements hook_field_attach_delete_bundle().
- *
- * Delete any flags' applicability to the deleted bundle.
- */
- function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) {
-
-
- db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flag} WHERE entity_type = :entity_type)", array(
- ':bundle' => $bundle,
- ':entity_type' => $entity_type,
- ));
- }
-
- * Flags or unflags an item.
- *
- * @param $account
- * The user on whose behalf to flag. Leave empty for the current user.
- * @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, $flag_name, $entity_id, $account = NULL) {
- if (!($flag = flag_get_flag($flag_name))) {
-
- return FALSE;
- }
- return $flag->flag($action, $entity_id, $account);
- }
-
- * Implements hook_flag_flag().
- */
- function flag_flag_flag($flag, $entity_id, $account, $flagging) {
- if (module_exists('trigger')) {
- flag_flag_trigger('flag', $flag, $entity_id, $account, $flagging);
- }
- }
-
- * Implements hook_flag_unflag().
- */
- function flag_flag_unflag($flag, $entity_id, $account, $flagging) {
- if (module_exists('trigger')) {
- flag_flag_trigger('unflag', $flag, $entity_id, $account, $flagging);
- }
- }
-
- * Trigger actions if any are available. Helper for hook_flag_(un)flag().
- *
- * @param $op
- * The operation being performed: one of 'flag' or 'unflag'.
- * @param $flag
- * The flag object.
- * @param $entity_id
- * The id of the entity the flag is on.
- * @param $account
- * The user account performing the action.
- * @param $flagging_id
- * The flagging entity.
- */
- function flag_flag_trigger($action, $flag, $entity_id, $account, $flagging) {
- $context['hook'] = 'flag';
- $context['account'] = $account;
- $context['flag'] = $flag;
- $context['op'] = $action;
-
- $context = array_merge($flag->get_relevant_action_objects($entity_id), $context);
-
- $object = $flag->fetch_entity($entity_id);
-
-
- foreach (trigger_get_assigned_actions('flag_' . $action) as $aid => $action_info) {
-
- if ($aid) {
- actions_do($aid, $object, $context);
- }
- }
-
- foreach (trigger_get_assigned_actions('flag_' . $action . '_' . $flag->name) as $aid => $action_info) {
- if ($aid) {
- actions_do($aid, $object, $context);
- }
- }
- }
-
- * Implements hook_flag_access().
- */
- function flag_flag_access($flag, $entity_id, $action, $account) {
-
- if (empty($flag->access_author)) {
- return;
- }
-
-
-
- if ($flag->entity_type == 'node') {
-
-
- if (empty($entity_id) || !($node = node_load($entity_id))) {
- return $flag->access_author == 'others' ? FALSE : NULL;
- }
-
- if ($flag->access_author == 'own' && $node->uid != $account->uid) {
- return FALSE;
- }
- elseif ($flag->access_author == 'others' && $node->uid == $account->uid) {
- return FALSE;
- }
- }
-
-
- if ($flag->entity_type == 'comment') {
-
-
- if (empty($entity_id) || !($comment = $flag->fetch_entity($entity_id))) {
- return $flag->access_author == 'comment_others' ? FALSE : NULL;
- }
-
- $node = node_load($comment->nid);
- if ($flag->access_author == 'node_own' && $node->uid != $account->uid) {
- return FALSE;
- }
- elseif ($flag->access_author == 'node_others' && $node->uid == $account->uid) {
- return FALSE;
- }
- elseif ($flag->access_author == 'comment_own' && $comment->uid != $account->uid) {
- return FALSE;
- }
- elseif ($flag->access_author == 'comment_others' && $comment->uid == $account->uid) {
- return FALSE;
- }
- }
- }
-
- * Implements hook_flag_access_multiple().
- */
- function flag_flag_access_multiple($flag, $entity_ids, $account) {
- $access = array();
-
-
- if (empty($flag->access_author)) {
- return $access;
- }
-
- if ($flag->entity_type == 'node') {
-
-
-
-
- $result = db_select('node', 'n')
- ->fields('n', array('nid', 'uid'))
- ->condition('nid', array_keys($entity_ids), 'IN')
- ->condition('type', $flag->types, 'IN')
- ->execute();
- foreach ($result as $row) {
- if ($flag->access_author == 'own') {
- $access[$row->nid] = $row->uid != $account->uid ? FALSE : NULL;
- }
- elseif ($flag->access_author == 'others') {
- $access[$row->nid] = $row->uid == $account->uid ? FALSE : NULL;
- }
- }
- }
-
- if ($flag->entity_type == 'comment') {
-
- $query = db_select('comment', 'c');
- $query->leftJoin('node', 'n', 'c.nid = n.nid');
- $query
- ->fields('c', array('cid', 'nid', 'uid'))
- ->condition('c.cid', $entity_ids, 'IN');
- $query->addField('c', 'uid', 'comment_uid');
- $result = $query->execute();
-
- foreach ($result as $row) {
- if ($flag->access_author == 'node_own') {
- $access[$row->cid] = $row->node_uid != $account->uid ? FALSE : NULL;
- }
- elseif ($flag->access_author == 'node_others') {
- $access[$row->cid] = $row->node_uid == $account->uid ? FALSE : NULL;
- }
- elseif ($flag->access_author == 'comment_own') {
- $access[$row->cid] = $row->comment_uid != $account->uid ? FALSE : NULL;
- }
- elseif ($flag->access_author == 'comment_others') {
- $access[$row->cid] = $row->comment_uid == $account->uid ? FALSE : NULL;
- }
- }
- }
-
-
- return $access;
- }
-
- * Trim a flag to a certain size.
- *
- * @param $fid
- * The flag object.
- * @param $account
- * The user object on behalf the trimming will occur.
- * @param $cutoff_size
- * The number of flaggings allowed. Any flaggings beyond that will be trimmed.
- */
- function flag_trim_flag($flag, $account, $cutoff_size) {
- $result = db_select('flagging', 'fc')
- ->fields('fc')
- ->condition('fid', $flag->fid)
- ->condition(db_or()->condition('uid', $account->uid)->condition('uid', 0))
- ->orderBy('timestamp', 'DESC')
- ->execute();
- $i = 1;
- foreach ($result as $row) {
- if ($i++ > $cutoff_size) {
- flag('unflag', $flag->name, $row->entity_id, $account);
- }
- }
- }
-
- * Remove all flagged entities from a flag.
- *
- * @param $flag
- * The flag object.
- * @param $entity_id
- * Optional. The entity ID on which all flaggings will be removed. If left
- * empty, this will remove all of this flag's entities.
- */
- function flag_reset_flag($flag, $entity_id = NULL) {
- $query = db_select('flagging', 'fc')
- ->fields('fc')
- ->condition('fid', $flag->fid);
-
- if ($entity_id) {
- $query->condition('entity_id', $entity_id);
- }
-
- $result = $query->execute()->fetchAllAssoc('flagging_id', PDO::FETCH_ASSOC);
- $rows = array();
- foreach ($result as $row) {
- $rows[] = $row;
- }
- module_invoke_all('flag_reset', $flag, $entity_id, $rows);
-
- $query = db_delete('flagging')->condition('fid' , $flag->fid);
-
- $count_query = db_delete('flag_counts')->condition('fid', $flag->fid);
- if ($entity_id) {
- $query->condition('entity_id', $entity_id);
- $count_query->condition('entity_id', $entity_id);
- }
- $count_query->execute();
- return $query->execute();
- }
-
- * Implements hook_node_operations().
- *
- * Add additional options on the admin/build/node page.
- */
- function flag_node_operations() {
- global $user;
-
- $flags = flag_get_flags('node', NULL, $user);
- $operations = array();
-
- foreach ($flags as $flag) {
- $operations['flag_' . $flag->name] = array(
- 'label' => $flag->get_label('flag_short'),
- 'callback' => 'flag_nodes',
- 'callback arguments' => array('flag', $flag->name),
- 'behavior' => array(),
- );
- $operations['unflag_' . $flag->name] = array(
- 'label' => $flag->get_label('unflag_short'),
- 'callback' => 'flag_nodes',
- 'callback arguments' => array('unflag', $flag->name),
- 'behavior' => array(),
- );
- }
- return $operations;
- }
-
- * Callback function for hook_node_operations().
- */
- function flag_nodes($nodes, $action, $flag_name) {
- $performed = FALSE;
- foreach ($nodes as $nid) {
- $performed |= flag($action, $flag_name, $nid);
- }
- if ($performed) {
- drupal_set_message(t('The update has been performed.'));
- }
- }
-
- * Implements hook_user_operations().
- */
- function flag_user_operations() {
- global $user;
-
- $flags = flag_get_flags('user', NULL, $user);
- $operations = array();
-
- foreach ($flags as $flag) {
- $operations['flag_' . $flag->name] = array(
- 'label' => $flag->get_label('flag_short'),
- 'callback' => 'flag_users',
- 'callback arguments' => array('flag', $flag->name),
- );
- $operations['unflag_' . $flag->name] = array(
- 'label' => $flag->get_label('unflag_short'),
- 'callback' => 'flag_users',
- 'callback arguments' => array('unflag', $flag->name),
- );
- }
- return $operations;
- }
- * Callback function for hook_user_operations().
- */
- function flag_users($users, $action, $flag_name) {
- foreach ($users as $uid) {
- flag($action, $flag_name, $uid);
- }
- }
-
- * Implements hook_mail().
- */
- function flag_mail($key, &$message, $params) {
- switch ($key) {
- case 'over_threshold':
- $message['subject'] = $params['subject'];
- $message['body'] = $params['body'];
- break;
- }
- }
-
- * Implements hook_theme().
- */
- function flag_theme() {
- $path = drupal_get_path('module', 'flag') . '/theme';
-
- return array(
- 'flag' => array(
- 'variables' => array('flag' => NULL, 'action' => NULL, 'entity_id' => NULL, 'after_flagging' => FALSE),
- 'template' => 'flag',
- 'pattern' => 'flag__',
- 'path' => $path,
- ),
- 'flag_tokens_browser' => array(
- 'variables' => array('types' => array('all'), 'global_types' => TRUE),
- 'file' => 'flag.tokens.inc',
- ),
- 'flag_admin_listing' => array(
- 'render element' => 'form',
- 'file' => 'includes/flag.admin.inc',
- ),
- 'flag_admin_listing_disabled' => array(
- 'variables' => array('flags' => NULL, 'default_flags' => NULL),
- 'file' => 'includes/flag.admin.inc',
- ),
- 'flag_admin_page' => array(
- 'variables' => array('flags' => NULL, 'default_flags' => NULL, 'flag_admin_listing' => NULL),
- 'file' => 'includes/flag.admin.inc',
- ),
- 'flag_form_roles' => array(
- 'render element' => 'element',
- 'file' => 'includes/flag.admin.inc',
- ),
- );
- }
-
- * A preprocess function for our theme('flag'). It generates the
- * variables needed there.
- *
- * The $variables array initially contains the following arguments:
- * - $flag
- * - $action
- * - $entity_id
- * - $after_flagging
- *
- * See 'flag.tpl.php' for their documentation.
- */
- function template_preprocess_flag(&$variables) {
- global $user;
- $initialized = &drupal_static(__FUNCTION__, array());
-
-
- $flag =& $variables['flag'];
- $action = $variables['action'];
- $entity_id = $variables['entity_id'];
- $flag_css_name = str_replace('_', '-', $flag->name);
-
-
- $link_type = $flag->get_link_type();
- $link = module_invoke($link_type['module'], 'flag_link', $flag, $action, $entity_id);
- if (isset($link['title']) && empty($link['html'])) {
- $link['title'] = check_plain($link['title']);
- }
-
-
- if ($action == 'unflag' && !$flag->access($entity_id, 'unflag')) {
- $link['title'] = $flag->get_label('unflag_denied_text', $entity_id);
- unset($link['href']);
- }
-
-
- if ($user->uid == 0) {
- $link_type['uses standard js'] = TRUE;
- }
-
-
- if (!isset($initialized[$link_type['name']])) {
- if ($link_type['uses standard css']) {
- drupal_add_css(drupal_get_path('module', 'flag') . '/theme/flag.css');
- }
- if ($link_type['uses standard js']) {
- drupal_add_js(drupal_get_path('module', 'flag') . '/theme/flag.js');
- }
- $initialized[$link_type['name']] = TRUE;
- }
-
- $variables['link'] = $link;
- $variables['link_href'] = isset($link['href']) ? check_url(url($link['href'], $link)) : FALSE;
- $variables['link_text'] = isset($link['title']) ? $link['title'] : $flag->get_label($action . '_short', $entity_id);
- $variables['link_title'] = isset($link['attributes']['title']) ? check_plain($link['attributes']['title']) : check_plain(strip_tags($flag->get_label($action . '_long', $entity_id)));
- $variables['status'] = ($action == 'flag' ? 'unflagged' : 'flagged');
- $variables['flag_name_css'] = $flag_css_name;
-
- $variables['flag_wrapper_classes_array'] = array();
- $variables['flag_wrapper_classes_array'][] = 'flag-wrapper';
- $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name;
- $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name . '-' . $entity_id;
- $variables['flag_wrapper_classes'] = implode(' ', $variables['flag_wrapper_classes_array']);
-
- $variables['flag_classes_array'] = array();
- $variables['flag_classes_array'][] = 'flag';
- if (isset($link['href'])) {
- $variables['flag_classes_array'][] = $variables['action'] . '-action';
- $variables['flag_classes_array'][] = 'flag-link-' . $flag->link_type;
- }
- else {
- $variables['flag_classes_array'][] = $variables['action'] . '-disabled';
- }
- if (isset($link['attributes']['class'])) {
- $link['attributes']['class'] = is_string($link['attributes']['class']) ? array_filter(explode(' ', $link['attributes']['class'])) : $link['attributes']['class'];
- $variables['flag_classes_array'] = array_merge($variables['flag_classes_array'], $link['attributes']['class']);
- }
- if ($variables['after_flagging']) {
- $inverse_action = ($action == 'flag' ? 'unflag' : 'flag');
- $variables['message_text'] = $flag->get_label($inverse_action . '_message', $entity_id);
- $variables['flag_classes_array'][] = $variables['status'];
- }
- $variables['flag_classes'] = implode(' ', $variables['flag_classes_array']);
-
-
-
-
- $variables['setup'] = FALSE;
- $variables['last_action'] = $variables['status'];
- }
-
- * Return an array of flag names keyed by fid.
- */
- function _flag_get_flag_names() {
- $flags = flag_get_flags();
- $flag_names = array();
- foreach ($flags as $flag) {
- $flag_names[$flag->fid] = $flag->name;
- }
- return $flag_names;
- }
-
- * Return an array of flag link types suitable for a select list or radios.
- */
- function _flag_link_type_options() {
- $options = array();
- $types = flag_get_link_types();
- foreach ($types as $type_name => $type) {
- $options[$type_name] = $type['title'];
- }
- return $options;
- }
-
- * Return an array of flag link type descriptions.
- */
- function _flag_link_type_descriptions() {
- $options = array();
- $types = flag_get_link_types();
- foreach ($types as $type_name => $type) {
- $options[$type_name] = $type['description'];
- }
- return $options;
- }
-
- * Return an array of flag link fields that are dependent on a link type.
- */
- function _flag_link_type_fields() {
- $options = array();
- $types = flag_get_link_types();
- foreach ($types as $type_name => $type) {
- $options[$type_name] = array_keys($type['options']);
- }
- return $options;
- }
-
-
- * Get flag counts for all flags on a node.
- *
- * @param $entity_type
- * The entity type (usually 'node').
- * @param $entity_id
- * The entity ID (usually the node ID).
- * @param $reset
- * Reset the internal cache and execute the SQL query another time.
- *
- * @return $flags
- * An array of the structure [name] => [number of flags].
- */
- function flag_get_counts($entity_type, $entity_id, $reset = FALSE) {
- $counts = &drupal_static(__FUNCTION__);
-
- if ($reset) {
- $counts = array();
- if (!isset($entity_type)) {
- return;
- }
- }
-
- if (!isset($counts[$entity_type][$entity_id])) {
- $counts[$entity_type][$entity_id] = array();
- $query = db_select('flag', 'f');
- $query->leftJoin('flag_counts', 'fc', 'f.fid = fc.fid');
- $result = $query
- ->fields('f', array('name'))
- ->fields('fc', array('count'))
- ->condition('fc.entity_type', $entity_type)
- ->condition('fc.entity_id', $entity_id)
- ->execute();
- foreach ($result as $row) {
- $counts[$entity_type][$entity_id][$row->name] = $row->count;
- }
- }
-
- return $counts[$entity_type][$entity_id];
- }
-
- * Get the total count of items flagged within a flag.
- *
- * @param $flag_name
- * The flag name for which to retrieve a flag count.
- * @param $reset
- * Reset the internal cache and execute the SQL query another time.
- */
- function flag_get_flag_counts($flag_name, $reset = FALSE) {
- $counts = &drupal_static(__FUNCTION__);
-
- if ($reset) {
- $counts = array();
- }
- if (!isset($counts[$flag_name])) {
- $flag = flag_get_flag($flag_name);
- $counts[$flag_name] = db_select('flag_counts', 'fc')
- ->fields('fc', array('flagging_id'))
- ->condition('fid', $flag->fid)
- ->countQuery()
- ->execute()
- ->fetchField();
- }
-
- return $counts[$flag_name];
- }
-
- * Load a single flag either by name or by flag ID.
- *
- * @param $name
- * (optional) The flag name.
- * @param $fid
- * (optional) The the flag id.
- *
- * @return
- * The flag object, or FALSE if no matching flag was found.
- */
- function flag_get_flag($name = NULL, $fid = NULL) {
- $flags = flag_get_flags();
- if (isset($name)) {
- if (isset($flags[$name])) {
- return $flags[$name];
- }
- }
- elseif (isset($fid)) {
- foreach ($flags as $flag) {
- if ($flag->fid == $fid) {
- return $flag;
- }
- }
- }
- return FALSE;
- }
-
- * List all flags available.
- *
- * If node type or account are entered, a list of all possible flags will be
- * returned.
- *
- * @param $entity_type
- * Optional. The type of entity for which to load the flags. Usually 'node'.
- * @param $content_subtype
- * Optional. The node type for which to load the flags.
- * @param $account
- * Optional. The user accont to filter available flags. If not set, all
- * flags for will this node will be returned.
- *
- * @return $flags
- * An array of the structure [fid] = flag_object.
- */
- function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL) {
- $flags = &drupal_static(__FUNCTION__);
-
-
- if (!isset($flags)) {
- $flags = array();
-
-
- $query = db_select('flag', 'f');
- $query->leftJoin('flag_types', 'fn', 'fn.fid = f.fid');
- $result = $query
- ->fields('f', array('fid', 'entity_type', 'name', 'title', 'global', 'options'))
- ->fields('fn', array('type'))
- ->execute();
- foreach ($result as $row) {
- if (!isset($flags[$row->name])) {
- $flags[$row->name] = flag_flag::factory_by_row($row);
- }
- else {
- $flags[$row->name]->types[] = $row->type;
- }
- }
-
-
- $default_flags = flag_get_default_flags();
- foreach ($default_flags as $name => $default_flag) {
-
- if ($default_flag->status && !isset($flags[$name])) {
- $default_flag->save();
- $flags[$name] = $default_flag;
- }
-
- if (isset($flags[$name])) {
-
- $flags[$name]->module = $default_flag->module;
-
-
- if (isset($default_flag->locked)) {
- $flags[$name]->locked = $default_flag->locked;
- foreach ($default_flag->locked as $property) {
- $flags[$name]->$property = $default_flag->$property;
- }
- }
- }
- }
-
-
- uasort($flags, '_flag_compare_weight');
-
- foreach ($flags as $flag) {
-
- drupal_alter('flag', $flag);
- }
- }
-
-
- $filtered_flags = $flags;
-
-
- if (isset($entity_type) || isset($content_subtype)) {
- foreach ($filtered_flags as $name => $flag) {
- if (!_flag_entity_enabled($flag, $entity_type, $content_subtype)) {
- unset($filtered_flags[$name]);
- }
- }
- }
-
-
- if (isset($account) && $account->uid != 1) {
- foreach ($filtered_flags as $name => $flag) {
-
-
- if (!$flag->user_access('flag', $account)) {
- unset($filtered_flags[$name]);
- }
- }
- }
-
- return $filtered_flags;
- }
-
- * Comparison function for uasort().
- */
- function _flag_compare_weight($flag1, $flag2) {
- if ($flag1->weight == $flag2->weight) {
- return 0;
- }
- return $flag1->weight < $flag2->weight ? -1 : 1;
- }
-
- * Utility function: Checks whether a flag applies to a certain type, and
- * possibly subtype, of entity.
- *
- * @param $entity_type
- * The type of entity being checked, usually "node".
- * @param $content_subtype
- * The subtype (node type) being checked.
- *
- * @return
- * TRUE if the flag is enabled for this type and subtype.
- */
- function _flag_entity_enabled($flag, $entity_type, $content_subtype = NULL) {
- $return = ($flag->entity_type == $entity_type) &&
- (!isset($content_subtype) || !count($flag->types) || in_array($content_subtype, $flag->types));
- return $return;
- }
-
- * Retrieve a list of flags defined by modules.
- *
- * @param $include_disabled
- * Unless specified, only enabled flags will be returned.
- * @return
- * An array of flag prototypes, not usable for flagging. Use flag_get_flags()
- * if needing to perform a flagging with any enabled flag.
- */
- function flag_get_default_flags($include_disabled = FALSE) {
- $default_flags = array();
- $flag_status = variable_get('flag_default_flag_status', array());
-
- foreach (module_implements('flag_default_flags') as $module) {
- $function = $module . '_flag_default_flags';
- foreach ($function() as $flag_name => $flag_info) {
-
-
- $flag_info += array(
- 'name' => $flag_name,
- 'module' => $module,
- );
- $flag = flag_flag::factory_by_array($flag_info);
-
-
- if (!$flag->is_compatible()) {
- $flag->status = FALSE;
- }
-
-
- if ((!isset($flag_status[$flag->name]) && (!isset($flag->status) || $flag->status)) || !empty($flag_status[$flag->name])) {
- $flag->status = TRUE;
- $default_flags[$flag->name] = $flag;
- }
-
- elseif ($include_disabled) {
- $flag->status = FALSE;
- $default_flags[$flag->name] = $flag;
- }
- }
- }
-
- return $default_flags;
- }
-
- * Get all flagged entities in a flag.
- *
- * @param
- * The flag name for which to retrieve flagged entites.
- */
- function flag_get_flag_flagging_data($flag_name) {
- $return = array();
- $flag = flag_get_flag($flag_name);
- $result = db_select('flagging', 'fc')
- ->fields('fc')
- ->condition('fid', $flag->fid)
- ->execute();
- return $result->fetchAllAssoc('flagging_id');
- }
-
- * Get entity ID from a flag content ID.
- *
- * @param $flagging_id
- * The flag content ID for which to look up the entity ID.
- */
- function flag_get_entity_id($flagging_id) {
- return db_select('flagging', 'fc')
- ->fields('fc', array('entity_id'))
- ->condition('flagging_id', $flagging_id)
- ->execute()
- ->fetchField();
- }
-
- * Find what a user has flagged, either a single node or on the entire site.
- *
- * @param $entity_type
- * The type of entity that will be retrieved. Usually 'node'.
- * @param $entity_id
- * Optional. The entity ID to check for flagging. If none given, all
- * entities flagged by this user will be returned.
- * @param $uid
- * Optional. The user ID whose flags we're checking. If none given, the
- * current user will be used.
- * @param $sid
- * Optional. The user SID (provided by Session API) whose flags we're
- * checking. If none given, the current user will be used. The SID is 0 for
- * logged in users.
- * @param $reset
- * Reset the internal cache and execute the SQL query another time.
- *
- * @return $flags
- * If returning a single item's flags (that is, when $entity_id isn't NULL),
- * an array of the structure
- * [flag_name] => (flagging_id => [flagging_id], uid => [uid], entity_id => [entity_id], timestamp => [timestamp], ...)
- *
- * If returning all items' flags, an array of arrays for each flag:
- * [flag_name] => [entity_id] => Object from above.
- *
- */
- function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) {
- $flagged_content = &drupal_static(__FUNCTION__);
-
- if ($reset) {
- $flagged_content = array();
- if (!isset($entity_type)) {
- return;
- }
- }
-
- $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid;
- $sid = !isset($sid) ? flag_get_sid($uid) : $sid;
-
- if (isset($entity_id)) {
- if (!isset($flagged_content[$uid][$sid][$entity_type][$entity_id])) {
- $flag_names = _flag_get_flag_names();
- $flagged_content[$uid][$sid][$entity_type][$entity_id] = array();
- $result = db_select('flagging', 'fc')
- ->fields('fc')
- ->condition('entity_type', $entity_type)
- ->condition('entity_id', $entity_id)
- ->condition(db_or()
- ->condition('uid', $uid)
- ->condition('uid', 0)
- )
- ->condition('sid', $sid)
- ->execute();
-
- foreach ($result as $flag_content) {
- $flagged_content[$uid][$sid][$entity_type][$entity_id][$flag_names[$flag_content->fid]] = $flag_content;
- }
- }
- return $flagged_content[$uid][$sid][$entity_type][$entity_id];
- }
-
- else {
- if (!isset($flagged_content[$uid][$sid][$entity_type]['all'])) {
- $flag_names = _flag_get_flag_names();
- $flagged_content[$uid][$sid][$entity_type]['all'] = array();
- $result = db_select('flagging', 'fc')
- ->fields('fc')
- ->condition('entity_type', $entity_type)
- ->condition(db_or()
- ->condition('uid', $uid)
- ->condition('uid', 0)
- )
- ->condition('sid', $sid)
- ->execute();
- foreach ($result as $flag_content) {
- $flagged_content[$uid][$sid][$entity_type]['all'][$flag_names[$flag_content->fid]][$flag_content->entity_id] = $flag_content;
- }
- }
- return $flagged_content[$uid][$sid][$entity_type]['all'];
- }
-
- }
-
- * Return a list of users who have flagged an entity.
- *
- * @param $entity_type
- * The type of entity that will be retrieved. Usually 'node'.
- * @param $entity_id
- * The entity ID to check for flagging.
- * @param $flag_name
- * Optional. The name of a flag if wanting a list specific to a single flag.
- *
- * @return
- * If no flag name is given, an array of flagging data, keyed by the user
- * ID that flagged the entity. Each flagging array is structured as
- * an array of flag information for each flag, keyed by the flag name. If
- * a flag name is specified, only the information for that flag is returned.
- * If no flags were found an empty array is returned.
- */
- function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) {
- $entity_flags = &drupal_static(__FUNCTION__, array());
-
- if (!isset($entity_flags[$entity_type][$entity_id])) {
- $flag_names = _flag_get_flag_names();
- $result = db_select('flagging', 'fc')
- ->fields('fc')
- ->condition('entity_type', $entity_type)
- ->condition('entity_id', $entity_id)
- ->orderBy('timestamp', 'DESC')
- ->execute();
- $entity_flags[$entity_type][$entity_id] = array();
- foreach ($result as $flag_content) {
-
- $entity_flags[$entity_type][$entity_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content;
-
- $entity_flags[$entity_type][$entity_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content;
- }
- }
- if (empty($entity_flags[$entity_type][$entity_id])) {
- return array();
- }
- if (isset($flag_name)) {
- if (isset($entity_flags[$entity_type][$entity_id]['flags'][$flag_name])) {
- return $entity_flags[$entity_type][$entity_id]['flags'][$flag_name];
- }
- return array();
- }
- return $entity_flags[$entity_type][$entity_id]['users'];
- }
-
- * A utility function for outputting a flag link.
- *
- * You should call this function from your template when you want to put the
- * link on the page yourself. For example, you could call this function from
- * your 'node.tpl.php':
- *
- * <?php print flag_create_link('bookmarks', $node->nid); ?>
- *
- * @param $flag_name
- * The "machine readable" name of the flag; e.g. 'bookmarks'.
- * @param $entity_id
- * The entity ID to check for flagging, for example a node ID.
- */
- function flag_create_link($flag_name, $entity_id) {
- $flag = flag_get_flag($flag_name);
- if (!$flag) {
-
- return;
- }
- if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) {
-
- return;
- }
- return $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id);
- }
-
- * Return an array of link types provided by modules.
- *
- * @return
- * An array of link types as defined by hook_flag_link_type_info(). These are keyed
- * by the type name, and each value is an array of properties. In addition to
- * those defined in hook_flag_link_type_info(), the following properties are set:
- * - 'module': The providing module.
- * - 'name': The machine name of the type.
- *
- * @see hook_flag_link_type_info()
- * @see hook_flag_link_type_info_alter()
- */
- function flag_get_link_types() {
- $link_types = &drupal_static(__FUNCTION__);
-
- if (!isset($link_types)) {
- if ($cache = cache_get('flag_link_type_info')) {
- $link_types = $cache->data;
- }
- else {
- $link_types = array();
- foreach (module_implements('flag_link_type_info') as $module) {
- $module_types = module_invoke($module, 'flag_link_type_info');
- foreach ($module_types as $type_name => $info) {
- $link_types[$type_name] = $info + array(
- 'module' => $module,
- 'name' => $type_name,
- 'title' => '',
- 'description' => '',
- 'options' => array(),
- 'uses standard js' => TRUE,
- 'uses standard css' => TRUE,
- 'provides form' => FALSE,
- );
- }
- }
- drupal_alter('flag_link_type_info', $link_types);
-
- cache_set('flag_link_type_info', $link_types);
- }
- }
-
- return $link_types;
- }
-
- * Get a private token used to protect links from spoofing - CSRF.
- */
- function flag_get_token($entity_id) {
-
-
- return ($GLOBALS['user']->uid) ? drupal_get_token($entity_id) : md5(drupal_get_private_key() . $entity_id);
- }
-
- * Check to see if a token value matches the specified node.
- */
- function flag_check_token($token, $entity_id) {
- return flag_get_token($entity_id) == $token;
- }
-
- * Set the Session ID for a user. Utilizes the Session API module.
- */
- function flag_set_sid($uid = NULL, $create = TRUE) {
- $sids = &drupal_static(__FUNCTION__, array());
-
- if (!isset($uid)) {
- $uid = $GLOBALS['user']->uid;
- }
-
- if (!isset($sids[$uid])) {
- if (module_exists('session_api') && session_api_available() && $uid == 0) {
- $sids[$uid] = session_api_get_sid($create);
- }
- else {
- $sids[$uid] = 0;
- }
- }
-
- return $sids[$uid];
- }
-
- * Get the Session ID for a user. Utilizes the Session API module.
- *
- * @param $uid
- * The user ID. If the UID is 0 (anonymous users), then a SID will be
- * returned. SID will always be 0 for any authenticated user.
- * @param $create
- * If the user doesn't yet have a session, should one be created? Defaults
- * to FALSE.
- */
- function flag_get_sid($uid = NULL, $create = FALSE) {
- return flag_set_sid($uid, $create);
- }
-
- * Implements hook_ctools_plugin_directory().
- */
- function flag_ctools_plugin_directory($module, $plugin) {
- if ($module == 'ctools' && !empty($plugin)) {
- return "plugins/$plugin";
- }
- }
-