search.rb 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. class Organization
  3. module Search
  4. extend ActiveSupport::Concern
  5. included do
  6. include HasSearchSortable
  7. end
  8. # methods defined here are going to extend the class, not the instance of it
  9. class_methods do
  10. =begin
  11. search organizations preferences
  12. result = Organization.search_preferences(user_model)
  13. returns if user has permissions to search
  14. result = {
  15. prio: 1000,
  16. direct_search_index: true
  17. }
  18. returns if user has no permissions to search
  19. result = false
  20. =end
  21. def search_preferences(current_user)
  22. return false if !current_user.permissions?('ticket.agent') && !current_user.permissions?('admin.organization')
  23. {
  24. prio: 1000,
  25. direct_search_index: true,
  26. }
  27. end
  28. =begin
  29. search organizations
  30. result = Organization.search(
  31. current_user: User.find(123),
  32. query: 'search something',
  33. limit: 15,
  34. offset: 100,
  35. # sort single column
  36. sort_by: 'created_at',
  37. order_by: 'asc',
  38. # sort multiple columns
  39. sort_by: [ 'created_at', 'updated_at' ],
  40. order_by: [ 'asc', 'desc' ],
  41. )
  42. returns
  43. result = [organization_model1, organization_model2]
  44. =end
  45. def search(params)
  46. # get params
  47. query = params[:query]
  48. limit = params[:limit] || 10
  49. offset = params[:offset] || 0
  50. current_user = params[:current_user]
  51. # check sort
  52. sort_by = search_get_sort_by(params, 'updated_at')
  53. # check order
  54. order_by = search_get_order_by(params, 'desc')
  55. # enable search only for agents and admins
  56. return [] if !search_preferences(current_user)
  57. # try search index backend
  58. if SearchIndexBackend.enabled?
  59. items = SearchIndexBackend.search(query, 'Organization', limit: limit,
  60. from: offset,
  61. sort_by: sort_by,
  62. order_by: order_by)
  63. organizations = []
  64. items.each do |item|
  65. organization = Organization.lookup(id: item[:id])
  66. next if !organization
  67. organizations.push organization
  68. end
  69. return organizations
  70. end
  71. order_select_sql = search_get_order_select_sql(sort_by, order_by, 'organizations.updated_at')
  72. order_sql = search_get_order_sql(sort_by, order_by, 'organizations.updated_at ASC')
  73. # fallback do sql query
  74. # - stip out * we already search for *query* -
  75. query.delete! '*'
  76. organizations = Organization.where_or_cis(%i[name note], "%#{query}%")
  77. .order(order_sql)
  78. .offset(offset)
  79. .limit(limit)
  80. .to_a
  81. # use result independent of size if an explicit offset is given
  82. # this is the case for e.g. paginated searches
  83. return organizations if params[:offset].present?
  84. return organizations if organizations.length > 3
  85. # if only a few organizations are found, search for names of users
  86. organizations_by_user = Organization.select("DISTINCT(organizations.id), #{order_select_sql}")
  87. .joins('LEFT OUTER JOIN users ON users.organization_id = organizations.id')
  88. .where(User.or_cis(%i[firstname lastname email], "%#{query}%"))
  89. .order(order_sql)
  90. .limit(limit)
  91. organizations_by_user.each do |organization_by_user|
  92. organization_exists = false
  93. organizations.each do |organization|
  94. next if organization.id != organization_by_user.id
  95. organization_exists = true
  96. break
  97. end
  98. # get model with full data
  99. next if organization_exists
  100. organizations.push Organization.find(organization_by_user.id)
  101. end
  102. organizations
  103. end
  104. end
  105. end
  106. end