From 5016dbde2ddb76b0104cfc8a01b5c1b8a58a41fe Mon Sep 17 00:00:00 2001 From: "vit.jonas@gmail.com" Date: Mon, 10 Oct 2011 12:06:12 +0000 Subject: [PATCH] * work on Issue 142: Copy Folder option git-svn-id: http://redmine-dmsf.googlecode.com/svn/trunk/redmine_dmsf@252 5e329b0b-a2ee-ea63-e329-299493fc886d --- app/controllers/dmsf_files_copy_controller.rb | 2 +- .../dmsf_folders_copy_controller.rb | 92 +++++++++++++++++++ app/models/dmsf_folder.rb | 11 +++ app/views/dmsf/edit.html.erb | 2 + app/views/dmsf_files_copy/new.html.erb | 1 - app/views/dmsf_folders_copy/new.html.erb | 39 ++++++++ config/locales/en.yml | 4 + init.rb | 2 +- 8 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 app/controllers/dmsf_folders_copy_controller.rb create mode 100644 app/views/dmsf_folders_copy/new.html.erb diff --git a/app/controllers/dmsf_files_copy_controller.rb b/app/controllers/dmsf_files_copy_controller.rb index 62e11c12..728be22b 100644 --- a/app/controllers/dmsf_files_copy_controller.rb +++ b/app/controllers/dmsf_files_copy_controller.rb @@ -24,7 +24,7 @@ class DmsfFilesCopyController < ApplicationController before_filter :find_file before_filter :authorize - verify :method => :post, :only => [:create], :render => { :nothing => true, :status => :method_not_allowed } + verify :method => :post, :only => [:create, :move], :render => { :nothing => true, :status => :method_not_allowed } def new @target_project = DmsfFile.allowed_target_projects_on_copy.detect {|p| p.id.to_s == params[:target_project_id]} if params[:target_project_id] diff --git a/app/controllers/dmsf_folders_copy_controller.rb b/app/controllers/dmsf_folders_copy_controller.rb new file mode 100644 index 00000000..a6a430c5 --- /dev/null +++ b/app/controllers/dmsf_folders_copy_controller.rb @@ -0,0 +1,92 @@ +# Redmine plugin for Document Management System "Features" +# +# Copyright (C) 2011 Vít Jonáš +# +# 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. + +class DmsfFoldersCopyController < ApplicationController + unloadable + + menu_item :dmsf + + before_filter :find_folder + before_filter :authorize + + verify :method => :post, :only => [:copy_to], :render => { :nothing => true, :status => :method_not_allowed } + + def new + @target_project = DmsfFolder.allowed_target_projects_on_copy.detect {|p| p.id.to_s == params[:target_project_id]} if params[:target_project_id] + @target_project ||= @project if User.current.allowed_to?(:folder_manipulation, @project) + if DmsfFile.allowed_target_projects_on_copy.blank? + flash.now[:warning] = l(:warning_no_project_to_copy_folder_to) + else + @target_project ||= DmsfFolder.allowed_target_projects_on_copy[0] + end + + @target_folder = DmsfFolder.find(params[:target_folder_id]) unless params[:target_folder_id].blank? + @target_folder ||= @folder.folder if @target_project == @project + + render :layout => !request.xhr? + end + + def copy_to + @target_project = DmsfFile.allowed_target_projects_on_copy.detect {|p| p.id.to_s == params[:target_project_id]} if params[:target_project_id] + unless @target_project + render_403 + return + end + @target_folder = DmsfFolder.find(params[:target_folder_id]) unless params[:target_folder_id].blank? + if !@target_folder.nil? && @target_folder.project != @target_project + raise DmsfAccessError, l(:error_entry_project_does_not_match_current_project) + end + + if (!@target_folder.nil? && @target_folder == @file.folder) || + (@target_folder.nil? && @file.folder.nil? && @target_project == @file.project) + flash[:error] = l(:error_target_folder_same) + redirect_to :action => "new", :id => @file, :target_project_id => @target_project, :target_folder_id => @target_folder + return + end + + new_folder = @folder.copy_to(@target_project, @target_folder) + + unless new_folder.errors.empty? + flash[:error] = "#{l(:error_folder_cannot_be_copied)}: #{new_folder.errors.full_messages.join(", ")}" + redirect_to :action => "new", :id => @file, :target_project_id => @target_project, :target_folder_id => @target_folder + return + end + + flash[:notice] = l(:notice_folder_copied) + log_activity(new_folder, "was copied (is copy)") + begin + DmsfMailer.deliver_files_updated(User.current, [new_file]) + rescue ActionView::MissingTemplate => e + Rails.logger.error "Could not send email notifications: " + e + end + + redirect_to :controller => "dmsf_files", :action => "show", :id => new_file + end + + private + + def log_activity(folder, action) + Rails.logger.info "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} #{User.current.login}@#{request.remote_ip}/#{request.env['HTTP_X_FORWARDED_FOR']}: #{action} dmsf://#{file.project.identifier}/#{file.id}/#{file.last_revision.id}" + end + + def find_folder + @folder = DmsfFolder.find(params[:id]) + @project = @folder.project + end + +end diff --git a/app/models/dmsf_folder.rb b/app/models/dmsf_folder.rb index b1f0b07c..4ee81a85 100644 --- a/app/models/dmsf_folder.rb +++ b/app/models/dmsf_folder.rb @@ -122,6 +122,17 @@ class DmsfFolder < ActiveRecord::Base size end + # Returns an array of projects that current user can copy folder to + def self.allowed_target_projects_on_copy + projects = [] + if User.current.admin? + projects = Project.visible.all + elsif User.current.logged? + User.current.memberships.each {|m| projects << m.project if m.roles.detect {|r| r.allowed_to?(:folder_manipulation) && r.allowed_to?(:file_manipulation)}} + end + projects + end + # To fullfill searchable module expectations def self.search(tokens, projects=nil, options={}) tokens = [] << tokens unless tokens.is_a?(Array) diff --git a/app/views/dmsf/edit.html.erb b/app/views/dmsf/edit.html.erb index 30ff4f55..919241a0 100644 --- a/app/views/dmsf/edit.html.erb +++ b/app/views/dmsf/edit.html.erb @@ -1,7 +1,9 @@ <% html_title(l(:dmsf)) %>
+ <%= link_to(image_tag("copy.png"), {:controller => :dmsf_folders_copy, :action => "new", :id => @folder }, :title => l(:title_copy)) %>
+ <% create = @pathfolder == @parent %>

<%= render(:partial => "path", :locals => {:path => @pathfolder.nil? ? [] : @pathfolder.dmsf_path}) %> diff --git a/app/views/dmsf_files_copy/new.html.erb b/app/views/dmsf_files_copy/new.html.erb index 7e82ad93..91877ba9 100644 --- a/app/views/dmsf_files_copy/new.html.erb +++ b/app/views/dmsf_files_copy/new.html.erb @@ -14,7 +14,6 @@ <% unless DmsfFile.allowed_target_projects_on_copy.blank? form_tag({:action => "create", :id => @file}, :id => "copyForm") do |f| %>
- <%= error_messages_for("file") %>

<%= select_tag("target_project_id", diff --git a/app/views/dmsf_folders_copy/new.html.erb b/app/views/dmsf_folders_copy/new.html.erb new file mode 100644 index 00000000..65e30ea7 --- /dev/null +++ b/app/views/dmsf_folders_copy/new.html.erb @@ -0,0 +1,39 @@ +<% html_title(l(:dmsf)) %> + +

+
+ +

<%= render(:partial => "/dmsf/path", :locals => {:path => @folder.dmsf_path}) %>

+ +<% unless DmsfFolder.allowed_target_projects_on_copy.blank? + form_tag({:action => "copy_to", :id => @folder}, :id => "copyForm") do |f| %> +
+

+ + <%= select_tag("target_project_id", + project_tree_options_for_select(DmsfFolder.allowed_target_projects_on_copy, :selected => @target_project), + :onchange => remote_function(:url => { :action => 'new' }, + :method => :get, + :update => 'content', + :with => "Form.serialize('copyForm')")) %> +

+

+ <%= label_tag("target_folder_id", l(:label_target_folder) + ":") %> + <%= select_tag("target_folder_id", + options_for_select(DmsfFolder.directory_tree(@target_project, @folder), + :selected => (@target_folder.id unless @target_folder.nil?))) %> +

+
+ + <%= submit_tag(l(:button_copy)) %> + <% end %> +<% end %> + +<% content_for :header_tags do %> + <%= stylesheet_link_tag "dmsf", :plugin => "redmine_dmsf" %> + <%= robot_exclusion_tag %> + <%= javascript_include_tag "jquery-1.6.1.min.js", :plugin => "redmine_dmsf" %> + +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 0bfa659a..64e3d5ad 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -178,4 +178,8 @@ en: :error_target_folder_same: "Target folder and project are the same as current" :error_file_cannot_be_moved: "File can't be moved" :error_file_cannot_be_copied: "File can't be copied" + + :warning_no_project_to_copy_folder_to: "No project to copy folder to" + :title_copy: "Copy" + :error_folder_cannot_be_copied: "Folder can't be copied" \ No newline at end of file diff --git a/init.rb b/init.rb index 48cc0fa5..e4f9cc01 100644 --- a/init.rb +++ b/init.rb @@ -52,7 +52,7 @@ Redmine::Plugin.register :redmine_dmsf do activity_provider :dmsf_files, :class_name => "DmsfFileRevision", :default => true project_module :dmsf do - permission :view_dmsf_folders, {:dmsf => [:show]} + permission :view_dmsf_folders, {:dmsf => [:show], :dmsf_folders_copy => [:new, :copy_to, :move_to]} permission :user_preferences, {:dmsf_state => [:user_pref_save]} permission :view_dmsf_files, {:dmsf => [:entries_operation, :entries_email], :dmsf_files => [:show], :dmsf_files_copy => [:new, :create, :move]}