diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2014-11-23 13:36:01 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2014-11-23 13:36:01 +0000 |
commit | e0a034164f3409336f686cfa381da8a5db15c40e (patch) | |
tree | e4bd9590116c03026375a3ae5c618e01cd7bddc3 /app | |
parent | 1ada789a6ccbbbaa55adc3a661ea7cef917d4b71 (diff) | |
download | redmine-e0a034164f3409336f686cfa381da8a5db15c40e.tar.gz redmine-e0a034164f3409336f686cfa381da8a5db15c40e.zip |
Move wiki page to other project (#5450).
git-svn-id: http://svn.redmine.org/redmine/trunk@13643 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/wiki_controller.rb | 11 | ||||
-rw-r--r-- | app/helpers/wiki_helper.rb | 10 | ||||
-rw-r--r-- | app/models/wiki.rb | 14 | ||||
-rw-r--r-- | app/models/wiki_page.rb | 76 | ||||
-rw-r--r-- | app/models/wiki_redirect.rb | 17 | ||||
-rw-r--r-- | app/views/wiki/rename.html.erb | 5 |
6 files changed, 108 insertions, 25 deletions
diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 9b3981655..5ce55f2ce 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -198,9 +198,10 @@ class WikiController < ApplicationController @page.redirect_existing_links = true # used to display the *original* title if some AR validation errors occur @original_title = @page.pretty_title - if request.post? && @page.update_attributes(params[:wiki_page]) + @page.safe_attributes = params[:wiki_page] + if request.post? && @page.save flash[:notice] = l(:notice_successful_update) - redirect_to project_wiki_page_path(@project, @page.title) + redirect_to project_wiki_page_path(@page.project, @page.title) end end @@ -344,7 +345,11 @@ private end def redirect_to_page(page) - redirect_to :action => action_name, :project_id => page.wiki.project, :id => page.title + if page.project && page.project.visible? + redirect_to :action => action_name, :project_id => page.project, :id => page.title + else + render_404 + end end # Returns true if the current user is allowed to edit the page, otherwise false diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb index 1e15c81fa..21b50fd6b 100644 --- a/app/helpers/wiki_helper.rb +++ b/app/helpers/wiki_helper.rb @@ -35,6 +35,16 @@ module WikiHelper s end + def wiki_page_wiki_options_for_select(page) + projects = Project.allowed_to(:rename_wiki_pages).joins(:wiki).preload(:wiki).to_a + projects << page.project unless projects.include?(page.project) + + project_tree_options_for_select(projects, :selected => page.project) do |project| + wiki_id = project.wiki.try(:id) + {:value => wiki_id, :selected => wiki_id == page.wiki_id} + end + end + def wiki_page_breadcrumb(page) breadcrumb(page.ancestors.reverse.collect {|parent| link_to(h(parent.pretty_title), {:controller => 'wiki', :action => 'show', :id => parent.title, :project_id => parent.project, :version => nil}) diff --git a/app/models/wiki.rb b/app/models/wiki.rb index b1ce29743..ce06a2a6e 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -19,7 +19,7 @@ class Wiki < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project has_many :pages, lambda {order('title')}, :class_name => 'WikiPage', :dependent => :destroy - has_many :redirects, :class_name => 'WikiRedirect', :dependent => :delete_all + has_many :redirects, :class_name => 'WikiRedirect' acts_as_watchable @@ -27,6 +27,8 @@ class Wiki < ActiveRecord::Base validates_format_of :start_page, :with => /\A[^,\.\/\?\;\|\:]*\z/ attr_protected :id + before_destroy :delete_redirects + safe_attributes 'start_page' def visible?(user=User.current) @@ -52,11 +54,11 @@ class Wiki < ActiveRecord::Base title = start_page if title.blank? title = Wiki.titleize(title) page = pages.where("LOWER(title) = LOWER(?)", title).first - if !page && !(options[:with_redirect] == false) + if page.nil? && options[:with_redirect] != false # search for a redirect redirect = redirects.where("LOWER(title) = LOWER(?)", title).first if redirect - page = find_page(redirect.redirects_to, :with_redirect => false) + page = redirect.target_page @page_found_with_redirect = true end end @@ -68,6 +70,12 @@ class Wiki < ActiveRecord::Base @page_found_with_redirect end + # Deletes all redirects from/to the wiki + def delete_redirects + WikiRedirect.where(:wiki_id => id).delete_all + WikiRedirect.where(:redirects_to_wiki_id => id).delete_all + end + # Finds a page by title # The given string can be of one of the forms: "title" or "project:title" # Examples: diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 8aed835ad..9d68de2b6 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -46,8 +46,9 @@ class WikiPage < ActiveRecord::Base attr_protected :id validate :validate_parent_title - before_destroy :remove_redirects - before_save :handle_redirects + before_destroy :delete_redirects + before_save :handle_rename_or_move + after_save :handle_children_move # eager load information about last updates, without loading text scope :with_updated_on, lambda { @@ -58,7 +59,7 @@ class WikiPage < ActiveRecord::Base # Wiki pages that are protected by default DEFAULT_PROTECTED_PAGES = %w(sidebar) - safe_attributes 'parent_id', 'parent_title', + safe_attributes 'parent_id', 'parent_title', 'title', 'redirect_existing_links', 'wiki_id', :if => lambda {|page, user| page.new_record? || user.allowed_to?(:rename_wiki_pages, page.project)} def initialize(attributes=nil, *args) @@ -74,30 +75,67 @@ class WikiPage < ActiveRecord::Base def title=(value) value = Wiki.titleize(value) - @previous_title = read_attribute(:title) if @previous_title.blank? write_attribute(:title, value) end - def handle_redirects - self.title = Wiki.titleize(title) - # Manage redirects if the title has changed - if !@previous_title.blank? && (@previous_title != title) && !new_record? + def safe_attributes=(attrs, user=User.current) + return unless attrs.is_a?(Hash) + attrs = attrs.deep_dup + + # Project and Tracker must be set before since new_statuses_allowed_to depends on it. + if (w_id = attrs.delete('wiki_id')) && safe_attribute?('wiki_id') + if (w = Wiki.find_by_id(w_id)) && w.project && user.allowed_to?(:rename_wiki_pages, w.project) + self.wiki = w + end + end + + super attrs, user + end + + # Manages redirects if page is renamed or moved + def handle_rename_or_move + if !new_record? && (title_changed? || wiki_id_changed?) # Update redirects that point to the old title - wiki.redirects.where(:redirects_to => @previous_title).each do |r| + WikiRedirect.where(:redirects_to => title_was, :redirects_to_wiki_id => wiki_id_was).each do |r| r.redirects_to = title - r.title == r.redirects_to ? r.destroy : r.save + r.redirects_to_wiki_id = wiki_id + (r.title == r.redirects_to && r.wiki_id == r.redirects_to_wiki_id) ? r.destroy : r.save end # Remove redirects for the new title - wiki.redirects.where(:title => title).each(&:destroy) + WikiRedirect.where(:wiki_id => wiki_id, :title => title).delete_all # Create a redirect to the new title - wiki.redirects << WikiRedirect.new(:title => @previous_title, :redirects_to => title) unless redirect_existing_links == "0" - @previous_title = nil + unless redirect_existing_links == "0" + WikiRedirect.create( + :wiki_id => wiki_id_was, :title => title_was, + :redirects_to_wiki_id => wiki_id, :redirects_to => title + ) + end + end + if !new_record? && wiki_id_changed? && parent.present? + unless parent.wiki_id == wiki_id + self.parent_id = nil + end end end + private :handle_rename_or_move + + # Moves child pages if page was moved + def handle_children_move + if !new_record? && wiki_id_changed? + children.each do |child| + child.wiki_id = wiki_id + child.redirect_existing_links = redirect_existing_links + unless child.save + WikiPage.where(:id => child.id).update_all :parent_nil => nil + end + end + end + end + private :handle_children_move - def remove_redirects - # Remove redirects to this page - wiki.redirects.where(:redirects_to => title).each(&:destroy) + # Deletes redirects to this page + def delete_redirects + WikiRedirect.where(:redirects_to_wiki_id => wiki_id, :redirects_to => title).delete_all end def pretty_title @@ -136,7 +174,7 @@ class WikiPage < ActiveRecord::Base end def project - wiki.project + wiki.try(:project) end def text @@ -196,7 +234,9 @@ class WikiPage < ActiveRecord::Base def validate_parent_title errors.add(:parent_title, :invalid) if !@parent_title.blank? && parent.nil? errors.add(:parent_title, :circular_dependency) if parent && (parent == self || parent.ancestors.include?(self)) - errors.add(:parent_title, :not_same_project) if parent && (parent.wiki_id != wiki_id) + if parent_id_changed? && parent && (parent.wiki_id != wiki_id) + errors.add(:parent_title, :not_same_project) + end end end diff --git a/app/models/wiki_redirect.rb b/app/models/wiki_redirect.rb index 166453138..3c4f08f3d 100644 --- a/app/models/wiki_redirect.rb +++ b/app/models/wiki_redirect.rb @@ -18,7 +18,22 @@ class WikiRedirect < ActiveRecord::Base belongs_to :wiki - validates_presence_of :title, :redirects_to + validates_presence_of :wiki_id, :title, :redirects_to validates_length_of :title, :redirects_to, :maximum => 255 attr_protected :id + + before_save :set_redirects_to_wiki_id + + def target_page + wiki = Wiki.find_by_id(redirects_to_wiki_id) + if wiki + wiki.find_page(redirects_to, :with_redirect => false) + end + end + + private + + def set_redirects_to_wiki_id + self.redirects_to_wiki_id ||= wiki_id + end end diff --git a/app/views/wiki/rename.html.erb b/app/views/wiki/rename.html.erb index 85319520d..c87641faf 100644 --- a/app/views/wiki/rename.html.erb +++ b/app/views/wiki/rename.html.erb @@ -16,6 +16,11 @@ @wiki.pages.includes(:parent).to_a - @page.self_and_descendants, @page.parent), :label => :field_parent_title %></p> + +<% if @page.safe_attribute? 'wiki_id' %> +<p><%= f.select :wiki_id, wiki_page_wiki_options_for_select(@page), :label => :label_project %></p> +<% end %> + </div> <%= submit_tag l(:button_rename) %> <% end %> |