diff --git a/app/controllers/file_controller.rb b/app/controllers/file_controller.rb index aa0dc9aa..17885ab1 100644 --- a/app/controllers/file_controller.rb +++ b/app/controllers/file_controller.rb @@ -129,7 +129,7 @@ class FileController < ApplicationController next else logger.info "Page '#{page_name}' already exists. Adding a new revision to it." - wiki.revise_page(@web.address, page_name, page_content, Time.now, @author, PageRenderer.new) + wiki.revise_page(@web.address, page_name, page_name, page_content, Time.now, @author, PageRenderer.new) end else wiki.write_page(@web.address, page_name, page_content, Time.now, @author, PageRenderer.new) diff --git a/app/controllers/revision_sweeper.rb b/app/controllers/revision_sweeper.rb index a2c0a972..b769db59 100644 --- a/app/controllers/revision_sweeper.rb +++ b/app/controllers/revision_sweeper.rb @@ -22,8 +22,9 @@ class RevisionSweeper < ActionController::Caching::Sweeper def expire_caches(page) expire_cached_summary_pages(page.web) - pages_to_expire = ([page.name] + WikiReference.pages_that_reference(page.web, page.name) + - WikiReference.pages_that_include(page.web, page.name)).uniq + pages_to_expire = ([page.name] + WikiReference.pages_that_reference(page.web, page.name) + + WikiReference.pages_redirected_to(page.web, page.name) + + WikiReference.pages_that_include(page.web, page.name)).uniq pages_to_expire.each { |page_name| expire_cached_page(page.web, page_name) } end diff --git a/app/controllers/web_sweeper.rb b/app/controllers/web_sweeper.rb index 838aa328..85451897 100644 --- a/app/controllers/web_sweeper.rb +++ b/app/controllers/web_sweeper.rb @@ -12,7 +12,7 @@ class WebSweeper < ActionController::Caching::Sweeper web.pages.each { |page| expire_cached_page(web, page.name) } expire_cached_summary_pages(web) elsif record.is_a?(WikiFile) - record.web.pages_that_link_to(record.file_name).each do |page| + record.web.pages_that_link_to_file(record.file_name).each do |page| expire_cached_page(record.web, page) end expire_cached_summary_pages(record.web) diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index c2bfad42..4407be0b 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -268,9 +268,13 @@ class WikiController < ApplicationController raise Instiki::ValidationError.new('Your content was not valid utf-8.') end if @page - wiki.revise_page(@web_name, @page_name, the_content, Time.now, + new_name = params['new_name'] || @page_name + raise Instiki::ValidationError.new('Your new title was not valid utf-8.') unless new_name.is_utf8? + raise Instiki::ValidationError.new('A page named "' + new_name.escapeHTML + '" already exists.') if @page_name != new_name && @web.has_page?(new_name) + wiki.revise_page(@web_name, @page_name, new_name, the_content, Time.now, Author.new(author_name, remote_ip), PageRenderer.new) @page.unlock + @page_name = new_name else wiki.write_page(@web_name, @page_name, the_content, Time.now, Author.new(author_name, remote_ip), PageRenderer.new) diff --git a/app/models/page.rb b/app/models/page.rb index 809015a0..7f8946dd 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -4,13 +4,14 @@ class Page < ActiveRecord::Base has_many :wiki_references, :order => 'referenced_name' has_one :current_revision, :class_name => 'Revision', :order => 'id DESC' - def revise(content, time, author, renderer) + def revise(content, name, time, author, renderer) revisions_size = new_record? ? 0 : revisions.size - if (revisions_size > 0) and content == current_revision.content + if (revisions_size > 0) and content == current_revision.content and name == self.name raise Instiki::ValidationError.new( "You have tried to save page '#{name}' without changing its content") end + self.name = name author = Author.new(author.to_s) unless author.is_a?(Author) # Try to render content to make sure that markup engine can take it, @@ -37,7 +38,7 @@ class Page < ActiveRecord::Base raise Instiki::ValidationError.new("Revision #{revision_number} not found") end author = Author.new(roll_back_revision.author.name, author_ip) - revise(roll_back_revision.content, time, author, renderer) + revise(roll_back_revision.content, self.name, time, author, renderer) end def revisions? @@ -70,6 +71,10 @@ class Page < ActiveRecord::Base def linked_from web.select.pages_that_link_to(name) end + + def redirects_for + wiki_references.select { |ref| ref.redirected_page?}.map { |ref| ref.referenced_name } + end def included_from web.select.pages_that_include(name) diff --git a/app/models/web.rb b/app/models/web.rb index 7024e155..b2e7e6c2 100644 --- a/app/models/web.rb +++ b/app/models/web.rb @@ -14,7 +14,7 @@ class Web < ActiveRecord::Base def add_page(name, content, time, author, renderer) page = page(name) || Page.new(:web => self, :name => name) - page.revise(content, time, author, renderer) + page.revise(content, name, time, author, renderer) end def authors @@ -42,6 +42,14 @@ class Web < ActiveRecord::Base def has_page?(name) Page.count(:conditions => ['web_id = ? AND name = ?', id, name]) > 0 end + + def has_redirect_for?(name) + WikiReference.page_that_redirects_for(self, name) + end + + def page_that_redirects_for(name) + page(WikiReference.page_that_redirects_for(self, name)) + end def has_file?(file_name) WikiFile.find_by_file_name(file_name) != nil @@ -51,10 +59,14 @@ class Web < ActiveRecord::Base WikiFile.all(:order => sort_order, :conditions => ['web_id = ?', id]) end - def pages_that_link_to(file_name) + def pages_that_link_to(page_name) + WikiReference.pages_that_link_to(self, page_name) + end + + def pages_that_link_to_file(file_name) WikiReference.pages_that_link_to_file(self, file_name) end - + def description(file_name) file = WikiFile.find_by_file_name(file_name) file.description if file diff --git a/app/models/wiki.rb b/app/models/wiki.rb index dc58e222..cf5cfd18 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -60,9 +60,9 @@ class Wiki web.remove_pages(pages_in_category.orphaned_pages) end - def revise_page(web_address, page_name, content, revised_at, author, renderer) + def revise_page(web_address, page_name, new_name, content, revised_at, author, renderer) page = read_page(web_address, page_name) - page.revise(content, revised_at, author, renderer) + page.revise(content, new_name, revised_at, author, renderer) end def rollback_page(web_address, page_name, revision_number, time, author_id = nil) diff --git a/app/models/wiki_reference.rb b/app/models/wiki_reference.rb index b00f37cd..a4b79c41 100644 --- a/app/models/wiki_reference.rb +++ b/app/models/wiki_reference.rb @@ -2,6 +2,7 @@ class WikiReference < ActiveRecord::Base LINKED_PAGE = 'L' WANTED_PAGE = 'W' + REDIRECTED_PAGE = 'R' INCLUDED_PAGE = 'I' CATEGORY = 'C' AUTHOR = 'A' @@ -9,7 +10,7 @@ class WikiReference < ActiveRecord::Base WANTED_FILE = 'E' belongs_to :page - validates_inclusion_of :link_type, :in => [LINKED_PAGE, WANTED_PAGE, INCLUDED_PAGE, CATEGORY, AUTHOR, FILE, WANTED_FILE] + validates_inclusion_of :link_type, :in => [LINKED_PAGE, WANTED_PAGE, REDIRECTED_PAGE, INCLUDED_PAGE, CATEGORY, AUTHOR, FILE, WANTED_FILE] def self.link_type(web, page_name) web.has_page?(page_name) ? LINKED_PAGE : WANTED_PAGE @@ -51,6 +52,28 @@ class WikiReference < ActiveRecord::Base names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] } end + def self.pages_redirected_to(web, page_name) + names = [] + if web.has_page?(page_name) + page = web.page(page_name) + redirected_names = page.redirects_for + redirected_names.each do |name| + names = names | self.pages_that_reference(web, name) + end + end + names + end + + def self.page_that_redirects_for(web, page_name) + query = 'SELECT name FROM pages JOIN wiki_references ' + + 'ON pages.id = wiki_references.page_id ' + + 'WHERE wiki_references.referenced_name = ? ' + + "AND wiki_references.link_type = '#{REDIRECTED_PAGE}' " + + "AND pages.web_id = '#{web.id}'" + names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] } + names[0] + end + def self.pages_in_category(web, category) query = "SELECT name FROM pages JOIN wiki_references " + @@ -82,6 +105,10 @@ class WikiReference < ActiveRecord::Base link_type == LINKED_PAGE end + def redirected_page? + link_type == REDIRECTED_PAGE + end + def wanted_page? link_type == WANTED_PAGE end diff --git a/app/views/wiki/edit.rhtml b/app/views/wiki/edit.rhtml index 76b36415..ee5725a1 100644 --- a/app/views/wiki/edit.rhtml +++ b/app/views/wiki/edit.rhtml @@ -12,6 +12,16 @@ <% form_tag({ :action => 'save', :web => @web.address, :id => @page.name }, { 'id' => 'editForm', 'method' => 'post', 'onsubmit' => 'cleanAuthorName()', 'accept-charset' => 'utf-8' }) do %> +<% if @page_name != 'HomePage' -%> +
+ <%= check_box_tag :alter_title, value = "1", checked=false,
+ 'onchange' => "toggleVisibility();" %>
+
+
rails-e2e.gif" + "?
", @@ -146,7 +146,7 @@ class FileControllerTest < ActionController::TestCase assert @web.has_file?('rails-e2e.gif') assert_equal(picture, WikiFile.find_by_file_name('rails-e2e.gif').content) PageRenderer.setup_url_generator(StubUrlGenerator.new) - @wiki.revise_page('wiki1', 'Oak', 'Try [[rails-e2e.gif:pic]] again.', + @wiki.revise_page('wiki1', 'Oak', 'Oak', 'Try [[rails-e2e.gif:pic]] again.', Time.now, 'AnonymousBrave', renderer) assert_equal "Try again.
", renderer.display_content diff --git a/test/unit/page_test.rb b/test/unit/page_test.rb index 38efd80a..e290a98b 100644 --- a/test/unit/page_test.rb +++ b/test/unit/page_test.rb @@ -32,7 +32,7 @@ class PageTest < ActiveSupport::TestCase end def test_revise - @page.revise('HisWay would be MyWay in kinda lame', Time.local(2004, 4, 4, 16, 55), + @page.revise('HisWay would be MyWay in kinda lame', @page.name, Time.local(2004, 4, 4, 16, 52), 'MarianneSyhler', test_renderer) @page.reload @@ -44,14 +44,14 @@ class PageTest < ActiveSupport::TestCase end def test_revise_continous_revision - @page.revise('HisWay would be MyWay in kinda lame', Time.local(2004, 4, 4, 16, 55), + @page.revise('HisWay would be MyWay in kinda lame', @page.name, Time.local(2004, 4, 4, 16, 55), 'MarianneSyhler', test_renderer) @page.reload assert_equal 2, @page.revisions.length assert_equal 'HisWay would be MyWay in kinda lame', @page.content # consecutive revision by the same author within 30 minutes doesn't create a new revision - @page.revise('HisWay would be MyWay in kinda update', Time.local(2004, 4, 4, 16, 57), + @page.revise('HisWay would be MyWay in kinda update', @page.name, Time.local(2004, 4, 4, 16, 57), 'MarianneSyhler', test_renderer) @page.reload assert_equal 2, @page.revisions.length @@ -59,7 +59,7 @@ class PageTest < ActiveSupport::TestCase assert_equal Time.local(2004, 4, 4, 16, 57), @page.revised_at # but consecutive revision by another author results in a new revision - @page.revise('HisWay would be MyWay in the house', Time.local(2004, 4, 4, 16, 58), + @page.revise('HisWay would be MyWay in the house', @page.name, Time.local(2004, 4, 4, 16, 58), 'DavidHeinemeierHansson', test_renderer) @page.reload assert_equal 3, @page.revisions.length @@ -67,18 +67,31 @@ class PageTest < ActiveSupport::TestCase # consecutive update after 30 minutes since the last one also creates a new revision, # even when it is by the same author - @page.revise('HisWay would be MyWay in my way', Time.local(2004, 4, 4, 17, 30), + @page.revise('HisWay would be MyWay in my way', @page.name, Time.local(2004, 4, 4, 17, 30), 'DavidHeinemeierHansson', test_renderer) @page.reload assert_equal 4, @page.revisions.length end + + def test_change_name + @page.revise('HisWay would be MyWay in my way', 'SecondPage', Time.local(2004, 4, 5, 17, 56), + 'MarianneSyhler', test_renderer) + @page.reload + + assert_equal "Second Page", @page.plain_name + assert_equal 2, @page.revisions.length, 'Should have two revisions' + assert_equal 'MarianneSyhler', @page.current_revision.author.to_s, + 'Marianne should be the author now' + assert_equal 'DavidHeinemeierHansson', @page.revisions.first.author.to_s, + 'David was the first author' + end def test_revise_content_unchanged last_revision_before = @page.current_revision revisions_number_before = @page.revisions.size assert_raises(Instiki::ValidationError) { - @page.revise(@page.current_revision.content, Time.now, 'AlexeyVerkhovsky', test_renderer) + @page.revise(@page.current_revision.content, @page.name, Time.now, 'AlexeyVerkhovsky', test_renderer) } assert_equal last_revision_before, @page.current_revision(true) @@ -88,7 +101,7 @@ class PageTest < ActiveSupport::TestCase def test_revise_changes_references_from_wanted_to_linked_for_new_pages web = Web.find(1) new_page = Page.new(:web => web, :name => 'NewPage') - new_page.revise('Reference to WantedPage, and to WantedPage2', Time.now, 'AlexeyVerkhovsky', + new_page.revise('Reference to WantedPage, and to WantedPage2', 'NewPage', Time.now, 'AlexeyVerkhovsky', test_renderer) references = new_page.wiki_references(true) @@ -99,7 +112,7 @@ class PageTest < ActiveSupport::TestCase assert_equal WikiReference::WANTED_PAGE, references[1].link_type wanted_page = Page.new(:web => web, :name => 'WantedPage') - wanted_page.revise('And here it is!', Time.now, 'AlexeyVerkhovsky', test_renderer) + wanted_page.revise('And here it is!', 'WantedPage', Time.now, 'AlexeyVerkhovsky', test_renderer) # link type stored for NewPage -> WantedPage reference should change from WANTED to LINKED # reference NewPage -> WantedPage2 should remain the same @@ -112,8 +125,8 @@ class PageTest < ActiveSupport::TestCase end def test_rollback - @page.revise("spot two", Time.now, "David", test_renderer) - @page.revise("spot three", Time.now + 2000, "David", test_renderer) + @page.revise("spot two", @page.name, Time.now, "David", test_renderer) + @page.revise("spot three", @page.name, Time.now + 2000, "David", test_renderer) assert_equal 3, @page.revisions(true).length, "Should have three revisions" @page.current_revision(true) @page.rollback(0, Time.now, '127.0.0.1', test_renderer)