You are here

autotag.module in Taxonomy Autotagger 7.3

Same filename and directory in other branches
  1. 8.3 autotag.module
  2. 6.2 autotag.module
  3. 6 autotag.module

Implements the API on tag suggestion/autotagging modules as outlined at http://groups.drupal.org/node/100179

File

autotag.module
View source
<?php

/**
 * @file
 * 
 * Implements the API on tag suggestion/autotagging modules as outlined at
 * http://groups.drupal.org/node/100179
 */

/**
 * Implementation of hook_tag_suggestion_info().
 */
function autotag_tag_suggestion_info() {
  return array(
    'autotag' => array(
      'label' => t('Taxonomy term searcher'),
      'description' => t('Automatically associates terms from a taxonomy if the term appears within the text of the node'),
      'request_callback' => 'autotag_tag_suggestions',
      'options' => array(
        'callback' => 'autotag_tag_options',
        'keys' => array(
          'autotag_vids',
          'tag_only_with_tips',
        ),
      ),
    ),
  );
}

/**
 * Callback as defined above in hook_tag_suggestion_info
 */
function autotag_tag_suggestions($text, $options) {

  // Simply passed the text.  We now need to get the vids that we're interested
  // in (specific for this module).
  $tags = array();
  foreach ($options['autotag_vids'] as $vid) {
    $term_count = db_query("SELECT COUNT(*) FROM {taxonomy_term_data} WHERE vid = ?", array(
      $vid,
    ))
      ->fetchField();
    if ($term_count > 0 && strlen(trim($text))) {
      $tags = array_merge($tags, autotag_search_text($text, $vid, $options['tag_only_with_tips']));
    }
  }
  return $tags;
}

/**
 * Compare functions
 */
function autotag_search_text($text, $vid, $tag_only_leaves) {
  $tags_to_return = array();

  /**
   * Discovered that the following only seems to work in PHP 5.2, FARP!
   * Thanks to
   * http://stackoverflow.com/questions/790596/split-a-text-into-single-words
   * $words_including_small = preg_split('/[\p{P}\s\{\}\[\]\(\)]/', strtolower($text), -1, PREG_SPLIT_NO_EMPTY);
   *
   * Note, we split the string only once, so we have to pass the body text
   * to the search functions
   */

  // Lower the text!
  $text = strtolower($text);
  $words = array_unique(preg_split('/[\\ `!"£$%^&*()_\\-+={\\[}\\]:;@\'~#<,>.?\\/|\\\\]/', $text, -1, PREG_SPLIT_NO_EMPTY));
  if (!count($words)) {
    return $tags_to_return;
  }

  // We have the words, we need to check
  // We create a temporary table with all the words in it, and then compare this
  // temporary table against the taxonomy_term_data table.
  // First, we create the temporary table
  $temporary_table_name = db_query_temporary('SELECT ? AS words', array(
    array_pop($words),
  ));

  // Now we insert the rest of the data into the table.  We also add an index
  // to ensure that searching the data is quick, and update the column to be
  // a varchar(255).  Note, this can actually fail, but it does not actually
  // matter.
  try {
    db_change_field($temporary_table_name, 'words', 'words', array(
      'type' => 'varchar',
      'length' => 255,
    ));
  } catch (Exception $e) {
  }
  try {
    db_add_primary_key($temporary_table_name, array(
      'words',
    ));
  } catch (Exception $e) {
  }
  $values = array();
  $insert = db_insert($temporary_table_name);
  $insert
    ->fields(array(
    'words',
  ));
  foreach ($words as $word) {
    if (strlen($word < 256)) {
      $insert
        ->values(array(
        'words' => $word,
      ));
    }
  }
  try {
    $insert
      ->execute();
  } catch (Exception $e) {

    // FIXME - This currently does not work with 4-byte characters.  I need to
    // change this code so that it does not use a temporary table.
    return array();
  }

  // Select the direct single word matches.
  $select = db_select('taxonomy_term_data', 't');
  $select
    ->condition('vid', $vid);
  $select
    ->join($temporary_table_name, 'a', 'a.words LIKE t.name');
  $select
    ->addField('t', 'tid');
  $select
    ->addField('t', 'name');
  if ($tag_only_leaves) {
    $notin = db_select('taxonomy_term_hierarchy', 'tth')
      ->fields('tth', array(
      'parent',
    ));
    $select
      ->condition('t.tid', $notin, 'NOT IN');
  }
  $results = $select
    ->execute();
  foreach ($results as $term) {
    $tags_to_return[] = taxonomy_term_load($term->tid);
  }

  // Next we need to get the multiple word terms
  $select = db_select('taxonomy_term_data', 't');
  $select
    ->condition('vid', $vid);
  $select
    ->condition('name', '% %', 'LIKE');
  $select
    ->addField('t', 'tid');
  $select
    ->addField('t', 'name');
  if ($tag_only_leaves) {
    $select
      ->condition('t.tid', $notin, 'NOT IN');
  }
  $results = $select
    ->execute();
  foreach ($results as $term) {
    if (strpos($text, strtolower($term->name)) !== FALSE) {
      $tags_to_return[] = taxonomy_term_load($term->tid);
    }
  }
  return $tags_to_return;
}

/**
 * Callback for the options form
 */
function autotag_tag_options($node_type, $settings) {
  $vocabularies = taxonomy_vocabulary_load_multiple(FALSE);
  $options = array();
  foreach ($vocabularies as $vid => $vocabulary) {
    $options[$vid] = $vocabulary->name;
  }
  return array(
    'tag_only_with_tips' => array(
      '#title' => t('Tag with leaves'),
      '#type' => 'checkbox',
      '#default_value' => isset($settings['autotag']['tag_only_with_tips']) ? $settings['autotag']['tag_only_with_tips'] : 0,
      '#description' => 'Check this box if you would only like "leaf" terms to be used for tagging, else ALL terms will be used.',
    ),
    'autotag_vids' => array(
      '#title' => t('Vocabularies'),
      '#type' => 'select',
      '#options' => $options,
      '#multiple' => TRUE,
      '#description' => t('Select the vocabularies you would like to search.'),
      '#default_value' => isset($settings['autotag']['autotag_vids']) ? $settings['autotag']['autotag_vids'] : array(),
    ),
  );
}

/**
 * Implements hook_update_dependencies()
 */
function autotag_update_dependencies() {
  return array(
    'autotag' => array(
      7001 => array(
        'tagtag' => 7001,
      ),
    ),
  );
}

Functions

Namesort descending Description
autotag_search_text Compare functions
autotag_tag_options Callback for the options form
autotag_tag_suggestions Callback as defined above in hook_tag_suggestion_info
autotag_tag_suggestion_info Implementation of hook_tag_suggestion_info().
autotag_update_dependencies Implements hook_update_dependencies()