diff sites/all/modules/entityreference/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php @ 4:ce11bbd8f642

added modules
author danieleb <danielebarchiesi@me.com>
date Thu, 19 Sep 2013 10:38:44 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/modules/entityreference/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php	Thu Sep 19 10:38:44 2013 +0100
@@ -0,0 +1,189 @@
+<?php
+
+/**
+ * @file
+ * CTools plugin class for the taxonomy-index behavior.
+ */
+
+/**
+ * Extends an entityreference field to maintain its references to taxonomy terms
+ * in the {taxonomy_index} table.
+ *
+ * Note, unlike entityPostInsert() and entityPostUpdate(), entityDelete()
+ * is not needed as cleanup is performed by taxonomy module in
+ * taxonomy_delete_node_index().
+ */
+class EntityReferenceBehavior_TaxonomyIndex extends EntityReference_BehaviorHandler_Abstract {
+
+  /**
+   * Overrides EntityReference_BehaviorHandler_Abstract::access().
+   *
+   * Ensure that it is only enabled for ER instances on nodes targeting
+   * terms, and the core variable to maintain index is enabled.
+   */
+  public function access($field, $instance) {
+    if ($instance['entity_type'] != 'node' || $field['settings']['target_type'] != 'taxonomy_term') {
+      return;
+    }
+
+    if ($field['storage']['type'] !== 'field_sql_storage') {
+      // Field doesn't use SQL storage.
+      return;
+    }
+
+    return variable_get('taxonomy_maintain_index_table', TRUE);
+  }
+
+  /**
+   * Overrides EntityReference_BehaviorHandler_Abstract::entityPostInsert().
+   *
+   * Runs after hook_node_insert() used by taxonomy module.
+   */
+  public function entityPostInsert($entity_type, $entity, $field, $instance) {
+    if ($entity_type != 'node') {
+      return;
+    }
+
+    $this->buildNodeIndex($entity);
+  }
+
+  /**
+   * Overrides EntityReference_BehaviorHandler_Abstract::entityPostUpdate().
+   *
+   * Runs after hook_node_update() used by taxonomy module.
+   */
+  public function entityPostUpdate($entity_type, $entity, $field, $instance) {
+    if ($entity_type != 'node') {
+      return;
+    }
+
+    $this->buildNodeIndex($entity);
+  }
+
+  /**
+   * Builds and inserts taxonomy index entries for a given node.
+   *
+   * The index lists all terms that are related to a given node entity, and is
+   * therefore maintained at the entity level.
+   *
+   * @param $node
+   *   The node object.
+   *
+   * @see taxonomy_build_node_index()
+   */
+  protected function buildNodeIndex($node) {
+    // We maintain a denormalized table of term/node relationships, containing
+    // only data for current, published nodes.
+    $status = NULL;
+    if (variable_get('taxonomy_maintain_index_table', TRUE)) {
+      // If a node property is not set in the node object when node_save() is
+      // called, the old value from $node->original is used.
+      if (!empty($node->original)) {
+        $status = (int)(!empty($node->status) || (!isset($node->status) && !empty($node->original->status)));
+        $sticky = (int)(!empty($node->sticky) || (!isset($node->sticky) && !empty($node->original->sticky)));
+      }
+      else {
+        $status = (int)(!empty($node->status));
+        $sticky = (int)(!empty($node->sticky));
+      }
+    }
+    // We only maintain the taxonomy index for published nodes.
+    if ($status) {
+      // Collect a unique list of all the term IDs from all node fields.
+      $tid_all = array();
+      foreach (field_info_instances('node', $node->type) as $instance) {
+        $field_name = $instance['field_name'];
+        $field = field_info_field($field_name);
+        if (!empty($field['settings']['target_type']) && $field['settings']['target_type'] == 'taxonomy_term' && $field['storage']['type'] == 'field_sql_storage') {
+          // If a field value is not set in the node object when node_save() is
+          // called, the old value from $node->original is used.
+          if (isset($node->{$field_name})) {
+            $items = $node->{$field_name};
+          }
+          elseif (isset($node->original->{$field_name})) {
+            $items = $node->original->{$field_name};
+          }
+          else {
+            continue;
+          }
+          foreach (field_available_languages('node', $field) as $langcode) {
+            if (!empty($items[$langcode])) {
+              foreach ($items[$langcode] as $item) {
+                $tid_all[$item['target_id']] = $item['target_id'];
+              }
+            }
+          }
+        }
+
+        // Re-calculate the terms added in taxonomy_build_node_index() so
+        // we can optimize database queries.
+        $original_tid_all = array();
+        if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') {
+          // If a field value is not set in the node object when node_save() is
+          // called, the old value from $node->original is used.
+          if (isset($node->{$field_name})) {
+            $items = $node->{$field_name};
+          }
+          elseif (isset($node->original->{$field_name})) {
+            $items = $node->original->{$field_name};
+          }
+          else {
+            continue;
+          }
+          foreach (field_available_languages('node', $field) as $langcode) {
+            if (!empty($items[$langcode])) {
+              foreach ($items[$langcode] as $item) {
+                $original_tid_all[$item['tid']] = $item['tid'];
+              }
+            }
+          }
+        }
+      }
+
+      // Insert index entries for all the node's terms, that were not
+      // already inserted in taxonomy_build_node_index().
+      $tid_all = array_diff($tid_all, $original_tid_all);
+
+      // Insert index entries for all the node's terms.
+      if (!empty($tid_all)) {
+        $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created'));
+        foreach ($tid_all as $tid) {
+          $query->values(array(
+            'nid' => $node->nid,
+            'tid' => $tid,
+            'sticky' => $sticky,
+            'created' => $node->created,
+          ));
+        }
+        $query->execute();
+      }
+    }
+  }
+
+  /**
+   * Overrides EntityReference_BehaviorHandler_Abstract::settingsForm().
+   */
+  public function settingsForm($field, $instance) {
+    $form = array();
+    $target = $field['settings']['target_type'];
+    if ($target != 'taxonomy_term') {
+      $form['ti-on-terms'] = array(
+        '#markup' => t('This behavior can only be set when the target type is taxonomy_term, but the target of this field is %target.', array('%target' => $target)),
+      );
+    }
+
+    $entity_type = $instance['entity_type'];
+    if ($entity_type != 'node') {
+      $form['ti-on-nodes'] = array(
+        '#markup' => t('This behavior can only be set when the entity type is node, but the entity type of this instance is %type.', array('%type' => $entity_type)),
+      );
+    }
+
+    if (!variable_get('taxonomy_maintain_index_table', TRUE)) {
+      $form['ti-disabled'] = array(
+        '#markup' => t('This core variable "taxonomy_maintain_index_table" is disabled.'),
+      );
+    }
+    return $form;
+  }
+}