synonyms_commerce.pages.inc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. /**
  3. * @file
  4. * Menu page callbacks of the module.
  5. */
  6. /**
  7. * Menu page callback for synonyms commerce autocomplete widget.
  8. */
  9. function synonyms_commerce_autocomplete($field_name, $entity_type, $bundle) {
  10. // If the request has a '/' in the search text, then the menu system will have
  11. // split it into multiple arguments, recover the intended $tags_typed.
  12. $args = func_get_args();
  13. // Shift off the $field_name argument.
  14. array_shift($args);
  15. // Shift off the $entity_type argument.
  16. array_shift($args);
  17. // Shift off the $bundle argument.
  18. array_shift($args);
  19. $tags_typed = implode('/', $args);
  20. if (!($field = field_info_field($field_name)) || $field['type'] != 'commerce_product_reference') {
  21. print t('Commerce product reference field @field_name not found.', array('@field_name' => $field_name));
  22. exit;
  23. }
  24. if (!($instance = field_info_instance($entity_type, $field['field_name'], $bundle))) {
  25. // Error string. The JavaScript handler will realize this is not JSON and
  26. // will display it as debugging information.
  27. print t('There was not found an instance of @field_name in @entity_type.', array(
  28. '@field_name' => $field_name,
  29. '@entity_type' => $entity_type,
  30. ));
  31. exit;
  32. }
  33. module_load_include('inc', 'synonyms', 'synonyms.pages');
  34. $widget = $instance['widget']['type'] == 'synonyms_commerce_autocomplete' ? $instance['widget']['settings'] : field_info_widget_settings('synonyms_commerce_autocomplete');
  35. // How many suggestions maximum we are able to output.
  36. $max_suggestions = $widget['suggestion_size'];
  37. // Whether we are allowed to suggest more than one entry per term, shall that
  38. // entry be either term name itself or one of its synonyms.
  39. $suggest_only_unique = $widget['suggest_only_unique'];
  40. $tags_typed = drupal_explode_tags($tags_typed);
  41. $tag_last = drupal_strtolower(array_pop($tags_typed));
  42. $prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : '';
  43. $matches = array();
  44. if ($tag_last) {
  45. $tags_typed_entity_ids = array();
  46. if (!empty($tags_typed)) {
  47. foreach (commerce_product_load_multiple(array(), array('title' => $tags_typed)) as $product) {
  48. $product_ids = entity_extract_ids('commerce_product', $product);
  49. $tags_typed_entity_ids[] = $product_ids[0];
  50. }
  51. }
  52. $new_target_ids = array();
  53. foreach (commerce_product_match_products($field, $instance, $tag_last, 'contains', array(), $max_suggestions) as $product) {
  54. $product = commerce_product_load_by_sku($product['sku']);
  55. $product_id = entity_extract_ids('commerce_product', $product);
  56. $product_id = $product_id[0];
  57. if (!in_array($product_id, $tags_typed_entity_ids)) {
  58. $matches[] = array(
  59. 'name' => entity_label('commerce_product', $product),
  60. );
  61. $new_target_ids[] = $product_id;
  62. }
  63. }
  64. if (count($matches) < $max_suggestions) {
  65. $target_bundles = synonyms_bundle_normalize('commerce_product', array_filter($instance['settings']['referenceable_types']));
  66. $behavior_implementations = synonyms_behavior_get('autocomplete', 'commerce_product', $target_bundles, TRUE);
  67. foreach ($behavior_implementations as $implementation) {
  68. $condition = db_and();
  69. $condition->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, '%' . db_like($tag_last) . '%', 'LIKE');
  70. if (!empty($tags_typed_entity_ids)) {
  71. $condition->condition(AbstractSynonymsBehavior::COLUMN_ENTITY_ID_PLACEHOLDER, $tags_typed_entity_ids, 'NOT IN');
  72. }
  73. if ($suggest_only_unique && !empty($new_target_ids)) {
  74. $condition->condition(AbstractSynonymsBehavior::COLUMN_ENTITY_ID_PLACEHOLDER, $new_target_ids, 'NOT IN');
  75. }
  76. foreach ($implementation['object']->synonymsFind($condition) as $synonym) {
  77. if (!$suggest_only_unique || !in_array($synonym->entity_id, $new_target_ids)) {
  78. $matches[] = array(
  79. 'target_id' => $synonym->entity_id,
  80. 'synonym' => $synonym->synonym,
  81. 'behavior_implementation' => $implementation,
  82. );
  83. $new_target_ids[] = $synonym->entity_id;
  84. if (count($matches) == $max_suggestions) {
  85. break (2);
  86. }
  87. }
  88. }
  89. }
  90. }
  91. $synonym_entities = array();
  92. foreach ($matches as $match) {
  93. if (!isset($match['wording']) && isset($match['synonym'])) {
  94. $synonym_entities[] = $match['target_id'];
  95. }
  96. }
  97. if (!empty($synonym_entities)) {
  98. $synonym_entities = commerce_product_load_multiple($synonym_entities);
  99. foreach ($matches as $k => $match) {
  100. if (!isset($match['name']) && isset($match['synonym'])) {
  101. $matches[$k]['name'] = entity_label('commerce_product', $synonym_entities[$match['target_id']]);
  102. }
  103. }
  104. $matches = array_values($matches);
  105. }
  106. }
  107. drupal_json_output(synonyms_autocomplete_format($matches, $prefix));
  108. }