You are here

taxonomy.inc in Node import 6

Same filename and directory in other branches
  1. 5 supported/taxonomy.inc

Support file for the core taxonomy module.

File

supported/taxonomy.inc
View source
<?php

/**
 * @file
 * Support file for the core taxonomy module.
 */

/**
 * Implementation of hook_node_import_types().
 */
function taxonomy_node_import_types() {
  $types = array();
  $vocabularies = taxonomy_get_vocabularies();

  // Import taxonomy vocabularies.
  $types['vocabulary'] = array(
    'title' => t('Vocabularies'),
    'can_create' => user_access('administer taxonomy'),
    'create' => 'node_import_create_taxonomy',
  );

  // Import taxonomy terms.
  foreach ((array) $vocabularies as $vid => $vocabulary) {
    $types['term:' . $vid] = array(
      'title' => t('Terms of %name vocabulary', array(
        '%name' => $vocabulary->name,
      )),
      'vocabulary' => $vocabulary,
      'can_create' => user_access('administer taxonomy'),
      'create' => 'node_import_create_taxonomy',
    );
  }
  return $types;
}

/**
 * Create a new vocabulary or term by submitting the corresponding
 * form.
 */
function node_import_create_taxonomy($type, $values, $preview) {
  $output = $preview ? '' : FALSE;
  if ($preview) {
    if ($type == 'vocabulary') {
      $node_types = array();
      foreach ($values['nodes'] as $node_type => $enabled) {
        if ($enabled) {
          $node_types[] = check_plain(node_get_types('name', $node_type));
        }
      }
      $output .= '<div class="preview">';
      $output .= '<h2>' . check_plain($values['name']) . '</h2>';
      $output .= '<div>' . filter_xss_admin($values['description']) . '</div>';
      $output .= '<dl>';
      $output .= '<dt>' . t('Help text') . '</dt>';
      $output .= '<dd>' . check_plain($values['help']) . '</dd>';
      $output .= '<dt>' . t('Content types') . '</dt>';
      $output .= '<dd>' . implode('</dd><dd>', $node_types) . '</dd>';
      $output .= '<dt>' . t('Settings') . '</dt>';
      $settings = array();
      if ($values['tags']) {
        $settings[] = t('Tags');
      }
      if ($values['multiple']) {
        $settings[] = t('Multiple select');
      }
      if ($values['required']) {
        $settings[] = t('Required');
      }
      if ($values['hierarchy'] == 1) {
        $settings[] = t('Single hierarchy');
      }
      if ($values['hierarchy'] == 2) {
        $settings[] = t('Multiple hierarchy');
      }
      $output .= '<dd>' . implode('</dd><dd>', $settings) . '</dd>';
      $output .= '<dt>' . t('Weight') . '</dt>';
      $output .= '<dd>' . check_plain($values['weight']) . '</dd>';
      $output .= '</dl>';
      $output .= '</div>';
    }
    else {
      $output .= '<div class="preview">';
      $output .= '<h2>' . check_plain($values['name']) . '</h2>';
      $output .= '<div>' . filter_xss_admin($values['description']) . '</div>';
      if (!empty($values['parent'])) {
        $output .= '<p><strong>' . t('Parent:') . '</strong> ';
        $output .= node_import_display_taxonomy_term($values['parent']) . '</p>';
      }
      if (!empty($values['relations']) || !empty($values['synonyms'])) {
        $output .= '<dl>';
        if (!empty($values['relations'])) {
          $output .= '<dt>' . t('Related terms:') . '</dt> ';
          $output .= '<dd>' . implode('</dd><dd>', array_map('node_import_display_taxonomy_term', (array) $values['relations'])) . '</dd>';
        }
        if (!empty($values['synonyms'])) {
          $output .= '<dt>' . t('Synonyms:') . '</dt> ';
          $output .= '<dd>' . implode('</dd><dd>', array_map('check_plain', (array) $values['synonyms'])) . '</dd>';
        }
        $output .= '</dl>';
      }
      $output .= '</div>';

      // If a term is created and a later term refers to it (as relation
      // or parent), we get an error in preview. In order to avoid this
      // we manually add the (will-be-created) term to the checking
      // function.
      $types = node_import_types();
      $vocabulary = $types[$type]['vocabulary'];
      $field = array(
        'vocabulary' => $vocabulary,
      );
      node_import_check_taxonomy_term($values['name'], $field, array(), $preview, 'add');
    }
  }
  else {
    module_load_include('inc', 'taxonomy', 'taxonomy.admin');
    $values['op'] = t('Save');
    $form_state = array(
      'values' => $values,
    );
    if ($type == 'vocabulary') {
      node_import_drupal_execute('taxonomy_form_vocabulary', $form_state);
      $output = $form_state['vid'];
    }
    else {
      $types = node_import_types();
      $vocabulary = $types[$type]['vocabulary'];
      node_import_drupal_execute('taxonomy_form_term', $form_state, $vocabulary);
      $output = $form_state['tid'];

      // As a term can refer to other terms (parent, relation), we
      // can not continue if we have created a term.
      global $node_import_can_continue;
      $node_import_can_continue = FALSE;
    }
  }
  return $output;
}

/**
 * Display a taxonomy term during preview.
 */
function node_import_display_taxonomy_term($tid) {
  static $output;
  if (!isset($output)) {
    $output = array();
  }
  if (!isset($output[$tid])) {
    if ($tid === 0) {
      $output[$tid] = theme('placeholder', t('The term will be created during import'));
    }
    else {
      if ($term = taxonomy_get_term($tid)) {
        $output[$tid] = l($term->name, 'taxonomy/term/' . $tid);
      }
      else {
        $output[$tid] = theme('placeholder', $tid);
      }
    }
  }
  return $output[$tid];
}

/**
 * Implementation of hook_node_import_fields().
 */
function taxonomy_node_import_fields($type) {
  $fields = array();

  // Import taxonomy vocabularies.
  if ($type == 'vocabulary') {
    $fields['name'] = array(
      'title' => t('Vocabulary name'),
      'group' => t('Identification'),
      'module' => 'taxonomy',
      'map_required' => TRUE,
      'default_value' => '',
    );
    $fields['description'] = array(
      'title' => t('Description'),
      'group' => t('Identification'),
      'module' => 'taxonomy',
      'default_value' => '',
    );
    $fields['help'] = array(
      'title' => t('Help text'),
      'group' => t('Identification'),
      'module' => 'taxonomy',
      'default_value' => '',
    );
    $fields['nodes'] = array(
      'title' => t('Content types'),
      'group' => t('Content types'),
      'module' => 'taxonomy',
      'has_multiple' => TRUE,
      'is_checkboxes' => TRUE,
      'allowed_values' => node_get_types('names'),
    );
    $fields['tags'] = array(
      'title' => t('Tags'),
      'group' => t('Settings'),
      'module' => 'taxonomy',
      'input_format' => 'boolean',
    );
    $fields['multiple'] = array(
      'title' => t('Multiple select'),
      'group' => t('Settings'),
      'module' => 'taxonomy',
      'input_format' => 'boolean',
    );
    $fields['required'] = array(
      'title' => t('Required'),
      'group' => t('Settings'),
      'module' => 'taxonomy',
      'input_format' => 'boolean',
    );
    $fields['weight'] = array(
      'title' => t('Weight'),
      'group' => t('Settings'),
      'module' => 'taxonomy',
      'input_format' => 'weight',
    );
    $fields['hierarchy'] = array(
      'title' => t('Hierarchy'),
      'group' => t('Advanced settings'),
      'module' => 'taxonomy',
      'allowed_values' => array(
        '0' => t('Disabled'),
        '1' => t('Single'),
        '2' => t('Multiple'),
      ),
    );
  }
  else {
    if (strpos($type, 'term:') === 0) {
      $types = node_import_types();
      $vocab = $types[$type]['vocabulary'];
      $fields['vid'] = array(
        'is_mappable' => FALSE,
        'default_value' => $vocab->vid,
      );
      $fields['name'] = array(
        'title' => t('Term name'),
        'group' => t('Identification'),
        'module' => 'taxonomy',
        'map_required' => TRUE,
        'default_value' => '',
      );
      $fields['description'] = array(
        'title' => t('Description'),
        'group' => t('Identification'),
        'module' => 'taxonomy',
        'default_value' => '',
      );
      $fields['parent'] = array(
        'title' => t('Parents'),
        'group' => t('Advanced options'),
        'module' => 'taxonomy',
        'has_multiple' => FALSE,
        // Although all vocabs in Drupal6.x allow for multiple parents, we only allow one.
        'has_hierarchy' => TRUE,
        'input_format' => 'taxonomy_term',
        'vocabulary' => $vocab,
      );
      $fields['relations'] = array(
        'title' => t('Related terms'),
        'group' => t('Advanced options'),
        'module' => 'taxonomy',
        'has_multiple' => TRUE,
        'has_hierarchy' => TRUE,
        'input_format' => 'taxonomy_term',
        'vocabulary' => $vocab,
      );
      $fields['synonyms'] = array(
        'title' => t('Synonyms'),
        'group' => t('Advanced options'),
        'module' => 'taxonomy',
        'has_multiple' => TRUE,
        'multiple_separator' => ',',
      );
      $fields['weight'] = array(
        'title' => t('Weight'),
        'group' => t('Advanced options'),
        'module' => 'taxonomy',
        'input_format' => 'weight',
      );
    }
    else {
      if (($node_type = node_import_type_is_node($type)) !== FALSE) {

        // Copy from taxonomy_form_alter().
        $c = db_query(db_rewrite_sql("SELECT v.* FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $node_type);
        while ($vocabulary = db_fetch_object($c)) {
          $fields['taxonomy:' . $vocabulary->vid] = array(
            'title' => $vocabulary->name,
            'group' => t('Vocabularies'),
            'module' => 'taxonomy',
            'input_format' => 'taxonomy_term',
            'vocabulary' => $vocabulary,
            'has_multiple' => $vocabulary->multiple || $vocabulary->tags,
            'has_hierarchy' => $vocabulary->hierarchy > 0,
            'multiple_separator' => $vocabulary->tags ? ',' : '||',
          );
        }
      }
    }
  }
  return $fields;
}

/**
 * Implementation of hook_node_import_fields_alter().
 */
function taxonomy_node_import_fields_alter(&$fields, $type) {
  foreach ($fields as $fieldname => $fieldinfo) {
    if ($fieldinfo['input_format'] == 'taxonomy_term') {
      $vocab = $fieldinfo['vocabulary'];
      if (!$vocab->tags) {
        $fields[$fieldname]['preprocess'][] = 'node_import_check_taxonomy_term';
      }
      $fields[$fieldname]['tips'][] = t('Taxonomy term (by tid, name or synonym).');
    }
  }
}

/**
 * Check if the value is a valid taxonomy term (by tid or name).
 *
 * Uses: $field['vocabulary'].
 *
 * @ingroup node_import_preprocess
 */
function node_import_check_taxonomy_term(&$value, $field, $options, $preview, $op = 'lookup') {
  static $tids;
  $vocab = $field['vocabulary'];
  if ($vocab->tags) {

    // No need to check when tags vocabulary.
    return TRUE;
  }

  // We cache the terms already looked up.
  if (!isset($tids)) {
    $tids = array();
  }
  if (!isset($tids[$vocab->vid])) {
    $tids[$vocab->vid] = array();
  }
  $store_value = is_array($value) ? implode("\n", array_map('drupal_strtolower', $value)) : drupal_strtolower($value);

  // Special case for previews: signify that the term will be created.
  if ($op == 'add') {
    $tids[$vocab->vid][$store_value] = 0;
    return;
  }
  if (isset($tids[$vocab->vid][$store_value])) {

    // We have looked up this value already.
    $value = $tids[$vocab->vid][$store_value];
  }
  else {
    if (!is_array($value)) {

      // One term specified, look up the tid or give error.
      if (($tid = db_result(db_query("SELECT tid FROM {term_data} WHERE vid = %d AND (tid = %d OR LOWER(name) = '%s')", $vocab->vid, is_numeric($store_value) && intval($store_value) > 0 ? $store_value : -1, $store_value))) || ($tid = db_result(db_query("SELECT td.tid FROM {term_synonym} AS ts, {term_data} AS td WHERE td.tid = ts.tid AND td.vid = %d AND LOWER(ts.name) = '%s'", $vocab->vid, $store_value)))) {
        $value = $tid;
      }
      else {
        $value = '';
      }
    }
    else {
      if (count($value) == 1) {

        // The user has specified the term as a hierarchy trail, but he
        // only specified one parent. Lookup that value.
        $value = array_shift($value);
        node_import_check_taxonomy_term($value, $field, $options, $preview);
      }
      else {

        // The user has specified the term as a hierarchy trail of terms.
        // Example: array(grandparent, parent, child). We need to find
        // the tid of the child.
        //
        // Pop child.
        // Find a parent_tid for array(grandparent, parent).
        // Find a tid for child that has a parent with parent_tid.
        $child = array_pop($value);
        $child = drupal_strtolower($child);
        node_import_check_taxonomy_term($value, $field, $options, $preview);
        if ($value === 0 || $value === '') {

          // We can't look for a proper child as we did not find a proper
          // parent (or the parent will be created). So stop.
        }
        else {
          if (($tid = db_result(db_query("SELECT td.tid FROM {term_data} td, {term_hierarchy} th WHERE td.vid = %d AND th.parent = %d AND td.tid = th.tid AND (td.tid = %d OR LOWER(td.name) = '%s')", $vocab->vid, $value, is_numeric($child) && intval($child) > 0 ? $child : -1, $child))) || ($tid = db_result(db_query("SELECT td.tid FROM {term_data} td, {term_hierarchy} th, {term_synonym} ts WHERE td.vid = %d AND th.parent = %d AND td.tid = th.tid AND td.tid = ts.tid AND LOWER(ts.name) = '%s'", $vocab->vid, $value, $child)))) {
            $value = $tid;
          }
          else {
            $value = '';
          }
        }
      }
    }
  }
  $tids[$vocab->vid][$store_value] = $value;

  // Report error.
  if ($value === 0) {
    drupal_set_message(t('The term %value will be added to %vocabulary during import and will be used for %name.', array(
      '%value' => $value,
      '%name' => $field['title'],
      '%vocabulary' => $vocab->name,
    )));
  }
  else {
    if ($value === '') {
      node_import_input_error(t('Input error: %value is not allowed for %name (not a term or synonym in %vocabulary).', array(
        '%value' => $value,
        '%name' => $field['title'],
        '%vocabulary' => $vocab->name,
      )));
      return FALSE;
    }
  }
  return TRUE;
}

/**
 * Implementation of hook_node_import_defaults().
 */
function taxonomy_node_import_defaults($type, $defaults, $fields, $map) {
  $form = array();

  // Import taxonomy vocabularies.
  if ($type == 'vocabulary') {
    $form['nodes'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Content types'),
      '#default_value' => isset($defaults['nodes']) ? $defaults['nodes'] : array(),
      '#options' => array_map('check_plain', node_get_types('names')),
    );
    $options = array(
      'tags' => t('Tags'),
      'multiple' => t('Multiple select'),
      'required' => t('Required'),
    );
    foreach ($options as $key => $title) {
      $form[$key] = array(
        '#title' => $title,
        '#type' => 'radios',
        '#options' => array(
          '0' => t('No'),
          '1' => t('Yes'),
        ),
        '#default_value' => isset($defaults[$key]) ? $defaults[$key] : '0',
      );
    }
    $form['weight'] = array(
      '#title' => t('Weight'),
      '#type' => 'weight',
      '#default_value' => isset($defaults['weight']) ? $defaults['weight'] : 0,
    );
    $form['hierarchy'] = array(
      '#title' => t('Hierarchy'),
      '#type' => 'radios',
      '#options' => array(
        '0' => t('Disabled'),
        '1' => t('Single'),
        '2' => t('Multiple'),
      ),
      '#default_value' => isset($defaults['hierarchy']) ? $defaults['hierarchy'] : '0',
    );
  }
  else {
    if (strpos($type, 'term:') === 0) {
      $types = node_import_types();
      $vocab = $types[$type]['vocabulary'];
      $form['vocabulary'] = array(
        '#type' => 'item',
        '#title' => t('Vocabulary'),
        '#value' => check_plain($vocab->name),
      );
      $options = array();
      foreach (taxonomy_get_tree($vocab->vid) as $term) {
        $choice = new stdClass();
        $choice->option = array(
          $term->tid => str_repeat('-', $term->depth) . $term->name,
        );
        $options[] = $choice;
      }
      if ($vocab->hierarchy > 0) {
        $form['parent'] = array(
          '#type' => 'select',
          '#title' => t('Parents'),
          '#multiple' => $vocab->hierarchy == 2,
          '#options' => array_merge(array(
            '' => '<' . t('root') . '>',
          ), $options),
          '#default_value' => isset($defaults['parent']) ? $defaults['parent'] : '',
        );
      }
      $form['relations'] = array(
        '#type' => 'select',
        '#title' => t('Related terms'),
        '#multiple' => TRUE,
        '#options' => array_merge(array(
          '' => '<' . t('none') . '>',
        ), $options),
        '#default_value' => isset($defaults['relations']) ? $defaults['relations'] : '',
      );
      $form['synonyms'] = array(
        '#type' => 'textarea',
        '#title' => t('Synonyms'),
        '#default_value' => isset($defaults['synonyms']) ? $defaults['synonyms'] : '',
      );
      $form['weight'] = array(
        '#title' => t('Weight'),
        '#type' => 'textfield',
        '#size' => 6,
        '#default_value' => isset($defaults['weight']) ? $defaults['weight'] : 0,
      );
    }
    else {
      if (($node_type = node_import_type_is_node($type)) !== FALSE) {

        // Copy from taxonomy_form_alter().
        $c = db_query(db_rewrite_sql("SELECT v.* FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $node_type);
        while ($vocabulary = db_fetch_object($c)) {
          if ($vocabulary->tags) {
            $form['taxonomy:' . $vocabulary->vid] = array(
              '#type' => 'textfield',
              '#title' => $vocabulary->name,
              '#default_value' => isset($defaults['taxonomy:' . $vocabulary->vid]) ? $defaults['taxonomy:' . $vocabulary->vid] : '',
              '#autocomplete_path' => 'taxonomy/autocomplete/' . $vocabulary->vid,
            );
          }
          else {
            $form['taxonomy:' . $vocabulary->vid] = taxonomy_form($vocabulary->vid, isset($defaults['taxonomy:' . $vocabulary->vid]) ? $defaults['taxonomy:' . $vocabulary->vid] : 0);
          }
        }
      }
    }
  }
  return $form;
}

/**
 * Implementation of hook_node_import_options().
 */
function taxonomy_node_import_options($type, $options, $fields, $map) {
  $form = array();
  return $form;

  //TODO: reenable this.

  // Import taxonomy terms for nodes.
  if (($node_type = node_import_type_is_node($type)) !== FALSE) {

    // Copy from taxonomy_form_alter().
    $c = db_query(db_rewrite_sql("SELECT v.* FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $node_type);
    $create_options = array(
      'create' => t('create it') . ',',
      'remove' => t('remove it from the selection') . ',',
      'error' => t('treat it as an import error') . '.',
    );
    if (user_access('administer taxonomy')) {
      $create_default = 'create';
    }
    else {
      unset($create_options['create']);
      $create_default = 'error';
    }
    while ($vocabulary = db_fetch_object($c)) {
      $field = 'taxonomy:' . $vocabulary->vid;
      if (isset($map[$field]) && !empty($map[$field])) {
        if (!$vocabulary->tags) {
          $form[$field] = array(
            '#title' => $vocabulary->name,
            'non_existing_terms' => array(
              '#title' => t('When a term does not exist'),
              '#type' => 'radios',
              '#options' => $create_options,
              '#default_value' => isset($options[$field]['non_existing_terms']) ? $options[$field]['non_existing_terms'] : $create_default,
            ),
          );
        }
      }
    }
  }
  return $form;
}

/**
 * Implementation of hook_node_import_values_alter().
 */
function taxonomy_node_import_values_alter(&$values, $type, $defaults, $options, $fields, $preview) {
  if (strpos($type, 'term:') === 0) {
    if (!$preview) {
      $values['synonyms'] = implode("\n", (array) $values['synonyms']);
      $values['parent'] = array(
        $values['parent'],
      );
    }
  }
  else {
    if (($node_type = node_import_type_is_node($type)) !== FALSE) {
      $taxonomy = isset($values['taxonomy']) ? $values['taxonomy'] : array();
      foreach ($fields as $fieldname => $fieldinfo) {
        if (strpos($fieldname, 'taxonomy:') === 0) {
          $vocab = $fieldinfo['vocabulary'];
          if ($vocab->tags) {
            $taxonomy['tags'] = isset($taxonomy['tags']) ? $taxonomy['tags'] : array();
            $taxonomy['tags'][$vocab->vid] = implode(',', (array) $values[$fieldname]);
          }
          else {
            $taxonomy[$vocab->vid] = $values[$fieldname];
          }
          unset($values[$fieldname]);
        }
      }
      $values['taxonomy'] = $taxonomy;
    }
  }
}

Functions

Namesort descending Description
node_import_check_taxonomy_term Check if the value is a valid taxonomy term (by tid or name).
node_import_create_taxonomy Create a new vocabulary or term by submitting the corresponding form.
node_import_display_taxonomy_term Display a taxonomy term during preview.
taxonomy_node_import_defaults Implementation of hook_node_import_defaults().
taxonomy_node_import_fields Implementation of hook_node_import_fields().
taxonomy_node_import_fields_alter Implementation of hook_node_import_fields_alter().
taxonomy_node_import_options Implementation of hook_node_import_options().
taxonomy_node_import_types Implementation of hook_node_import_types().
taxonomy_node_import_values_alter Implementation of hook_node_import_values_alter().