Class: Neofiles::AdminController

Inherits:
ApplicationController
  • Object
show all
Defined in:
app/controllers/neofiles/admin_controller.rb

Overview

The main controller, doing all persistence related activities. It extends ApplicationController to derive any application-specific business logic, like before/after filters, auth & auth and stuff.

To setup routes to this controller use Neofiles.routes_proc, @see lib/neofiles.rb

As the main principle behind whole Neofiles thing is AJAX file manipulations, actions of this controller mainly form backend for AJAX calls.

Instance Method Summary collapse

Instance Method Details

#file_compact(fake_request = nil) ⇒ Object

Build AJAX edit/upload form for a single file in compact way: small file thumbnail + misc buttons, like “delete”, “change options” etc.

It is expected that someday there will be “full” view (hence the prefix “compact” here), with metadata shown and all kinds of tools exposed.

If param is present, the form displayed is for editing a file, while empty or non existent ID displays an upload form.

The parameter fake_request allows to build form when needed, when there is no actual request available (@see #file_save).

Main parameters:

request[:input_name]    - input with this name will be present in HTML and populated with ID of persisted file
request[:widget_id]     - DOM identifier for this file widget instance
request[:clean_remove]  - after deleting this file, no substituting upload form should be shown (default '0')
request[:append_create] - after persisting new file, action should return form for the file + an upload form
                          (default '0')
request[:disabled]      - only show file, not allow anything to be edited (default '0')
request[:multiple]      - allow uploading of multiple files at once (default '0')
request[:with_desc]     - show short file description (default '0')
request[:no_wm]         - disable adding a watermark  (default '0')

Parameters clear_remove & append_create are used to organize Albums — technically a collection of single files.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/controllers/neofiles/admin_controller.rb', line 40

def file_compact(fake_request = nil)
  request = fake_request || self.request

  begin
    @file = Neofiles::File.find request[:id] if request[:id].present?
  rescue Mongoid::Errors::DocumentNotFound
    @file = nil
  end

  @error = I18n.t('neofiles.file_not_found') if request[:id].present? and @file.blank?

  @input_name     = request[:input_name].to_s
  @widget_id      = request[:widget_id].presence
  @clean_remove   = request[:clean_remove].present? && request[:clean_remove] != '0'
  @append_create  = request[:append_create].present? && request[:append_create] != '0'
  @disabled       = request[:disabled].present? && request[:disabled] != '0'
  @multiple       = request[:multiple].present? && request[:multiple] != '0'
  @with_desc      = request[:with_desc].present? && request[:with_desc] != '0'
  @no_wm          = request[:no_wm].present? && request[:no_wm] != '0'
  @error        ||= ''

  if fake_request
    return render_to_string action: :file_compact, layout: false
  else
    render layout: false
  end
end

#file_removeObject

As we don’t actually delete anything, this method only marks file as deleted.

This method uses clean_remove parameter originally passed to #file_compact (stored by JavaScript and sent again via AJAX call).



125
126
127
128
129
130
131
132
133
134
# File 'app/controllers/neofiles/admin_controller.rb', line 125

def file_remove
  file, data = find_file_and_data

  file.is_deleted = true
  file.save!

  return render plain: '' if data[:clean_remove].present? && data[:clean_remove] != '0'

  redirect_to neofiles_file_compact_path(data.merge(id: nil))
end

#file_saveObject

Persist new file(s) to database and return view forms for all of them (@see #file_compact) as one big HTML.

Raises exception if something went wrong.

This method uses append_create parameter originally passed to #file_compact (stored by JavaScript and sent again via AJAX call).



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'app/controllers/neofiles/admin_controller.rb', line 75

def file_save
  data = request[:neofiles]
  raise ArgumentError.new I18n.t('neofiles.data_not_passed') unless data.is_a? Hash

  files = data[:file]
  files = [files] unless files.is_a? Array
  old_file = data[:id].present? ? Neofiles::File.find(data[:id]) : nil

  file_objects = []
  errors = []
  last_exception = nil
  files.each_with_index do |uploaded_file, i|
    errors.push("#{I18n.t('neofiles.file_not_passed')} (#{i + 1})") and next unless uploaded_file.respond_to? :read

    file_class = Neofiles::File.class_by_file_object(uploaded_file)
    file = file_class.new do |f|
      f.description = data[:description].presence || old_file.try(:description)
      f.no_wm = data[:no_wm].present? && data[:no_wm] != '0' if f.respond_to? :no_wm
      f.file = uploaded_file
    end

    begin
      Rails.application.config.neofiles.before_save.try!(:call, file)
      file.save!
    rescue Exception => ex
      last_exception = ex
      notify_airbrake(ex) if defined? notify_airbrake
      next
    end

    file_objects << file
  end

  result = []
  file_objects.each_with_index do |file, i|
    result << file_compact(data.merge(id: file.id, widget_id: "#{data[:widget_id]}_ap_#{i}", append_create: i == file_objects.count - 1 && !old_file && data[:append_create] == '1' ? '1' : '0'))
  end

  if result.empty?
    raise ArgumentError.new(last_exception || (errors.empty? ? I18n.t('neofiles.file_not_passed') : errors.join("\n")))
  end

  render plain: result.join, layout: false
end

#file_updateObject

As Neofiles treats files as immutables, this method updates only auxiliary fields: description, no_wm etc.

Returns nothing.



140
141
142
143
144
# File 'app/controllers/neofiles/admin_controller.rb', line 140

def file_update
  file, data = find_file_and_data
  file.update data.slice(:description, :no_wm)
  render plain: '', layout: false
end

#redactor_listObject

Returns JSON of files assigned to specific owner to show them in Redactor.js tab “previously uploaded files”.



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'app/controllers/neofiles/admin_controller.rb', line 177

def redactor_list
  type, owner_type, owner_id = request[:type], prepare_owner_type(request[:owner_type]), request[:owner_id]

  type ||= 'file'

  begin
    file_class = "Neofiles::#{type.classify}".constantize
  rescue
    raise ArgumentError.new I18n.t('neofiles.unknown_file_type', type: type)
  end

  result = []
  files = file_class.where(owner_type: owner_type, owner_id: owner_id)
  files.each do |f|
    if f.is_a?(Neofiles::Image)
      result << {
        thumb: neofiles_image_path(f, format: '100x100'),
        image: neofiles_file_path(f),
        title: f.description.to_s,
        #folder: '',
      }
    else
      result << {
        filelink: neofiles_file_path(f),
        title: f.description.to_s,
        #folder: '',
      }
    end
  end

  # returns JSON [{filelink: '/neofiles/serve-file/#{file.id}', title: '...', thumb: '/neo.../100x100'}, {...}, ...]
  render json: result

rescue
  render json: []
end

#redactor_uploadObject

Neofiles knows how to play with Redactor.js and this method persists files uploaded via this WYSIWYG editor.

Redactor.js may know which owner object is edited so we can store owner_type/id for later use.

Returns JSON list of persisted files.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'app/controllers/neofiles/admin_controller.rb', line 152

def redactor_upload
  owner_type, owner_id, file = prepare_owner_type(request[:owner_type]), request[:owner_id], request[:file]
  raise ArgumentError.new I18n.t('neofiles.data_not_passed') if owner_type.blank? || owner_id.blank?
  raise ArgumentError.new I18n.t('neofiles.file_not_passed') unless file.present? && file.respond_to?(:read)

  file_class = Neofiles::File.class_by_file_object(file)

  file = file_class.new do |f|
    f.owner_type  = owner_type
    f.owner_id    = owner_id
    f.description = request[:description].presence

    f.no_wm = true if f.respond_to? :no_wm
    f.file  = file
  end

  Rails.application.config.neofiles.before_save.try!(:call, file)
  file.save!

  # returns JSON {url: '/neofiles/serve-file/#{file.id}'}
  render json: {filelink: neofiles_file_path(file), filename: file.filename, url: neofiles_file_path(file), name: file.filename}
end