0) { return 1; } else return $num; } /** * Retrieve the settings for a given helptip block. Provide defaults * if necessary. */ function _helptip_get_block_settings($delta) { $var_name = "helptip_block_".$delta."_settings"; $defaults = array('how_many' => 1, 'title' => '%title', 'min_weight' => -10, 'max_weight' => 10); $settings = variable_get($var_name, array()); // array_merge ensures default values will exist for all settings. return array_merge($defaults, $settings); } /** * Implementation of hook_block(). */ function helptip_block($op = 'list', $delta = 0, $edit = array()) { $var_name = "helptip_block_".$delta."_settings"; if ($op == 'list') { $blocks[0]['info'] = t('Help tips'); for ($i = 1; $i < _helptip_num_blocks(); $i++) { $blocks[$i]['info'] = t('Help tips %num', array('%num' => $i)); } return $blocks; } else if ($op == 'configure') { $defaults = _helptip_get_block_settings($delta); $form[$var_name] = array('#tree' => true); $form[$var_name]['title'] = array('#type' => 'textfield', '#title' => t('Title'), '#default_value' => $defaults['title'], '#size' => 64, '#maxlength' => 128, '#description' => t('Block title. For example "Tip of the Day". Use %title for the title of the first help tip.'), ); $form[$var_name]['how_many'] = array('#type' => 'textfield', '#title' => t('Number of help tips'), '#default_value' => $defaults['how_many'], '#size' => 2, '#maxlength' => 2, '#description' => t('How many tips to display? If more than one tip applies to the current page, more than one can be displayed. Order of tips is random.'), ); $form[$var_name]['min_weight'] = array('#type' => 'weight', '#title' => t('Minimum Weight'), '#default_value' => $defaults['min_weight'], '#description' => t('Show only helptips with this weight or greater. This allows you to define multiple helptip blocks, and position helptips on the page by their weight.'), ); $form[$var_name]['max_weight'] = array('#type' => 'weight', '#title' => t('Maximum Weight'), '#default_value' => $defaults['max_weight'], '#description' => t('Show only helptips with this weight or less. This allows you to define multiple helptip blocks, and position helptips on the page by their weight.'), ); return $form; } else if ($op == 'save') { variable_set($var_name, $edit[$var_name]); } else if ($op == 'view') { global $user; if (!user_access(HELPTIP_ACCESS_VIEW)) return; $settings = _helptip_get_block_settings($delta); $paths = _helptip_get_current_paths(); $path_clause = "('" . implode("' LIKE ht.path OR '", $paths) . "' LIKE ht.path)"; // use db_rewrite_sql for people with node_access modules $result = db_query(db_rewrite_sql("SELECT nid FROM {node} n LEFT JOIN {helptip} ht ON ht.nid = n.nid LEFT JOIN {helptip_user_data} ht_hidden ON ht_hidden.uid=$user->uid AND ht_hidden.nid=n.nid AND ht_hidden.relation='hidden' WHERE n.status = 1 AND ht_hidden.relation IS NULL AND $path_clause AND weight >= $settings[min_weight] AND weight <= $settings[max_weight] ORDER BY ht.weight, RAND() LIMIT %d"), $settings['how_many']); $block = array(); while ($data = db_fetch_object($result)) { $node = node_load($data->nid); if (!$block['subject']) $block['subject'] = t($settings['title'], array('%title' => check_plain($node->title))); $items[] = theme('helptip_body', $node); } if (count($items)) { $block['content'] = theme('helptip_list', $items); } return $block; } } /** * Implementation of hook_help(). */ function helptip_help($section) { switch ($section) { case 'admin/help#helptip': return t('TODO: Create admin help text.'); case 'admin/modules#description': return t('context sensitive help messages (display and edit)'); case 'node/add#helptip': return t('A helptip is text which can appear in a block on context-sensitive pages. For example, to provide detailed instructions to users on a specific page.'); } } // some values we'll refer to many times define('HELPTIP_ACCESS_VIEW', 'view help tips'); define('HELPTIP_ACCESS_CREATE', 'create help tips'); define('HELPTIP_ACCESS_EDIT_OWN', 'edit own help tips'); define('HELPTIP_ACCESS_ADMINISTER', 'administer help tips'); /** * Implementation of hook_menu(). */ function helptip_menu($may_cache) { global $user; $items = array(); if ($may_cache) { $items[] = array ( 'path' => 'node/add/helptip', 'title' => t('help tip'), 'access' => user_access(HELPTIP_ACCESS_CREATE), 'type' => MENU_NORMAL_ITEM, ); $items[] = array ( 'path' => 'helptip/hide', 'title' => t('hide help tip'), 'callback' => 'helptip_hide_cb', 'access' => user_access(HELPTIP_ACCESS_VIEW), 'type' => MENU_CALLBACK, ); } return $items; } /** * User has requested to hide the given helptip */ function helptip_hide_cb($nid) { global $user; if ($user->uid && $nid > 0) { db_query("DELETE FROM {helptip_user_data} WHERE nid=%d AND uid=%d AND relation='hidden'", $nid, $user->uid); db_query("INSERT INTO {helptip_user_data} (nid, uid, relation) VALUES (%d, %d, 'hidden')", $nid, $user->uid); } // copied following from devel module header('Location: '. referer_uri()); exit(); } /** * Implementation of hook_perm(). */ function helptip_perm() { return array(HELPTIP_ACCESS_CREATE, HELPTIP_ACCESS_EDIT_OWN, HELPTIP_ACCESS_ADMINISTER, HELPTIP_ACCESS_VIEW); } /** * Implementation of hook_access(). */ function helptip_access($op, $node) { global $user; if (!($ret_val = user_access(HELPTIP_ACCESS_ADMINISTER))) { switch ($op) { case 'create': $ret_val = user_access(HELPTIP_ACCESS_CREATE); break; case 'delete': case 'update': $ret_val = user_access(HELPTIP_ACCESS_EDIT_OWN); break; case 'view': $ret_val = user_access(HELPTIP_ACCESS_VIEW); break; } } return $ret_val; } /** * Implementation of hook_delete(). */ function helptip_delete(&$node) { db_query("DELETE FROM {helptip} WHERE nid = %d", $node->nid); } /** * Implementation of hook_form(). */ function helptip_form(&$node, &$param) { $form['title'] = array('#type' => 'textfield', '#title' => t('Title'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5); if (!$node->helptip->path) { // for convenience, default path to the previous page global $base_url; $referer = $_SERVER['HTTP_REFERER']; $pattern = "|$base_url\/(\?q=)?([^\?\&]*)|"; $result = preg_match($pattern, $referer, $matches); if ($result) $node->helptip->path = $matches[2]; } $form['helptip'] = array('#tree' => true); $form['helptip']['path'] = array('#type' => 'textfield', '#title' => t('Context Sensitive Path'), '#default_value' => $node->helptip->path, '#description' => t('Where to display this help. Use "%" as wildcard.'), '#required' => true); $form['helptip']['weight'] = array('#type' => 'weight', '#title' => t('Weight'), '#default_value' => $node->helptip->weight, '#description' => t('When more than one help tip applies to a page, this controls the order in which they are displayed. It may also determine in which block the helptip appears.'), '#required' => false); $form['helptip']['settings'] = array('#tree' => true); $form['helptip']['settings']['may_hide'] = array('#type' => 'checkbox', '#title' => t('User May Hide'), '#default_value' => $node->helptip->settings['may_hide'], '#description' => t('Enable "do not show again" link.')); $form['body_filter']['body'] = array('#type' => 'textarea', '#title' => t('Body'), '#default_value' => $node->body, '#rows' => 20, '#required' => TRUE); $form['body_filter']['format'] = filter_form($node->format); return $form; } /** * Implementation of hook_insert(). */ function helptip_insert($node) { $helptip = (object) $node->helptip; db_query("INSERT INTO {helptip} (nid, path, weight, settings) VALUES (%d, '%s', %d, '%s')", $node->nid, $helptip->path, $helptip->weight, serialize($helptip->settings)); } /** * Implementation of hook_update(). */ function helptip_update($node) { $helptip = (object) $node->helptip; db_query("REPLACE INTO {helptip} (nid, path, weight, settings) VALUES (%d, '%s', %d, '%s')", $node->nid, $helptip->path, $helptip->weight, serialize($helptip->settings)); } /** * Implementation of hook_load(). */ function helptip_load($node) { $data = db_fetch_object(db_query('SELECT * FROM {helptip} WHERE nid=%d', $node->nid)); $data->settings = unserialize($data->settings); return array('helptip' => $data); } /** * Implementation of hook_node_info(). */ function helptip_node_info() { return array('helptip' => array('name' => t('help tip'), 'base' => 'helptip')); } /** * Implementation of hook_validate(). */ function helptip_validate(&$node) { // TODO } /** * Implementation of hook_view(). */ function helptip_view(&$node, $teaser = FALSE, $page = FALSE) { $node = node_prepare($node, $teaser); } /** * Implementation of hook_settings(). */ function helptip_settings() { $form['helptip_num_blocks'] = array('#type' => 'textfield', '#title' => t('Number of blocks'), '#default_value' => variable_get('helptip_num_blocks', 1), '#size' => 1, '#maxlength' => 1, '#description' => t('How many helptip blocks would you like? For example, if you want help tips to appear in the header on some pages, and in a sidebar on others, you need two blocks.'), ); return $form; } /** * Display the body of the help tip. In this implementation, we show teaser. */ function theme_helptip_body($node) { $node->teaser = check_markup($node->teaser, $node->format, FALSE); $node->body = check_markup($node->body, $node->format, FALSE); return '
'.$node->teaser. theme('helptip_links', $node)."
\n"; } /** * This is like hook_links when displaying a node, but applies to * helptips shown in help blocks. * * Responsible for displaying readmore and don't show anymore links */ function theme_helptip_links($node) { global $user; if ($node->body != $node->teaser) { $links[] = l(t('read more'), "node/$node->nid", array('title' => t('Read the rest of this help tip.'), 'class' => 'read-more')); } // some helptips can be hidden by the user. Ideally some javascript // will come along and replace this link with an ajaxy thing that // does not require a page reload if ($user->uid && $node->helptip->settings['may_hide']) $links[] = l(t('do not show again'), "helptip/hide/$node->nid", array('title' => t('Do not display this message again'), 'class' => 'helptip_hide')); // for admin convenience, let them edit this tip if (user_access(HELPTIP_ACCESS_ADMINISTER) || ($user->uid == $node->uid && user_access(HELPTIP_ACCESS_EDIT_OWN))) $links[] = l(t('edit'), "node/$node->nid/edit", array('title' => t('edit this help tip'))); return '\n"; } /** * If more than one helptip body is being shown, this is how we do it. */ function theme_helptip_list($items) { if (count($items) == 1) return $items[0]; else return theme('item_list', $items); } /** * Returns an array of paths which match the current page, * escaped for use in database queries. */ function _helptip_get_current_paths() { $paths = array(db_escape_string($_GET['q'])); if ($alias = drupal_lookup_path('alias', $_GET['q'])) $paths[] = db_escape_string($alias); return $paths; }