123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class KnowledgeBase::SearchController < ApplicationController
- skip_before_action :verify_csrf_token
- prepend_before_action :authentication_check_only
- include KnowledgeBaseHelper
- include ActionView::Helpers::SanitizeHelper
- include CanPaginate
- # POST /api/v1/knowledge_bases/search
- # knowledge_base_id, locale, flavor, index, page, per_page, limit, include_locale
- def search
- knowledge_base = KnowledgeBase
- .active
- .find_by id: params[:knowledge_base_id]
- kb_locale = knowledge_base
- &.kb_locales
- &.joins(:system_locale)
- &.find_by(locales: { locale: params[:locale] })
- scope = knowledge_base
- &.categories
- &.find_by(id: params[:scope_id])
- search_backend = SearchKnowledgeBaseBackend.new(
- knowledge_base: knowledge_base,
- locale: kb_locale,
- scope: scope,
- flavor: params[:flavor],
- index: params[:index],
- limit: params[:limit],
- highlight_enabled: params[:highlight_enabled],
- order_by: { updated_at: :desc }
- )
- include_locale = params[:include_locale] && KnowledgeBase.with_multiple_locales_exists?
- result = search_backend.search params[:query], user: current_user, pagination: pagination
- if (exclude_ids = params[:exclude_ids]&.map(&:to_i))
- result.reject! { |meta| meta[:type] == params[:index] && exclude_ids.include?(meta[:id]) }
- end
- details = result.map { |item| public_item_details(item, include_locale) }
- render json: {
- result: result,
- details: details,
- }
- end
- private
- def item_assets(meta)
- object = meta[:type].constantize.find(meta[:id])
- object.assets
- end
- def public_item_details(meta, include_locale)
- object = meta[:type].constantize.find(meta[:id])
- output = case object
- when KnowledgeBase::Answer::Translation
- public_item_details_answer(meta, object)
- when KnowledgeBase::Category::Translation
- public_item_details_category(meta, object)
- when KnowledgeBase::Translation
- public_item_details_base(meta, object)
- end
- if include_locale && (system_locale = object.kb_locale.system_locale)
- output[:title] += " (#{system_locale.locale.upcase})"
- end
- output
- end
- def public_item_details_answer(meta, object)
- category_translation = object.answer.category.translation_preferred(object.kb_locale)
- path = help_answer_path(category_translation, object, locale: object.kb_locale.system_locale.locale)
- subtitle = object.answer.category.self_with_parents.map { |c| strip_tags(c.translation_preferred(object.kb_locale).title) }.reverse
- subtitle = if subtitle.count <= 2
- subtitle.join(' > ')
- else
- subtitle.values_at(0, -1).join(' > .. > ')
- end
- url = case url_type
- when :public
- custom_path_if_needed(path, object.answer.category.knowledge_base)
- when :agent
- knowledge_base_answer_path(object.answer.category.knowledge_base, object.answer) + "?include_contents=#{object.id}"
- end
- {
- id: object.id,
- type: object.class.name,
- icon: 'knowledge-base-answer',
- date: object.updated_at,
- url: url,
- title: meta.dig(:highlight, 'title')&.first || object.title,
- subtitle: subtitle,
- body: meta.dig(:highlight, 'content.body')&.first || strip_tags(object.content.body).truncate(100),
- tags: object.answer.tag_list
- }
- end
- def public_item_details_category(meta, object)
- parent_category_translation = object.category.parent&.translation_preferred(object.kb_locale)
- path = help_category_path(object, locale: object.kb_locale.system_locale.locale)
- url = case url_type
- when :public
- custom_path_if_needed(path, object.category.knowledge_base)
- when :agent
- knowledge_base_category_path(object.category.knowledge_base, object.category)
- end
- {
- id: object.id,
- type: object.class.name,
- fontName: object.category.knowledge_base.iconset,
- date: object.updated_at,
- url: url,
- icon: object.category.category_icon,
- subtitle: strip_tags(parent_category_translation&.title.presence),
- title: meta.dig(:highlight, 'title')&.first || strip_tags(object.title)
- }
- end
- def public_item_details_base(meta, object)
- path = help_root_path(object.kb_locale.system_locale.locale)
- url = case url_type
- when :public
- custom_path_if_needed(path, object.knowledge_base)
- when :agent
- knowledge_base_path(object.knowledge_base)
- end
- {
- id: object.id,
- type: object.class.name,
- icon: 'knowledge-base',
- date: object.updated_at,
- url: url,
- title: meta.dig(:highlight, 'title')&.first || strip_tags(object.title)
- }
- end
- def url_type
- params[:url_type]&.to_sym || :public
- end
- end
|