You are here

nodewords.module in Nodewords: D6 Meta Tags 6.3

Same filename and directory in other branches
  1. 5 nodewords.module
  2. 6 nodewords.module
  3. 6.2 nodewords.module

Implement an version that other modules can use to add meta tags.

File

nodewords.module
View source
<?php

/**
 * @file
 * Implement an version that other modules can use to add meta tags.
 */

/**
 * The type of objects to which the meta tags are associated.
 */
define('NODEWORDS_TYPE_CONTENT_TYPE', 12);
define('NODEWORDS_TYPE_DEFAULT', 1);
define('NODEWORDS_TYPE_ERRORPAGE', 2);
define('NODEWORDS_TYPE_NONE', 0);
define('NODEWORDS_TYPE_NODE', 5);
define('NODEWORDS_TYPE_OFFLINE', 11);
define('NODEWORDS_TYPE_PAGE', 10);
define('NODEWORDS_TYPE_PAGER', 4);
define('NODEWORDS_TYPE_TERM', 6);
define('NODEWORDS_TYPE_USER', 8);
define('NODEWORDS_TYPE_VOCABULARY', 9);

/**
 * The types of meta tags the module is able to handle.
 */
define('NODEWORDS_META', 0);
define('NODEWORDS_HTTP_EQUIV', 1);
define('NODEWORDS_LINK_REL', 2);
define('NODEWORDS_LINK_REV', 3);

/**
 * The minimum version version supported.
 */
define('NODEWORDS_MINIMUM_VERSION', '2.16');

/**
 * The current version version implemented.
 */
define('NODEWORDS_VERSION', '2.16');

/**
 * Implements hook_nodeapi().
 */
function nodewords_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'delete':
      nodewords_delete_tags(array(
        'type' => NODEWORDS_TYPE_NODE,
        'id' => $node->nid,
        'sid' => '*',
      ));
      break;
    case 'insert':
    case 'update':
      if (isset($node->nodewords)) {
        nodewords_save_tags($node->nodewords['metatags'], array(
          'type' => NODEWORDS_TYPE_NODE,
          'id' => $node->nid,
          'sid' => $node->vid,
          'language' => $node->language,
        ));
        unset($node->nodewords);
      }
      break;
    case 'load':
      $result = array();
      $result['nodewords']['metatags'] = nodewords_load_tags(array(
        'type' => NODEWORDS_TYPE_NODE,
        'id' => $node->nid,
        'sid' => $node->vid,
        'language' => $node->language,
      ));
      return $result;
  }
}

/**
 * Implements hook_perm().
 */
function nodewords_perm() {
  return array(
    'administer meta tags',
  );
}

/**
 * Implements hook_preprocess_page().
 */
function nodewords_preprocess_page(&$variables) {
  $output_tags = array();
  $head_tags = variable_get('nodewords_head', array());
  $options = nodewords_detect_type_id();
  $bool = $options['type'] != NODEWORDS_TYPE_NONE && $options['type'] != NODEWORDS_TYPE_OFFLINE;
  if ($bool) {
    $options['output'] = 'head';
    if ($options['type'] == NODEWORDS_TYPE_PAGER) {
      nodewords_load_all_includes('nodewords.tags.inc');
      foreach (nodewords_get_possible_tags() as $name => $info) {
        if (empty($head_tags[$name])) {
          continue;
        }
        $bool = !empty($info['context']['allowed']) && in_array(NODEWORDS_TYPE_PAGER, $info['context']['allowed']) && function_exists($function = $info['callback'] . '_prepare');
        if ($bool) {
          $options['parameters'] = !empty($info['callback arguments']) ? $info['callback arguments'] : array();
          $function($output_tags, array(), $options);
        }
      }
    }
    elseif ($options['type'] == NODEWORDS_TYPE_NODE) {
      $node = node_load(array(
        'nid' => $options['id'],
        'vid' => $options['sid'],
      ));
      if ($node && node_access('view', $node)) {
        $tags = nodewords_load_tags($options + array(
          'language' => $node->language,
        ));
      }
      else {
        $tags = array();
      }
    }
    else {
      $tags = nodewords_load_tags($options);
      nodewords_load_all_includes('nodewords.tags.inc');

      // Prepare the tags.
      foreach (nodewords_get_possible_tags() as $name => $info) {
        if (empty($head_tags[$name])) {
          continue;
        }
        if (function_exists($function = $info['callback'] . '_prepare')) {
          $options['parameters'] = !empty($info['callback arguments']) ? $info['callback arguments'] : array();
          $function($output_tags, _nodewords_tag_value($name, isset($tags[$name]) ? $tags[$name] : array(), $options + array(
            'admin' => FALSE,
          )), $options);
        }
      }
    }
    nodewords_load_all_includes('nodewords.hooks.inc');
    drupal_alter('metatags', $output_tags, $options);
    $output = _nodewords_output_tags($output_tags);
    drupal_alter('metatags_output', $output, $options);
    $variables['head'] = $output . "\n" . $variables['head'];
  }
}

/**
 * Implements hook_taxonomy().
 */
function nodewords_taxonomy($op, $type, $array = NULL) {
  switch ($type) {
    case 'term':
      $id = $array['tid'];
      $type = NODEWORDS_TYPE_TERM;
      break;
    case 'vocabulary':
      $id = $array['vid'];
      $type = NODEWORDS_TYPE_VOCABULARY;
      break;
    default:
      return;
  }
  switch ($op) {
    case 'delete':
      nodewords_delete_tags(array(
        'type' => $type,
        'id' => $id,
      ));
      break;
    case 'insert':
    case 'update':
      if (isset($array['nodewords']['metatags'])) {
        nodewords_save_tags($array['nodewords']['metatags'], array(
          'type' => $type,
          'id' => $id,
        ));
        unset($array['nodewords']);
      }
      break;
  }
}

/**
 * Implements hook_user().
 */
function nodewords_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'load':
      $account->nodewords['metatags'] = nodewords_load_tags(array(
        'type' => NODEWORDS_TYPE_USER,
        'id' => $account->uid,
      ));
      break;
    case 'delete':
      nodewords_delete_tags(array(
        'type' => NODEWORDS_TYPE_USER,
        'id' => $account->uid,
      ));
      break;
    case 'insert':
    case 'update':
      if (isset($edit['nodewords']['metatags'])) {
        nodewords_save_tags($edit['nodewords']['metatags'], array(
          'type' => NODEWORDS_TYPE_USER,
          'id' => $account->uid,
        ));
        unset($edit['nodewords']);
        unset($account->nodewords);
      }
      break;
  }
}

/**
 * Add the tokens help to the form.
 *
 * Add the tokens help to the form passed as argument.
 * It is responsability of the calling function to verify that token.module is
 * enabled.
 *
 * @param &$form
 *   The form to which the help text will be added.
 * @param $type
 *   An array containing information about the object for which the meta tags
 *   are being edited.
 */
function nodewords_add_tokens_help(&$form, $type) {
  switch ($type['type']) {
    case NODEWORDS_TYPE_ERRORPAGE:
    case NODEWORDS_TYPE_PAGE:
      $tokens_type[] = 'global';
      $tokens_type[] = 'global meta tags';
      break;
    case NODEWORDS_TYPE_DEFAULT:
      $tokens_type[] = 'global';
      $tokens_type[] = 'global meta tags';
      $tokens_type[] = 'node';
      $tokens_type[] = 'node meta tags';
      $tokens_type[] = 'taxonomy';
      $tokens_type[] = 'user';
      break;
    case NODEWORDS_TYPE_CONTENT_TYPE:
    case NODEWORDS_TYPE_NODE:
      $tokens_type[] = 'global';
      $tokens_type[] = 'global meta tags';
      $tokens_type[] = 'node';
      $tokens_type[] = 'node meta tags';
      break;
    case NODEWORDS_TYPE_TERM:
    case NODEWORDS_TYPE_VOCABULARY:
      $tokens_type[] = 'global';
      $tokens_type[] = 'global meta tags';
      $tokens_type[] = 'taxonomy';
      break;
    case NODEWORDS_TYPE_USER:
      $tokens_type[] = 'global';
      $tokens_type[] = 'global meta tags';
      $tokens_type[] = 'user';
      break;
    default:
      $tokens_type = '';
  }
  if ($tokens_type) {
    $form['token_help'] = array(
      '#title' => t('Replacement patterns'),
      '#type' => 'fieldset',
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#description' => t('Prefer raw-text replacements for text to avoid problems with HTML entities.'),
    );
    $form['token_help']['help'] = array(
      '#value' => theme('token_help', $tokens_type),
    );
  }
}

/**
 * Verify the version version is one currently supported by Nodewords.
 *
 * @param $version
 *   The version string as accepted by version_compare().
 *
 * @return
 *   TRUE, if the version version is currently supported by Nodewords.
 */
function nodewords_check_version($version) {
  return version_compare($version, NODEWORDS_MINIMUM_VERSION, '>=') && version_compare($version, NODEWORDS_VERSION, '<=');
}

/**
 * Delete tags from table.
 */
function nodewords_delete_tags(array $options = array()) {
  $options += array(
    'type' => NODEWORDS_TYPE_DEFAULT,
    'id' => '',
    'sid' => 0,
    'language' => '*',
  );
  $args = array(
    $options['type'],
    $options['id'],
  );
  $query = "DELETE FROM {nodewords} WHERE type = %d AND id = %d";
  if ($options['sid'] != '*') {
    $args[] = $options['sid'];
    $query .= ' AND sid = %d';
  }
  if ($options['language'] != '*') {
    $args[] = $options['language'];
    $query .= " AND language = '%s'";
  }
  db_query($query, $args);
  nodewords_load_all_includes('nodewords.hooks.inc');
  module_invoke_all('metatags_delete', $options);
}

/**
 * Try to guess the type and the ID associated with the viewed page.
 *
 * @param $options
 *   An array of parameters that describe the page to check. If the array is
 *   is not passed, the function will return the type of the currently viewed
 *   page.
 *
 * @return
 *   An array containing information about the type of the page.
 */
function nodewords_detect_type_id(array $options = array()) {
  $arg = empty($options['q']) ? arg() : array_filter(explode('/', $options['q']));
  $page = empty($options['page']) ? isset($_REQUEST['page']) ? $_REQUEST['page'] : -1 : $options['page'];
  $headers = empty($options['headers']) ? drupal_get_headers() : $options['headers'];
  $bool = variable_get('site_offline', 0) && !user_access('administer site configuration');
  if ($bool) {
    return array(
      'type' => NODEWORDS_TYPE_OFFLINE,
      'id' => 0,
    );
  }
  if (preg_match('@HTTP/1\\.[01]\\x20+403[^a-zA-Z0-9]@', $headers)) {
    return array(
      'type' => NODEWORDS_TYPE_ERRORPAGE,
      'id' => 403,
    );
  }
  if (preg_match('@HTTP/1\\.[01]\\x20+404[^a-zA-Z0-9]@', $headers)) {
    return array(
      'type' => NODEWORDS_TYPE_ERRORPAGE,
      'id' => 404,
    );
  }
  $bool = !variable_get('nodewords_list_repeat', FALSE) && intval($page) > 0;
  if ($bool) {
    return array(
      'type' => NODEWORDS_TYPE_PAGER,
      'id' => 0,
    );
  }
  if (!isset($arg[0])) {
    return array(
      'type' => NODEWORDS_TYPE_NONE,
      'id' => 0,
    );
  }
  _nodewords_load_hook_files();
  $result = array(
    'type' => NODEWORDS_TYPE_NONE,
    'id' => 0,
  );
  foreach (module_implements('nodewords_type_id') as $module) {
    $function = $module . '_nodewords_type_id';
    $function($result, $arg);
    if ($result['type'] != NODEWORDS_TYPE_NONE) {
      return $result;
    }
  }
  return array(
    'type' => NODEWORDS_TYPE_NONE,
    'id' => 0,
  );
}

/**
 * Query all the modules implementing meta tags and return the list of meta tags.
 *
 * @return
 *   An array containing the list of meta tags definitions.
 */
function nodewords_get_possible_tags() {
  static $tags_info = array();
  nodewords_load_all_includes('nodewords.hooks.inc');
  if (empty($tags_info)) {

    // Allow third-party modules to alter the  meta tags list, or to add new
    // meta tags.
    foreach (module_implements('metatags_info') as $module) {
      $result = module_invoke($module, 'metatags_info');
      if (isset($result) && is_array($result)) {
        $tags_info = array_merge($tags_info, $result);
      }
    }
  }
  drupal_alter('metatags_info', $tags_info);
  return $tags_info;
}

/**
 * Return the term object matching a term ID. This is a modified version of
 * taxonomy_get_term() which uses db_rewrite_sql().
 *
 * @param $tid
 *   A term's ID.
 * @param $uid
 *  The user ID; if not passed, the function will use the global user ID.
 *
 * @return
 *   A term object, or FALSE. Results are statically cached.
 */
function nodewords_get_term($tid, $uid = NULL) {
  global $user;
  static $terms = array();
  if (!isset($uid)) {
    $uid = $user->uid;
  }
  if (!isset($terms[$uid][$tid])) {
    $terms[$uid][$tid] = db_fetch_object(db_query(db_rewrite_sql('SELECT * FROM {term_data} t WHERE t.tid = %d', 't', 'tid'), $tid));
  }
  return !empty($terms[$uid][$tid]) ? $terms[$uid][$tid] : FALSE;
}

/**
 * Load an include file for each of the modules that have support for Nodewords.
 *
 * @param $file
 *   The file to load; the name of the module will be preappended to the file
 *   name passed. By default the file name is 'nodewords.inc'.
 */
function nodewords_load_all_includes($file = 'nodewords.inc') {
  foreach (module_implements('metatags_api') as $module) {
    $info = module_invoke($module, 'metatags_api');
    if (isset($info['version']) && nodewords_check_version($info['version'])) {
      if (isset($info['path']) && $info['path'] == '') {

        // Special case: if the path is an empty string, the directory used will be
        // the directory include in the module directory.
        $include_path = drupal_get_path('module', $module) . '/includes/';
      }
      elseif (isset($info['path'])) {
        $include_path = $info['path'] . '/';
      }
      else {
        $include_path = drupal_get_path('module', $module) . '/';
      }
      $include_file = $include_path . $module . '.' . $file;
      if (is_file($include_file)) {
        require_once $include_file;
      }
      elseif ($file != 'nodewords.inc' && is_file($include_file = $include_path . $module . '.' . 'nodewords.inc')) {
        require_once $include_file;
      }
    }
  }
}

/**
 * Load an include file.
 *
 * @param $module
 *   The module for which the file is loaded.
 *
 * @param $file
 *   The file to load; the name of the module will be preappended to the file
 *   name passed. By default the file name is 'nodewords.inc'.
 *
 */
function nodewords_load_include($module, $file = 'nodewords.inc') {
  $info = module_invoke($module, 'metatags_api');
  if (isset($info['path']) && $info['path'] == '') {

    // Special case: if the path is an empty string, the directory used will be
    // the directory include in the module directory.
    $include_path = drupal_get_path('module', $module) . '/includes/';
  }
  elseif (isset($info['path'])) {
    $include_path = $info['path'] . '/';
  }
  else {
    $include_path = drupal_get_path('module', $module) . '/';
  }
  $include_file = $include_path . $module . '.' . $file;
  if (is_file($include_file)) {
    require_once $include_file;
  }
  elseif ($file != 'nodewords.inc' && is_file($include_file = $include_path . $module . '.' . 'nodewords.inc')) {
    require_once $include_file;
  }
  else {
    return FALSE;
  }
}

/**
 * Load tags from table.
 *
 * @param $options
 *  An array of options.
 *
 * @return
 *  An array of meta tags data as saved in the database table.
 */
function nodewords_load_tags(array $options = array()) {
  global $language;
  $tags = array();
  $options += array(
    'language' => $language->language,
  ) + _nodewords_get_default_metatags_type();
  $tags_info = nodewords_get_possible_tags();
  $result = _nodewords_get_tags_data_query($options);
  while ($row = db_fetch_object($result)) {
    if (isset($tags_info[$row->name])) {
      $tags[$row->name] = unserialize($row->content);
    }
  }
  if (empty($tags) && $options['type'] == NODEWORDS_TYPE_TERM) {
    $id = db_result(db_query_range('SELECT vid FROM {term_data} WHERE tid = %d', $options['id'], 0, 1));
    if ($id !== FALSE) {
      $options['type'] = NODEWORDS_TYPE_VOCABULARY;
      $options['id'] = $id;
      return nodewords_load_tags($options);
    }
  }
  return $tags;
}

/**
 * Create the content of a meta tag from a node teaser.
 *
 * @param $text
 *   The string to use.
 * @param $format
 *   The format set for the node.
 * @param $options
 *  An array of options; currently, the only used is the maximum allowed
 *  length.
 *
 * @return
 *   The string to use to populate the meta tag.
 */
function nodewords_replace_tokens($content, array $options = array()) {
  global $user;
  $token_objects = array();
  $options += _nodewords_get_default_metatags_type();
  if (empty($content) || !module_exists('token')) {
    return $content;
  }
  switch ($options['type']) {
    case NODEWORDS_TYPE_ERRORPAGE:
    case NODEWORDS_TYPE_PAGE:
      $token_objects['global'] = NULL;
      $token_objects['global meta tags'] = NULL;
      break;
    case NODEWORDS_TYPE_NODE:
      $token_objects['global'] = NULL;
      $token_objects['global meta tags'] = NULL;
      $token_objects['node'] = _nodewords_node_load($options);
      $token_objects['node meta tags'] = $token_objects['node'];
      break;
    case NODEWORDS_TYPE_TERM:
    case NODEWORDS_TYPE_VOCABULARY:
      $token_objects['global'] = NULL;
      $token_objects['global meta tags'] = NULL;
      $token_objects['taxonomy'] = _nodewords_taxonomy_load($options);
      break;
    case NODEWORDS_TYPE_USER:
      $token_objects['global'] = NULL;
      $token_objects['global meta tags'] = NULL;
      $token_objects['user'] = user_load($options['id']);
      break;
    default:
      return $content;
  }

  // Remove the not replaced tokens.
  $content = token_replace_multiple($content, $token_objects);
  $replacements = array();
  token_include();
  foreach (module_implements('token_list') as $module) {
    $function = $module . '_token_list';
    $result = $function('all');
    if (is_array($result)) {
      foreach ($result as $category => $tokens) {
        foreach ($tokens as $token => $title) {
          $replacements['[' . $token . ']'] = '';
        }
      }
    }
  }
  if (!empty($replacements)) {
    $content = strtr($content, $replacements);
  }
  return $content;
}

/**
 * Update or insert tags in the table.
 */
function nodewords_save_tags($tags, $options = array()) {
  global $language, $user;
  $done = FALSE;
  $options += array(
    'language' => $language->language,
    'log_message' => TRUE,
  ) + _nodewords_get_default_metatags_type();
  $tags_info = nodewords_get_possible_tags();
  $types_str = _nodewords_get_type_strings();
  foreach ($tags as $name => $content) {
    if (isset($tags_info[$name])) {
      $content = serialize($content);
      $result = _nodewords_get_tags_data($name, $options);
      if ($result === FALSE) {
        $row = _nodewords_init_tags_data($name, $options);
      }
      else {
        $row = $result;
      }
      $row->content = $content;
      $ret = drupal_write_record('nodewords', $row, isset($row->mtid) ? 'mtid' : array());
      if (!$done && $options['log_message'] && $ret) {
        watchdog('meta tags', 'User %name changed the meta tags for type %type (%id - %sid).', array(
          '%name' => $user->name,
          isset($types_str[$options['type']]) ? $types_str[$options['type']] : t('unknown'),
          '%id' => $options['id'],
          '%sid' => $options['sid'],
        ));
        $done = TRUE;
      }
    }
  }
}

/**
 * Return the form used to set the meta tags values.
 *
 * @param $type
 *   An array containing the type of the object, and its ID.
 *
 * @param $tags
 *   The meta tags array as returned by nodewords_load_tags().
 *
 * @return
 *   An array as requested by the form version.
 */
function nodewords_tags_edit_fields($object, $tags, array $options = array()) {
  $form = array();
  $tokens_support = FALSE;
  $tokens_type = array();
  $options += array(
    'admin' => FALSE,
    'collapsed' => TRUE,
    'collapsible' => TRUE,
    'description' => '',
    'fieldset' => FALSE,
    'title' => t('Meta tags'),
    'weight' => 20,
  );
  $edit_tags = variable_get(!empty($options['admin']) ? 'nodewords_admin_edit' : 'nodewords_ui_edit', array());
  $head_output = variable_get('nodewords_head', array());
  $tokens_enabled = module_exists('token') && variable_get('nodewords_enable_tokens', TRUE);
  $object += _nodewords_get_default_metatags_type();
  if (isset($options['tag options']) && is_array($options['tag options'])) {
    $tag_options = $options['tag options'] + $object;
  }
  else {
    $tag_options = $object;
  }
  nodewords_load_all_includes('nodewords.tags.inc');
  nodewords_load_all_includes('nodewords.hooks.inc');
  $filter_metatags = $object['type'] != NODEWORDS_TYPE_DEFAULT;
  foreach (nodewords_get_possible_tags() as $name => $info) {
    $description = array();
    $permission = TRUE;
    drupal_alter('metatags_permission', $permission, $object, $name, $info);
    if ($permission) {
      $bool = !empty($info['context']['allowed']) && is_array($info['context']['allowed']) && !in_array($object['type'], $info['context']['allowed']) || !empty($info['context']['denied']) && is_array($info['context']['denied']) && in_array($object['type'], $info['context']['denied']);
      if ($bool || $filter_metatags && empty($edit_tags[$name])) {
        continue;
      }
      if (!empty($info['tokens'])) {
        $description[] = ' <strong>' . t('This meta tag supports tokens.') . '</strong>';
        $tokens_support = TRUE;
      }
      if (empty($head_output[$name]) && user_access('administer meta tags')) {
        $description[] = ' ' . t('This meta tag has not been selected to be output in HTML.');
      }
      if (function_exists($function = $info['callback'] . '_form')) {
        if (!empty($description)) {
          $tag_options['description'] = implode('', $description);
        }
        else {
          $tag_options['description'] = '';
        }
        $tag_options['parameters'] = !empty($info['callback arguments']) ? $info['callback arguments'] : array();
        $function($form_metatags, _nodewords_tag_value($name, isset($tags[$name]) ? $tags[$name] : array(), $object + array(
          'admin' => $options['admin'],
        )), $tag_options);
      }
    }
  }
  if (!empty($form_metatags) && $options['fieldset']) {
    $form['#tree'] = TRUE;
    $form['#type'] = 'fieldset';
    $form['#title'] = $options['title'];
    $form['#description'] = $options['description'];
    $form['#collapsible'] = $options['collapsible'];
    $form['#collapsed'] = $options['collapsed'];
    $form['#weight'] = $options['weight'];
    $form['#group'] = 'additional_settings';
  }
  if (!empty($options['first fields'])) {
    $form = $options['first fields'] + $form;
  }
  if (!empty($form_metatags)) {
    $form['metatags'] = $form_metatags;
  }
  if ($tokens_enabled && $tokens_support) {
    nodewords_add_tokens_help($form, $type);
  }
  if (!empty($options['last fields'])) {
    $form += $options['last fields'];
  }
  return $form;
}

/*
 * Remove the duplicates from a list of items separated from the separator,
 * preserving the order in which they appear.
 * @param $text
 *   The string containing the list of items concatenated using $separator.
 * @param $separator
 *   The string used to split the string into an array. A space will be appended
 *   to the string before it is used to create the string from the array of
 *   unique items found in the string passed as argument.
 * @param $max_items
 *   The maximum number of items accepted in the returned array; the default
 *   value is -1, which means no limit.
 *
 * @return
 *   A string containing only unique items present in the string of concatenated
 *   items.
 */
function nodewords_unique_values($text, array $options = array()) {
  $lc_values = array();
  $unique_values = array();
  $options += array(
    'separator' => ',',
    'max_items' => -1,
  );
  if (empty($text)) {
    return '';
  }
  foreach (array_filter(array_map('trim', explode($options['separator'], $text))) as $item) {
    $lowercase = drupal_strtolower($item);
    if (!in_array($lowercase, $lc_values)) {
      $lc_values[] = $lowercase;
      $unique_values[] = $item;
    }
  }
  if ($options['max_items'] > 0) {
    $unique_values = array_slice($unique_values, 0, $options['max_items']);
  }
  return implode($options['separator'], $unique_values);
}

/**
 * Return the absolute URL of a path.
 *
 * Return the absolute URL of a path built using the base URL saved in the
 * Drupal variable nodewords_base_url.
 *
 * @param $path
 *  The path for which the absolute must be built.
 * @param $options
 *  An array of options as used by url().
 */
function nodewords_url($path, array $options = array()) {
  $options += array(
    'alias' => TRUE,
    'absolute' => TRUE,
    'base_url' => rtrim(variable_get('nodewords_base_url', ''), '/'),
    'fragment' => '',
    'query' => '',
    'prefix' => '',
  );
  if (empty($options['base_url'])) {
    $options['base_url'] = NULL;
  }
  return url($path, $options);
}

/**
 * Return the default values that identify the object associated with the meta tags.
 *
 * @return
 *   An array containing the indexes 'type', 'sid', and 'id'.
 */
function _nodewords_get_default_metatags_type() {
  return array(
    'type' => NODEWORDS_TYPE_DEFAULT,
    'id' => 0,
    'sid' => 0,
    'language' => '',
  );
}
function _nodewords_get_tags_data($name, array $options) {
  return db_fetch_object(db_query_range("SELECT * FROM {nodewords} WHERE type = %d AND id = '%s' AND sid = %d AND name = '%s' AND language = '%s'", $options['type'], $options['id'], $options['sid'], $name, $options['language'], 0, 1));
}
function _nodewords_get_tags_data_query(array $options) {
  $exists = db_result(db_query_range("SELECT 1 FROM {nodewords} WHERE type = %d AND id = '%s' AND sid = %d AND language = '%s'", $options['type'], $options['id'], $options['sid'], $options['language'], 0, 1));
  if (!$exists) {
    $options['language'] = '';
  }
  $result = db_query("SELECT * FROM {nodewords} WHERE type = %d AND id = '%s' AND sid = %d AND language = '%s'", $options['type'], $options['id'], $options['sid'], $options['language']);
  return $result;
}
function _nodewords_get_type_strings() {
  return array(
    NODEWORDS_TYPE_DEFAULT => t('default'),
    NODEWORDS_TYPE_ERRORPAGE => t('HTTP error page'),
    NODEWORDS_TYPE_NODE => t('node'),
    NODEWORDS_TYPE_PAGE => t('custom page'),
    NODEWORDS_TYPE_TERM => t('taxonomy term'),
    NODEWORDS_TYPE_USER => t('user profile'),
    NODEWORDS_TYPE_VOCABULARY => t('vocabulary'),
  );
}
function _nodewords_init_tags_data($name, array $options) {
  $row = new stdClass();
  $row->type = $options['type'];
  $row->id = $options['id'];
  $row->sid = $options['sid'];
  $row->name = $name;
  $row->language = $options['language'];
  return $row;
}

/**
 * Load the files in the directory "includes" basing on the enabled modules.
 *
 */
function _nodewords_load_hook_files() {
  $dir = drupal_get_path('module', 'nodewords') . '/includes';
  foreach (file_scan_directory($dir, '.*\\.inc', array(
    '.',
    '..',
    'CVS',
  ), 0, FALSE) as $filename => $info) {
    $bool = module_exists($info->name) && !module_hook($info->name, 'metatags_type');
    if ($bool) {
      module_load_include('inc', 'nodewords', 'includes/' . $info->name);
    }
  }
  nodewords_load_all_includes('nodewords.hooks.inc');
}
function _nodewords_node_load($options) {
  return node_load(array(
    'nid' => $options['id'],
    'vid' => $options['sid'],
  ));
}

/**
 * Render the meta tag values as HTML.
 *
 * @param $tags
 *   An array of tags.
 *
 * @param $output_type
 *  The type of output, 'head' (default), or 'update index'.
 *
 * @return
 *   A string containing the HTML output for the META tag.
 */
function _nodewords_output_tags(array $tags) {
  $output = array();
  $tags_info = nodewords_get_possible_tags();
  $weights = array();
  foreach ($tags as $name => $content) {
    if (empty($content)) {
      continue;
    }
    $parts = explode(':', $name);
    $template = '';
    if (!isset($parts[1])) {
      $parts[1] = $parts[0];
    }
    if (!is_array($content)) {
      $content = array(
        $content,
      );
    }
    foreach ($content as $value) {
      $bool = isset($tags_info[$parts[0]]['templates']['head'][$parts[1]]) && ($meta_name = check_plain(decode_entities(strip_tags($parts[1])))) && ($meta_content = trim(check_plain(decode_entities(strip_tags(preg_replace('/(\\s)\\s+/', '$1', $value))))));
      if ($bool) {
        $replace = array(
          '%name' => $meta_name,
          '%content' => $meta_content,
          '%attributes' => empty($tags_info[$parts[0]]['attributes'][$parts[1]]) ? '' : drupal_attributes($tags_info[$parts[0]]['attributes'][$parts[1]]),
        );
        $template = $tags_info[$parts[0]]['templates']['head'][$parts[1]];
        $weight = isset($tags_info[$parts[0]]['weight'][$parts[1]]) ? $tags_info[$parts[0]]['weight'][$parts[1]] : 0;
        switch ($template) {
          case NODEWORDS_META:
            $template = '<meta name="%name" content="%content"%attributes />';
            break;
          case NODEWORDS_HTTP_EQUIV:
            $template = '<meta http-equiv="%name" content="%content"%attributes />';
            break;
          case NODEWORDS_LINK_REL:
            $template = '<link rel="%name" href="%content"%attributes />';
            break;
          case NODEWORDS_LINK_REV:
            $template = '<link rev="%name" href="%content"%attributes />';
            break;
          default:
            if (!is_string($template)) {
              $template = '';
            }
            break;
        }
      }
      if (!empty($template)) {
        $output[] = strtr($template, $replace);
        $weights[] = $weight;
      }
    }
  }
  if (count($output)) {
    array_multisort($weights, $output);
    return implode("\n", $output);
  }
  else {
    return '';
  }
}
function _nodewords_tag_value($tag, $value, $options = array()) {
  static $default = NULL;
  $options += _nodewords_get_default_metatags_type();
  $id = $options['id'];
  $sid = $options['sid'];
  $type = $options['type'];
  if (!isset($default[$type][$id][$sid])) {
    $default_values = array();
    nodewords_load_all_includes('nodewords.hooks.inc');
    drupal_alter('metatags_default_values', $default_values, $options + array(
      'phase' => 'pre_load',
    ));
    if (!empty($default_values)) {
      $default[$type][$id][$sid] = $default_values;
    }
    else {
      $default[$type][$id][$sid] = nodewords_load_tags();
      drupal_alter('metatags_default_values', $default[$type][$id][$sid], $options + array(
        'phase' => 'post_load',
      ));
    }
  }
  if ($type == NODEWORDS_TYPE_DEFAULT) {
    $value = isset($default[$type][$id][$sid][$tag]) ? $default[$type][$id][$sid][$tag] : array();
  }
  else {
    $tags_info = nodewords_get_possible_tags();
    $variable = empty($options['admin']) ? 'nodewords_ui_use_default_value_' . $tag : 'nodewords_admin_use_default_value_' . $tag;
    switch (variable_get($variable, 'empty')) {
      case 'empty':
        $bool = isset($tags_info[$tag]['callback']) && function_exists($function = $tags_info[$tag]['callback'] . '_is_empty');
        if ($bool && $function($value)) {
          $value = isset($default[$type][$id][$sid][$tag]) ? $default[$type][$id][$sid][$tag] : array();
        }
        elseif (!$bool && empty($value['value'])) {
          $value = isset($default[$type][$id][$sid][$tag]) ? $default[$type][$id][$sid][$tag] : array();
        }
        break;
      case 'always':
        $value = isset($default[$type][$id][$sid][$tag]) ? $default[$type][$id][$sid][$tag] : array();
        break;
    }
  }
  return $value;
}
function _nodewords_taxonomy_load(array $options) {
  $value = NULL;
  if ($options['type'] == NODEWORDS_TYPE_TERM) {
    $value = taxonomy_get_term($options['id']);
  }
  elseif ($options['type'] == NODEWORDS_TYPE_TERM) {
    $value = taxonomy_vocabulary_load($options['id']);
  }
  return $value;
}

Functions

Namesort descending Description
nodewords_add_tokens_help Add the tokens help to the form.
nodewords_check_version Verify the version version is one currently supported by Nodewords.
nodewords_delete_tags Delete tags from table.
nodewords_detect_type_id Try to guess the type and the ID associated with the viewed page.
nodewords_get_possible_tags Query all the modules implementing meta tags and return the list of meta tags.
nodewords_get_term Return the term object matching a term ID. This is a modified version of taxonomy_get_term() which uses db_rewrite_sql().
nodewords_load_all_includes Load an include file for each of the modules that have support for Nodewords.
nodewords_load_include Load an include file.
nodewords_load_tags Load tags from table.
nodewords_nodeapi Implements hook_nodeapi().
nodewords_perm Implements hook_perm().
nodewords_preprocess_page Implements hook_preprocess_page().
nodewords_replace_tokens Create the content of a meta tag from a node teaser.
nodewords_save_tags Update or insert tags in the table.
nodewords_tags_edit_fields Return the form used to set the meta tags values.
nodewords_taxonomy Implements hook_taxonomy().
nodewords_unique_values
nodewords_url Return the absolute URL of a path.
nodewords_user Implements hook_user().
_nodewords_get_default_metatags_type Return the default values that identify the object associated with the meta tags.
_nodewords_get_tags_data
_nodewords_get_tags_data_query
_nodewords_get_type_strings
_nodewords_init_tags_data
_nodewords_load_hook_files Load the files in the directory "includes" basing on the enabled modules.
_nodewords_node_load
_nodewords_output_tags Render the meta tag values as HTML.
_nodewords_tag_value
_nodewords_taxonomy_load

Constants