'Favorite nodes', 'description' => 'Settings for favorite nodes', 'page callback' => 'drupal_get_form', 'page arguments' => array('favorite_nodes_settings'), 'type' => MENU_NORMAL_ITEM, 'access arguments' => array(FAVORITE_NODES_PERM_ADMINISTER), ); $items['favorite_nodes/add'] = array( 'page callback' => 'favorite_nodes_add_page', 'type' => MENU_CALLBACK, 'access arguments' => array(FAVORITE_NODES_PERM_ADD), ); $items['favorite_nodes/delete'] = array( 'page callback' => 'favorite_nodes_delete_page', 'type' => MENU_CALLBACK, 'access arguments' => array(FAVORITE_NODES_PERM_ADD), ); $items['favorite_nodes/view'] = array( 'page callback' => 'favorite_nodes_view_page', 'title' => 'Favorites', 'type' => MENU_CALLBACK, 'access arguments' => array(FAVORITE_NODES_PERM_VIEW), ); $items['favorites/view'] = array( 'page callback' => 'favorite_nodes_view_page', 'type' => MENU_CALLBACK, 'access arguments' => array(FAVORITE_NODES_PERM_VIEW), ); if ($user->uid && variable_get(FAVORITE_NODES_MENUS, 0)) { foreach (_node_types_natcasesort() as $type) { if (variable_get(FAVORITE_NODES_NODE_TYPE . $type->type, 0)) { $items["favorites/view/$user->uid/$type->type"] = array( 'title' => 'Favorite @type', array('@type' => $type->name), 'page callback' => 'favorite_nodes_view_page', 'type' => MENU_NORMAL_ITEM, 'access arguments' => array(FAVORITE_NODES_PERM_VIEW), ); } } } return $items; } /** * Implementation of hook_theme(). */ function favorite_nodes_theme() { return array( 'favorite_nodes_view_table' => array( 'arguments' => array('list' => array(), 'uid' => NULL, 'type' => NULL), ), 'favorite_nodes_view_teasers' => array( 'arguments' => array('list' => array(), 'uid' => NULL, 'type' => NULL), ) ); } /** * Implementation of hook_xmlrpc(). */ function favorite_nodes_xmlrpc() { $items = array(); $items[] = array( 'favorite_nodes.add', 'favorite_nodes_add', array('boolean', 'int'), t('Add a favorite node to the current user\'s list.') ); } function _node_types_natcasesort() { static $node_types; if (!isset($node_types)) { $node_types = node_get_types(); uasort($node_types, create_function('$a, $b', 'return strnatcasecmp($a->name, $b->name);')); } return $node_types; } /** * Implementation of hook_user(). */ function favorite_nodes_user($op, &$edit, &$user, $category = null) { switch ($op) { case 'view': $user->content['faveliste'] = array( '#type' => 'user_profile_category', '#title' => t('My favorites'), '#value' => theme('item_list', $items), ); $fav_list = array(); foreach (_node_types_natcasesort() as $type) { if (variable_get(FAVORITE_NODES_NODE_TYPE . $type->type, 0)) { $uid = intval($user->uid); $favorites = favorite_nodes_get($uid, $type->type, variable_get(FAVORITE_NODES_BLOCK_LIMIT, 5)); $items = array(); if (!empty($favorites)) { foreach ($favorites as $favorite) { $items[] = l($favorite->title, "node/$favorite->nid"); } $user->content['faveliste'][$type->name] = array( '#type' => 'user_profile_item', '#title' => l($type->name, "favorite_nodes/view/$user->uid/$type->type"), '#value' => theme('item_list', $items), ); } } } break; case 'delete': favorite_nodes_delete_favorites($user->uid); break; } } /** * Implementation of hook_nodeapi(). */ function favorite_nodes_nodeapi(&$node, $op, $teaser = null, $page = null) { switch ($op) { case 'delete': // Delete all favorite entries of the node being deleted. db_query("DELETE FROM {favorite_nodes} WHERE nid = %d", $node->nid); break; } } /** * Implementation of hook_block(). */ function favorite_nodes_block($op = 'list', $delta = 0, $edit = array()) { global $user; $node_types = _node_types_natcasesort(); switch ($op) { case 'list': return array(array('info' => t('Favorite nodes'))); case 'view': if (user_access(FAVORITE_NODES_PERM_VIEW)) { $block = array(); $block['subject'] = variable_get(FAVORITE_NODES_BLOCK_TITLE, t('Favorites')); $block['content'] = ''; foreach ($node_types as $type) { if (variable_get(FAVORITE_NODES_NODE_TYPE . $type->type, 0)) { $uid = intval($user->uid); $favorites = favorite_nodes_get($uid, $type->type, variable_get(FAVORITE_NODES_BLOCK_LIMIT, 5)); $items = array(); if (!empty($favorites)) { foreach ($favorites as $favorite) { $items[] = l($favorite->title, "node/$favorite->nid"); } $block['content'] .= theme('item_list', $items, variable_get(FAVORITE_NODES_BLOCK . $type->type, $type->name)); } $sql = "SELECT COUNT(*) FROM {node} n INNER JOIN {favorite_nodes} f USING(nid) WHERE n.type = '%s' AND f.uid = %d ORDER by f.last DESC"; $count = db_result(db_query($sql, $type->type, $user->uid)); if ($count > variable_get(FAVORITE_NODES_BLOCK_LIMIT, 5)) { $block['content'] .= "
\n"; $block['content'] .= l(t('More Favorite %types', array('%types' => variable_get(FAVORITE_NODES_BLOCK . $type->type, $type->name))), "favorite_nodes/view/$user->uid/$type->type"); $block['content'] .= "
\n"; } } } } return $block; case 'configure': $form = array(); $form['titles'] = array( '#type' => 'fieldset', '#title' => t('Titles'), '#collapsible' => true, '#collapsed' => false, ); $form['titles']['title'] = array( '#type' => 'textfield', '#title' => t('Block title'), '#size' => 60, '#description' => t('This title will be displayed at the top of the block.'), '#default_value' => variable_get(FAVORITE_NODES_BLOCK_TITLE, t('Favorites')), ); $form['limit'] = array( '#type' => 'textfield', '#title' => t('Number of favorites to display'), '#size' => 4, '#description' => t('Up to this many favorites of each type of content will be displayed in the block. If there are no marked favorites of a type, then that type won\'t show up.'), '#default_value' => variable_get(FAVORITE_NODES_BLOCK_LIMIT, 5), ); $form['titles']['subtitles'] = array( '#type' => 'fieldset', '#title' => t('Type subtitles'), '#collapsible' => true, '#collapsed' => true, ); foreach ($node_types as $type) { if (variable_get(FAVORITE_NODES_NODE_TYPE . $type->type, 0)) { $form['titles']['subtitles'][FAVORITE_NODES_BLOCK . $type->type] = array( '#type' => 'textfield', '#title' => t('Subtitle for the %name content type', array('%name' => $type->name)), '#size' => 60, '#description' => t('Within the block, any links to content of the %name type will be categorized under this subtitle.', array('%name' => $name)), '#default_value' => variable_get(FAVORITE_NODES_BLOCK . $type->type, $type->name), ); } } return $form; case 'save': variable_set(FAVORITE_NODES_BLOCK_TITLE, $edit['title']); variable_set(FAVORITE_NODES_BLOCK_LIMIT, $edit['limit']); foreach ($node_types as $type) { if (variable_get(FAVORITE_NODES_NODE_TYPE . $type->type, 0)) { variable_set(FAVORITE_NODES_BLOCK . $type->type, $edit[FAVORITE_NODES_BLOCK . $type->type]); } } break; default: break; } } /** * Implementation of hook_links(). */ function favorite_nodes_link($type, $node = null, $teaser = false) { global $user; $links = array(); if ($type == 'node' && !$teaser) { if (variable_get(FAVORITE_NODES_NODE_TYPE . $node->type, 0)) { if (user_access(FAVORITE_NODES_PERM_ADD)) { if (!_favorite_nodes_check($node->nid)) { $links[] = array('title' => t('add to favorites'), 'href' => 'favorite_nodes/add/'. $node->nid); } else { if (user_access(FAVORITE_NODES_PERM_VIEW)) { $links[] = array('title' => t('in favorites')); $links[] = array('title' => t('remove from favorites'), 'href' => 'favorite_nodes/delete/'. $node->nid); } } } } } return $links; } /** * Settings page for this module. */ function favorite_nodes_settings() { $set = 'page'; $form[$set] = array( '#type' => 'fieldset', '#title' => t('Favorites Page Settings'), '#collapsible' => true, '#collapsed' => false, ); $form[$set][FAVORITE_NODES_PAGE_LIMIT] = array( '#type' => 'textfield', '#title' => t('Favorite Nodes Page Limit'), '#default_value' => variable_get(FAVORITE_NODES_PAGE_LIMIT, 10), '#description' => t('How many items to display on a single page of marked favorites.'), ); $form[$set][FAVORITE_NODES_PROFILE_LIMIT] = array( '#type' => 'textfield', '#title' => t('Favorite Nodes Profile Limit'), '#default_value' => variable_get(FAVORITE_NODES_PROFILE_LIMIT, 3), '#description' => t('How many items per type to display on the profile page.'), ); $form[$set][FAVORITE_NODES_PAGE_TYPE] = array( '#type' => 'select', '#title' => t('Type of Page Display for Favorite Nodes'), '#options' => array( 'table' => 'Table', 'teasers' => 'Teasers', ), '#default_value' => variable_get(FAVORITE_NODES_PAGE_TYPE, 'table'), '#description' => t('How should favorites be displayed on the favorite nodes page?'), ); $form[$set][FAVORITE_NODES_MENUS] = array( '#type' => 'checkbox', '#title' => t('Navigation menu items'), '#return_value' => 1, '#default_value' => variable_get(FAVORITE_NODES_MENUS, 0), '#description' => t('Whether to show a menu item in the navigation block for each node type?'), ); $set = 'types'; $form[$set] = array( '#type' => 'fieldset', '#title' => t('Enable favorites for these node types'), '#collapsible' => true, '#collapsed' => false, ); foreach (_node_types_natcasesort() as $type) { $form[$set][FAVORITE_NODES_NODE_TYPE . $type->type] = array( '#type' => 'checkbox', '#title' => $type->name, '#return_value' => 1, '#default_value' => variable_get(FAVORITE_NODES_NODE_TYPE . $type->type, 0), ); } // $form['#submit'][] = 'example_admin_settings_submit'; return system_settings_form($form); } /** * Add a favorite node. */ function favorite_nodes_add($nid) { global $user; $node = node_load($nid); if ($node->nid) { db_query("DELETE FROM {favorite_nodes} WHERE nid = %d AND uid = %d", $nid, $user->uid); db_query("INSERT INTO {favorite_nodes} (nid, uid, last) VALUES (%d, %d, %d)", $nid, $user->uid, time()); return true; } else { return false; } } /** * Delete a favorite node. */ function favorite_nodes_delete($nid) { global $user; db_query("DELETE FROM {favorite_nodes} WHERE nid = %d AND uid = %d", $nid, $user->uid); } /** * Select all the favorite nodes a user has. * TODO why don't return all node if tpye are nul. So we can display all favorite node on path favorite_nodes/view/"uid" */ function favorite_nodes_get($uid, $type = null, $limit = null) { if (is_null($limit)) { $limit = variable_get(FAVORITE_NODES_PAGE_LIMIT, 10); } $row = array(); if ($type && variable_get(FAVORITE_NODES_NODE_TYPE . $type, 0)) { $sql = "SELECT n.nid, n.title, f.uid, f.last FROM {node} n INNER JOIN {favorite_nodes} f ON n.nid = f.nid WHERE n.type = '%s' AND f.uid = %d ORDER by f.last DESC"; $result = pager_query($sql, $limit, 0, null, $type, $uid); if ($result) { while ($data = db_fetch_object($result)) { $row[$data->nid] = $data; } } } return $row; } /** * Page to add a favorite node. */ function favorite_nodes_add_page() { $nid = arg(2); if (is_numeric($nid)) { $result = favorite_nodes_add($nid); if ($result) { drupal_set_message(t('The node was added to your favorites.')); } else { } drupal_goto('node/'. $nid); } drupal_not_found(); } /** * Page to delete a favorite node. */ function favorite_nodes_delete_page() { global $user; $nid = arg(2); favorite_nodes_delete($nid); drupal_set_message(t('The node was deleted from your favorites')); drupal_goto("user/$user->uid"); } /** * Page to display a user's favorite list. */ function favorite_nodes_view_page() { $uid = arg(2); $type = arg(3); $output = theme('favorite_nodes_view_'. variable_get(FAVORITE_NODES_PAGE_TYPE, 'table'), favorite_nodes_get($uid, $type), $uid, $type); print theme('page', $output); } /** * Delete favorite nodes a user has. */ function favorite_nodes_delete_favorites($uid) { db_query("DELETE FROM {favorite_nodes} WHERE uid = %d", $uid); } /** * Get all the favorite nodes inner joining the users. * TODO: currently not being used.. do we need this? */ function _favorite_nodes_get_users($nid) { $sql = "SELECT u.*, f.last FROM {users} u INNER JOIN {favorite_nodes} f USING(uid) WHERE f.nid = %d ORDER by f.last DESC"; $result = db_query($sql, $nid); $row = array(); while ($data = db_fetch_object($result)) { $row[$data->uid] = $data; } return $row; } /** * Check if a user already has a node in their favorite list. */ function _favorite_nodes_check($nid) { global $user; $sql = "SELECT COUNT(*) FROM {favorite_nodes} WHERE uid = %d AND nid = %d"; return db_result(db_query($sql, $user->uid, $nid)); } /** * TODO: This is not being used.. do we need it? */ function theme_favorite_nodes_view_teasers($list = array(), $uid = null, $type = null) { $type_desc = variable_get(FAVORITE_NODES_BLOCK . $type, $type); $user = user_load(array('uid' => $uid)); if (!$type) { $output .= t('Please select favorite type.'); } else { if (!empty($list)) { $output .= '

'. t('Favorite !type for !user', array('!type' => $type_desc, '!user' => theme('username', $user))) ."

\n"; foreach ($list as $nid => $data) { $node = node_load($nid); $output .= node_view($node, true); } } else { $output .= t('No favorites of type !type.', array('!type' => $type_desc)); } } $output .= theme('pager'); return $output; } /** * Table which displays favorite node lists. */ function theme_favorite_nodes_view_table($list = array(), $uid = null, $type = null) { global $user; $account = user_load(array('uid' => $uid)); $header = array(t('Title'), t('Added'), t('Operations')); $rows = array(); if (isset($list)) { foreach ($list as $nid => $data) { $title = array(l($data->title, "node/$nid"), format_date($data->last, 'custom', 'Y-m-d H:i')); if ($user->uid == $data->uid || $user->uid == 1) { $delete = array(l(t('delete'), "favorite_nodes/delete/$nid")); $result = array_merge($title, $delete); } else { $result = $title; } $rows[] = array('data' => $result); } } $output .= '

'. t('Favorite !types for !user', array('!type' => variable_get(FAVORITE_NODES_BLOCK . $type, node_get_types('name', $type)), '!user' => theme('username', $account))) ."

\n"; $output .= theme('table', $header, $rows); $output .= theme('pager'); return $output; } function favorite_nodes_views_tables() { $tables['favorite_nodes'] = array( 'name' => 'favorite_nodes', 'provider' => 'internal', 'join' => array( 'left' => array( 'table' => 'node', 'field' => 'nid', ), 'right' => array( 'field' => 'nid', ), ), 'fields' => array( 'last' => array( 'name' => t('Favorite Nodes: Time Added'), 'sortable' => true, 'handler' => views_handler_field_dates(), 'option' => 'string', 'help' => t('Display the date/time the favorite node was added.'), ), 'count' => array( 'name' => t('Favorite Nodes: Count'), 'handler' => 'favorite_nodes_handler_user_count', 'help' => t('Number of times this node was added to favorites by any user.'), 'sortable' => FALSE, 'notafield' => TRUE, ), ), 'sorts' => array( 'last' => array( 'name' => t('Favorite Nodes: Time Added'), 'help' => t('Sort by the date/time the favorite node was added.'), ), ), 'filters' => array( 'uid' => array( 'field' => 'uid', 'name' => t('Favorite Nodes: User ID'), 'operator' => 'views_handler_operator_eqneq', 'handler' => 'views_handler_filter_favorite_nodes', 'list-type' => 'select', 'list' => array( 'uid_current' => t('Currently Logged In User'), 'uid_all' => t('All Users'), ), 'help' => t('This allows you to filter based on favorites nodes.'), ), 'last' => array( 'name' => t('Favorite Nodes: Time Added'), 'operator' => 'views_handler_operator_gtlt', 'value' => views_handler_filter_date_value_form(), 'handler' => 'views_handler_filter_timestamp', 'option' => 'string', 'help' => t('This filter allows favorite nodes to be filtered by the date and time the user added them. Enter dates in the format: CCYY-MM-DD HH:MM:SS. Enter \'now\' to use the current time. You may enter a delta (in seconds) to the option that will be added to the time; this is most useful when combined with now.'), ), ), ); return $tables; } function views_handler_filter_favorite_nodes($op, $filter, $filterinfo, &$query) { global $user; $table_data = _views_get_tables(); $joininfo = $table_data['favorite_nodes']['join']; $joininfo['type'] = 'inner'; $table_num = $query->add_table('favorite_nodes', FALSE, 1, $joininfo); $table = $query->get_table_name('favorite_nodes', $table_num); $query->set_distinct(); switch ($filter['value']) { case 'uid_current': if ($user->uid) { $query->add_where("$table.uid = $user->uid"); } break; case 'uid_all': // No special processing needed, since we do an inner join anyways break; } } function favorite_nodes_views_arguments() { $args['user_id'] = array( 'name' => t("Favorite Nodes: User ID"), 'handler' => 'favorite_nodes_handler_argument_uid', 'help' => t('User ID for Favorite node.'), ); return $args; } function favorite_nodes_handler_argument_uid($op, &$query, $argtype, $arg = '') { switch ($op) { case 'sort': // no luck using add_orderby method. $query->orderby[] = ' num_nodes '. $argtype; break; case 'filter': list($and_or, $uids) = _views_break_phrase($arg); $and_or = drupal_strtoupper($and_or); // Similar to taxonomy AND/OR query. if ($and_or == 'OR') { $query->ensure_table('favorite_nodes'); $cond = array_fill(0, count($uids), "favorite_nodes.uid = %d"); $query->add_where(implode(" $and_or ", $cond), $uids); } else { foreach ((array)$uids as $uid) { $num = $query->add_table('favorite_nodes'); $tablename = $query->get_table_name('favorite_nodes', $num); $query->add_where("$tablename.uid = %d", $uid); } } break; } } function favorite_nodes_handler_user_count($fieldinfo, $fielddata, $value, $data) { return db_result(db_query("SELECT COUNT(*) FROM {favorite_nodes} WHERE nid = %d", $data->nid)); }