Class: AttachmentsController

Inherits:
ApplicationController show all
Includes:
ActionView::Helpers::NumberHelper
Defined in:
app/controllers/attachments_controller.rb

Overview

Redmine - project management software Copyright © 2006-2022 Jean-Philippe Lang

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Instance Method Summary collapse

Methods inherited from ApplicationController

#_include_layout?, accept_api_auth, #accept_api_auth?, accept_rss_auth, #accept_rss_auth?, #api_key_from_request, #api_offset_and_limit, #api_request?, #api_switch_user_from_request, #authorize, #authorize_global, #autologin_cookie_name, #back_url, #check_if_login_required, #check_password_change, #check_project_privacy, #check_twofa_activation, #deny_access, #filename_for_content_disposition, #find_attachments, #find_current_user, #find_issue, #find_issues, #find_model_object, #find_optional_project, #find_optional_project_by_id, #find_project, #find_project_by_project_id, #find_project_from_association, #handle_unverified_request, #init_twofa_pairing_and_send_code_for, #logged_user=, #logout_user, #missing_template, model_object, #parse_params_for_bulk_update, #parse_qvalues, #per_page_option, #query_error, #query_statement_invalid, #record_project_usage, #redirect_back_or_default, #redirect_to_referer_or, #render_403, #render_404, #render_api_errors, #render_api_head, #render_api_ok, #render_attachment_warning_if_needed, #render_error, #render_feed, #render_validation_errors, #replace_none_values_with_blank, #require_admin, #require_admin_or_api_request, #require_login, #session_expiration, #session_expired?, #set_localization, #start_user_session, #try_to_autologin, #use_layout, #user_setup, #verify_authenticity_token

Methods included from Redmine::SudoMode::Controller

#process_sudo_form, #render_sudo_form, #require_sudo_mode, #sudo_mode, #sudo_timestamp_valid?, #update_sudo_timestamp!

Methods included from Redmine::MenuManager::MenuController

#current_menu, included, #menu_items, #redirect_to_menu_item, #redirect_to_project_menu_item

Methods included from Redmine::Search::Controller

#default_search_scope, #default_search_scopes, included

Methods included from AvatarsHelper

#assignee_avatar, #author_avatar, #avatar, #avatar_edit_link

Methods included from GravatarHelper::PublicMethods

#gravatar, #gravatar_api_url, #gravatar_for, #gravatar_url

Methods included from RoutesHelper

#_bulk_update_issues_path, #_new_project_issue_path, #_new_time_entry_path, #_project_calendar_path, #_project_gantt_path, #_project_issues_path, #_project_issues_url, #_project_news_path, #_report_time_entries_path, #_time_entries_path, #board_path

Methods included from Redmine::Hook::Helper

#call_hook

Methods included from Redmine::Pagination

#paginate, #paginator

Methods included from Redmine::I18n

#current_language, #day_letter, #day_name, #find_language, #format_date, #format_hours, #format_time, included, #l, #l_hours, #l_hours_short, #l_or_humanize, #languages_options, #ll, #lu, #month_name, #set_language_if_valid, #valid_languages

Instance Method Details

#current_menu_itemObject

Returns the menu item that should be selected when viewing an attachment



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'app/controllers/attachments_controller.rb', line 187

def current_menu_item
  container = @attachment.try(:container) || @container

  if container
    case container
    when WikiPage
      :wiki
    when Message
      :boards
    when Project, Version
      :files
    else
      container.class.name.pluralize.downcase.to_sym
    end
  end
end

#destroyObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/controllers/attachments_controller.rb', line 168

def destroy
  if @attachment.container.respond_to?(:init_journal)
    @attachment.container.init_journal(User.current)
  end
  if @attachment.container
    # Make sure association callbacks are called
    @attachment.container.attachments.delete(@attachment)
  else
    @attachment.destroy
  end

  respond_to do |format|
    format.html {redirect_to_referer_or project_path(@project)}
    format.js
    format.api {render_api_ok}
  end
end

#downloadObject



72
73
74
75
76
77
78
79
80
81
82
83
# File 'app/controllers/attachments_controller.rb', line 72

def download
  if @attachment.container.is_a?(Version) || @attachment.container.is_a?(Project)
    @attachment.increment_download
  end

  if stale?(:etag => @attachment.digest, :template => false)
    # images are sent inline
    send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
                                    :type => detect_content_type(@attachment),
                                    :disposition => disposition(@attachment)
  end
end

#download_allObject



139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'app/controllers/attachments_controller.rb', line 139

def download_all
  zip_data = Attachment.archive_attachments(@attachments)
  if zip_data
    file_name = "#{@container.class.to_s.downcase}-#{@container.id}-attachments.zip"
    send_data(
      zip_data,
      :type => Redmine::MimeType.of(file_name),
      :filename => file_name
    )
  else
    render_404
  end
end

#edit_allObject

Edit all the attachments of a container



127
128
# File 'app/controllers/attachments_controller.rb', line 127

def edit_all
end

#showObject



38
39
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
67
68
69
70
# File 'app/controllers/attachments_controller.rb', line 38

def show
  respond_to do |format|
    format.html do
      if @attachment.container.respond_to?(:attachments)
        @attachments = @attachment.container.attachments.to_a
        if index = @attachments.index(@attachment)
          @paginator = Redmine::Pagination::Paginator.new(
            @attachments.size, 1, index+1
          )
        end
      end
      if @attachment.is_diff?
        @diff = File.read(@attachment.diskfile, :mode => "rb")
        @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
        @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
        # Save diff type as user preference
        if User.current.logged? && @diff_type != User.current.pref[:diff_type]
          User.current.pref[:diff_type] = @diff_type
          User.current.preference.save
        end
        render :action => 'diff'
      elsif @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte
        @content = File.read(@attachment.diskfile, :mode => "rb")
        render :action => 'file'
      elsif @attachment.is_image?
        render :action => 'image'
      else
        render :action => 'other'
      end
    end
    format.api
  end
end

#thumbnailObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/controllers/attachments_controller.rb', line 85

def thumbnail
  if @attachment.thumbnailable? && tbnail = @attachment.thumbnail(:size => params[:size])
    if stale?(:etag => tbnail, :template => false)
      send_file(
        tbnail,
        :filename => filename_for_content_disposition(@attachment.filename),
        :type => detect_content_type(@attachment, true),
        :disposition => 'inline')
    end
  else
    # No thumbnail for the attachment or thumbnail could not be created
    head 404
  end
end

#updateObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'app/controllers/attachments_controller.rb', line 153

def update
  @attachment.safe_attributes = params[:attachment]
  saved = @attachment.save

  respond_to do |format|
    format.api do
      if saved
        render_api_ok
      else
        render_validation_errors(@attachment)
      end
    end
  end
end

#update_allObject

Update all the attachments of a container



131
132
133
134
135
136
137
# File 'app/controllers/attachments_controller.rb', line 131

def update_all
  if Attachment.update_attachments(@attachments, update_all_params)
    redirect_back_or_default home_path
    return
  end
  render :action => 'edit_all'
end

#uploadObject



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'app/controllers/attachments_controller.rb', line 100

def upload
  # Make sure that API users get used to set this content type
  # as it won't trigger Rails' automatic parsing of the request body for parameters
  unless request.content_type == 'application/octet-stream'
    head 406
    return
  end

  @attachment = Attachment.new(:file => raw_request_body)
  @attachment.author = User.current
  @attachment.filename = params[:filename].presence || Redmine::Utils.random_hex(16)
  @attachment.content_type = params[:content_type].presence
  saved = @attachment.save

  respond_to do |format|
    format.js
    format.api do
      if saved
        render :action => 'upload', :status => :created
      else
        render_validation_errors(@attachment)
      end
    end
  end
end