<?php


/**
 * @file Rules integration for the taxonomy module.
 *
 * @addtogroup rules
 * @{
 */

/**
 * Implementation of hook_rules_event_info().
 */
function taxonomy_rules_event_info() {
  return array(
    'taxonomy_term_insert' => array(
      'label' => t('After saving a new term'),
      'module' => 'Taxonomy',
      'arguments' => rules_events_hook_taxonomy_term_arguments(t('created term')),
    ),
    'taxonomy_term_update' => array(
      'label' => t('After updating a term'),
      'module' => 'Taxonomy',
      'arguments' => rules_events_hook_taxonomy_term_arguments(t('updated term'), TRUE),
    ),
  );
}

/**
 * Returns some arguments suitable for using it with a term
 */
function rules_events_hook_taxonomy_term_arguments($term_label, $update = FALSE) {
  $args = array(
    'term' => array(
      'type' => 'taxonomy_term',
      'label' => $term_label,
    ),
  );
  if ($update) {
    $args += array(
      'term_unchanged' => array(
        'type' => 'taxonomy_term',
        'label' => t('unchanged term'),
        'handler' => 'rules_events_argument_taxonomy_term_unchanged',
      ),
    );
  }
  return $args + rules_events_global_user_argument();
}

/**
 * Gets the term object, that doesn't contain the modified changes
 */
function rules_events_argument_taxonomy_term_unchanged($taxonomy_term) {
  return $taxonomy_term->tid ? taxonomy_get_term($taxonomy_term->tid) : $taxonomy_term;
}

/**
 * Implementation of hook_rules_action_info().
 */
function taxonomy_rules_action_info() {
  $info = array();
  // Term actions.
  $info['rules_action_taxonomy_load_term'] = array(
    'label' => t('Load a term'),
    'new variables' => array(
      'taxonomy_term' => array(
        'type' => 'taxonomy_term',
        'label' => t('Taxonomy term'),
      ),
    ),
    'eval input' => array('term|term_text'),
    'help' => t('Loading a taxonomy term will allow you to act on this term, for example you will be able to assign this term to a content.'),
    'module' => 'Taxonomy',
  );
  $info['rules_action_taxonomy_add_term'] = array(
    'label' => t('Add a new term to vocabulary'),
    'arguments' => array(
      'taxonomy_vocab' => array(
        'type' => 'taxonomy_vocab',
        'label' => t('Taxonomy vocabulary'),
      ),
    ),
    'new variables' => array(
      'taxonomy_term' => array(
        'type' => 'taxonomy_term',
        'label' => t('Taxonomy term'),
      ),
    ),
    'eval input' => array('term|name', 'term|description'),
    'module' => 'Taxonomy',
  );

  $info['rules_action_taxonomy_delete_term'] = array(
    'label' => t('Delete a term'),
    'arguments' => array(
      'taxonomy_term' => array(
        'type' => 'taxonomy_term',
        'label' => t('Taxonomy term'),
      ),
    ),
    'module' => 'Taxonomy',
  );

  $info['rules_action_taxonomy_term_assign_to_content'] = array(
    'label' => t('Assign a term to content'),
    'arguments' => array(
      'node' => array(
        'type' => 'node',
        'label' => t('Content'),
      ),
      'taxonomy_term' => array(
        'type' => 'taxonomy_term',
        'label' => t('Taxonomy term'),
      ),
    ),
    'module' => 'Taxonomy',
  );
  $info['rules_action_taxonomy_term_remove_from_content'] = array(
    'label' => t('Remove a term from content'),
    'arguments' => array(
      'node' => array(
        'type' => 'node',
        'label' => t('Content'),
      ),
      'taxonomy_term' => array(
        'type' => 'taxonomy_term',
        'label' => t('Taxonomy term'),
      ),
    ),
    'module' => 'Taxonomy',
  );
  // Vocabulary actions.
  $info['rules_action_taxonomy_load_vocab'] = array(
    'label' => t('Load a vocabulary'),
    'new variables' => array(
      'taxonomy_vocab' => array(
        'type' => 'taxonomy_vocab',
        'label' => t('Taxonomy vocabulary'),
      ),
    ),
    'eval input' => array('vocabulary|vocab_text'),
    'help' => t('Loading a taxonomy vocabulary will allow you to act on this vocabulary.'),
    'module' => 'Taxonomy',
  );
  $info['rules_action_taxonomy_add_vocab'] = array(
    'label' => t('Add a new vocabulary'),
    'new variables' => array(
      'taxonomy_vocab' => array(
        'type' => 'taxonomy_vocab',
        'label' => t('Taxonomy vocabulary'),
      ),
    ),
    'eval input' => array('name', 'description', 'help'),
    'module' => 'Taxonomy',
  );
  return $info;
}

/**
 * Action: Load a term.
 */
function rules_action_taxonomy_load_term($settings) {
  if ($term = taxonomy_get_term(!empty($settings['term']['term_text']) ? $settings['term']['term_text'] : $settings['term']['term_select'])) {
    return array('taxonomy_term' => $term);
  }
}

/**
 * Action: Add a new term to vocabulary.
 */
function rules_action_taxonomy_add_term($taxonomy_vocab, $settings) {
  // Prepare the values to pass to taxonomy_save_term();
  $settings['term']['vid'] = $taxonomy_vocab->vid;
  $form_values = $settings['term'];
  taxonomy_save_term($form_values);
  // Get the newly created term.
  $term = taxonomy_get_term($form_values['tid']);
  return array('taxonomy_term' => $term);
}

/**
 * Action: Delete a term.
 */
function rules_action_taxonomy_delete_term($taxonomy_term) {
  taxonomy_del_term($taxonomy_term->tid);
}

/**
 * Action: Assign or remove a term to content.
 */
function rules_action_taxonomy_term_assign_to_content($node, $taxonomy_term, $settings) {
  if (!isset($node->taxonomy[$taxonomy_term->tid])) {
    $node->taxonomy[$taxonomy_term->tid] = $taxonomy_term;
    return array('node' => $node);
  }
}

/**
 * Action: Remove a term from content.
 */
function rules_action_taxonomy_term_remove_from_content($node, $taxonomy_term, $settings) {
  if (isset($node->taxonomy[$taxonomy_term->tid])) {
    unset($node->taxonomy[$taxonomy_term->tid]);
    return array('node' => $node);
  }
}

/**
 * Action: Load a vocabulary.
 */
function rules_action_taxonomy_load_vocab($settings) {
  $vid = !empty($settings['vocabulary']['vocab_text']) ? $settings['vocabulary']['vocab_text'] : $settings['vocabulary']['vocab_select'];
  return array('taxonomy_vocab' => taxonomy_vocabulary_load($vid));
}

/**
 * Action: Add a new vocabulary.
 */
function rules_action_taxonomy_add_vocab($settings) {
  taxonomy_save_vocabulary($settings);
  $vocabs = taxonomy_get_vocabularies();
  return array('taxonomy_vocab' => $vocabs[$settings['vid']]);
}

/**
 * Implementation of hook_rules_data_type_info().
 */
function taxonomy_rules_data_type_info() {
  return array(
    'taxonomy_term' => array(
      'label' => t('taxonomy term'),
      'class' => 'rules_data_type_taxonomy_term',
      'savable' => FALSE,
      'identifiable' => TRUE,
      'module' => 'Taxonomy',
      'token type' => 'taxonomy',
    ),
    'taxonomy_vocab' => array(
      'label' => t('taxonomy vocabulary'),
      'class' => 'rules_data_type_taxonomy_vocab',
      'savable' => FALSE,
      'identifiable' => TRUE,
      'module' => 'Taxonomy',
      'token type' => FALSE,
    ),
  );
}

/**
 * Defines the taxonomy term data type.
 */
class rules_data_type_taxonomy_term extends rules_data_type {
  function load($tid) {
    return taxonomy_get_term($tid);
  }

  function get_identifier() {
    $term = &$this->get();
    return $term->tid;
  }
}

/**
 * Defines the taxonomy vocab data type.
 */
class rules_data_type_taxonomy_vocab extends rules_data_type {
  function load($vid) {
    return taxonomy_vocabulary_load($vid);
  }

  function get_identifier() {
    $vocab = &$this->get();
    return $vocab->vid;
  }
}

/**
 * Implementation of hook_rules_condition_info().
 */
function taxonomy_rules_condition_info() {
  return array(
    'rules_condition_content_has_term' => array(
      'label' => t('Content has term'),
      'help' => t('Evaluates to TRUE if the given content has one of the selected terms.'),
      'module' => 'Taxonomy',
      'arguments' => array(
        'node' => array('type' => 'node', 'label' => t('Content')),
      ),
    ),
  );
}

/**
 * Condition: Check for selected terms.
 */
function rules_condition_content_has_term(&$node, $settings) {

  $taxonomy = $node->taxonomy;

  // If vocab is marked as tag, we format it to the proper format.
  if (isset($taxonomy['tags']) && count($taxonomy['tags']) > 0) {
    foreach ($taxonomy['tags'] as $vid => $term) {
      $terms_names = explode(', ', $term);
      foreach ($terms_names as $term_name) {
        // It can return multiple terms with the same name.
        $terms_objects = taxonomy_get_term_by_name($term_name);
        foreach ($terms_objects as $term_object) {
          $tid = $term_object->tid;
          // Avoid terms with same name in different vocabularies.
          if ($term_object->vid == $vid){
            $taxonomy[$vid][$tid] = $tid;
          }
        }
      }
    }
    // Since we won't use it unset to not bother us.
    unset($taxonomy['tags']);
  }


  if (isset($taxonomy) && (count($taxonomy) > 0)) {
    $tids = array();

    foreach ($taxonomy as $vocab) {
      if (!empty($vocab) && is_array($vocab)) {
        foreach ($vocab as $term) {
          $tid = is_object($term) ? $term->tid : (is_array($term) ? reset($term) : $term);
          $tids[$tid] = $tid;
        }
      }
      else {
        if (!empty($vocab) && is_numeric($vocab)) {
          $tids[$vocab] = $vocab;
        }
      }
    }

    foreach ($settings['tids'] as $tid) {
      if (isset($tids[$tid])) {
        return TRUE;
      }
    }
  }
  return FALSE;
}

/**
 * @}
 */
