SynonymsBehavior.interface.inc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. /**
  3. * @file
  4. * Interfaces of synonyms behaviors that are shipped with Synonyms module.
  5. */
  6. /**
  7. * General interface of a synonyms behavior.
  8. *
  9. * All synonyms behaviors must extend this interface.
  10. */
  11. interface SynonymsBehavior {
  12. /**
  13. * Extract synonyms from an entity within a specific behavior implementation.
  14. *
  15. * @param object $entity
  16. * Entity from which to extract synonyms
  17. * @param string $langcode
  18. * Language code for which to extract synonyms from the entity, if one is
  19. * known
  20. *
  21. * @return array Array of synonyms extracted from $entity
  22. * Array of synonyms extracted from $entity
  23. */
  24. public function extractSynonyms($entity, $langcode = NULL);
  25. /**
  26. * Add an entity as a synonym into another entity.
  27. *
  28. * Basically this method should be called when you want to add some entity as
  29. * a synonym to another entity (for example when you merge one entity into
  30. * another and besides merging want to add synonym of the merged entity into
  31. * the trunk entity). You should update $trunk_entity in such a way that it
  32. * holds $synonym_entity as a synonym (it all depends on how data is stored in
  33. * your behavior implementation, but probably you will store entity label or
  34. * its ID as you cannot literally store an entity inside of another entity).
  35. * If entity of type $synonym_entity_type cannot be converted into a format
  36. * expected by your behavior implementation, just do nothing.
  37. *
  38. * @param object $trunk_entity
  39. * Entity into which another one should be added as synonym
  40. * @param object $synonym_entity
  41. * Fully loaded entity object which has to be added as synonym
  42. * @param string $synonym_entity_type
  43. * Entity type of $synonym_entity
  44. */
  45. public function mergeEntityAsSynonym($trunk_entity, $synonym_entity, $synonym_entity_type);
  46. /**
  47. * Look up entities by their synonyms within a behavior implementation.
  48. *
  49. * You are provided with a SQL condition that you should apply to the storage
  50. * of synonyms within the provided behavior implementation. And then return
  51. * result: what entities match by the provided condition through what
  52. * synonyms.
  53. *
  54. * @param QueryConditionInterface $condition
  55. * Condition that defines what to search for. Apart from normal SQL
  56. * conditions as known in Drupal, it may contain the following placeholders:
  57. * - AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER: to denote
  58. * synonyms column which you should replace with the actual column name
  59. * where the synonyms data for your provider is stored in plain text.
  60. * - AbstractSynonymsBehavior::COLUMN_ENTITY_ID_PLACEHOLDER: to denote
  61. * column that holds entity ID. You are supposed to replace this
  62. * placeholder with actual column name that holds entity ID in your case.
  63. * For ease of work with these placeholders, you may extend the
  64. * AbstractSynonymsBehavior class and then just invoke the
  65. * AbstractSynonymsBehavior->synonymsFindProcessCondition() method, so you
  66. * won't have to worry much about it. Important note: if you plan on
  67. * re-using the same $condition object for multiple invocations of this
  68. * method you must pass in here a clone of your condition object, since the
  69. * internal implementation of this method will change the condition (will
  70. * swap the aforementioned placeholders with actual column names)
  71. *
  72. * @return Traversable
  73. * Traversable result set of found synonyms and entity IDs to which those
  74. * belong. Each element in the result set should be an object and will have
  75. * the following structure:
  76. * - synonym: (string) Synonym that was found and which satisfies the
  77. * provided condition
  78. * - entity_id: (int) ID of the entity to which the found synonym belongs
  79. */
  80. public function synonymsFind(QueryConditionInterface $condition);
  81. /**
  82. * Collect info on features pipe during invocation of hook_features_export().
  83. *
  84. * If your synonyms provider depends on some other features components, this
  85. * method should return them.
  86. *
  87. * @return array
  88. * Array of features pipe as per hook_features_export() specification
  89. */
  90. public function featuresExportPipe();
  91. }
  92. /**
  93. * Exception thrown by implementations of SynonymsBehavior interface.
  94. */
  95. class SynonymsBehaviorException extends Exception {}
  96. /**
  97. * Starting point for implementing SynonymsBehavior interface.
  98. */
  99. abstract class AbstractSynonymsBehavior implements SynonymsBehavior {
  100. /**
  101. * Constant which denotes placeholder of a synonym column.
  102. *
  103. * @var string
  104. */
  105. const COLUMN_SYNONYM_PLACEHOLDER = '***COLUMN***';
  106. /**
  107. * Constant which denotes placeholder of an entity ID column.
  108. *
  109. * @var string
  110. */
  111. const COLUMN_ENTITY_ID_PLACEHOLDER = '***ENTITY_ID***';
  112. /**
  113. * Behavior implementation on which this class was initialized.
  114. *
  115. * @var array
  116. */
  117. protected $behavior_implementation;
  118. public function __construct($behavior_implementation) {
  119. $this->behavior_implementation = $behavior_implementation;
  120. }
  121. public function featuresExportPipe() {
  122. return array();
  123. }
  124. /**
  125. * Process condition in 'synonymsFind' method.
  126. *
  127. * Process condition in 'synonymsFind' method replacing all references of
  128. * synonym and entity ID columns with the real names of those columns.
  129. *
  130. * @param QueryConditionInterface $condition
  131. * Condition that should be processed
  132. * @param string $column_synonym
  133. * Real name of the synonym column
  134. * @param string $column_entity_id
  135. * Real name of the entity ID column
  136. */
  137. protected function synonymsFindProcessCondition(QueryConditionInterface $condition, $column_synonym, $column_entity_id) {
  138. $condition_array = &$condition->conditions();
  139. foreach ($condition_array as &$v) {
  140. if (is_array($v) && isset($v['field'])) {
  141. if ($v['field'] instanceof QueryConditionInterface) {
  142. // Recursively process this condition too.
  143. $this->synonymsFindProcessCondition($v['field'], $column_synonym, $column_entity_id);
  144. }
  145. else {
  146. $replace = array(
  147. self::COLUMN_SYNONYM_PLACEHOLDER => $column_synonym,
  148. self::COLUMN_ENTITY_ID_PLACEHOLDER => $column_entity_id,
  149. );
  150. $v['field'] = str_replace(array_keys($replace), array_values($replace), $v['field']);
  151. }
  152. }
  153. }
  154. }
  155. }
  156. /**
  157. * Interface of the autocomplete synonyms behavior.
  158. */
  159. interface AutocompleteSynonymsBehavior extends SynonymsBehavior {
  160. }
  161. /**
  162. * Interface of the synonyms friendly select behavior.
  163. */
  164. interface SelectSynonymsBehavior extends SynonymsBehavior {
  165. }