summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2014-11-23 13:36:01 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2014-11-23 13:36:01 +0000
commite0a034164f3409336f686cfa381da8a5db15c40e (patch)
treee4bd9590116c03026375a3ae5c618e01cd7bddc3 /app
parent1ada789a6ccbbbaa55adc3a661ea7cef917d4b71 (diff)
downloadredmine-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.rb11
-rw-r--r--app/helpers/wiki_helper.rb10
-rw-r--r--app/models/wiki.rb14
-rw-r--r--app/models/wiki_page.rb76
-rw-r--r--app/models/wiki_redirect.rb17
-rw-r--r--app/views/wiki/rename.html.erb5
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 %>