##// END OF EJS Templates
Project copy: let the user choose what to copy from the source project (everything by default)....
Jean-Philippe Lang -
r2852:5b787785b476
parent child
Show More
@@ -104,7 +104,7 class ProjectsController < ApplicationController
104 else
104 else
105 @project = Project.new(params[:project])
105 @project = Project.new(params[:project])
106 @project.enabled_module_names = params[:enabled_modules]
106 @project.enabled_module_names = params[:enabled_modules]
107 if @project.copy(params[:id])
107 if @project.copy(params[:id], :only => params[:only])
108 flash[:notice] = l(:notice_successful_create)
108 flash[:notice] = l(:notice_successful_create)
109 redirect_to :controller => 'admin', :action => 'projects'
109 redirect_to :controller => 'admin', :action => 'projects'
110 end
110 end
@@ -391,73 +391,30 class Project < ActiveRecord::Base
391 end
391 end
392
392
393 # Copies and saves the Project instance based on the +project+.
393 # Copies and saves the Project instance based on the +project+.
394 # Will duplicate the source project's:
394 # Duplicates the source project's:
395 # * Wiki
396 # * Versions
397 # * Categories
395 # * Issues
398 # * Issues
396 # * Members
399 # * Members
397 # * Queries
400 # * Queries
398 def copy(project)
401 #
402 # Accepts an +options+ argument to specify what to copy
403 #
404 # Examples:
405 # project.copy(1) # => copies everything
406 # project.copy(1, :only => 'members') # => copies members only
407 # project.copy(1, :only => ['members', 'versions']) # => copies members and versions
408 def copy(project, options={})
399 project = project.is_a?(Project) ? project : Project.find(project)
409 project = project.is_a?(Project) ? project : Project.find(project)
400
401 Project.transaction do
402 # Wikis
403 self.wiki = Wiki.new(project.wiki.attributes.dup.except("project_id"))
404 project.wiki.pages.each do |page|
405 new_wiki_content = WikiContent.new(page.content.attributes.dup.except("page_id"))
406 new_wiki_page = WikiPage.new(page.attributes.dup.except("wiki_id"))
407 new_wiki_page.content = new_wiki_content
408
409 self.wiki.pages << new_wiki_page
410 end
411
412 # Versions
413 project.versions.each do |version|
414 new_version = Version.new
415 new_version.attributes = version.attributes.dup.except("project_id")
416 self.versions << new_version
417 end
418
419 project.issue_categories.each do |issue_category|
420 new_issue_category = IssueCategory.new
421 new_issue_category.attributes = issue_category.attributes.dup.except("project_id")
422 self.issue_categories << new_issue_category
423 end
424
425 # Issues
426 project.issues.each do |issue|
427 new_issue = Issue.new
428 new_issue.copy_from(issue)
429 # Reassign fixed_versions by name, since names are unique per
430 # project and the versions for self are not yet saved
431 if issue.fixed_version
432 new_issue.fixed_version = self.versions.select {|v| v.name == issue.fixed_version.name}.first
433 end
434 # Reassign the category by name, since names are unique per
435 # project and the categories for self are not yet saved
436 if issue.category
437 new_issue.category = self.issue_categories.select {|c| c.name == issue.category.name}.first
438 end
439
440 self.issues << new_issue
441 end
442
410
443 # Members
411 to_be_copied = %w(wiki versions issue_categories issues members queries)
444 project.members.each do |member|
412 to_be_copied = to_be_copied & options[:only].to_a unless options[:only].nil?
445 new_member = Member.new
413
446 new_member.attributes = member.attributes.dup.except("project_id")
414 Project.transaction do
447 new_member.role_ids = member.role_ids.dup
415 to_be_copied.each do |name|
448 new_member.project = self
416 send "copy_#{name}", project
449 self.members << new_member
450 end
451
452 # Queries
453 project.queries.each do |query|
454 new_query = Query.new
455 new_query.attributes = query.attributes.dup.except("project_id", "sort_criteria")
456 new_query.sort_criteria = query.sort_criteria if query.sort_criteria
457 new_query.project = self
458 self.queries << new_query
459 end
417 end
460
461 Redmine::Hook.call_hook(:model_project_copy_before_save, :source_project => project, :destination_project => self)
418 Redmine::Hook.call_hook(:model_project_copy_before_save, :source_project => project, :destination_project => self)
462 self.save
419 self.save
463 end
420 end
@@ -486,7 +443,78 class Project < ActiveRecord::Base
486 end
443 end
487 end
444 end
488
445
489 private
446 private
447
448 # Copies wiki from +project+
449 def copy_wiki(project)
450 self.wiki = Wiki.new(project.wiki.attributes.dup.except("project_id"))
451 project.wiki.pages.each do |page|
452 new_wiki_content = WikiContent.new(page.content.attributes.dup.except("page_id"))
453 new_wiki_page = WikiPage.new(page.attributes.dup.except("wiki_id"))
454 new_wiki_page.content = new_wiki_content
455 self.wiki.pages << new_wiki_page
456 end
457 end
458
459 # Copies versions from +project+
460 def copy_versions(project)
461 project.versions.each do |version|
462 new_version = Version.new
463 new_version.attributes = version.attributes.dup.except("project_id")
464 self.versions << new_version
465 end
466 end
467
468 # Copies issue categories from +project+
469 def copy_issue_categories(project)
470 project.issue_categories.each do |issue_category|
471 new_issue_category = IssueCategory.new
472 new_issue_category.attributes = issue_category.attributes.dup.except("project_id")
473 self.issue_categories << new_issue_category
474 end
475 end
476
477 # Copies issues from +project+
478 def copy_issues(project)
479 project.issues.each do |issue|
480 new_issue = Issue.new
481 new_issue.copy_from(issue)
482 # Reassign fixed_versions by name, since names are unique per
483 # project and the versions for self are not yet saved
484 if issue.fixed_version
485 new_issue.fixed_version = self.versions.select {|v| v.name == issue.fixed_version.name}.first
486 end
487 # Reassign the category by name, since names are unique per
488 # project and the categories for self are not yet saved
489 if issue.category
490 new_issue.category = self.issue_categories.select {|c| c.name == issue.category.name}.first
491 end
492 self.issues << new_issue
493 end
494 end
495
496 # Copies members from +project+
497 def copy_members(project)
498 project.members.each do |member|
499 new_member = Member.new
500 new_member.attributes = member.attributes.dup.except("project_id")
501 new_member.role_ids = member.role_ids.dup
502 new_member.project = self
503 self.members << new_member
504 end
505 end
506
507 # Copies queries from +project+
508 def copy_queries(project)
509 project.queries.each do |query|
510 new_query = Query.new
511 new_query.attributes = query.attributes.dup.except("project_id", "sort_criteria")
512 new_query.sort_criteria = query.sort_criteria if query.sort_criteria
513 new_query.project = self
514 self.queries << new_query
515 end
516 end
517
490 def allowed_permissions
518 def allowed_permissions
491 @allowed_permissions ||= begin
519 @allowed_permissions ||= begin
492 module_names = enabled_modules.collect {|m| m.name}
520 module_names = enabled_modules.collect {|m| m.name}
@@ -12,5 +12,15
12 <% end %>
12 <% end %>
13 </fieldset>
13 </fieldset>
14
14
15 <fieldset class="box"><legend><%= l(:button_copy) %></legend>
16 <label class="floating"><%= check_box_tag 'only[]', 'members', true %> <%= l(:label_member_plural) %></label>
17 <label class="floating"><%= check_box_tag 'only[]', 'versions', true %> <%= l(:label_version_plural) %></label>
18 <label class="floating"><%= check_box_tag 'only[]', 'issue_categories', true %> <%= l(:label_issue_category_plural) %></label>
19 <label class="floating"><%= check_box_tag 'only[]', 'issues', true %> <%= l(:label_issue_plural) %></label>
20 <label class="floating"><%= check_box_tag 'only[]', 'queries', true %> <%= l(:label_query_plural) %></label>
21 <label class="floating"><%= check_box_tag 'only[]', 'wiki', true %> <%= l(:label_wiki) %></label>
22 <%= hidden_field_tag 'only[]', '' %>
23 </fieldset>
24
15 <%= submit_tag l(:button_copy) %>
25 <%= submit_tag l(:button_copy) %>
16 <% end %>
26 <% end %>
@@ -499,6 +499,18 class ProjectTest < ActiveSupport::TestCase
499 end
499 end
500 end
500 end
501
501
502 should "limit copy with :only option" do
503 assert @project.members.empty?
504 assert @project.issue_categories.empty?
505 assert @source_project.issues.any?
506
507 assert @project.copy(@source_project, :only => ['members', 'issue_categories'])
508
509 assert @project.members.any?
510 assert @project.issue_categories.any?
511 assert @project.issues.empty?
512 end
513
502 should "copy issue relations"
514 should "copy issue relations"
503 should "link issue relations if cross project issue relations are valid"
515 should "link issue relations if cross project issue relations are valid"
504
516
General Comments 0
You need to be logged in to leave comments. Login now