123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
- module ApplicationModel::HasAttachments
- extend ActiveSupport::Concern
- included do
- after_create :attachments_buffer_check
- after_update :attachments_buffer_check
- after_destroy :attachments_remove_all, if: :attachments_cleanup?
- class_attribute :attachments_cleanup, default: false
- end
- class_methods do
- =begin
- mark model for cleaning up after destroying
- =end
- def attachments_cleanup!
- self.attachments_cleanup = true
- end
- end
- def attachments_remove_all
- attachments.each { |attachment| Store.remove_item(attachment.id) }
- end
- =begin
- get list of attachments of this object
- item = Model.find(123)
- list = item.attachments
- returns
- # array with Store model objects
- =end
- def attachments
- Store.list(object: self.class.to_s, o_id: id)
- end
- =begin
- store attachments for this object with store objects or hashes
- item = Model.find(123)
- item.attachments = [
- Store-Object1,
- Store-Object2,
- {
- filename: 'test.txt',
- data: 'test',
- preferences: {},
- }
- ]
- =end
- def attachments=(attachments)
- self.attachments_buffer = attachments
- # update if object already exists
- return if !id&.nonzero?
- attachments_buffer_check
- end
- =begin
- Returns attachments in ElasticSearch-compatible format
- For use in #search_index_attribute_lookup
- =end
- def attachments_for_search_index_attribute_lookup
- # list ignored file extensions
- attachments_ignore = Setting.get('es_attachment_ignore') || [ '.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe' ]
- # max attachment size
- attachment_max_size_in_mb = (Setting.get('es_attachment_max_size_in_mb') || 10).megabytes
- attachment_total_max_size_in_kb = 314_572.kilobytes
- attachment_total_max_size_in_kb_current = 0.kilobytes
- attachments.each_with_object([]) do |attachment, memo|
- # check if attachment exists
- next if !attachment.content
- size_in_bytes = attachment.content.size.bytes
- # check file size
- next if size_in_bytes > attachment_max_size_in_mb
- # check ignored files
- next if !attachment.filename || attachments_ignore.include?(File.extname(attachment.filename).downcase)
- # check if fits into total size limit
- next if attachment_total_max_size_in_kb_current + size_in_bytes > attachment_total_max_size_in_kb
- attachment_total_max_size_in_kb_current += size_in_bytes
- memo << {
- '_name' => attachment.filename,
- '_content' => Base64.encode64(attachment.content).delete("\n")
- }
- end
- end
- private
- def attachments_buffer
- @attachments_buffer_data
- end
- def attachments_buffer=(attachments)
- @attachments_buffer_data = attachments
- end
- def attachments_buffer_check
- # do nothing if no attachment exists
- return 1 if attachments_buffer.nil?
- # store attachments
- article_store = []
- attachments_buffer.each do |attachment|
- data = {
- object: self.class.to_s,
- o_id: id,
- created_by_id: created_by_id,
- }
- if attachment.is_a?(Store)
- data[:data] = attachment.content
- data[:filename] = attachment.filename
- data[:preferences] = attachment.preferences
- else
- data[:data] = attachment[:data]
- data[:filename] = attachment[:filename]
- data[:preferences] = attachment[:preferences]
- end
- article_store.push Store.create!(data)
- end
- end
- end
|