You are here

wikitools.module in Wikitools 5

Same filename and directory in other branches
  1. 6.2 wikitools.module
  2. 6 wikitools.module
  3. 7 wikitools.module

A non-intrusive module to have some wiki-like behaviour.

File

wikitools.module
View source
<?php

/**
 * @file
 * A non-intrusive module to have some wiki-like behaviour.
 */

/**
 * Implementation of hook_help().
 */
function wikitools_help($section) {
  switch ($section) {
    case 'admin/help#wikitools':
      $output = '<p>' . t('The wikitools module allows you to set several options for your content to get a more wiki-like behaviour.') . '</p>';
      return $output;
    case 'admin/content/wikitools':
      $output = '<p>' . t('Wikitools allows restrictions on node titles so that all new created nodes have guaranteed unique titles. Titles of nodes that were created before it was included in this option, however, are not guaranteed to have unique page titles. This page lists all nodes that have duplicate page titles, so that their titles may be changed to be unique.') . '</p>';
      return $output;
  }
}

/*
 * Setup functions
 */

/**
 * Implementation of hook_menu().
 */
function wikitools_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/settings/wikitools',
      'title' => t('Wikitools'),
      'description' => t('Settings for wiki-like behaviour.'),
      'access' => user_access('administer site configuration'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'wikitools_admin_settings',
      ),
      'type' => MENU_NORMAL_ITEM,
    );
  }
  else {
    $wiki_path = wikitools_wiki_path();
    if (!empty($wiki_path)) {
      if ($wiki_path != '<none>') {
        $items[] = array(
          'path' => $wiki_path,
          'callback' => 'wikitools_handle_request',
          'access' => user_access('access content'),
          'type' => MENU_CALLBACK,
        );
      }
    }
    else {
      $result = wikitools_handle_request();
      if ($result !== FALSE) {
        $items[] = array(
          'path' => $_GET['q'],
          'callback' => 'wikitools_page_value',
          'callback arguments' => $result,
          'access' => user_access('access content'),
          'type' => MENU_CALLBACK,
        );
      }
    }

    // Override the callback for node deletion if the delete protection option is set.
    if (arg(0) == 'node' && is_numeric(arg(1))) {
      $node = node_load(arg(1));
      if (wikitools_type_affected($node->type) && wikitools_delete_protection()) {

        // Hijack delete callback and call custom handler.
        $items[] = array(
          'path' => 'node/' . arg(1) . '/delete',
          'title' => t('Delete'),
          'callback' => 'wikitools_delete_protection_delete_confirm',
          'callback arguments' => array(
            $node,
          ),
          'access' => node_access('delete', $node),
          'weight' => 1,
          'type' => MENU_CALLBACK,
        );
      }
    }

    // Only hijack freelinking path if an argument is specified, otherwise let the freelinking page show.
    if (module_exists('freelinking') && wikitools_hijack_freelinking() && arg(1)) {
      $items[] = array(
        'path' => 'freelinking',
        'callback' => 'wikitools_handle_request',
        'access' => user_access('access content'),
        'type' => MENU_CALLBACK,
      );
    }
    if (wikitools_enforce_unique_titles()) {
      $items[] = array(
        'path' => 'admin/content/wikitools',
        'title' => t('Duplicate titles'),
        'description' => t('List nodes which have duplicate titles'),
        'access' => user_access('administer nodes'),
        'callback' => 'wikitools_page_duplicates',
        'type' => MENU_NORMAL_ITEM,
      );
    }
  }
  return $items;
}

/**
 * Builder function for settings form.
 */
function wikitools_admin_settings() {
  $form = array();
  list($select_query, $count_query, $arguments) = _wikitools_duplicate_nodes_query();
  if ($count_query) {
    $duplicates_exist = db_result(db_query($count_query, $arguments));
    if ($duplicates_exist) {
      drupal_set_message(t('Nodes with duplicate titles exist in your wiki. To clear up this issue, visit the <a href="!url">duplicate titles</a> page.', array(
        '!url' => url('admin/content/wikitools'),
      )), 'warning');
    }
  }
  $form['wikitools_path'] = array(
    '#type' => 'textfield',
    '#title' => t('Wiki path'),
    '#default_value' => wikitools_wiki_path(),
    '#description' => t('The drupal path for the wiki. Do not include a trailing slash. Set to &lt;none&gt; to disable the wiki path.'),
    '#field_prefix' => url(NULL, NULL, NULL, TRUE) . (variable_get('clean_url', 0) ? '' : '?q='),
  );
  $form['wikitools_main_page_title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title of main page'),
    '#default_value' => wikitools_main_page_title(),
    '#description' => t('The main page is shown if you type in the wiki path. Leave empty to disable the main page.'),
  );
  $form['wikitools_node_types'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Wiki node types'),
    '#options' => node_get_types('names'),
    '#size' => count(node_get_types('names')),
    '#default_value' => wikitools_node_types(),
    '#multiple' => TRUE,
    '#description' => t('Select the node types which will be affected by the specified options. If you select multiple node types, all nodes of these types will be searched for when a wikipath is entered. If a wikipage doesn\'t exist, an option to create any of these types will be given.'),
  );
  $form['wikitools_options'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Options'),
    '#options' => array(
      'node creation' => t('Node Creation: Let users create new nodes when they type in a node name which does not exist.'),
      'node search' => t('Node Search: Let users search for nodes when they type in a node name which does not exist.'),
      'auto redirect' => t('Automatic Redirect: If a title of a moved page is entered, redirect automatically.'),
      'unique titles' => t('Unique Titles: Enforce that titles of new nodes are different from existing ones.'),
      'move protection' => t('Move Protection: Disallow change of node titles for users without <em>administer nodes</em> permission.'),
      'delete protection' => t('Delete Protection: Disallow deletion of nodes for users without <em>administer nodes</em> permission.'),
      'underscore as space' => t('Treat underscores as spaces when looking for node titles.'),
      'dash as space' => t('Treat dashes as spaces when looking for node titles.'),
    ),
    '#default_value' => wikitools_options(),
    '#description' => '<ul><li>' . t('To take full advantage of the options <em>Node Creation</em>, <em>Node Search</em> and <em>Automatic Redirect</em> you should use an input format which creates wikilinks which point to the wiki path set. For exapmle a wikilink [[Page Name]] should be linked to <em>wikipath/Page Name</em>.') . '</li><li>' . t('The options <em>Node Creation</em>, <em>Node Search</em> and <em>Automatic Redirect</em> work only if a wiki path is set or if freelinking hijacking is enabled. They take the page name from the path after the wiki path, i.e. <em>wikipath/Page Name</em>, or the page name of a freelinking link, i.e. <em>freelinking/Page Name</em>.') . '</li><li>' . t('The option <em>Automatic Redirect</em> works only if node revisions are created.') . '</li></ul>',
  );
  $form['wikitools_disallowed_characters'] = array(
    '#type' => 'textfield',
    '#title' => t('Disallowed characters in titles'),
    '#description' => t('A list of characters which are not allowed in the title of a wiki page. This setting is important for the wikilink feature to work. Set it so that your input syntax will not be confused by titles. Make sure you don\'t enter a space character unless you really want to disallow spaces in titles. Leave empty to disable this feature.'),
    '#default_value' => wikitools_disallowed_characters(),
  );
  $form['wikitools_hijack_freelinking'] = array(
    '#type' => 'checkbox',
    '#title' => t('Hijack freelinking filter'),
    '#default_value' => wikitools_hijack_freelinking(),
    '#description' => t('If you activate this option, the links of the freelinking filter will be processed by the wikitools module rather than the freelinking module. When active, a link to <em>freelinking/Page Name</em> behaves exactly as a link to <em>wikipath/Page Name</em>.'),
  );
  $form['subpages'] = array(
    '#type' => 'fieldset',
    '#title' => t('Subpages'),
    '#description' => t('Subpages can be appended to a URL (either directly or via a query string) and will redirect the user to the named subpage.'),
  );
  $form['subpages']['wikitools_subpages_handling'] = array(
    '#type' => 'radios',
    '#title' => t('Activation'),
    '#options' => array(
      'disabled' => t('Disabled'),
      'url' => t('Enable url suffixes: With url suffixes, you can append the subpage to the URL. For example  <em>wikipath/Page/edit</em>.'),
      'query' => t('Enable query string: With query strings, you can append the subpage as a query. For example <em>wikipath/Page?wt_action=edit</em>.'),
    ),
    '#default_value' => wikitools_subpages_handling(),
  );
  $form['subpages']['wikitools_subpages'] = array(
    '#type' => 'textfield',
    '#title' => t('URL subpages'),
    '#description' => t('A list of available subpages. Only these subpages can be used as url suffixes or with the query string.'),
    '#default_value' => implode(", ", wikitools_subpages()),
  );
  return system_settings_form($form);
}

/**
 * Menu callback for duplicate pages list.
 */
function wikitools_page_duplicates() {
  $output = '';
  $found_nodes = FALSE;
  list($select_query, $count_query, $arguments) = _wikitools_duplicate_nodes_query();
  if ($select_query) {
    $nodes_per_page = variable_get('default_nodes_main', 10);

    // Grab all nodes that have the same title
    $result = pager_query($select_query, $nodes_per_page, 0, $count_query, $arguments);
    while ($node = db_fetch_object($result)) {
      $output .= node_view(node_load($node->nid), 1);
      $found_nodes = TRUE;
    }
  }
  if ($found_nodes) {
    $output .= theme('pager', NULL, $nodes_per_page);
  }

  // Return a nice listing of all the duplicate nodes
  return $output;
}

/**
 * Create queries to find nodes with duplicate titles.
 */
function _wikitools_duplicate_nodes_query() {
  $node_types = array_values(wikitools_node_types());
  if (count($node_types)) {

    // Make sure we deal with various title equalities
    $n1_title = 'n1.title';
    $n2_title = 'n2.title';
    if (wikitools_treat_underscore_as_space()) {
      $n1_title = 'REPLACE(' . $n1_title . ', "_", " ")';
      $n2_title = 'REPLACE(' . $n2_title . ', "_", " ")';
    }
    if (wikitools_treat_dash_as_space()) {
      $n1_title = 'REPLACE(' . $n1_title . ', "-", " ")';
      $n2_title = 'REPLACE(' . $n2_title . ', "-", " ")';
    }

    // Grab all nodes that have the same title
    $node_types_placeholders = NULL;
    foreach ($node_types as $node_type) {
      if ($node_types_placeholders) {
        $node_types_placeholders .= ",'%s'";
      }
      else {
        $node_types_placeholders = "'%s'";
      }
    }
    $from_part = 'FROM {node} n1, {node} n2 WHERE LOWER(' . $n1_title . ') = LOWER(' . $n2_title . ') AND n1.nid != n2.nid AND n1.type IN(' . $node_types_placeholders . ') AND n2.type IN(' . $node_types_placeholders . ')';
    $select_query = 'SELECT DISTINCT(n1.nid) ' . $from_part . ' ORDER BY n1.title ASC';
    $count_query = 'SELECT COUNT(DISTINCT(n1.nid)) ' . $from_part;
    return array(
      $select_query,
      $count_query,
      array_merge($node_types, $node_types),
    );
  }
  return array(
    NULL,
    NULL,
    NULL,
  );
}

/**
 * Implementation of hook_requirements().
 */
function wikitools_requirements($phase) {

  // Don't check when installing
  if ($phase == 'install') {
    return;
  }
  if (wikitools_hijack_freelinking()) {
    wikitools_autoadjust();
  }
}

/**
 * Adjust the module weights for wikitools to load after freelinking module.
 */
function wikitools_autoadjust() {
  $modules = array_keys(module_list());
  if (array_search('wikitools', $modules) <= array_search('freelinking', $modules)) {
    $freelinking_module_weight = db_result(db_query("SELECT weight FROM {system} WHERE name='freelinking'"));
    db_query("UPDATE {system} SET weight=%d WHERE name='wikitools'", $freelinking_module_weight + 1);
    drupal_set_message(t('Weight of %wikitools module set to %weight.', array(
      '%wikitools' => t('wikitools'),
      '%weight' => $wikitools_module_weight + 1,
    )));
  }
}

/*
 * Settings
 */

/**
 * Drupal path of wiki.
 */
function wikitools_wiki_path($value = NULL) {
  if (is_null($value)) {
    return variable_get('wikitools_path', 'wiki');
  }
  variable_set('wikitools_path', $value);
}

/**
 * Title of node on root path of wiki.
 */
function wikitools_main_page_title($value = NULL) {
  if (is_null($value)) {
    return variable_get('wikitools_main_page_title', 'Main Page');
  }
  variable_set('wikitools_main_page_title', $value);
}

/**
 * Node types of wiki pages.
 */
function wikitools_node_types($value = NULL) {
  if (is_null($value)) {
    static $node_types = NULL;
    if (is_null($node_types)) {
      $node_types = array();
      foreach (variable_get('wikitools_node_types', array()) as $type => $active) {
        if ($active) {
          $node_types[$type] = $type;
        }
      }
    }
    return $node_types;
  }
  variable_set('wikitools_node_types', $value);
}

/**
 * Is node type affected by wikitool options?
 */
function wikitools_type_affected($type) {
  static $node_types = NULL;
  if (is_null($node_types)) {
    $node_types = wikitools_node_types();
  }
  return isset($node_types[$type]) && $node_types[$type];
}

/**
 * String of characters which are not allowed in a wiki page title.
 */
function wikitools_disallowed_characters($value = NULL) {
  if (is_null($value)) {
    return variable_get('wikitools_disallowed_characters', '[]{}|');
  }
  variable_set('wikitools_disallowed_characters', $value);
}

/**
 * Various wikitool options.
 */
function wikitools_options($value = NULL) {
  if (is_null($value)) {
    return variable_get('wikitools_options', array(
      'node creation',
      'node search',
      'unique titles',
      'underscore as space',
    ));
  }
  return variable_set('wikitools_options', $value);
}

/**
 * Is node creation activated?
 */
function wikitools_node_creation() {
  $options = wikitools_options();
  return $options['node creation'];
}

/**
 * Is node search activated?
 */
function wikitools_node_search() {
  $options = wikitools_options();
  return $options['node search'];
}

/**
 * Is delete protection activated?
 */
function wikitools_delete_protection() {
  $options = wikitools_options();
  return $options['delete protection'];
}

/**
 * Is move protection activated?
 */
function wikitools_move_protection() {
  $options = wikitools_options();
  return $options['move protection'];
}

/**
 * Is automatic redirection activated?
 */
function wikitools_auto_redirect() {
  $options = wikitools_options();
  return $options['auto redirect'];
}

/**
 * Are unique titles enforced?
 */
function wikitools_enforce_unique_titles() {
  $options = wikitools_options();
  return $options['unique titles'];
}

/**
 * Are underscore characters treated as spaces?
 */
function wikitools_treat_underscore_as_space() {
  $options = wikitools_options();
  return $options['underscore as space'];
}

/**
 * Are dashes treated as spaces?
 */
function wikitools_treat_dash_as_space() {
  $options = wikitools_options();
  return $options['dash as space'];
}

/**
 * The subpage handling used?
 * @return
 *   'disabled', 'url' or 'query'
 */
function wikitools_subpages_handling($value = NULL) {
  if (is_null($value)) {
    return variable_get('wikitools_subpages_handling', 'disabled');
  }
  variable_set('wikitools_subpages_handling', $value);
}

/**
 * The query string used to specify subpages.
 */
function wikitools_subpages_query_string() {
  return 'wt_action';
}

/**
 * Array of URL subpages.
 */
function wikitools_subpages($value = NULL) {
  if (is_null($value)) {
    return preg_split("/[\\s,]+/", variable_get('wikitools_subpages', 'edit, delete, view, revisions'));
  }
  variable_set('wikitools_subpages', implode(", ", $value));
}

/**
 * Is the freelinking path hijacked?
 */
function wikitools_hijack_freelinking($value = NULL) {
  if (is_null($value)) {
    return variable_get('wikitools_hijack_freelinking', TRUE);
  }
  variable_set('wikitools_hijack_freelinking', $value);
}

/*
 * Operations
 */

/**
 * Decode page name given via URL.
 */
function wikitools_decode_page_name($encoded_page_name) {
  $page_name = trim(urldecode($encoded_page_name));
  if (wikitools_treat_underscore_as_space()) {
    $page_name = str_replace('_', ' ', $page_name);
  }
  if (wikitools_treat_dash_as_space()) {
    $page_name = str_replace('-', ' ', $page_name);
  }
  return $page_name;
}

/**
 * Menu callback for wiki path.
 * This function is called if a page without an alias is called below the wiki path.
 */
function wikitools_handle_request() {
  $output = '';

  // Create list of path parts.
  $args = explode('/', $_GET['q']);

  // Calculate index of first path argument after wiki path.
  if (arg(0) != 'freelinking') {
    $i = strlen(wikitools_wiki_path()) ? count(explode('/', wikitools_wiki_path())) : 0;
  }
  else {
    $i = 1;
  }

  // Determine subpage.
  $subpage = NULL;
  if (wikitools_subpages_handling() == 'query') {

    // Check if a query string is in the URL with a valid subpage
    if (isset($_GET[wikitools_subpages_query_string()])) {
      $subpage = $_GET[wikitools_subpages_query_string()];
      if (!in_array($subpage, wikitools_subpages())) {
        $subpage = NULL;
      }
    }
  }
  elseif (wikitools_subpages_handling() == 'url') {

    // Check if there are more than one part, and if the last one is a valid subpage.
    if (count($args) - $i > 1 && in_array(end($args), wikitools_subpages())) {
      $subpage = end($args);
      array_pop($args);
    }
  }

  // Determine page name.
  if (isset($args[$i])) {
    $page_name = wikitools_decode_page_name(implode('/', array_slice($args, $i)));
  }
  else {

    // Use default page title if only wiki path is entered.
    $page_name = wikitools_main_page_title();
  }

  // Don't do anything if no node types are active or no page name is available
  $node_types = wikitools_node_types();
  if (count($node_types) && $page_name) {

    // Try to find the current page with this name.
    $result = db_query("SELECT nid, type FROM {node} WHERE LOWER(title) = LOWER('%s')", $page_name);
    $found_nodes = array();
    while ($node = db_fetch_object($result)) {
      if (wikitools_type_affected($node->type)) {
        $found_nodes[] = $node;
      }
    }
    if (count($found_nodes) == 1) {

      // Single match for title.
      $node = current($found_nodes);
      if ($subpage) {
        drupal_goto("node/{$node->nid}/{$subpage}");
      }
      else {
        drupal_goto("node/{$node->nid}");
      }
    }
    else {
      if (count($found_nodes) > 1) {

        // Multiple match for title.
        drupal_set_title(t('Page found: %page', array(
          '%page' => $page_name,
        )));
        $output .= theme('wikitools_page_found', $page_name, $found_nodes);
      }
      else {

        // No match for title. Try to find an old page with this name
        $result = db_query("SELECT n.nid, n.type, n.title FROM {node} n LEFT JOIN {node_revisions} r ON n.nid = r.nid WHERE LOWER(r.title) = LOWER('%s') ORDER BY n.vid DESC", $page_name);
        $moved_nodes = array();
        while ($node = db_fetch_object($result)) {
          if (wikitools_type_affected($node->type)) {
            $moved_nodes[] = $node;
          }
        }
        if (count($moved_nodes) > 0 && wikitools_auto_redirect() && !isset($_REQUEST['noredirect'])) {
          $node = current($moved_nodes);
          drupal_set_message(t('Redirected from <a href="@url">%page</a>', array(
            '%page' => $page_name,
            '@url' => wikitools_wikilink_url($page_name, 'noredirect'),
          )));
          drupal_goto("node/{$node->nid}");
        }
        else {
          if (count($moved_nodes) > 0) {
            drupal_set_title(t('Page moved: %page', array(
              '%page' => $page_name,
            )));
            $output = theme('wikitools_page_moved', $page_name, $moved_nodes);
          }
          else {
            $wiki_path = wikitools_wiki_path();
            if (empty($wiki_path)) {
              return FALSE;
            }
            drupal_set_title(t('Page does not exist: %page', array(
              '%page' => $page_name,
            )));
            $output = theme('wikitools_page_does_not_exist', $page_name);
          }
        }
      }
    }
  }
  return $output;
}

/**
 * Dummy callback to return the page value sent.
 */
function wikitools_page_value($value) {
  return $value;
}

/**
 * Implementation of hook_nodeapi().
 */
function wikitools_nodeapi(&$node, $op, $form = NULL, $a4 = NULL) {
  switch ($op) {
    case 'validate':
      wikitools_node_validate($node);
      break;
  }
}

/**
 * Validate check of node edit form.
 */
function wikitools_node_validate($node) {
  if (wikitools_type_affected($node->type)) {

    // Check for unique titles.
    if (wikitools_enforce_unique_titles()) {

      // Build node type condition.
      $types_clause = NULL;
      foreach (wikitools_node_types() as $type) {
        if ($types_clause) {
          $types_clause .= ",'" . db_escape_string($type) . "'";
        }
        else {
          $types_clause = "type IN ('" . db_escape_string($type) . "'";
        }
      }

      // There is at least one node type, so this will always be well-formed.
      $types_clause .= ')';
      $nid = db_result(db_query("SELECT nid FROM {node} WHERE LOWER(title) = LOWER('%s') AND {$types_clause}", $node->title));
      if (!$nid && wikitools_treat_underscore_as_space()) {
        $nid = db_result(db_query("SELECT nid FROM {node} WHERE LOWER(REPLACE(title, '_', ' ')) = LOWER(REPLACE('%s', '_', ' ')) AND {$types_clause}", $node->title));
      }
      if (!$nid && wikitools_treat_dash_as_space()) {
        $nid = db_result(db_query("SELECT nid FROM {node} WHERE LOWER(REPLACE(title, '-', ' ')) = LOWER(REPLACE('%s', '-', ' ')) AND {$types_clause}", $node->title));
      }

      // It is only an error if the node which already exists is not the currently edited node.
      if ($nid && $nid != $node->nid) {
        form_set_error('title', t('A <a href="@page_url">page</a> with this name already exists.', array(
          '@page_url' => url("node/{$nid}"),
        )));
      }
    }

    // Check for disallowed characters in title.
    if ($disallowed_characters = wikitools_disallowed_characters()) {
      for ($i = 0; $i < strlen($node->title); $i++) {
        if (strpos($disallowed_characters, $node->title[$i]) !== FALSE) {
          form_set_error('title', t('The character %c is not allowed in a title', array(
            '%c' => $node->title[$i],
          )));
          break;
        }
      }
    }

    // Check for invalid title names if url subpages are enabled and "/" is allowed in titles.
    if (wikitools_subpages_handling() == 'url' && strpos("/", $disallowed_characters) === FALSE) {
      $title_parts = explode('/', $node->title);
      if (count($title_parts) > 1 && in_array(end($title_parts), wikitools_subpages())) {
        form_set_error('title', t('The title is not allowed to end in: %string', array(
          '%string' => '/' . implode(', /', wikitools_subpages()),
        )));
      }
    }
  }
}

/**
 * Implementation of hook_form_alter().
 */
function wikitools_form_alter($form_id, &$form) {

  // Check if it is a node editing form of an affected type.
  if (isset($form['type']) && $form['type']['#value'] . '_node_form' == $form_id) {
    if (wikitools_type_affected($form['type']['#value'])) {
      if ($form['nid']['#value']) {

        // Node is edited.
        if (wikitools_delete_protection() && !user_access('administer nodes')) {
          unset($form['delete']);
        }
        if (wikitools_move_protection() && !user_access('administer nodes')) {
          $form['title']['#disabled'] = TRUE;
        }
      }
      else {

        // Node is new.
        if (isset($_GET['edit'])) {
          $form['title']['#default_value'] = urldecode($_GET['edit']['title']);
        }
      }
    }
  }
}

/**
 * Callback of node delete action in protected mode.
 */
function wikitools_delete_protection_delete_confirm(&$node) {
  if (!wikitools_type_affected($node->type) || user_access('administer nodes')) {

    // Call original function.
    return drupal_get_form('node_delete_confirm', $node);
  }
  else {
    return drupal_access_denied();
  }
}

/**
 * Build an url to create a new node.
 * @param $type
 *   type of new node
 * @param $title
 *   title of new node
 */
function wikitools_create_url($type, $title) {
  return url("node/add/{$type}", 'edit[title]=' . urlencode($title));
}

/**
 * Build an url to search for a title.
 * @param $title
 *   title to search for
 */
function wikitools_search_url($title) {
  return url('search/node/' . urlencode($title));
}

/**
 * Build an url to link to a page.
 * @param $title
 *   title to link to
 * @param $query
 *   an optional query string to append to the link
 */
function wikitools_wikilink_url($title, $query = NULL) {
  $drupal_path = wikitools_wikilink_drupal_path($title);
  if ($drupal_path) {
    return url($drupal_path, $query);
  }
}

/**
 * Build a Drupal path to link to a page.
 * @param $title
 *   title to link to
 * @param $query
 *   an optional query string to append to the link
 */
function wikitools_wikilink_drupal_path($title) {
  if (wikitools_treat_underscore_as_space()) {
    $title = str_replace(' ', '_', $title);
  }
  if (wikitools_treat_dash_as_space()) {
    $title = str_replace(' ', '-', $title);
  }
  if ($wiki_path = wikitools_wiki_path()) {
    return $wiki_path . '/' . urlencode($title);
  }
  elseif (wikitools_hijack_freelinking()) {
    return 'freelinking/' . urlencode($title);
  }
  else {

    // Neither wikitools nor freelinking will handle the link.
    // Try to find a node with the given name and link directly to the first match.
    $result = db_query("SELECT nid, type FROM {node} WHERE LOWER(title) = LOWER('%s')", $title);
    $found_nodes = array();
    while ($node = db_fetch_object($result)) {
      if (wikitools_type_affected($node->type)) {
        return "node/{$node->nid}";
      }
    }
  }
}

/*
 * Theme functions
 */
function theme_wikitools_page_found($page_name, $found_nodes) {
  $output = '<p>' . t('Multiple pages have this name:') . '</p>';
  foreach ($found_nodes as $info) {
    $node = node_load($info->nid);
    $output .= node_view($node, TRUE, FALSE, FALSE);
  }
  $output .= theme('wikitools_search_notice', $page_name);
  if (!wikitools_enforce_unique_titles()) {
    $output .= theme('wikitools_create_notice', $page_name);
  }
  return $output;
}
function theme_wikitools_page_moved($page_name, $moved_nodes) {
  $output = '<p>' . t('The page %page_name has been moved.', array(
    '%page_name' => $page_name,
  )) . '</p>';
  $node = current($moved_nodes);
  $output .= '<p>' . t('The new page name is !new_name', array(
    '!new_name' => l($node->title, "node/{$node->nid}"),
  )) . '</p>';

  // Todo: show all moved pages
  $output .= theme('wikitools_search_notice', $page_name);
  $output .= theme('wikitools_create_notice', $page_name);
  return $output;
}
function theme_wikitools_page_does_not_exist($page_name) {
  $output = '<p>' . t('The page %page_name does not exist.', array(
    '%page_name' => $page_name,
  )) . '</p>';
  $output .= theme('wikitools_search_notice', $page_name);
  $output .= theme('wikitools_create_notice', $page_name);
  return $output;
}
function theme_wikitools_search_notice($page_name) {
  $output = '';
  if (module_exists('search') && user_access('search content') && wikitools_node_search()) {
    $output .= '<p>' . t('You can <a href="@url">search for %page_name</a>', array(
      '@url' => wikitools_search_url($page_name),
      '%page_name' => $page_name,
    )) . '</p>';
  }
  return $output;
}
function theme_wikitools_create_notice($page_name) {
  $output = '';
  $node_types = wikitools_node_types();
  if (wikitools_node_creation() && count($node_types)) {
    $create = '';
    foreach ($node_types as $type) {
      $type = node_get_types('type', $type);
      if (node_access('create', $type->type)) {
        $create .= '<dt><a href="' . wikitools_create_url($type->type, $page_name) . '">' . $type->name . '</a></dt>';
        $create .= '<dd>' . filter_xss_admin($type->description) . '</dd>';
      }
    }
    if ($create) {
      $output .= '<p>' . t('You can create the page as:') . '</p>';
      $output .= '<dl>' . $create . '</dl>';
    }
  }
  return $output;
}

Functions

Namesort descending Description
theme_wikitools_create_notice
theme_wikitools_page_does_not_exist
theme_wikitools_page_found
theme_wikitools_page_moved
theme_wikitools_search_notice
wikitools_admin_settings Builder function for settings form.
wikitools_autoadjust Adjust the module weights for wikitools to load after freelinking module.
wikitools_auto_redirect Is automatic redirection activated?
wikitools_create_url Build an url to create a new node.
wikitools_decode_page_name Decode page name given via URL.
wikitools_delete_protection Is delete protection activated?
wikitools_delete_protection_delete_confirm Callback of node delete action in protected mode.
wikitools_disallowed_characters String of characters which are not allowed in a wiki page title.
wikitools_enforce_unique_titles Are unique titles enforced?
wikitools_form_alter Implementation of hook_form_alter().
wikitools_handle_request Menu callback for wiki path. This function is called if a page without an alias is called below the wiki path.
wikitools_help Implementation of hook_help().
wikitools_hijack_freelinking Is the freelinking path hijacked?
wikitools_main_page_title Title of node on root path of wiki.
wikitools_menu Implementation of hook_menu().
wikitools_move_protection Is move protection activated?
wikitools_nodeapi Implementation of hook_nodeapi().
wikitools_node_creation Is node creation activated?
wikitools_node_search Is node search activated?
wikitools_node_types Node types of wiki pages.
wikitools_node_validate Validate check of node edit form.
wikitools_options Various wikitool options.
wikitools_page_duplicates Menu callback for duplicate pages list.
wikitools_page_value Dummy callback to return the page value sent.
wikitools_requirements Implementation of hook_requirements().
wikitools_search_url Build an url to search for a title.
wikitools_subpages Array of URL subpages.
wikitools_subpages_handling The subpage handling used?
wikitools_subpages_query_string The query string used to specify subpages.
wikitools_treat_dash_as_space Are dashes treated as spaces?
wikitools_treat_underscore_as_space Are underscore characters treated as spaces?
wikitools_type_affected Is node type affected by wikitool options?
wikitools_wikilink_drupal_path Build a Drupal path to link to a page.
wikitools_wikilink_url Build an url to link to a page.
wikitools_wiki_path Drupal path of wiki.
_wikitools_duplicate_nodes_query Create queries to find nodes with duplicate titles.