updated synonyms to 1.5
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Enables Entity Reference field type to be source of synonyms.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Definition of EntityReferenceSynonymsBehavior class.
|
||||
*/
|
||||
class EntityReferenceSynonymsBehavior extends AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehavior, AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
|
||||
|
||||
public function extractSynonyms($items, $field, $instance, $entity, $entity_type) {
|
||||
$synonyms = array();
|
||||
|
||||
$target_tids = array();
|
||||
foreach ($items as $item) {
|
||||
$target_tids[] = $item['target_id'];
|
||||
}
|
||||
$entities = entity_load($field['settings']['target_type'], $target_tids);
|
||||
foreach ($entities as $entity) {
|
||||
$synonyms[] = entity_label($field['settings']['target_type'], $entity);
|
||||
}
|
||||
|
||||
return $synonyms;
|
||||
}
|
||||
|
||||
public function mergeEntityAsSynonym($items, $field, $instance, $synonym_entity, $synonym_entity_type) {
|
||||
// Firstly validating that this entity reference is able to reference to
|
||||
// that type of entity.
|
||||
$expected_synonym_entity_type = $field['settings']['target_type'];
|
||||
if ($expected_synonym_entity_type != $synonym_entity_type) {
|
||||
return array();
|
||||
}
|
||||
$synonym_entity_id = entity_id($synonym_entity_type, $synonym_entity);
|
||||
return array(array(
|
||||
'target_id' => $synonym_entity_id,
|
||||
));
|
||||
}
|
||||
|
||||
public function synonymItemHash($item, $field, $instance) {
|
||||
return $field['settings']['target_type'] . $item['target_id'];
|
||||
}
|
||||
|
||||
public function synonymsFind(QueryConditionInterface $condition, $field, $instance) {
|
||||
if ($field['storage']['type'] != 'field_sql_storage') {
|
||||
throw new SynonymsSynonymsBehaviorException(t('Not supported storage engine %type in synonymsFind() method.', array(
|
||||
'%type' => $field['storage']['type'],
|
||||
)));
|
||||
}
|
||||
$table = array_keys($field['storage']['details']['sql'][FIELD_LOAD_CURRENT]);
|
||||
$table = reset($table);
|
||||
$column = $field['storage']['details']['sql'][FIELD_LOAD_CURRENT][$table]['target_id'];
|
||||
|
||||
$query = db_select($table, 'field');
|
||||
|
||||
$target_entity_type_info = entity_get_info($field['settings']['target_type']);
|
||||
if (!isset($target_entity_type_info['base table']) || !$target_entity_type_info['base table']) {
|
||||
throw new SynonymsSynonymsBehaviorException(t('Target entity type %entity_type is not stored in database.', array(
|
||||
'%entity_type' => $field['settings']['target_type'],
|
||||
)));
|
||||
}
|
||||
if (!isset($target_entity_type_info['entity keys']['id'])) {
|
||||
throw new SynonymsSynonymsBehaviorException(t('Target entity type %entity_type does not declare primary key.', array(
|
||||
'%entity_type' => $field['settings']['target_type'],
|
||||
)));
|
||||
}
|
||||
if (!isset($target_entity_type_info['entity keys']['label'])) {
|
||||
throw new SynonymsSynonymsBehaviorException(t('Target entity type %entity_type does not declare label column.', array(
|
||||
'%entity_type' => $field['settings']['target_type'],
|
||||
)));
|
||||
}
|
||||
|
||||
$target_entity_alias = $query->innerJoin($target_entity_type_info['base table'], 'target_entity', 'field.' . $column . ' = target_entity.' . $target_entity_type_info['entity keys']['id']);
|
||||
$query->addField($target_entity_alias, $target_entity_type_info['entity keys']['label'], 'synonym');
|
||||
$query->fields('field', array('entity_id'));
|
||||
$query->condition('field.entity_type', $instance['entity_type']);
|
||||
$query->condition('field.bundle', $instance['bundle']);
|
||||
|
||||
$this->synonymsFindProcessCondition($condition, $target_entity_alias . '.' . $target_entity_type_info['entity keys']['label']);
|
||||
$query->condition($condition);
|
||||
return $query->execute();
|
||||
}
|
||||
}
|
@@ -11,114 +11,61 @@
|
||||
* All synonyms behaviors must extend this interface.
|
||||
*/
|
||||
interface SynonymsBehavior {
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface of "synonyms" behavior.
|
||||
*
|
||||
* The most basic synonyms behavior.
|
||||
*/
|
||||
interface SynonymsSynonymsBehavior extends SynonymsBehavior {
|
||||
|
||||
/**
|
||||
* Extract synonyms from a field attached to an entity.
|
||||
* Extract synonyms from an entity within a specific behavior implementation.
|
||||
*
|
||||
* We try to pass as many info about context as possible, however, normally
|
||||
* you will only need $items to extract the synonyms.
|
||||
*
|
||||
* @param array $items
|
||||
* Array of items
|
||||
* @param array $field
|
||||
* Array of field definition according to Field API
|
||||
* @param array $instance
|
||||
* Array of instance definition according to Field API
|
||||
* @param object $entity
|
||||
* Fully loaded entity object to which the $field and $instance with $item
|
||||
* values is attached to
|
||||
* @param string $entity_type
|
||||
* Type of the entity $entity according to Field API definition of entity
|
||||
* types
|
||||
* Entity from which to extract synonyms
|
||||
*
|
||||
* @return array
|
||||
* Array of synonyms extracted from $items
|
||||
* Array of synonyms extracted from $entity
|
||||
*/
|
||||
public function extractSynonyms($items, $field, $instance, $entity, $entity_type);
|
||||
public function extractSynonyms($entity);
|
||||
|
||||
/**
|
||||
* Add an entity as a synonym into a field of another entity.
|
||||
* Add an entity as a synonym into another entity.
|
||||
*
|
||||
* Basically this method should be called when you want to add some entity
|
||||
* as a synonym to another entity (for example when you merge one entity
|
||||
* into another and besides merging want to add synonym of the merged entity
|
||||
* into the trunk entity). You should extract synonym value (according to what
|
||||
* value is expected in this field) and return it. We try to provide you with
|
||||
* as much of context as possible, but normally you would only need
|
||||
* $synonym_entity and $synonym_entity_type parameters. Return an empty array
|
||||
* if entity of type $synonym_entity_type cannot be converted into a format
|
||||
* expected by $field.
|
||||
* Basically this method should be called when you want to add some entity as
|
||||
* a synonym to another entity (for example when you merge one entity into
|
||||
* another and besides merging want to add synonym of the merged entity into
|
||||
* the trunk entity). You should update $trunk_entity in such a way that it
|
||||
* holds $synonym_entity as a synonym (it all depends on how data is stored in
|
||||
* your behavior implementation, but probably you will store entity label or
|
||||
* its ID as you cannot literally store an entity inside of another entity).
|
||||
* If entity of type $synonym_entity_type cannot be converted into a format
|
||||
* expected by your behavior implementation, just do nothing.
|
||||
*
|
||||
* @param array $items
|
||||
* Array items that already exist in the field into which new synonyms is to
|
||||
* be added
|
||||
* @param array $field
|
||||
* Field array definition according to Field API of the field into which new
|
||||
* synonym is to be added
|
||||
* @param array $instance
|
||||
* Instance array definition according to Field API of the instance into
|
||||
* which new synonym is to be added
|
||||
* @param object $trunk_entity
|
||||
* Entity into which another one should be added as synonym
|
||||
* @param object $synonym_entity
|
||||
* Fully loaded entity object which has to be added as synonym
|
||||
* @param string $synonym_entity_type
|
||||
* Entity type of $synonym_entity
|
||||
*
|
||||
* @return array
|
||||
* Array of extra items to be merged into the items that already exist in
|
||||
* field values
|
||||
*/
|
||||
public function mergeEntityAsSynonym($items, $field, $instance, $synonym_entity, $synonym_entity_type);
|
||||
public function mergeEntityAsSynonym($trunk_entity, $synonym_entity, $synonym_entity_type);
|
||||
|
||||
/**
|
||||
* Hash a field item that is enabled as synonym.
|
||||
*
|
||||
* Your hash function must return such hash that for 2 items that yield the
|
||||
* same synonyms their hash must be the same. There is no limit on minimal or
|
||||
* maximum hash length, but keep it reasonable, something below 512 symbols.
|
||||
* Also, your hash function should strive to minimize hash collisions, i.e.
|
||||
* when 2 different items yield the same hash.
|
||||
*
|
||||
* @param array $item
|
||||
* Field item whose hash is requested
|
||||
* @param array $field
|
||||
* Field from which the $item comes from
|
||||
* @param array $instance
|
||||
* Instance from which the $item comes from
|
||||
*
|
||||
* @return string
|
||||
* Hash of the provided $item
|
||||
*/
|
||||
public function synonymItemHash($item, $field, $instance);
|
||||
|
||||
/**
|
||||
* Look up entities by their synonyms within a provided field.
|
||||
* Look up entities by their synonyms within a behavior implementation.
|
||||
*
|
||||
* You are provided with a SQL condition that you should apply to the storage
|
||||
* of synonyms within the provided field. And then return result: what
|
||||
* entities match by the provided condition through what synonyms.
|
||||
* of synonyms within the provided behavior implementation. And then return
|
||||
* result: what entities match by the provided condition through what
|
||||
* synonyms.
|
||||
*
|
||||
* @param QueryConditionInterface $condition
|
||||
* Condition that defines what to search for. It may contain a placeholder
|
||||
* of AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER which you should
|
||||
* replace by the column name where the synonyms data for your field is
|
||||
* stored in plain text. For it to do, you may extend the
|
||||
* AbstractSynonymsSynonymsBehavior class and then just invoke the
|
||||
* AbstractSynonymsSynonymsBehavior->synonymsFindProcessCondition() method,
|
||||
* so you won't have to worry much about it
|
||||
* @param array $field
|
||||
* Field API field definition array of the field within which the search
|
||||
* for synonyms should be performed
|
||||
* @param array $instance
|
||||
* Field API instance definition array of the instance within which the
|
||||
* search for synonyms should be performed
|
||||
* Condition that defines what to search for. Apart from normal SQL
|
||||
* conditions as known in Drupal, it may contain the following placeholders:
|
||||
* - AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER: to denote
|
||||
* synonyms column which you should replace with the actual column name
|
||||
* where the synonyms data for your provider is stored in plain text.
|
||||
* - AbstractSynonymsBehavior::COLUMN_ENTITY_ID_PLACEHOLDER: to denote
|
||||
* column that holds entity ID. You are supposed to replace this
|
||||
* placeholder with actual column name that holds entity ID in your case.
|
||||
* For ease of work with these placeholders, you may extend the
|
||||
* AbstractSynonymsBehavior class and then just invoke the
|
||||
* AbstractSynonymsBehavior->synonymsFindProcessCondition() method, so you
|
||||
* won't have to worry much about it
|
||||
*
|
||||
* @return Traversable
|
||||
* Traversable result set of found synonyms and entity IDs to which those
|
||||
@@ -128,47 +75,86 @@ interface SynonymsSynonymsBehavior extends SynonymsBehavior {
|
||||
* provided condition
|
||||
* - entity_id: (int) ID of the entity to which the found synonym belongs
|
||||
*/
|
||||
public function synonymsFind(QueryConditionInterface $condition, $field, $instance);
|
||||
public function synonymsFind(QueryConditionInterface $condition);
|
||||
|
||||
/**
|
||||
* Collect info on features pipe during invocation of hook_features_export().
|
||||
*
|
||||
* If your synonyms provider depends on some other features components, this
|
||||
* method should return them.
|
||||
*
|
||||
* @return array
|
||||
* Array of features pipe as per hook_features_export() specification
|
||||
*/
|
||||
public function featuresExportPipe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown by implementations of SynonymsSynonymsBehavior interface.
|
||||
* Exception thrown by implementations of SynonymsBehavior interface.
|
||||
*/
|
||||
class SynonymsSynonymsBehaviorException extends Exception {}
|
||||
class SynonymsBehaviorException extends Exception {}
|
||||
|
||||
/**
|
||||
* Starting point for implementing SynonymsSynonymsBehavior interface.
|
||||
* Starting point for implementing SynonymsBehavior interface.
|
||||
*/
|
||||
abstract class AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehavior {
|
||||
abstract class AbstractSynonymsBehavior implements SynonymsBehavior {
|
||||
|
||||
/**
|
||||
* Constant which denotes placeholder of a synonym column.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLUMN_PLACEHOLDER = '***COLUMN***';
|
||||
const COLUMN_SYNONYM_PLACEHOLDER = '***COLUMN***';
|
||||
|
||||
/**
|
||||
* Constant which denotes placeholder of an entity ID column.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLUMN_ENTITY_ID_PLACEHOLDER = '***ENTITY_ID***';
|
||||
|
||||
/**
|
||||
* Behavior implementation on which this class was initialized.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $behavior_implementation;
|
||||
|
||||
public function __construct($behavior_implementation) {
|
||||
$this->behavior_implementation = $behavior_implementation;
|
||||
}
|
||||
|
||||
public function featuresExportPipe() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process condition in 'synonymsFind' method.
|
||||
*
|
||||
* Process condition in 'synonymsFind' method replacing all references of
|
||||
* synonym column with the real name of that column.
|
||||
* synonym and entity ID columns with the real names of those columns.
|
||||
*
|
||||
* @param QueryConditionInterface $condition
|
||||
* Condition that should be processed
|
||||
* @param string $column
|
||||
* @param string $column_synonym
|
||||
* Real name of the synonym column
|
||||
* @param string $column_entity_id
|
||||
* Real name of the entity ID column
|
||||
*/
|
||||
protected function synonymsFindProcessCondition(QueryConditionInterface $condition, $column) {
|
||||
protected function synonymsFindProcessCondition(QueryConditionInterface $condition, $column_synonym, $column_entity_id) {
|
||||
$condition_array = &$condition->conditions();
|
||||
foreach ($condition_array as &$v) {
|
||||
if (is_array($v) && isset($v['field'])) {
|
||||
if ($v['field'] instanceof QueryConditionInterface) {
|
||||
// Recursively process this condition too.
|
||||
$this->synonymsFindProcessCondition($v['field'], $column);
|
||||
$this->synonymsFindProcessCondition($v['field'], $column_synonym, $column_entity_id);
|
||||
}
|
||||
else {
|
||||
$v['field'] = str_replace(self::COLUMN_PLACEHOLDER, $column, $v['field']);
|
||||
$replace = array(
|
||||
self::COLUMN_SYNONYM_PLACEHOLDER => $column_synonym,
|
||||
self::COLUMN_ENTITY_ID_PLACEHOLDER => $column_entity_id,
|
||||
);
|
||||
$v['field'] = str_replace(array_keys($replace), array_values($replace), $v['field']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,11 +164,11 @@ abstract class AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehav
|
||||
/**
|
||||
* Interface of the autocomplete synonyms behavior.
|
||||
*/
|
||||
interface AutocompleteSynonymsBehavior extends SynonymsSynonymsBehavior {
|
||||
interface AutocompleteSynonymsBehavior extends SynonymsBehavior {
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface of the synonyms friendly select behavior.
|
||||
*/
|
||||
interface SelectSynonymsBehavior extends SynonymsSynonymsBehavior {
|
||||
interface SelectSynonymsBehavior extends SynonymsBehavior {
|
||||
}
|
||||
|
@@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Enables Taxonomy Term Reference field type to be source of synonyms.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Definition of TaxonomySynonymsBehavior class.
|
||||
*/
|
||||
class TaxonomySynonymsBehavior extends AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehavior, AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
|
||||
|
||||
public function extractSynonyms($items, $field, $instance, $entity, $entity_type) {
|
||||
$synonyms = array();
|
||||
|
||||
$terms = array();
|
||||
foreach ($items as $item) {
|
||||
$terms[] = $item['tid'];
|
||||
}
|
||||
$terms = taxonomy_term_load_multiple($terms);
|
||||
foreach ($terms as $term) {
|
||||
$synonyms[] = entity_label('taxonomy_term', $term);
|
||||
}
|
||||
return $synonyms;
|
||||
}
|
||||
|
||||
public function mergeEntityAsSynonym($items, $field, $instance, $synonym_entity, $synonym_entity_type) {
|
||||
// Taxonomy term reference supports only referencing of entity types
|
||||
// 'taxonomy_term'.. duh.
|
||||
if ($synonym_entity_type != 'taxonomy_term') {
|
||||
return array();
|
||||
}
|
||||
// Checking that $field is configured to reference the vocabulary of
|
||||
// $synonym_entity term.
|
||||
$is_allowed = FALSE;
|
||||
foreach ($field['settings']['allowed_values'] as $setting) {
|
||||
if ($synonym_entity->vocabulary_machine_name == $setting['vocabulary']) {
|
||||
if ($setting['parent'] == 0) {
|
||||
// No need to check parent property as there is no limitation on it.
|
||||
$is_allowed = TRUE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
foreach (taxonomy_get_parents_all($synonym_entity->tid) as $parent) {
|
||||
if ($parent->tid == $setting['parent']) {
|
||||
$is_allowed = TRUE;
|
||||
break(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$is_allowed) {
|
||||
// Synonym term is from a vocabulary that is not expected by this field,
|
||||
// or under unexpected parent.
|
||||
return array();
|
||||
}
|
||||
return array(array(
|
||||
'tid' => $synonym_entity->tid,
|
||||
));
|
||||
}
|
||||
|
||||
public function synonymItemHash($item, $field, $instance) {
|
||||
return $item['tid'];
|
||||
}
|
||||
|
||||
public function synonymsFind(QueryConditionInterface $condition, $field, $instance) {
|
||||
if ($field['storage']['type'] != 'field_sql_storage') {
|
||||
throw new SynonymsSynonymsBehaviorException(t('Not supported storage engine %type in synonymsFind() method.', array(
|
||||
'%type' => $field['storage']['type'],
|
||||
)));
|
||||
}
|
||||
$table = array_keys($field['storage']['details']['sql'][FIELD_LOAD_CURRENT]);
|
||||
$table = reset($table);
|
||||
$column = $field['storage']['details']['sql'][FIELD_LOAD_CURRENT][$table]['tid'];
|
||||
|
||||
$query = db_select($table, 'field');
|
||||
$term_alias = $query->innerJoin('taxonomy_term_data', 'term', 'field.' . $column . ' = term.tid');
|
||||
$query->addField($term_alias, 'name', 'synonym');
|
||||
$query->fields('field', array('entity_id'));
|
||||
$query->condition('field.entity_type', $instance['entity_type']);
|
||||
$query->condition('field.bundle', $instance['bundle']);
|
||||
|
||||
$this->synonymsFindProcessCondition($condition, $term_alias . '.name');
|
||||
$query->condition($condition);
|
||||
return $query->execute();
|
||||
}
|
||||
}
|
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Enables text and number field types to be source of synonyms.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Definition of TextSynonymsBehavior class.
|
||||
*/
|
||||
class TextSynonymsBehavior extends AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehavior, AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
|
||||
|
||||
public function extractSynonyms($items, $field, $instance, $entity, $entity_type) {
|
||||
$synonyms = array();
|
||||
|
||||
foreach ($items as $item) {
|
||||
$synonyms[] = $item['value'];
|
||||
}
|
||||
|
||||
return $synonyms;
|
||||
}
|
||||
|
||||
public function mergeEntityAsSynonym($items, $field, $instance, $synonym_entity, $synonym_entity_type) {
|
||||
$synonym = entity_label($synonym_entity_type, $synonym_entity);
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
break;
|
||||
|
||||
// We add synonyms for numbers only if $synonym is a number.
|
||||
case 'number_integer':
|
||||
case 'number_float':
|
||||
case 'number_decimal':
|
||||
if (!is_numeric($synonym)) {
|
||||
return array();
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return array(array(
|
||||
'value' => $synonym,
|
||||
));
|
||||
}
|
||||
|
||||
public function synonymItemHash($item, $field, $instance) {
|
||||
return $item['value'];
|
||||
}
|
||||
|
||||
public function synonymsFind(QueryConditionInterface $condition, $field, $instance) {
|
||||
if ($field['storage']['type'] != 'field_sql_storage') {
|
||||
throw new SynonymsSynonymsBehaviorException(t('Not supported storage engine %type in synonymsFind() method.', array(
|
||||
'%type' => $field['storage']['type'],
|
||||
)));
|
||||
}
|
||||
$table = array_keys($field['storage']['details']['sql'][FIELD_LOAD_CURRENT]);
|
||||
$table = reset($table);
|
||||
$column = $field['storage']['details']['sql'][FIELD_LOAD_CURRENT][$table]['value'];
|
||||
|
||||
$this->synonymsFindProcessCondition($condition, $column);
|
||||
|
||||
$query = db_select($table);
|
||||
$query->fields($table, array('entity_id'));
|
||||
$query->addField($table, $column, 'synonym');
|
||||
return $query->condition($condition)
|
||||
->condition('entity_type', $instance['entity_type'])
|
||||
->condition('bundle', $instance['bundle'])
|
||||
->execute();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user