search.rb 3.3 KB

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