translation.rb 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class KnowledgeBase::Answer::Translation < ApplicationModel
  3. include HasDefaultModelUserRelations
  4. include HasAgentAllowedParams
  5. include HasLinks
  6. include HasSearchIndexBackend
  7. include KnowledgeBase::Search
  8. include KnowledgeBase::HasUniqueTitle
  9. AGENT_ALLOWED_ATTRIBUTES = %i[title kb_locale_id].freeze
  10. AGENT_ALLOWED_NESTED_RELATIONS = %i[content].freeze
  11. belongs_to :kb_locale, class_name: 'KnowledgeBase::Locale', inverse_of: :answer_translations
  12. belongs_to :answer, class_name: 'KnowledgeBase::Answer', inverse_of: :translations, touch: true
  13. belongs_to :content, class_name: 'KnowledgeBase::Answer::Translation::Content', inverse_of: :translation, dependent: :destroy
  14. accepts_nested_attributes_for :content, update_only: true
  15. validates :title, presence: true, length: { maximum: 250 }
  16. validates :kb_locale_id, uniqueness: { case_sensitive: true, scope: :answer_id }
  17. scope :neighbours_of, ->(translation) { joins(:answer).where(knowledge_base_answers: { category_id: translation.answer&.category_id }) }
  18. alias assets_essential assets
  19. def assets(data = {})
  20. return data if assets_added_to?(data)
  21. data = super(data)
  22. answer.assets(data)
  23. ApplicationModel::CanAssets.reduce inline_linked_objects, data
  24. end
  25. def to_param
  26. [answer_id, title.parameterize].join('-')
  27. end
  28. def search_index_attribute_lookup(include_references: true)
  29. attrs = super
  30. attrs.merge({
  31. title: ActionController::Base.helpers.strip_tags(attrs['title']),
  32. content: content&.search_index_attribute_lookup,
  33. scope_id: answer.category_id,
  34. attachment: answer.attachments_for_search_index_attribute_lookup,
  35. tags: answer.tag_list
  36. })
  37. end
  38. def inline_linked_objects
  39. output = []
  40. scrubber = Loofah::Scrubber.new do |node|
  41. next if node.name != 'a'
  42. next if !node.key? 'data-target-type'
  43. case node['data-target-type']
  44. when 'knowledge-base-answer'
  45. if (translation = KnowledgeBase::Answer::Translation.find_by(id: node['data-target-id']))
  46. output.push translation
  47. end
  48. end
  49. end
  50. Loofah.scrub_fragment(content.body, scrubber)
  51. output
  52. end
  53. class << self
  54. def search_preferences(current_user)
  55. return false if !KnowledgeBase.exists? || !current_user.permissions?('knowledge_base.*')
  56. {
  57. prio: 1209,
  58. direct_search_index: false,
  59. }
  60. end
  61. def search_es_filter(es_response, _query, kb_locales, options)
  62. return es_response if options[:user]&.permissions?('knowledge_base.editor')
  63. answer_translations_id = es_response.pluck(:id)
  64. allowed_answer_translation_ids = KnowledgeBase::Answer
  65. .internal
  66. .joins(:translations)
  67. .where(knowledge_base_answer_translations: { id: answer_translations_id, kb_locale_id: kb_locales.map(&:id) })
  68. .pluck('knowledge_base_answer_translations.id')
  69. es_response.filter { |elem| allowed_answer_translation_ids.include? elem[:id].to_i }
  70. end
  71. def search_fallback(query, scope = nil, options: {})
  72. fields = %w[title]
  73. fields << KnowledgeBase::Answer::Translation::Content.arel_table[:body]
  74. output = where_or_cis(fields, query)
  75. .joins(:content)
  76. if !options[:user]&.permissions?('knowledge_base.editor')
  77. answer_ids = KnowledgeBase::Answer.internal.pluck(:id)
  78. output = output.where(answer_id: answer_ids)
  79. end
  80. if scope.present?
  81. output = output
  82. .joins(:answer)
  83. .where(knowledge_base_answers: { category_id: scope })
  84. end
  85. output
  86. end
  87. end
  88. end