search.rb 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. module Ticket::Search
  3. =begin
  4. search tickets preferences
  5. result = Ticket.search_preferences(user_model)
  6. returns if user has permissions to search
  7. result = {
  8. prio: 3000,
  9. direct_search_index: false
  10. }
  11. returns if user has no permissions to search
  12. result = false
  13. =end
  14. def search_preferences(_current_user)
  15. {
  16. prio: 3000,
  17. direct_search_index: false,
  18. }
  19. end
  20. =begin
  21. search tickets via search index
  22. result = Ticket.search(
  23. current_user: User.find(123),
  24. query: 'search something',
  25. limit: 15,
  26. )
  27. returns
  28. result = [ticket_model1, ticket_model2]
  29. search tickets via search index
  30. result = Ticket.search(
  31. current_user: User.find(123),
  32. query: 'search something',
  33. limit: 15,
  34. full: false,
  35. )
  36. returns
  37. result = [1,3,5,6,7]
  38. search tickets via database
  39. result = Ticket.search(
  40. current_user: User.find(123),
  41. query: 'some query', # query or condition is required
  42. condition: {
  43. 'tickets.owner_id' => {
  44. operator: 'is',
  45. value: user.id,
  46. },
  47. 'tickets.state_id' => {
  48. operator: 'is',
  49. value: Ticket::State.where(
  50. state_type_id: Ticket::StateType.where(
  51. name: [
  52. 'pending reminder',
  53. 'pending action',
  54. ],
  55. ).map(&:id),
  56. },
  57. ),
  58. },
  59. limit: 15,
  60. full: false,
  61. )
  62. returns
  63. result = [1,3,5,6,7]
  64. =end
  65. def search(params)
  66. # get params
  67. query = params[:query]
  68. condition = params[:condition]
  69. limit = params[:limit] || 12
  70. current_user = params[:current_user]
  71. full = false
  72. if params[:full] || !params.key?(:full)
  73. full = true
  74. end
  75. # try search index backend
  76. if condition.blank? && SearchIndexBackend.enabled?
  77. query_extention = {}
  78. query_extention['bool'] = {}
  79. query_extention['bool']['must'] = []
  80. if current_user.permissions?('ticket.agent')
  81. group_ids = current_user.group_ids_access('read')
  82. access_condition = {
  83. 'query_string' => { 'default_field' => 'group_id', 'query' => "\"#{group_ids.join('" OR "')}\"" }
  84. }
  85. else
  86. access_condition = if !current_user.organization || ( !current_user.organization.shared || current_user.organization.shared == false )
  87. {
  88. 'query_string' => { 'default_field' => 'customer_id', 'query' => current_user.id }
  89. }
  90. # customer_id: XXX
  91. # conditions = [ 'customer_id = ?', current_user.id ]
  92. else
  93. {
  94. 'query_string' => { 'query' => "customer_id:#{current_user.id} OR organization_id:#{current_user.organization.id}" }
  95. }
  96. # customer_id: XXX OR organization_id: XXX
  97. # conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
  98. end
  99. end
  100. query_extention['bool']['must'].push access_condition
  101. items = SearchIndexBackend.search(query, limit, 'Ticket', query_extention)
  102. if !full
  103. ids = []
  104. items.each do |item|
  105. ids.push item[:id]
  106. end
  107. return ids
  108. end
  109. tickets = []
  110. items.each do |item|
  111. ticket = Ticket.lookup(id: item[:id])
  112. next if !ticket
  113. tickets.push ticket
  114. end
  115. return tickets
  116. end
  117. # fallback do sql query
  118. access_condition = Ticket.access_condition(current_user, 'read')
  119. # do query
  120. # - stip out * we already search for *query* -
  121. if query
  122. query.delete! '*'
  123. tickets_all = Ticket.select('DISTINCT(tickets.id), tickets.created_at')
  124. .where(access_condition)
  125. .where('(tickets.title LIKE ? OR tickets.number LIKE ? OR ticket_articles.body LIKE ? OR ticket_articles.from LIKE ? OR ticket_articles.to LIKE ? OR ticket_articles.subject LIKE ?)', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%" )
  126. .joins(:articles)
  127. .order('tickets.created_at DESC')
  128. .limit(limit)
  129. else
  130. query_condition, bind_condition, tables = selector2sql(condition)
  131. tickets_all = Ticket.select('DISTINCT(tickets.id), tickets.created_at')
  132. .joins(tables)
  133. .where(access_condition)
  134. .where(query_condition, *bind_condition)
  135. .order('tickets.created_at DESC')
  136. .limit(limit)
  137. end
  138. # build result list
  139. if !full
  140. ids = []
  141. tickets_all.each do |ticket|
  142. ids.push ticket.id
  143. end
  144. return ids
  145. end
  146. tickets = []
  147. tickets_all.each do |ticket|
  148. tickets.push Ticket.lookup(id: ticket.id)
  149. end
  150. tickets
  151. end
  152. end