You are here

gmap_taxonomy.module in GMap Module 7.2

GMap Taxonomy Markers

Taxonomy based markers.

File

gmap_taxonomy.module
View source
<?php

/**
 * @file
 * GMap Taxonomy Markers
 *
 * Taxonomy based markers.
 */

/**
 * Implements hook_form_alter().
 *
 * @todo move this to GmapTaxonomyForms class
 */
function gmap_taxonomy_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'taxonomy_form_vocabulary') {
    $form['gmap_taxonomy'] = array(
      '#type' => 'fieldset',
      '#title' => t('GMap markers'),
    );
    $vid = isset($form['vid']) ? $form['vid']['#value'] : -1;
    $form['gmap_taxonomy']['gmap_taxonomy_enable'] = array(
      '#type' => 'checkbox',
      '#title' => t('Enable'),
      '#description' => t('Enable choosing a marker for terms in this vocabulary.'),
      '#default_value' => gmap_taxonomy_vocabulary_is_enabled($vid),
    );
  }

  // @@@ Why does this get called up on delete?
  if ($form_id == 'taxonomy_form_term' && empty($form['confirm']['#value'])) {
    $term = (object) $form['#term'];
    if (gmap_taxonomy_vocabulary_is_enabled($form['#vocabulary'])) {
      $temp = '';
      if (!empty($term->tid)) {
        if ($t = db_query('SELECT marker FROM {gmap_taxonomy_term} WHERE tid = :tid', array(
          ':tid' => $term->tid,
        ))
          ->fetchField()) {
          $temp = $t;
        }
      }
      $form['gmap_taxonomy_marker'] = array(
        '#title' => t('GMap Marker'),
        '#type' => 'select',
        '#options' => array(
          '' => t('No Marker'),
        ) + gmap_get_marker_titles(),
        '#description' => t('If you would like nodes tagged as this term to have a special marker, choose one here.'),
        '#default_value' => $temp,
      );
    }
  }

  // Move the Save and Delete buttons down below our additions.

  /*
  if ($form_id == 'taxonomy_form_vocabulary'
  || $form_id == 'taxonomy_form_term') {
  if (isset($form['submit']['#weight'])) {
  $form['submit']['#weight']++;
  }
  else {
  $form['submit']['#weight'] = 1;
  }
  if (isset($form['delete'])) {
  if (isset($form['delete']['#weight'])) {
  $form['delete']['#weight']+=2;
  }
  else {
  $form['delete']['#weight'] = 2;
  }
  }
  }
  */
}

/**
 * Implements hook_taxonomy_vocabulary_insert().
 *
 * @todo move this to GmapTaxonomyCRUDi class
 */
function gmap_taxonomy_taxonomy_vocabulary_insert($vocabulary) {
  return gmap_taxonomy_taxonomy_vocabulary_update($vocabulary);
}

/**
 * Implements hook_taxonomy_vocabulary_update().
 *
 * @todo move this to GmapTaxonomyCRUDi class
 */
function gmap_taxonomy_taxonomy_vocabulary_update($vocabulary) {
  if (isset($vocabulary->gmap_taxonomy_enable)) {
    variable_set('gmap_taxonomy_vocab_' . $vocabulary->machine_name, TRUE);
  }
  else {
    variable_del('gmap_taxonomy_vocab_' . $vocabulary->machine_name);
  }
}

/**
 * Implements hook_taxonomy_vocabulary_delete().
 *
 * @todo move this to GmapTaxonomyCRUDi class
 */
function gmap_taxonomy_taxonomy_vocabulary_delete($vocabulary) {
  variable_del('gmap_taxonomy_vocab_' . $vocabulary->machine_name);
}

/**
 * Implements hook_taxonomy_term_insert().
 *
 * @todo move this to GmapTaxonomyCRUDi class
 */
function gmap_taxonomy_taxonomy_term_insert($term) {
  return gmap_taxonomy_taxonomy_term_update($term);
}

/**
 * Implements hook_taxonomy_term_update().
 *
 * @todo move this to GmapTaxonomyCRUDi class
 */
function gmap_taxonomy_taxonomy_term_update($term) {
  if (gmap_taxonomy_vocabulary_is_enabled($term->vid)) {

    // If Synchronize translations module is enabled,
    // and the term reference field is set to a i18n_sync field,
    // when we update a node, will trigger a term
    // update, and the $term->gmap_taxonomy_marker is not set.
    // Indicates this is a term edit form submit.
    if (isset($term->gmap_taxonomy_marker)) {
      db_delete('gmap_taxonomy_term')
        ->condition('tid', $term->tid)
        ->execute();

      // Do we have an assigned marker?
      if (!empty($term->gmap_taxonomy_marker)) {
        db_insert('gmap_taxonomy_term')
          ->fields(array(
          'tid' => $term->tid,
          'marker' => $term->gmap_taxonomy_marker,
        ))
          ->execute();

        // Update name changes in the gmap_taxonomy_node table.
        db_update('gmap_taxonomy_node')
          ->fields(array(
          'marker' => $term->gmap_taxonomy_marker,
        ))
          ->condition('tid', $term->tid)
          ->execute();
      }
      gmap_taxonomy_reassign_marker($term->tid);
    }
  }
}

/**
 * Implements hook_taxonomy_term_delete().
 *
 * @todo move this to GmapTaxonomyCRUDi class
 */
function gmap_taxonomy_taxonomy_term_delete($term) {
  db_delete('gmap_taxonomy_term')
    ->condition('tid', $term->tid)
    ->execute();

  // Use gmap_taxonomy_node for search because term_node rows are already gone.
  gmap_taxonomy_reassign_marker($term->tid, TRUE);
}

/**
 * Implements hook_node_insert().
 *
 * @todo move this to GmapNodeCRUDi class
 */
function gmap_taxonomy_node_insert($node) {
  gmap_taxonomy_node_update($node);
}

/**
 * Implements hook_node_update().
 *
 * @todo move this to GmapNodeCRUDi class
 */
function gmap_taxonomy_node_update($node) {

  // Remove the marker association if present. We'll read it later if it's
  // still applicable.
  db_delete('gmap_taxonomy_node')
    ->condition('nid', $node->nid)
    ->execute();

  // Get list of taxonomy_term_reference field names.
  $gmap_taxonomy_fields = gmap_taxonomy_get_instances();

  // Get the markers.
  $gmap_taxonomy_markers = gmap_taxonomy_get_markers();

  // If this node doesn't use taxonomy_term_reference fields at all,
  // skip the rest.
  if (!isset($gmap_taxonomy_fields[$node->type])) {
    return;
  }

  // Loop through the page's terms and insert markers if applicable.
  foreach ($gmap_taxonomy_fields[$node->type] as $fieldname) {

    // Get this node's field values for this field.
    $terms = field_get_items('node', $node, $fieldname, $node->language);

    // Skip if term has no value.
    if (!$terms) {
      continue;
    }

    // Otherwise loop through and set marker for term, if term has marker.
    foreach ($terms as $term) {
      if (!isset($gmap_taxonomy_markers[$term['tid']])) {
        continue;
      }

      // Insert to gmap_taxonomy table.
      db_insert('gmap_taxonomy_node')
        ->fields(array(
        'nid' => $node->nid,
        'tid' => $term['tid'],
        'marker' => $gmap_taxonomy_markers[$term['tid']],
      ))
        ->execute();

      // because only 1 term marker per node is allowed (db schema constraint) break here
      // @see https://www.drupal.org/node/2043673
      break;
    }
  }
}

/**
 * Implements hook_node_delete().
 *
 * @todo move this to GmapNodeCRUDi class
 */
function gmap_taxonomy_node_delete($node) {
  db_delete('gmap_taxonomy_node')
    ->condition('nid', $node->nid)
    ->execute();
}

/**
 * Implements hook_node_revision_delete().
 *
 * @todo move this to GmapNodeCRUDi class
 */

/*
function gmap_taxonomy_node_revision_delete($node) {
  db_delete('gmap_taxonomy_node')
    ->condition('vid', $node->vid)
    ->execute();
}
*/

/**
 * Check if gmap taxonomy is enabled for the given vocabulary.
 *
 * @todo move this to GmapTaxonomyCRUDi class
 *
 * @param object $vocabulary
 *   The vocabulary to check. Entire object and vid are allowed.
 *
 * @return bool
 *   TRUE if the vocabulary is enabled
 */
function gmap_taxonomy_vocabulary_is_enabled($vocabulary) {
  if (!is_object($vocabulary)) {
    $vocabulary = taxonomy_vocabulary_load($vocabulary);
  }
  return $vocabulary && variable_get('gmap_taxonomy_vocab_' . $vocabulary->machine_name, FALSE);
}

/**
 * Get all gmap taxonomy markers.
 *
 * @todo move this to GmapTaxonomyCRUDi class
 * Helper function to return cached version of
 * gmap taxonomy markers from the database.
 *
 * @return array
 *   Associative array of tid => marker.
 */
function gmap_taxonomy_get_markers() {
  $gmap_taxonomy_markers =& drupal_static(__FUNCTION__);
  if (!isset($gmap_taxonomy_markers)) {
    if ($cache = cache_get('gmap_taxonomy_markers_data')) {
      $gmap_taxonomy_markers = $cache->data;
    }
    else {
      $gmap_taxonomy_markers = db_query('SELECT tid, marker FROM {gmap_taxonomy_term}')
        ->fetchAllKeyed();
      cache_set('gmap_taxonomy_markers_data', $gmap_taxonomy_markers, 'cache', CACHE_TEMPORARY);
    }
  }
  return $gmap_taxonomy_markers;
}

/**
 * Get fields that are using taxonomy_term_reference + gmap taxonomy.
 *
 * @todo move this to GmapFieldsCRUDi class
 * Helper function to return cached version of
 * fields using taxonomy_term_reference.
 *
 * @return array
 *   Associative array keyed with node type
 *   and with values as array of field names.
 */
function gmap_taxonomy_get_instances() {
  $gmap_taxonomy_fields =& drupal_static(__FUNCTION__);

  // TODO: Could do something with the vid,
  // but probably too much overhead to use it here.
  // As field_info_fields() only gives us machine names
  // and gmap_taxonomy_vocabs only gives us vid.
  // $gmap_taxonomy_vocabs = variable_get('gmap_taxonomy_vocabs', array());
  if (!isset($gmap_taxonomy_fields)) {
    if ($cache = cache_get('gmap_taxonomy_fields_data')) {
      $gmap_taxonomy_fields = $cache->data;
    }
    else {
      $gmap_taxonomy_fields = array();

      // Get all field info.
      $fields = field_info_fields();

      // Loop through to get the ones of field type taxonomy_term_reference.
      foreach ($fields as $field) {
        if ($field['type'] == 'taxonomy_term_reference' && isset($field['bundles']['node'])) {
          foreach ($field['bundles']['node'] as $node_type) {
            $gmap_taxonomy_fields[$node_type][] = $field['field_name'];
          }
        }
      }
      cache_set('gmap_taxonomy_fields_data', $gmap_taxonomy_fields, 'cache', CACHE_TEMPORARY);
    }
  }
  return $gmap_taxonomy_fields;
}

/**
 * Reassign markers associated with a term that's going away.
 *
 * @todo move this to GmapTaxonomyCRUDi class
 */
function gmap_taxonomy_reassign_marker($tid, $deletion = FALSE) {
  $nids = array();
  if ($deletion) {
    $result = db_query('SELECT nid FROM {gmap_taxonomy_node} WHERE tid = :tid', array(
      ':tid' => $tid,
    ));
    foreach ($result as $node) {
      $nids[] = $node->nid;
    }
  }
  else {
    $result = db_query('SELECT nid FROM {taxonomy_index} WHERE tid = :tid', array(
      ':tid' => $tid,
    ));
    foreach ($result as $node) {
      $nids[] = $node->nid;
    }
  }
  foreach ($nids as $nid) {
    $markers = db_query('SELECT t.tid, gt.marker FROM {taxonomy_index} r INNER JOIN {gmap_taxonomy_term} gt ON r.tid = gt.tid INNER JOIN {taxonomy_term_data} t ON r.tid = t.tid INNER JOIN {taxonomy_vocabulary} v ON t.vid = v.vid WHERE r.nid = :nid ORDER BY v.weight DESC, t.weight DESC, t.name DESC', array(
      ':nid' => $nid,
    ));
    if ($marker = $markers
      ->fetchObject()) {

      // Fallback found.
      db_update('gmap_taxonomy_node')
        ->fields(array(
        'tid' => $marker->tid,
        'marker' => $marker->marker,
      ))
        ->condition('nid', $nid)
        ->execute();
    }
    else {

      // No replacement marker, delete the row.
      db_delete('gmap_taxonomy_node')
        ->condition('nid', $nid)
        ->execute();
    }
  }

  // Clear cache to keep data updated.
  cache_clear_all('gmap_taxonomy_markers_data', 'cache');
}

/**
 * Implements hook_views_api().
 *
 * @todo move this to GmapTaxonomyViews class
 */
function gmap_taxonomy_views_api() {
  return array(
    'api' => 2,
  );
}