189
plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php
Normal file
189
plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
@@ -107,6 +107,27 @@ interface EntityReference_BehaviorHandler {
|
||||
*/
|
||||
public function postDelete($entity_type, $entity, $field, $instance);
|
||||
|
||||
/**
|
||||
* Act after inserting an entity.
|
||||
*
|
||||
* @see hook_entity_insert()
|
||||
*/
|
||||
public function entityPostInsert($entity_type, $entity, $field, $instance);
|
||||
|
||||
/**
|
||||
* Act after updating an entity.
|
||||
*
|
||||
* @see hook_entity_update()
|
||||
*/
|
||||
public function entityPostUpdate($entity_type, $entity, $field, $instance);
|
||||
|
||||
/**
|
||||
* Act after deleting an entity.
|
||||
*
|
||||
* @see hook_entity_delete()
|
||||
*/
|
||||
public function entityPostDelete($entity_type, $entity, $field, $instance);
|
||||
|
||||
/**
|
||||
* Generate a settings form for this handler.
|
||||
*/
|
||||
@@ -167,6 +188,12 @@ abstract class EntityReference_BehaviorHandler_Abstract implements EntityReferen
|
||||
|
||||
public function postDelete($entity_type, $entity, $field, $instance) {}
|
||||
|
||||
public function entityPostInsert($entity_type, $entity, $field, $instance) {}
|
||||
|
||||
public function entityPostUpdate($entity_type, $entity, $field, $instance) {}
|
||||
|
||||
public function entityPostDelete($entity_type, $entity, $field, $instance) {}
|
||||
|
||||
public function settingsForm($field, $instance) {}
|
||||
|
||||
public function access($field, $instance) {
|
||||
|
16
plugins/behavior/taxonomy-index.inc
Normal file
16
plugins/behavior/taxonomy-index.inc
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* CTools plugin declaration for taxonomy-index behavior.
|
||||
*/
|
||||
|
||||
if (module_exists('taxonomy')) {
|
||||
$plugin = array(
|
||||
'title' => t('Taxonomy index'),
|
||||
'description' => t('Include the term references created by instances of this field carried by node entities in the core {taxonomy_index} table. This will allow various modules to handle them like core term_reference fields.'),
|
||||
'class' => 'EntityReferenceBehavior_TaxonomyIndex',
|
||||
'behavior type' => 'instance',
|
||||
'force enabled' => TRUE,
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user