You are here

favorites.module in Favorites 6

Same filename and directory in other branches
  1. 8.2 favorites.module
  2. 7.2 favorites.module
  3. 7 favorites.module

The favorites module allows users to bookmark any path within a site.

File

favorites.module
View source
<?php

/**
 * @file
 * The favorites module allows users to bookmark any path within a site.
 */

/**
 * Implements hook_perm().
 */
function favorites_perm() {
  return array(
    'manage own favorites',
  );

  // this is not implemented yet: , 'manage all favorites');
}

/**
 * Implements hook_menu().
 */
function favorites_menu() {
  $items['favorites/remove/%favorite'] = array(
    'page callback' => 'favorites_remove_favorite',
    'page arguments' => array(
      2,
    ),
    'access arguments' => array(
      'manage own favorites',
    ),
    'title' => 'Remove Favorite',
    'type' => MENU_CALLBACK,
  );
  $items['favorites/js/add'] = array(
    'page callback' => 'favorites_add_favorite_js',
    'access arguments' => array(
      'manage own favorites',
    ),
    'title' => 'Add favorite via js',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Helper function to load a favorite.
 *
 * @param int $fid
 *   The DB ID of the favorite
 *
 * @return object
 *   The DB row from the favorites table.
 */
function favorite_load($fid) {
  return db_fetch_object(db_query("SELECT * FROM {favorites} WHERE fid = %d", $fid));
}

/**
 * Implements hook_theme().
 */
function favorites_theme() {
  return array(
    'favorites' => array(
      'arguments' => array(
        'favorites' => array(),
      ),
    ),
  );
}

/**
 * Deletes a favorite.
 */
function favorites_remove_favorite($favorite) {
  global $user;
  $access = user_access('manage own favorites') && $user->uid == $favorite->uid;

  // no admin page implemented yet! || user_access('manage all favorites');
  if ($access && drupal_valid_token($_GET['token'], $favorite->timestamp . $favorite->uid . $favorite->path)) {
    db_query("DELETE FROM {favorites} WHERE fid = %d", $favorite->fid);
    if ($_GET['js'] == 1) {
      drupal_json(array(
        'list' => favorites_list(),
      ));
      return;
    }
  }
  else {
    drupal_set_message(t('You do not have permission to remove this favorite.'), 'error');
  }

  // Unless this is an AJAX request, the query string contains the redirection page.
  if (!$_GET['js']) {
    drupal_goto();
  }
}

/**
 * Implements hook_block().
 */
function favorites_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      $blocks[0]['info'] = t('User Favorites block');
      $blocks[0]['cache'] = BLOCK_NO_CACHE;
      return $blocks;
    case 'view':
      if ($delta == 0 && user_access('manage own favorites')) {

        // Add Ajax support.
        drupal_add_js(drupal_get_path('module', 'favorites') . '/favorites.js');

        // Create the block content.
        $output = '<div id="favorites-list">' . favorites_list() . '</div>' . drupal_get_form('favorites_add_favorite_form');
        $block = array(
          'subject' => t('My Favorites'),
          'content' => $output,
        );
        return $block;
      }
      break;
  }
}

/**
 * Generate the "My Favorites" list.
 */
function favorites_list() {
  global $user;
  $favorites = favorites_load_favorites($user->uid);
  return theme('favorites', $favorites);
}

/**
 * Theme callback.
 *
 * Return a themed item list of favorites with title, link and link to delete.
 */
function theme_favorites($favorites = array()) {
  $items = array();
  $destination = explode('=', drupal_get_destination(), 2);
  foreach ($favorites as $favorite) {
    $items[] = l($favorite->title, $favorite->path, array(
      'query' => $favorite->query,
    )) . ' ' . l('x', 'favorites/remove/' . $favorite->fid, array(
      'query' => array(
        'token' => $favorite->token,
        'destination' => $destination[1],
      ),
      'attributes' => array(
        'class' => 'favorites-remove',
        'title' => t('delete this item'),
      ),
    ));
  }
  return theme('item_list', $items);
}

/**
 * Add a favorite.
 */
function favorites_add_favorite($values) {
  global $user;
  if (empty($user->uid)) {
    return;
  }
  $now = time();

  // Normalize the path to the drupal internal path.
  // This helps in case the path alias changes or will be removed.
  $values['path'] = drupal_get_normal_path($values['path']);

  // Delete an existing entry with the same link to avoid duplicates.
  db_query("DELETE FROM {favorites} WHERE uid = %d AND path = '%s' AND query = '%s'", $user->uid, $values['path'], $values['query']);
  db_query("INSERT INTO {favorites} (uid, path, query, title, timestamp) VALUES (%d, '%s', '%s', '%s', %d)", $user->uid, $values['path'], $values['query'], $values['title'], $now);
}

/**
 * Form callback for the "add favorite form"
 *
 * @see favorites_user_block()
 */
function favorites_add_favorite_form() {
  global $user;

  // Try to get a default value for the title field.
  // drupal_get_title() has run through check_plain. This is useless for us
  // and needs to fixed, which only works easily with PHP >= 5.1.
  if (function_exists('version_compare') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
    $title = htmlspecialchars_decode(drupal_get_title());
  }
  if (!isset($title)) {
    $title = menu_get_active_title();
  }
  if ($title == '') {
    $title = variable_get('site_name', 'Home');
  }
  $title = strip_tags($title);
  $path = strip_tags($_GET['q']);
  $query = drupal_query_string_encode($_GET, array(
    'q',
  ));

  // Add a collapsible container.
  $form = array(
    'add' => array(
      '#type' => 'fieldset',
      '#collapsible' => true,
      '#collapsed' => true,
      '#title' => t('add this page'),
      'title' => array(
        '#type' => 'textfield',
        '#size' => 20,
        '#maxlength' => 255,
        '#default_value' => $title,
        '#attributes' => array(
          'style' => 'width: 90%',
          'class' => 'favorites-add-textfield',
        ),
      ),
      'submit' => array(
        '#type' => 'submit',
        '#value' => t("Add"),
        '#submit' => array(
          'favorites_add_favorite_form_submit',
        ),
      ),
      'path' => array(
        '#type' => 'value',
        '#value' => $path,
      ),
      'query' => array(
        '#type' => 'value',
        '#value' => $query,
      ),
    ),
  );

  //Preserve the current path with query string.
  $destination = drupal_get_destination();
  $form['#redirect'] = array(
    $_GET['q'],
    drupal_query_string_encode($_GET, array(
      'q',
    )),
  );

  // Additionally add path and query to the JS settings.
  drupal_add_js(array(
    'favorites' => array(
      'path' => $path,
      'query' => $query,
      'addCallbackPath' => url('favorites/js/add'),
    ),
  ), 'setting');
  return $form;
}

/**
 * Submit callback for "add favorite" form.
 */
function favorites_add_favorite_form_submit($form, &$form_state) {
  favorites_add_favorite($form_state['values']);
}

/**
 * Load the favorites for a particular user.
 */
function favorites_load_favorites($uid = 0) {
  $favorites = array();
  if ($uid) {
    $query = db_query("SELECT * FROM {favorites} WHERE uid = %d ORDER BY timestamp DESC", $uid);
    while ($favorite = db_fetch_object($query)) {
      $favorite->token = favorite_token($favorite);
      $favorite->path = drupal_get_path_alias($favorite->path);
      $favorites[] = $favorite;
    }
  }
  return $favorites;
}

/**
 * Generate a token for a particular favorite.
 */
function favorite_token($favorite = NULL) {
  return drupal_get_token($favorite->timestamp . $favorite->uid . $favorite->path);
}

/**
 * AHAH callback for add favorites form.
 *
 * @see favorites_add_favorite_form()
 */
function favorites_add_favorite_js() {
  favorites_add_favorite($_POST);
  drupal_json(array(
    'list' => favorites_list(),
  ));
}

Functions

Namesort descending Description
favorites_add_favorite Add a favorite.
favorites_add_favorite_form Form callback for the "add favorite form"
favorites_add_favorite_form_submit Submit callback for "add favorite" form.
favorites_add_favorite_js AHAH callback for add favorites form.
favorites_block Implements hook_block().
favorites_list Generate the "My Favorites" list.
favorites_load_favorites Load the favorites for a particular user.
favorites_menu Implements hook_menu().
favorites_perm Implements hook_perm().
favorites_remove_favorite Deletes a favorite.
favorites_theme Implements hook_theme().
favorite_load Helper function to load a favorite.
favorite_token Generate a token for a particular favorite.
theme_favorites Theme callback.