@@ -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 |
# |
|
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