search.rb 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. # Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
  2. module Ticket::Search
  3. =begin
  4. search tickets
  5. result = Ticket.search(
  6. :current_user => User.find(123),
  7. :query => 'search something',
  8. :limit => 15,
  9. )
  10. returns
  11. result = [ticket_model1, ticket_model2]
  12. search tickets
  13. result = Ticket.search(
  14. :current_user => User.find(123),
  15. :query => 'search something',
  16. :limit => 15,
  17. :full => 0
  18. )
  19. returns
  20. result = [1,3,5,6,7]
  21. =end
  22. def search (params)
  23. # get params
  24. query = params[:query]
  25. limit = params[:limit] || 12
  26. current_user = params[:current_user]
  27. full = false
  28. if params[:full] || !params.has_key?(:full)
  29. full = true
  30. end
  31. # try search index backend
  32. if !params[:detail] && SearchIndexBackend.enabled?
  33. query_extention = {}
  34. query_extention['bool'] = {}
  35. query_extention['bool']['must'] = []
  36. if current_user.is_role('Agent')
  37. groups = Group.joins(:users).
  38. where( 'groups_users.user_id = ?', current_user.id ).
  39. where( 'groups.active = ?', true )
  40. group_condition = []
  41. groups.each {|group|
  42. group_condition.push group.name
  43. }
  44. access_condition = {
  45. 'query_string' => { 'default_field' => 'Ticket.group.name', 'query' => "\"#{group_condition.join('" OR "')}\"" }
  46. }
  47. query_extention['bool']['must'].push access_condition
  48. else
  49. if !current_user.organization || ( !current_user.organization.shared || current_user.organization.shared == false )
  50. access_condition = {
  51. 'query_string' => { 'default_field' => 'Ticket.customer_id', 'query' => current_user.id }
  52. }
  53. # customer_id: XXX
  54. # conditions = [ 'customer_id = ?', current_user.id ]
  55. else
  56. access_condition = {
  57. 'query_string' => { 'query' => "Ticket.customer_id:#{current_user.id} OR Ticket.organization_id:#{current_user.organization.id}" }
  58. }
  59. # customer_id: XXX OR organization_id: XXX
  60. # conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
  61. end
  62. query_extention['bool']['must'].push access_condition
  63. end
  64. ids = SearchIndexBackend.search( query, limit, 'Ticket', query_extention )
  65. if !full
  66. return ids
  67. end
  68. tickets = []
  69. ids.each { |id|
  70. tickets.push Ticket.lookup( :id => id )
  71. }
  72. return tickets
  73. end
  74. # fallback do sql query
  75. access_condition = []
  76. if current_user.is_role('Agent')
  77. group_ids = Group.select( 'groups.id' ).joins(:users).
  78. where( 'groups_users.user_id = ?', current_user.id ).
  79. where( 'groups.active = ?', true ).
  80. map( &:id )
  81. access_condition = [ 'group_id IN (?)', group_ids ]
  82. else
  83. if !current_user.organization || ( !current_user.organization.shared || current_user.organization.shared == false )
  84. access_condition = [ 'customer_id = ?', current_user.id ]
  85. else
  86. access_condition = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
  87. end
  88. end
  89. # do query
  90. # - stip out * we already search for *query* -
  91. if query
  92. query.gsub! '*', ''
  93. tickets_all = Ticket.select('DISTINCT(tickets.id)').
  94. where(access_condition).
  95. 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}%" ).
  96. joins(:articles).
  97. order('`tickets`.`created_at` DESC').
  98. limit(limit)
  99. else
  100. tickets_all = Ticket.select('DISTINCT(tickets.id)').
  101. where(access_condition).
  102. where(params[:condition]).
  103. order('`tickets`.`created_at` DESC').
  104. limit(limit)
  105. end
  106. # build result list
  107. if !full
  108. ids = []
  109. tickets_all.each { |ticket|
  110. ids.push ticket.id
  111. }
  112. return ids
  113. end
  114. tickets = []
  115. tickets_all.each { |ticket|
  116. tickets.push Ticket.lookup( :id => ticket.id )
  117. }
  118. return tickets
  119. end
  120. end