flag_lists.module in Flag Lists 7
Same filename and directory in other branches
The Flag Lists module.
Extends flag to allow individual users to create personal flags.
File
flag_lists.moduleView source
<?php
module_load_include('inc', 'flag', 'includes/flag.admin');
module_load_include('inc', 'flag', 'flag');
/**
* @file
* The Flag Lists module.
*
* Extends flag to allow individual users to create personal flags.
*/
/**
* Implementation of hook_menu().
*/
function flag_lists_menu() {
$items = array();
$items[FLAG_ADMIN_PATH . '/lists'] = array(
'title' => 'Lists',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'flag_lists_settings_form',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer flags',
),
'description' => 'Configure default settings allowing users to mark content with personal flags.',
'file' => 'flag_lists.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 100,
);
$items[FLAG_ADMIN_PATH . '/lists/settings'] = array(
'title' => 'Settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'flag_lists_settings_form',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer flags',
),
'description' => 'Configure default settings allowing users to mark content with personal flags.',
'file' => 'flag_lists.admin.inc',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items[FLAG_ADMIN_PATH . '/lists/list'] = array(
'title' => 'List',
'page callback' => 'flag_lists_admin_page',
'access callback' => 'user_access',
'access arguments' => array(
'administer flags',
),
'file' => 'flag_lists.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items[FLAG_ADMIN_PATH . '/lists/template'] = array(
'title' => 'New template',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'flag_lists_create_template_form',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer flags',
),
'file' => 'flag_lists.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
if (module_exists('devel_generate')) {
$items['admin/config/development/generate/flag-lists'] = array(
'title' => 'Generate lists',
'description' => 'Generate a given number of lists and listings on site content. Optionally delete existing lists and listings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'flag_lists_generate_lists_form',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer flags',
),
'file' => 'flag_lists.admin.inc',
);
}
$items['flag-lists/add/%'] = array(
'title' => 'Add a list',
'page callback' => 'flag_lists_add',
'page arguments' => array(
2,
),
'access callback' => 'user_access',
'access arguments' => array(
'create flag lists',
),
'file' => 'flag_lists.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
// Callback for adding a new list through JS
$items['flag-lists/add/%/js'] = array(
'title' => 'Add a list',
'page callback' => 'flag_lists_add_js',
'page arguments' => array(
2,
),
'access callback' => 'user_access',
'access arguments' => array(
'create flag lists',
),
'file' => 'flag_lists.admin.inc',
'type' => MENU_CALLBACK,
);
$items['flags/lists/edit/%'] = array(
'title' => 'Edit a list',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'flag_lists_form',
3,
),
'access callback' => 'flag_lists_is_owner',
'access arguments' => array(
2,
3,
),
'file' => 'flag_lists.admin.inc',
'type' => MENU_CALLBACK,
);
$items['flags/lists/delete/%'] = array(
'title' => 'Delete a list',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'flag_lists_delete_confirm',
3,
),
'access callback' => 'flag_lists_is_owner',
'access arguments' => array(
2,
3,
),
'file' => 'flag_lists.admin.inc',
'type' => MENU_CALLBACK,
);
$items[FLAG_ADMIN_PATH . '/flag-lists/rebuild'] = array(
'title' => 'Rebuild all flag lists',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'flag_lists_rebuild_confirm',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer flag lists',
),
'file' => 'flag_lists.admin.inc',
'type' => MENU_CALLBACK,
);
$items['flag-lists'] = array(
'title' => 'Flag',
'page callback' => 'flag_lists_page',
'access callback' => 'user_access',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
$items['user/%user/flags/lists'] = array(
'title' => ucfirst(variable_get('flag_lists_name', 'list')),
'page callback' => 'flag_lists_user_page',
'page arguments' => array(
1,
),
'access callback' => 'user_access',
'access arguments' => array(
'view flag lists',
),
'type' => MENU_LOCAL_TASK,
);
$items['user/%user/flags/lists/%'] = array(
'title' => ucfirst(variable_get('flag_lists_name', 'list')) . ' content',
'page callback' => 'flag_lists_user_list',
'page arguments' => array(
1,
4,
),
'access callback' => 'user_access',
'access arguments' => array(
'view flag lists',
),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* User flag page. Display a list of user-created flag lists.
*/
function flag_lists_user_page($user) {
// Can we use our default view?
if (module_exists('views')) {
$view = views_get_view('flag_lists_user_lists', FALSE);
if (!empty($view)) {
$view
->set_display('default');
$view
->set_arguments(array(
$user->uid,
));
$output = $view
->render();
drupal_set_title(str_replace(array_keys($view->build_info['substitutions']), $view->build_info['substitutions'], $view->build_info['title']));
}
return $output;
}
else {
return theme('flag_lists_user_page', array(
'uid' => $user->uid,
));
}
}
/**
* Theme the output for a user flag administration page.
*/
function theme_flag_lists_user_page($variables) {
$uid = $variables['uid'];
$account = user_load($uid);
drupal_set_title(t('Lists'));
if ($flags = flag_lists_get_user_flags(NULL, $account)) {
// Build the list of flag lists for this node.
foreach ($flags as $flag) {
$ops = theme('flag_lists_ops', array(
'flag' => $flag,
));
$items[] = l($flag->title, "user/{$uid}/flags/lists/" . $flag->fid) . $ops;
}
}
drupal_add_css(drupal_get_path('module', 'flag_lists') . '/theme/flag_lists.css');
return theme('item_list', array(
'items' => $items,
));
}
/**
* List the contents of a user-defined list
*/
function flag_lists_user_list($user, $fid) {
$uid = $user->uid;
// Can we use our default view?
if (module_exists('views')) {
$view = views_get_view('flag_lists_user_list', FALSE);
if (!empty($view)) {
$view
->set_display('default');
$view
->set_arguments(array(
$fid,
));
$output = $view
->render();
drupal_set_title(str_replace(array_keys($view->build_info['substitutions']), $view->build_info['substitutions'], $view->build_info['title']));
}
return $output;
}
else {
return theme('flag_lists_user_list', array(
'uid' => $uid,
'fid' => $fid,
));
}
}
/**
* Theme the output of user-defined list page
*/
function theme_flag_lists_user_list($variables) {
$uid = $variables['uid'];
$fid = $variables['fid'];
$flag = flag_lists_get_flag($fid);
drupal_set_title($flag->title);
$content = flag_lists_get_flagged_content($fid, $uid);
foreach ($content as $item) {
if ($item->content_type == 'node') {
$node = node_load($item->content_id);
$items[] = l($node->title, 'node/' . $node->nid);
}
}
$breadcrumb = menu_get_active_breadcrumb();
$breadcrumb[] = l(t('@name lists', array(
'@name' => drupal_ucfirst(variable_get('flag_lists_name', t('lists'))),
)), 'user/' . arg(1) . '/flags/lists');
drupal_set_breadcrumb($breadcrumb);
return theme('item_list', array(
'items' => $items,
));
}
/**
* Implementation of hook_theme().
*/
function flag_lists_theme() {
$path = drupal_get_path('module', 'flag') . '/theme';
return array(
'flag_lists_list' => array(
'variables' => array(
'node' => NULL,
'create' => NULL,
'ops' => NULL,
'use_flags' => NULL,
),
),
'flag_lists_admin_page' => array(
'variables' => array(
'flags' => NULL,
),
),
'flag_lists_user_page' => array(
'variables' => array(
'uid' => NULL,
),
),
'flag_lists_user_list' => array(
'variables' => array(
'flag_name' => NULL,
),
),
'flag_lists_ops' => array(
'variables' => array(
'flag' => NULL,
),
),
);
}
/**
* Implementation of hook_permission().
*/
function flag_lists_permission() {
return array(
'create flag lists' => array(
'title' => t('Create flag lists'),
'description' => t(''),
),
'edit own flag lists' => array(
'title' => t('Edit own flag lists'),
'description' => t(''),
),
'delete own flag lists' => array(
'title' => t('Delete own flag lists'),
'description' => t(''),
),
'view flag lists' => array(
'title' => t('View flag lists'),
'description' => t(''),
),
);
}
/**
* Implementation of hook_form_alter().
*/
function flag_lists_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'flag_form':
// A template flag should always have a record in the flag_lists_types table.
$result = db_select('flag_lists_types', 'f')
->fields('f')
->execute();
foreach ($result as $type) {
$types[$type->name] = $type->type;
}
if (isset($types[$form['name']['#default_value']])) {
$form['name']['#type'] = 'value';
$form['global']['#type'] = 'value';
$form['title']['#description'] = t('A short, descriptive title for this template. It will be used in administrative interfaces to refer to this template.');
// Warn about types that already have a template.
foreach ($form['access']['types']['#options'] as $option => $value) {
if (in_array($option, $types) && $form['access']['types']['#default_value'] != $option) {
$form['access']['types']['#options'][$option] .= '<span class="description">' . t('(Already has a template.)') . '</span>';
}
}
$form['access']['types']['#description'] .= t('A type may only be selected in one list template.');
// Unset anon permissions for now. @todo allow anon listing.
unset($form['access']['roles']['flag']['#options'][1]);
unset($form['access']['roles']['unflag']['#options'][1]);
foreach (element_children($form['display']) as $display) {
$form['display'][$display]['#type'] = 'value';
}
$form['display']['link_type']['#default_value'] = 'fl_template';
$form['display']['#description'] = t('Unlike normal flags, lists are only displayed in a block provided by this module or in views blocks. See <a href="/admin/build/block/list">the block admin page</a> to place the block.');
$form['#validate'][] = 'flag_lists_template_validate';
$form['#submit'][] = 'flag_lists_template_submit';
}
break;
case 'views_exposed_form':
// Force the exposed filters to perform actions on the page itself because
// the views default viwe didn't come with a page display
if ($form['#id'] == 'views-exposed-form-flag-lists-default') {
$form['#action'] = '/' . implode('/', arg());
}
break;
}
// Flag lists operations related changes
if (strpos($form_id, 'views_form_') === 0) {
$flo = _flag_lists_ops_get_field($form_state['build_info']['args'][0]);
// Not a FLO-enabled views form.
if (empty($flo)) {
return;
}
// Add FLO's custom callbacks.
$form['#validate'][] = 'flag_lists_ops_form_validate';
$form['#submit'][] = 'flag_lists_ops_form_submit';
// Allow FLO to work when embedded using views_embed_view(), or in a block.
if (empty($flo->view->override_path)) {
if (!empty($flo->view->preview) || $flo->view->display_handler instanceof views_plugin_display_block) {
$flo->view->override_path = $_GET['q'];
}
}
// Quickfix for FLO & exposed filters using ajax. See http://drupal.org/node/1191928.
$query = drupal_get_query_parameters($_GET, array(
'q',
));
$form['#action'] = url($flo->view
->get_url(), array(
'query' => $query,
));
// Add basic FLO functionality.
if ($form_state['step'] == 'views_form_views_form') {
$form = flag_lists_ops_form($form, $form_state, $flo);
}
}
}
/**
* Add the Flag list select menu widget.
*/
function flag_lists_ops_form($form, &$form_state, $flo) {
$form['#attached']['js'][] = drupal_get_path('module', 'flag_lists') . '/js/flag_lists_ops.js';
$form['#attached']['css'][] = drupal_get_path('module', 'flag_lists') . '/css/flag_lists_ops.css';
$form['#prefix'] = '<div class="flo-views-form">';
$form['#suffix'] = '</div>';
$form_state['flo_operation'] = $flo->options['flo']['operation'];
// Force browser to reload the page if Back is hit.
if (preg_match('/msie/i', $_SERVER['HTTP_USER_AGENT'])) {
drupal_add_http_header('Cache-Control', 'no-cache');
// works for IE6+
}
else {
drupal_add_http_header('Cache-Control', 'no-store');
// works for Firefox and other browsers
}
global $user;
global $base_url;
$account = user_load($user->uid);
$items = array();
if ($flags = flag_lists_get_user_flags(NULL, $account)) {
// Build the list of flag lists for this node.
foreach ($flags as $flag) {
$items[(string) $flag->fid] = $flag->title;
}
}
// Group items into a fieldset for easier theming.
$form['flag_lists_' . $form_state['flo_operation']] = array(
'#type' => 'fieldset',
'#title' => t('List operations'),
'#tree' => TRUE,
'#attributes' => array(
'class' => array(
'flag-lists-ops-fieldset',
),
),
);
switch ($flo->options['flo']['operation']) {
case 'unflag':
$null_text = 'Remove from a list';
$operation = 'unflag';
$form['flag_lists_' . $form_state['flo_operation']]['list'] = array(
'#type' => 'button',
'#value' => t('Remove from list'),
'#ajax' => array(
'callback' => 'flag_lists_ops_form_ajax_callback',
'wrapper' => 'flag-list-ops-container-' . $flo->options['flo']['operation'],
),
);
break;
default:
$null_text = 'Add to a list';
$operation = 'flag';
drupal_add_library('system', 'ui.dialog');
$form['flag_lists_' . $form_state['flo_operation']]['list'] = array(
'#type' => 'select',
'#options' => array(
'0' => t('- ' . $null_text . ' -'),
) + $items,
'#default_value' => '0',
'#ajax' => array(
'callback' => 'flag_lists_ops_form_ajax_callback',
'wrapper' => 'flag-list-ops-container-' . $flo->options['flo']['operation'],
),
'#attributes' => array(
'class' => array(
'flag-lists-ops-dropdown',
),
),
);
// Add the necessary JS for creating a new list via AJAX
$result = db_select('flag_lists_types')
->fields('flag_lists_types')
->execute();
$list_types = array();
foreach ($result as $row) {
if (!empty($row->type)) {
$list_types[] = $row->type;
}
}
drupal_add_js(array(
'flag_lists' => array(
'types' => $list_types,
'json_path' => $base_url . '/flag-lists/add/%/js',
),
), 'setting');
break;
}
// Get the $ops from the originating form.
if (!empty($form_state['values']['flag_lists_' . $form_state['flo_operation']]['list'])) {
$list = $form_state['values']['flag_lists_' . $form_state['flo_operation']]['list'];
}
if (!empty($_REQUEST['flag_lists_ops'])) {
$ops = $_REQUEST['flag_lists_ops'];
}
if (!empty($ops) && !empty($list) && $form_state['values']['flag_lists_' . $form_state['flo_operation']]['operation'] == 'unflag') {
$hidden_deleted_values = '';
foreach ($ops as $nid) {
$hidden_deleted_values .= '<input type="hidden" class="flo-deleted-value" value="' . $nid . '" />';
}
}
$form['flag_lists_' . $form_state['flo_operation']]['operation'] = array(
'#type' => 'hidden',
'#value' => $operation,
);
$form['flag_lists_' . $form_state['flo_operation']]['go'] = array(
'#type' => 'submit',
'#value' => t('Go'),
'#attributes' => array(
'class' => array(
'flag-lists-ops-go',
),
),
);
unset($form['actions']['submit']);
// Generate a status message for AJAX submission.
$form['flag_lists_' . $form_state['flo_operation']]['status_message'] = array(
'#markup' => '',
);
$form['flag_lists_' . $form_state['flo_operation']]['#prefix'] = '<div id="flag-list-ops-container-' . $flo->options['flo']['operation'] . '">';
$form['flag_lists_' . $form_state['flo_operation']]['#suffix'] = !empty($hidden_deleted_values) ? $hidden_deleted_values : '' . '</div>';
return $form;
}
function flag_lists_ops_form_ajax_callback($form, $form_state) {
// The form has already been submitted and updated. We can return the replaced
// item as it is.
if (!flag_lists_ops_form_validate($form, $form_state)) {
$message = flag_lists_ops_form_submit($form, $form_state);
}
$form['flag_lists_' . $form_state['flo_operation']]['status_message']['#markup'] = '<div class="alert alert-success">' . $message . '</div>';
if ($form_state['flo_operation'] == 'flag') {
$form['flag_lists_' . $form_state['flo_operation']]['list']['#value'] = '0';
}
$form['flag_lists_' . $form_state['flo_operation']]['status_message']['#attributes']['class'][] = 'alert-success';
return $form['flag_lists_' . $form_state['flo_operation']];
}
function flag_lists_ops_form_validate(&$form, &$form_state) {
global $user;
$error_count = 0;
// Check to see if an items are selected, if not fail right away.
if (!isset($_REQUEST['flag_lists_ops']) || empty($_REQUEST['flag_lists_ops'])) {
form_set_error('', t('No content selected.'));
$error_count++;
return $error_count;
}
switch ($form_state['values']['flag_lists_' . $form_state['flo_operation']]['operation']) {
case 'unflag':
$ops = $_REQUEST['flag_lists_ops'];
foreach ($ops as $key => $op) {
$ops[$key] = explode('-', $op);
if (empty($ops[$key][1]) || !($flag = flag_lists_get_flag($ops[$key][1]))) {
form_set_error('flag_lists][remove', t('Invalid options list selected to remove from.'));
$error_count++;
}
else {
if ($flag->uid != $user->uid) {
form_set_error('flag_lists][remove', t('You are only allowed to remove content from your own lists.'));
$error_count++;
}
}
}
break;
default:
if (empty($form_state['values']['flag_lists_' . $form_state['flo_operation']]['list'])) {
form_set_error('flag_lists][list', t('No list selected. Please select a list to add to.'));
$error_count++;
}
else {
if (!($flag = flag_lists_get_flag($form_state['values']['flag_lists_' . $form_state['flo_operation']]['list']))) {
form_set_error('flag_lists][list', t('Invalid list selected. Please select a list to add to.'));
$error_count++;
}
else {
if ($flag->uid != $user->uid) {
form_set_error('flag_lists][list', t('Invalid list selected. Please select a list to add to.'));
$error_count++;
}
}
}
break;
}
return $error_count;
}
function flag_lists_ops_form_submit(&$form, &$form_state) {
// Get the $ops from the originating form.
$ops = $_REQUEST['flag_lists_ops'];
$success_count = 0;
// Get the operation, or set it
switch ($form_state['values']['flag_lists_' . $form_state['flo_operation']]['operation']) {
case 'unflag':
$operation = 'unflag';
$message = 'removed from';
foreach ($ops as $op) {
// Process the ID into 2 parts
list($nid, $fid) = explode('-', $op);
if (empty($nid) || empty($fid)) {
return;
}
if (($flag = flag_lists_get_flag($fid)) && ($node = node_load($nid))) {
if (flag_lists_do_flag($flag, $operation, $nid)) {
$success_count++;
}
}
}
break;
default:
$operation = 'flag';
$message = 'added to';
if ($flag = flag_lists_get_flag($form_state['values']['flag_lists_' . $form_state['flo_operation']]['list'])) {
foreach ($ops as $nid) {
if (flag_lists_do_flag($flag, $operation, $nid)) {
$success_count++;
}
}
}
break;
}
$message = t('@count item(s) ' . $message . ' !title', array(
'@count' => $success_count,
'!title' => $flag->title,
));
if ($_GET['q'] != 'system/ajax') {
drupal_set_message($message);
}
else {
return $message;
}
}
/**
* Gets the FLO field if it exists on the passed-in view.
*
* @return
* The field object if found. Otherwise, FALSE.
*/
function _flag_lists_ops_get_field($view) {
foreach ($view->field as $field_name => $field) {
if ($field instanceof flag_lists_handler_field_ops) {
// Add in the view object for convenience.
$field->view = $view;
return $field;
}
}
return FALSE;
}
function flag_lists_template_validate($form, &$form_state) {
$types = array_filter($form_state['values']['types']);
$errors = array();
foreach ($types as $type) {
$result = db_select('flag_lists_types', 'f')
->fields('f')
->condition('type', $type)
->condition('name', $form_state['values']['name'], '<>')
->execute();
foreach ($result as $errors) {
$content_types[] = $errors->type;
$templates[] = $errors->name;
}
}
if (isset($content_types) && count($content_types)) {
$content_types = implode(', ', $content_types);
$templates = implode(', ', array_unique($templates));
form_set_error('types', t('The flaggable content type(s) "@type" is(are) already assigned to the template(s) "@template." A content type may be assigned to only one template. To reassign a content type you must first remove its other assignment.', array(
'@type' => $content_types,
'@template' => $templates,
)));
}
}
function flag_lists_template_submit($form, &$form_state) {
$types = array_filter($form_state['values']['types']);
// Clean out the old types, then add the new.
$num_deleted = db_delete('flag_lists_types')
->condition('name', $form_state['values']['name'])
->execute();
foreach ($types as $type) {
db_insert('flag_lists_types')
->fields(array(
'name' => $form_state['values']['name'],
'type' => $type,
))
->execute();
}
}
/**
* Helper function to build an array of all lists available to or owned by the
* current user and that are available on the current content type.
*/
function flag_lists_get_content_fids() {
global $user;
// This is a node view. We only care about nodes for now.
if (arg(0) == 'node' && is_numeric(arg(1)) && is_null(arg(2))) {
$type = db_select('node', 'n')
->fields('n', array(
'type',
))
->condition('nid', arg(1))
->execute()
->fetchField();
// Get current user's flags for this node.
$query = db_select('flag_lists', 'fc')
->fields('f', 'fid')
->condition('fc.uid', $user->uid)
->condition('fn.type', $type);
$query
->leftJoin('flag_types', 'fn', 'fn.fid = fc.fid');
$query
->leftJoin('flags', 'f', 'fc.fid = f.fid');
$fc_result = $query
->execute();
foreach ($fc_result as $row) {
$fids[] = $row->fid;
}
}
elseif (arg(0) == 'flag' && (arg(1) == 'flag' || arg(1) == 'unflag')) {
// Get the flag for this request.
$fids[] = db_select('flags', 'f')
->fields('f', array(
'fid',
))
->condition('name', arg(2))
->execute()
->fetchField();
}
// Get the regular flags for this node. The flag module will narrow by role,
// etc. when flag_get_flags() is called. These flag ids are always returned.
$query = db_select('flags', 'f')
->fields('f', array(
'fid',
))
->condition('fc.fid', NULL);
$query
->leftJoin('flag_lists', 'fc', 'fc.fid = f.fid');
$f_result = $query
->execute();
foreach ($f_result as $obj) {
$fids[] = $obj->fid;
}
if (is_array($fids)) {
return array_unique($fids);
}
else {
return array();
}
}
/**
* Implements hook_block_info();
*/
function flag_lists_block_info() {
return array(
'flag_lists' => array(
'info' => t('Lists'),
'cache' => DRUPAL_NO_CACHE,
),
'flag_lists_list' => array(
'info' => t('My lists'),
'cache' => DRUPAL_NO_CACHE,
),
);
}
/**
* Implements hook_block_configure().
*/
function flag_lists_block_configure($delta = '') {
$form = array();
switch ($delta) {
case 'flag_lists':
$form = array(
'create_lists' => array(
'#type' => 'checkbox',
'#title' => t('Show link to add new list'),
'#default_value' => variable_get('flag_lists_create_lists', 0),
'#description' => t('Checking this adds a link to the create new list form.'),
),
'ops' => array(
'#type' => 'checkbox',
'#title' => t('Show edit and delete links'),
'#default_value' => variable_get('flag_lists_ops', 0),
'#description' => t('Checking this appends edit and delete links to each list name for users with access.'),
),
'include_flags' => array(
'#type' => 'checkbox',
'#title' => t('Include flag module flags'),
'#default_value' => variable_get('flag_lists_include_flags', 0),
'#description' => t('Checking this will append flag module flags to the list of lists.'),
),
);
break;
}
return $form;
}
/**
* Implements hook_block_save().
*/
function flag_lists_block_save($delta = '', $edit = array()) {
switch ($delta) {
case 'flag_lists':
variable_set('flag_lists_create_lists', $edit['create_lists']);
variable_set('flag_lists_ops', $edit['ops']);
variable_set('flag_lists_include_flags', $edit['include_flags']);
break;
}
}
/**
* Implements hook_block_view().
*/
function flag_lists_block_view($delta = '') {
$block = array();
switch ($delta) {
case 'flag_lists':
if (user_access('create flag lists')) {
$block = array(
'subject' => t('My lists'),
'content' => theme('flag_lists_list', array(
'node' => NULL,
'create' => variable_get('flag_lists_create_lists', 0),
'ops' => variable_get('flag_lists_ops', 0),
'use_flags' => variable_get('flag_lists_include_flags', 0),
)),
);
}
break;
case 'flag_lists_list':
if (user_access('create flag lists')) {
global $user;
$account = user_load($user->uid);
$block = array(
'subject' => t('My lists'),
'content' => flag_lists_user_page($account),
);
}
break;
}
return !empty($block['content']) ? $block : array();
}
/**
* Implementation of hook_user_delete().
*/
function flag_lists_user_delete($account) {
// Remove personal flags by this user.
$num_deleted = db_delete('flag_lists_flags')
->condition('uid', $account->uid)
->execute();
}
/**
* Build a flag's messages.
*/
function flag_lists_set_messages(&$flag) {
// Get the parent flag. These are cached by the flag module.
$pflag = flag_get_flag(NULL, $flag->pfid);
$title = $flag->title;
$lists_name = variable_get('flag_lists_name', t('list'));
$flag->flag_short = $pflag->flag_short;
$flag->flag_long = $pflag->flag_long;
$flag->flag_message = $pflag->flag_message;
$flag->unflag_short = $pflag->unflag_short;
$flag->unflag_long = $pflag->unflag_long;
$flag->unflag_message = $pflag->unflag_message;
}
/**
* Implementation of hook_flag_access().
*
* Make sure a user can only see his/her own personal flags.
*/
function flag_lists_flag_access($flag, $content_id, $action, $account) {
if (!empty($flag->module) && $flag->module == 'flag_lists') {
switch ($action) {
case 'flag':
case 'unflag':
$fid = db_select('flag_lists_flags', 'f')
->fields('f')
->condition('f.uid', $account->uid)
->execute()
->fetchField();
if (!empty($fid)) {
return array(
'flag_lists' => TRUE,
);
}
else {
return array(
'flag_lists' => FALSE,
);
}
}
}
}
/**
* Implementation of hook_link().
*/
// There may be a better way to keep flag lists out of the links, but this
// works for now. @todo Find a better way to keep flags lists out of links.
function flag_lists_link_alter(&$links, $node) {
if (!variable_get('flag_lists_use_links', 1)) {
foreach ($links as $name => $link) {
if (stristr($name, 'flag-fl_')) {
unset($links[$name]);
}
}
}
}
/**
* Implementation of hook_flag_alter().
*/
function flag_lists_flag_alter(&$flag) {
}
/**
* Implementation of hook_flag_delete().
*
* This is not in flag yet.
*/
function flag_lists_flag_delete($flag) {
// Template flag is being deleted. Clean up our tables.
// Collect the sub-flag fids so we can delete counts and content records.
$results = db_select('flag_lists_flags', 'f')
->fields('f', array(
'fid',
'name',
))
->condition('pfid', $flag->fid)
->execute();
foreach ($results as $fid) {
db_delete('flag_lists_counts')
->condition('fid', $flag->fid)
->execute();
db_delete('flag_lists_content')
->condition('fid', $flag->fid)
->execute();
}
// flag_lists_types uses the template flag name, not our own fid.
db_delete('flag_lists_types')
->condition('name', $flag->name)
->execute();
// Now delete the sub-flags.
$num_deleted = db_delete('flag_lists_flags')
->condition('pfid', $flag->fid)
->execute();
if (!empty($num_deleted)) {
drupal_set_message(t('The template flag "@title" and all its sub-flags have been deleted.', array(
'@title' => $flag->title,
)));
}
}
/**
* Implementation of hook_views_api().
*/
function flag_lists_views_api() {
return array(
'api' => 2.0,
'path' => drupal_get_path('module', 'flag_lists') . '/includes',
);
}
/**
* Helper function to test if a flag is owned by the current user, or current
* user can administer flags.
*/
function flag_lists_is_owner($action, $name) {
global $user;
if (user_access('administer flags')) {
return TRUE;
}
// If we don't have an fid, then we have the flag name.
if (is_numeric($name)) {
$query = db_select('flag_lists_flags', 'f')
->condition('fid', $name);
$query
->addField('f', 'name');
$name = $query
->execute()
->fetchField();
}
if (!user_access($action . ' own flag lists')) {
return FALSE;
}
if (db_select('flag_lists_flags', 'f')
->fields('f')
->condition('f.name', $name)
->condition('f.uid', $user->uid)
->countQuery()
->execute()
->fetchField()) {
return TRUE;
}
return FALSE;
}
/**
* Get a single user's lists, and merge in flag module flags
*/
function flag_lists_get_user_flags($content_type = NULL, $account = NULL, $use_flags = FALSE) {
$flags = array();
$lists = array();
if (!isset($account)) {
$account = $GLOBALS['user'];
}
// Get flag lists flags
$query = db_select('flag_lists_flags', 'fl')
->fields('fl')
->condition('fl.uid', $account->uid);
$query
->leftJoin('flags', 'f', 'fl.pfid = f.fid');
$query
->leftJoin('flag_lists_types', 'ft', 'ft.name = f.name');
$query
->addField('ft', 'type');
if ($content_type) {
$query
->condition('ft.type', $content_type);
}
$result = $query
->execute();
foreach ($result as $row) {
if (!isset($lists[$row->name])) {
$lists[$row->name] = flag_flag::factory_by_row($row);
$lists[$row->name]->module = 'flag_lists';
}
else {
$lists[$row->name]->types[] = $row->type;
}
}
// Get regular flags.
if ($use_flags) {
$flags = flag_get_flags('node', $content_type, $account);
// Strip out any list templates
foreach ($flags as $key => $flag) {
if (stristr($flag->name, 'fl_template') !== FALSE) {
unset($flags[$key]);
}
}
}
$flags = array_merge($lists, $flags);
return $flags;
}
/**
* Theme function to return edit, delete links.
*
* @param $flag
* The flag whose links are being built.
*/
function theme_flag_lists_ops($variables) {
$flag = $variables['flag'];
$links = array(
'flags_edit' => array(
'title' => t('edit'),
'href' => 'flags/lists/edit/' . $flag->name,
'query' => drupal_get_destination(),
),
'flags_delete' => array(
'title' => t('delete'),
'href' => 'flags/lists/delete/' . $flag->name,
'query' => drupal_get_destination(),
),
);
return theme('links', array(
'links' => $links,
'attributes' => array(
'class' => 'flag_lists_ops',
),
));
}
/**
* Theme a list of lists
*
* @param $node
* The listable node
* @param boolean $create
* Show the create list form.
* @param boolean $ops
* Show the edit / delete links for lists
* @param boolean $use_flags
* Show flags from the flag module
* @return <type>
*/
// @todo Separate out the code from the theming better.
function theme_flag_lists_list($variables) {
$node = $variables['node'];
$create = $variables['create'];
$ops = $variables['ops'];
$use_flags = $variables['use_flags'];
$items = array();
// Make sure we have a node.
if (is_object($node) && user_access('create flag lists')) {
$content_type = $node->type;
$content_id = $node->nid;
}
elseif (arg(0) == 'node' && is_numeric(arg(1)) && user_access('create flag lists')) {
$content_id = arg(1);
$query = db_select('node')
->condition('nid', $content_id);
$query
->addField('node', 'type');
$content_type = $query
->execute()
->fetchField();
}
else {
return;
}
// Do we have a list template for this node type, or are we s
if (!flag_lists_template_exists($content_type) && !$use_flags) {
return;
}
global $user;
if ($flags = flag_lists_get_user_flags($content_type, $user, $use_flags)) {
// Build the list of lists for this node.
foreach ($flags as $flag) {
if ($flag->module == 'flag_lists') {
$action = _flag_lists_is_flagged($flag, $content_id, $user->uid, 0) ? 'unflag' : 'flag';
}
else {
$action = $flag
->is_flagged($content_id) ? 'unflag' : 'flag';
}
// Do we need the ops?
if ($ops && $flag->module == 'flag_lists') {
$ops_links = theme('flag_lists_ops', array(
'flag' => $flag,
));
$link = $flag
->theme($action, $content_id) . $ops_links;
}
else {
$link = $flag
->theme($action, $content_id);
}
// If it's a list, fix the link.
if ($flag->module == 'flag_lists') {
flag_lists_fix_link($link, $action);
}
$items[] = $link;
}
}
if ($create && flag_lists_template_exists($content_type)) {
$items[] = l(t('Make a new @name', array(
'@name' => variable_get('flag_lists_name', t('list')),
)), 'flag-lists/add/' . $content_type, array(
'query' => drupal_get_destination(),
));
}
// Return if nothing to display.
if (empty($items) || !count($items)) {
return;
}
drupal_add_css(drupal_get_path('module', 'flag_lists') . '/theme/flag_lists.css');
return theme('item_list', array(
'items' => $items,
'type' => 'ul',
'attributes' => array(
'class' => 'flag-lists-links',
),
));
}
// Do we still need this, and/or do we need our own cache?
/**
* Clear the flag cache.
*
* This is a less severe cache clear than provided by flag. All flag lists
* users must be authorized, so we don't need to flush the page cache. For now,
* flag lists titles won't be in the menu, so no need to clear that.
*/
function _flag_lists_clear_cache() {
// We're not using _flag_clear_cache because we probably don't need the menu
// rebuild and don't need to clear the page cache.
if (module_exists('views')) {
views_invalidate_cache();
}
}
/**
* Update ALL flag lists with settings form values.
*/
function flag_lists_rebuild() {
$flags = flag_lists_get_flags();
foreach ($flags as $flag) {
flag_lists_set_messages($flag);
$flag->link_type = 'toggle';
flag_lists_save($flag);
}
}
/**
* Build array of all flag lists.
*
* @return If limit and header arguments are provided, the paged flags, otherwise
* an array of all flags.
*/
function flag_lists_get_flags($limit = NULL, $header = NULL) {
$flags = array();
if ($limit) {
$query = db_select('flag_lists_flags', 'fl')
->fields('fl')
->groupBy('fl.fid')
->extend('PagerDefault')
->limit($limit);
$query
->leftJoin('flag_types', 'ft', 'ft.fid = fl.pfid');
$query
->addExpression('GROUP_CONCAT(ft.type)', 'types');
$result = $query
->execute();
}
else {
$query = db_select('flag_lists_flags', 'fl')
->fields('fl')
->groupBy('fl.fid');
$query
->leftJoin('flag_types', 'ft', 'ft.fid = fl.pfid');
$query
->addExpression('GROUP_CONCAT(ft.type)', 'types');
$result = $query
->execute();
}
foreach ($result as $row) {
$flags[$row->name] = flag_flag::factory_by_row($row);
$flags[$row->name]->types = explode(',', $row->types);
$flags[$row->name]->uid = $row->uid;
}
return $flags;
}
/**
* Get a specific flag.
*
* Using this instead of flag_get_flag() for performance.
*/
function flag_lists_get_flag($fid) {
// If we don't have an fid, then we have the flag name.
if (!is_numeric($fid)) {
$query = db_select('flag_lists_flags')
->condition('name', $fid);
$query
->addField('flag_lists_flags', 'fid');
$fid = $query
->execute()
->fetchField();
}
$query = db_select('flag_lists_flags', 'fl')
->fields('fl')
->condition('fl.fid', $fid);
$query
->leftJoin('flag_types', 'ft', 'ft.fid = fl.pfid');
$query
->addField('ft', 'type');
$result = $query
->execute();
foreach ($result as $row) {
if (!isset($flag->name)) {
$flag = flag_flag::factory_by_row($row);
}
else {
$flag->types[] = $row->type;
}
}
return $flag;
}
/**
* Get all flagged content in a flag.
*
* Using this instead of flag_get_flagged_content() because we need to make sure that we use flag_lists_get_flags()
*
* @param
* The flag name for which to retrieve flagged content.
*/
function flag_lists_get_flagged_content($fid, $uid) {
$return = array();
$flag = flag_lists_get_flag($fid);
$result = db_select('flag_lists_content', 'f')
->fields('f')
->condition('f.fid', $flag->fid)
->condition('f.uid', $uid)
->execute();
foreach ($result as $row) {
$return[] = $row;
}
return $return;
}
/**
* Implementation of hook_flag_link().
*
* When Flag uses a link type provided by this module, it will call this
* implementation of hook_flag_link(). It returns a single link's attributes,
* using the same structure as hook_link(). Note that "title" is provided by
* the Flag configuration if not specified here.
*
* @param $flag
* The full flag object of for the flag link being generated.
* @param $action
* The action this link will perform. Either 'flag' or 'unflag'.
* @param $content_id
* The ID of the node, comment, user, or other object being flagged.
* @return
* An array defining properties of the link.
*/
function flag_lists_flag_link($flag, $action, $content_id) {
return array();
}
/**
* Implementation of hook_flag_link_types().
*/
function flag_lists_flag_link_types() {
return array(
'fl_template' => array(
'title' => t('Flag Lists toggle'),
'description' => t('If you are creating a Flag lists template flag, you must select this link type.'),
),
);
}
function flag_lists_flag_default_flags($name = 'fl_template') {
return array(
array(
'api_version' => 2,
'name' => $name,
'module' => 'flag_lists',
'content_type' => 'node',
'global' => 0,
'show_on_page' => 0,
'show_on_teaser' => 0,
'show_on_form' => 0,
// The following UI labels aren't wrapped in t() because they are written
// to the DB in English. They are passed to t() later, thus allowing for
// multilingual sites.
'title' => 'Flag lists template',
'flag_short' => 'Add to your [flag_lists:title] [flag_lists:term]',
'flag_long' => 'Add this post to your [flag_lists:title] [flag_lists:term]',
'flag_message' => 'This post has been added to your [flag_lists:title] [flag_lists:term]',
'unflag_short' => 'Remove this from your [flag_lists:title] [flag_lists:term]',
'unflag_long' => 'Remove this post from your [flag_lists:title] [flag_lists:term]',
'unflag_message' => 'This post has been removed from your [flag_lists:title] [flag_lists:term]',
'types' => array(),
'link_type' => 'toggle',
),
);
}
/**
* Saves a flag to the database. It is a wrapper around update($flag) and insert($flag).
*/
function flag_lists_save(&$flag, $account = NULL) {
if (!isset($account)) {
$account = $GLOBALS['user'];
}
if (isset($flag->fid)) {
flag_lists_update($flag);
$flag->is_new = FALSE;
module_invoke_all('flag_lists', $flag, $account);
}
else {
flag_lists_insert($flag);
$flag->is_new = TRUE;
module_invoke_all('flag_lists', $flag, $account);
}
// Clear the page cache for anonymous users.
// cache_clear_all('*', 'cache_page', TRUE);
}
/**
* Saves an existing flag to the database. Better use save($flag).
*/
function flag_lists_update($flag) {
$num_updated = db_update('flag_lists_flags')
->fields(array(
'title' => $flag->title,
'name' => $flag->name,
'options' => $flag
->get_serialized_options($flag),
))
->condition('fid', $flag->fid)
->execute();
}
/**
* Saves a new flag to the database. Better use save($flag).
*/
function flag_lists_insert($flag) {
$flag->fid = db_insert('flag_lists_flags')
->fields(array(
'pfid' => $flag->pfid,
'uid' => $flag->uid,
'content_type' => $flag->content_type,
'name' => $flag->name,
'title' => $flag->title,
'options' => $flag
->get_serialized_options($flag),
))
->execute();
$flag->name = 'flag_lists_' . $flag->uid . '_' . $flag->fid;
flag_lists_update($flag);
}
/**
* Delete a flag_lists flag.
*
*/
function flag_lists_fl_delete($flag, $account = NULL) {
if (!isset($account)) {
$account = $GLOBALS['user'];
}
db_delete('flag_lists_counts')
->condition('fid', $flag->fid)
->execute();
db_delete('flag_lists_content')
->condition('fid', $flag->fid)
->execute();
db_delete('flag_lists_flags')
->condition('fid', $flag->fid)
->execute();
$flag->is_deleted = TRUE;
module_invoke_all('flag_lists', $flag, $account);
_flag_lists_clear_cache();
drupal_set_message(t('The @name @title has been deleted.', array(
'@name' => variable_get('flag_lists_name', t('list')),
'@title' => $flag->title,
)));
}
/**
* Menu callback for (un)flagging a node.
*
* Used both for the regular callback as well as the JS version. We use this
* instead of the flag module's because our flags are not in the flags table.
*/
function flag_lists_page($action = NULL, $flag_name = NULL, $content_id = NULL) {
global $user;
// Shorten up the variables that affect the behavior of this page.
$js = isset($_REQUEST['js']);
$token = $_REQUEST['token'];
// Specifically $_GET to avoid getting the $_COOKIE variable by the same key.
$has_js = isset($_GET['has_js']);
// Check the flag token, then perform the flagging.
if (!flag_check_token($token, $content_id)) {
$error = t('Bad token. You seem to have followed an invalid link.');
}
elseif ($user->uid == 0 && !$has_js) {
$error = t('You must have JavaScript and cookies enabled in your browser to flag content.');
}
else {
if (empty($flag_name) || !($flag = flag_lists_get_flag($flag_name))) {
// Flag does not exist.
$error = t('You are not allowed to flag, or unflag, this content.');
}
// Identify it as ours.
$flag->module = 'flag_lists';
flag_lists_do_flag($flag, $action, $content_id);
}
// If an error was received, set a message and exit.
if (isset($error)) {
if ($js) {
drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8');
print drupal_to_js(array(
'status' => FALSE,
'errorMessage' => $error,
));
exit;
}
else {
drupal_set_message($error);
drupal_access_denied();
return;
}
}
// If successful, return data according to the request type.
if ($js) {
drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8');
// $flag = flag_lists_get_flag($flag_name);
// $flag->link_type = 'toggle';
$sid = flag_get_sid($user->uid);
$new_action = _flag_lists_is_flagged($flag, $content_id, $user->uid, $sid) ? 'unflag' : 'flag';
$new_link = $flag
->theme($new_action, $content_id, TRUE);
flag_lists_fix_link($new_link, $new_action);
drupal_json_output(array(
'status' => TRUE,
'newLink' => $new_link,
// Further information for the benefit of custom JavaScript event handlers:
'contentId' => $content_id,
'contentType' => $flag->content_type,
'flagName' => $flag->name,
'flagStatus' => $action,
));
exit;
}
else {
$flag = flag_lists_get_flag($flag->fid);
drupal_set_message($flag
->get_label($action . '_message', $content_id));
drupal_goto();
}
}
function flag_lists_fix_link(&$link, $action) {
// This is a hack to let us use our own flag/unflag callbacks without having
// to override $flag->theme and creating our own flag_link type.
$link = str_replace('/flag/' . $action . '/', '/flag-lists/' . $action . '/', $link);
}
/**
* Flags, or unflags, an item.
*
* @param $action
* Either 'flag' or 'unflag'.
* @param $content_id
* The ID of the item to flag or unflag.
* @param $account
* The user on whose behalf to flag. Leave empty for the current user.
* @param $skip_permission_check
* Flag the item even if the $account user doesn't have permission to do so.
* @return
* FALSE if some error occured (e.g., user has no permission, flag isn't
* applicable to the item, etc.), TRUE otherwise.
*/
function flag_lists_do_flag($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 (!$flag
->access($content_id, $action, $account)) {
// User has no permission to flag/unflag this object.
return FALSE;
}
}
else {
// We are skipping permission checks. However, at a minimum we must make
// sure the flag applies to this content type:
if (!$flag
->applies_to_content_id($content_id)) {
return FALSE;
}
}
// Clear various caches; We don't want code running after us to report
// wrong counts or false flaggings.
// flag_get_counts(NULL, NULL, TRUE);
// flag_get_user_flags(NULL, NULL, NULL, NULL, TRUE);
// Find out which user id to use.
$uid = $flag->global ? 0 : $account->uid;
$sid = flag_get_sid($uid);
// Anonymous users must always have a session id.
if ($sid == 0 && $account->uid == 0) {
return FALSE;
}
// Perform the flagging or unflagging of this flag. We invoke hook_flag here
// because we do our own flagging.
$flagged = _flag_lists_is_flagged($flag, $content_id, $uid, $sid);
if ($action == 'unflag') {
if ($flagged) {
$fcid = _flag_lists_unflag($flag, $content_id, $uid, $sid);
module_invoke_all('flag', 'unflag', $flag, $content_id, $account, $fcid);
}
}
elseif ($action == 'flag') {
if (!$flagged) {
$fcid = _flag_lists_flag($flag, $content_id, $uid, $sid);
module_invoke_all('flag', 'flag', $flag, $content_id, $account, $fcid);
}
}
return TRUE;
}
/**
* Returns TRUE if a certain user has flagged this content.
*
*
* This method is similar to is_flagged() except that it does direct SQL and
* doesn't do caching. Use it when you want to not affect the cache, or to
* bypass it.
*
*/
function _flag_lists_is_flagged($flag, $content_id, $uid, $sid) {
$query = db_select('flag_lists_content')
->condition('fid', $flag->fid)
->condition('uid', $uid)
->condition('sid', $sid)
->condition('content_id', $content_id);
$query
->addField('flag_lists_content', 'fid');
return $query
->execute()
->fetchField();
}
/**
* A low-level method to flag content.
*
* You probably shouldn't call this raw private method: call the
* flag_lists_do_flag() function instead.
*
*/
function _flag_lists_flag($flag, $content_id, $uid, $sid) {
$fcid = db_insert('flag_lists_content')
->fields(array(
'fid' => $flag->fid,
'content_type' => $flag->content_type,
'content_id' => $content_id,
'uid' => $uid,
'sid' => $sid,
'timestamp' => REQUEST_TIME,
))
->execute();
_flag_lists_update_count($flag, $content_id);
return $fcid;
}
/**
* A low-level method to unflag content.
*
* You probably shouldn't call this raw private method: call the
* flag_lists_do_flag() function instead.
*
*/
function _flag_lists_unflag($flag, $content_id, $uid, $sid) {
$query = db_select('flag_lists_content')
->condition('fid', $flag->fid)
->condition('content_id', $content_id)
->condition('uid', $uid)
->condition('sid', $sid);
$query
->addField('flag_lists_content', 'fcid');
$fcid = $query
->execute()
->fetchField();
if ($fcid) {
db_delete('flag_lists_content')
->condition('fcid', $fcid)
->execute();
_flag_lists_update_count($flag, $content_id);
}
return $fcid;
}
/**
* Updates the flag count for this content
*/
function _flag_lists_update_count($flag, $content_id) {
$count = db_select('flag_lists_content', 'f')
->fields('f')
->condition('fid', $flag->fid)
->condition('content_id', $content_id)
->countQuery()
->execute()
->fetchField();
if (empty($count)) {
$num_deleted = db_delete('flag_lists_counts')
->condition('fid', $flag->fid)
->condition('content_id', $content_id)
->execute();
}
else {
$num_updated = db_update('flag_lists_counts')
->fields(array(
'count' => $count,
))
->condition('fid', $flag->fid)
->condition('content_id', $content_id)
->execute();
if (empty($num_updated)) {
db_insert('flag_lists_counts')
->fields(array(
'fid' => $flag->fid,
'content_type' => $flag->content_type,
'content_id' => $content_id,
'count' => $count,
))
->execute();
}
}
}
/**
* Checks for a list template for a content type.
*/
function flag_lists_template_exists($type) {
$query = db_select('flag_lists_types')
->condition('type', $type);
$query
->addField('flag_lists_types', 'type');
$exists = $query
->execute()
->fetchField();
if (!empty($exists)) {
return TRUE;
}
return FALSE;
}
/**
* Checks for a list title by node type.
*/
function flag_lists_title_exists($title, $type) {
return db_query("SELECT COUNT(flf.fid) FROM {flag_lists_flags} flf LEFT JOIN {flag_types} ft ON flf.pfid=ft.fid WHERE flf.title=:title AND ft.type=:type AND flf.uid=:uid", array(
':title' => $title,
':type' => $type,
':uid' => $GLOBALS['user']->uid,
))
->fetchField();
}
/**
* Get a list of template flag names.
*/
function flag_lists_get_templates() {
$templates = array();
$result = db_select('flag_lists_types', 'f')
->fields('f', array(
'name',
))
->distinct()
->execute();
foreach ($result as $obj) {
$templates[] = flag_get_flag($obj->name);
}
return $templates;
}
/**
* Implements hook_token_info().
*/
function flag_lists_token_info() {
$type = array(
'name' => t('Flag lists'),
'description' => t('Tokens related to flag lists.'),
'needs-data' => 'flag_lists',
);
$flag_lists['term'] = array(
'name' => t("Term"),
'description' => t("The terminology used to name the lists, such as list, wishlist, favorites, etc."),
);
$flag_lists['title'] = array(
'name' => t("Title"),
'description' => t("The title of the list."),
);
return array(
'types' => array(
'flag_lists' => $type,
),
'tokens' => array(
'flag_lists' => $flag_lists,
),
);
}
/**
* Implements hook_tokens().
*/
function flag_lists_tokens($type, $tokens, array $data = array(), array $options = array()) {
$sanitize = !empty($options['sanitize']);
$replacements = array();
if ($type == 'flag_lists' && !empty($data['flag_lists'])) {
$flag_list = $data['flag_lists'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'title':
$replacements[$original] = $sanitize ? check_plain($flag_list->title) : $flag_lists->title;
break;
case 'term':
$replacements[$original] = $sanitize ? check_plain(variable_get('flag_lists_name', t('list'))) : variable_get('flag_lists_name', t('list'));
break;
}
}
}
return $replacements;
}
/**
* Preprocess link title and text for the flag.tpl.php
*
* This seems to be the only place to do this
*/
function flag_lists_preprocess_flag(&$variables) {
if (module_exists('token') && !empty($variables['flag']->module) && $variables['flag']->module == 'flag_lists') {
if (!empty($variables['link_text'])) {
$variables['link_text'] = token_replace($variables['link_text'], array(
'flag_lists' => $variables['flag'],
));
}
if (!empty($variables['link_title'])) {
$variables['link_title'] = token_replace($variables['link_title'], array(
'flag_lists' => $variables['flag'],
));
}
if (!empty($variables['message_text'])) {
$variables['message_text'] = token_replace($variables['message_text'], array(
'flag_lists' => $variables['flag'],
));
}
}
}
/**
* Implements hook_views_form_substitutions().
*/
function flag_lists_views_form_substitutions() {
// Views check_plains the column label, so Flag lists needs to do the same
// in order for the replace operation to succeed.
$select_all_placeholder = check_plain('<!--flag-lists-ops-select-all-->');
$select_all = array(
'#type' => 'checkbox',
'#default_value' => FALSE,
'#attributes' => array(
'class' => array(
'flo-table-select-all',
),
),
);
return array(
$select_all_placeholder => drupal_render($select_all),
);
}
Functions
Name | Description |
---|---|
flag_lists_block_configure | Implements hook_block_configure(). |
flag_lists_block_info | Implements hook_block_info(); |
flag_lists_block_save | Implements hook_block_save(). |
flag_lists_block_view | Implements hook_block_view(). |
flag_lists_do_flag | Flags, or unflags, an item. |
flag_lists_fix_link | |
flag_lists_flag_access | Implementation of hook_flag_access(). |
flag_lists_flag_alter | Implementation of hook_flag_alter(). |
flag_lists_flag_default_flags | |
flag_lists_flag_delete | Implementation of hook_flag_delete(). |
flag_lists_flag_link | Implementation of hook_flag_link(). |
flag_lists_flag_link_types | Implementation of hook_flag_link_types(). |
flag_lists_fl_delete | Delete a flag_lists flag. |
flag_lists_form_alter | Implementation of hook_form_alter(). |
flag_lists_get_content_fids | Helper function to build an array of all lists available to or owned by the current user and that are available on the current content type. |
flag_lists_get_flag | Get a specific flag. |
flag_lists_get_flagged_content | Get all flagged content in a flag. |
flag_lists_get_flags | Build array of all flag lists. |
flag_lists_get_templates | Get a list of template flag names. |
flag_lists_get_user_flags | Get a single user's lists, and merge in flag module flags |
flag_lists_insert | Saves a new flag to the database. Better use save($flag). |
flag_lists_is_owner | Helper function to test if a flag is owned by the current user, or current user can administer flags. |
flag_lists_link_alter | |
flag_lists_menu | Implementation of hook_menu(). |
flag_lists_ops_form | Add the Flag list select menu widget. |
flag_lists_ops_form_ajax_callback | |
flag_lists_ops_form_submit | |
flag_lists_ops_form_validate | |
flag_lists_page | Menu callback for (un)flagging a node. |
flag_lists_permission | Implementation of hook_permission(). |
flag_lists_preprocess_flag | Preprocess link title and text for the flag.tpl.php |
flag_lists_rebuild | Update ALL flag lists with settings form values. |
flag_lists_save | Saves a flag to the database. It is a wrapper around update($flag) and insert($flag). |
flag_lists_set_messages | Build a flag's messages. |
flag_lists_template_exists | Checks for a list template for a content type. |
flag_lists_template_submit | |
flag_lists_template_validate | |
flag_lists_theme | Implementation of hook_theme(). |
flag_lists_title_exists | Checks for a list title by node type. |
flag_lists_tokens | Implements hook_tokens(). |
flag_lists_token_info | Implements hook_token_info(). |
flag_lists_update | Saves an existing flag to the database. Better use save($flag). |
flag_lists_user_delete | Implementation of hook_user_delete(). |
flag_lists_user_list | List the contents of a user-defined list |
flag_lists_user_page | User flag page. Display a list of user-created flag lists. |
flag_lists_views_api | Implementation of hook_views_api(). |
flag_lists_views_form_substitutions | Implements hook_views_form_substitutions(). |
theme_flag_lists_list | |
theme_flag_lists_ops | Theme function to return edit, delete links. |
theme_flag_lists_user_list | Theme the output of user-defined list page |
theme_flag_lists_user_page | Theme the output for a user flag administration page. |
_flag_lists_clear_cache | Clear the flag cache. |
_flag_lists_flag | A low-level method to flag content. |
_flag_lists_is_flagged | Returns TRUE if a certain user has flagged this content. |
_flag_lists_ops_get_field | Gets the FLO field if it exists on the passed-in view. |
_flag_lists_unflag | A low-level method to unflag content. |
_flag_lists_update_count | Updates the flag count for this content |