]> source.dussan.org Git - redmine.git/commitdiff
Adds export of all wiki pages to a PDF file (#3463).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Mon, 30 Jan 2012 18:42:14 +0000 (18:42 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Mon, 30 Jan 2012 18:42:14 +0000 (18:42 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@8734 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/wiki_controller.rb
app/views/wiki/date_index.html.erb
app/views/wiki/index.html.erb
lib/redmine/export/pdf.rb
test/functional/wiki_controller_test.rb
test/integration/routing/wiki_test.rb

index 1aaff407186a7f146d37c30aa10e128bda725165..aaf593e2b723965a0b551f25cfc1b825a23d1fcb 100644 (file)
@@ -73,7 +73,7 @@ class WikiController < ApplicationController
     @content = @page.content_for_version(params[:version])
     if User.current.allowed_to?(:export_wiki_pages, @project)
       if params[:format] == 'pdf'
-        send_data(wiki_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
+        send_data(wiki_page_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
         return
       elsif params[:format] == 'html'
         export = render_to_string :action => 'export', :layout => false
@@ -239,14 +239,22 @@ class WikiController < ApplicationController
     redirect_to :action => 'index', :project_id => @project
   end
 
-  # Export wiki to a single html file
+  # Export wiki to a single pdf or html file
   def export
-    if User.current.allowed_to?(:export_wiki_pages, @project)
-      @pages = @wiki.pages.find :all, :order => 'title'
-      export = render_to_string :action => 'export_multiple', :layout => false
-      send_data(export, :type => 'text/html', :filename => "wiki.html")
-    else
+    unless User.current.allowed_to?(:export_wiki_pages, @project)
       redirect_to :action => 'show', :project_id => @project, :id => nil
+      return
+    end
+
+    @pages = @wiki.pages.all(:order => 'title', :include => [:content, :attachments], :limit => 75)
+    respond_to do |format|
+      format.html {
+        export = render_to_string :action => 'export_multiple', :layout => false
+        send_data(export, :type => 'text/html', :filename => "wiki.html")
+      }
+      format.pdf {
+        send_data(wiki_pages_to_pdf(@pages, @project), :type => 'application/pdf', :filename => "#{@project.identifier}.pdf")
+      }
     end
   end
 
index c822d8a3931ddeace41ea5c4e985730f5a7ab145..4bc31dcd7699b827b8c06cea67d6bca711f04e5e 100644 (file)
 <% unless @pages.empty? %>
 <% other_formats_links do |f| %>
   <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :key => User.current.rss_key} %>
-  <%= f.link_to('HTML', :url => {:action => 'export'}) if User.current.allowed_to?(:export_wiki_pages, @project) %>
+  <% if User.current.allowed_to?(:export_wiki_pages, @project) %>
+  <%= f.link_to('PDF', :url => {:action => 'export', :format => 'pdf'}) %>
+  <%= f.link_to('HTML', :url => {:action => 'export'}) %>
+  <% end %>
 <% end %>
 <% end %>
 
index e89513906602365987a19cbaa913bc8c93cd501f..60dbd58f25e7f3fd0ea98b9a368a3c437dc2cf45 100644 (file)
                 :url => {:controller => 'activities', :action => 'index',
                          :id => @project, :show_wiki_edits => 1,
                          :key => User.current.rss_key} %>
-  <%= f.link_to('HTML',
-                :url => {:action => 'export'}
-               ) if User.current.allowed_to?(:export_wiki_pages, @project) %>
+       <% if User.current.allowed_to?(:export_wiki_pages, @project) %>
+  <%= f.link_to('PDF', :url => {:action => 'export', :format => 'pdf'}) %>
+  <%= f.link_to('HTML', :url => {:action => 'export'}) %>
+       <% end %>
 <% end %>
 <% end %>
 
index f59ff5461d148b406f5fd04f79945f88e788550f..75bf8e8630f44d108ee65a0be33687e5d56872bd 100644 (file)
@@ -573,8 +573,25 @@ module Redmine
         pdf.Output
       end
 
+      # Returns a PDF string of a set of wiki pages
+      def wiki_pages_to_pdf(pages, project)
+        pdf = ITCPDF.new(current_language)
+        pdf.SetTitle(project.name)
+        pdf.alias_nb_pages
+        pdf.footer_date = format_date(Date.today)
+        pdf.AddPage
+        pdf.SetFontStyle('B',11)
+        pdf.RDMMultiCell(190,5, project.name)
+        pdf.Ln
+        # Set resize image scale
+        pdf.SetImageScale(1.6)
+        pdf.SetFontStyle('',9)
+        write_page_hierarchy(pdf, pages.group_by(&:parent_id))
+        pdf.Output
+      end
+
       # Returns a PDF string of a single wiki page
-      def wiki_to_pdf(page, project)
+      def wiki_page_to_pdf(page, project)
         pdf = ITCPDF.new(current_language)
         pdf.SetTitle("#{project} - #{page.title}")
         pdf.alias_nb_pages
@@ -587,6 +604,26 @@ module Redmine
         # Set resize image scale
         pdf.SetImageScale(1.6)
         pdf.SetFontStyle('',9)
+        write_wiki_page(pdf, page)
+        pdf.Output
+      end
+
+      def write_page_hierarchy(pdf, pages, node=nil, level=0)
+        if pages[node]
+          pages[node].each do |page|
+            if @new_page
+              pdf.AddPage
+            else
+              @new_page = true
+            end
+            pdf.Bookmark page.title, level
+            write_wiki_page(pdf, page)
+            write_page_hierarchy(pdf, pages, page.id, level + 1) if pages[page.id]
+          end
+        end
+      end
+
+      def write_wiki_page(pdf, page)
         pdf.RDMwriteHTMLCell(190,5,0,0,
               page.content.text.to_s, page.attachments, "TLRB")
         if page.attachments.any?
@@ -603,7 +640,6 @@ module Redmine
             pdf.Ln
           end
         end
-        pdf.Output
       end
 
       class RDMPdfEncoding
index 3665a75fd3f17d287ae8accc1aafcbbe8c243969..59b1a4319d6a7ab91e86a96cbc16f1ab993652e8 100644 (file)
@@ -618,12 +618,13 @@ class WikiControllerTest < ActionController::TestCase
     assert_tag 'a', :attributes => { :href => '/projects/ecookbook/activity.atom?show_wiki_edits=1'}
   end
 
-  def test_export
+  def test_export_to_html
     @request.session[:user_id] = 2
     get :export, :project_id => 'ecookbook'
 
     assert_response :success
     assert_not_nil assigns(:pages)
+    assert assigns(:pages).any?
     assert_equal "text/html", @response.content_type
 
     assert_select "a[name=?]", "CookBook_documentation"
@@ -631,7 +632,19 @@ class WikiControllerTest < ActionController::TestCase
     assert_select "a[name=?]", "Page_with_an_inline_image"
   end
 
-  def test_export_without_permission
+  def test_export_to_pdf
+    @request.session[:user_id] = 2
+    get :export, :project_id => 'ecookbook', :format => 'pdf'
+
+    assert_response :success
+    assert_not_nil assigns(:pages)
+    assert assigns(:pages).any?
+    assert_equal 'application/pdf', @response.content_type
+    assert_equal 'attachment; filename="ecookbook.pdf"', @response.headers['Content-Disposition']
+    assert @response.body.starts_with?('%PDF')
+  end
+
+  def test_export_without_permission_should_redirect
     get :export, :project_id => 'ecookbook'
 
     assert_response 302
index 1445442b5e7630048e24f74988034bc256797399..35ee4310ca9fa75812a9d2c5c2a66e479fcb0c89 100644 (file)
@@ -28,6 +28,11 @@ class RoutingWikiTest < ActionController::IntegrationTest
         { :controller => 'wiki', :action => 'show', :project_id => '567',
           :id => 'lalala' }
         )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/lalala.pdf" },
+        { :controller => 'wiki', :action => 'show', :project_id => '567',
+          :id => 'lalala', :format => 'pdf' }
+        )
     assert_routing(
          { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/diff" },
          { :controller => 'wiki', :action => 'diff', :project_id => '1',
@@ -59,6 +64,10 @@ class RoutingWikiTest < ActionController::IntegrationTest
         { :method => 'get', :path => "/projects/567/wiki/export" },
         { :controller => 'wiki', :action => 'export', :project_id => '567' }
       )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/export.pdf" },
+        { :controller => 'wiki', :action => 'export', :project_id => '567', :format => 'pdf' }
+      )
     assert_routing(
          { :method => 'get', :path => "/projects/567/wiki/index" },
          { :controller => 'wiki', :action => 'index', :project_id => '567' }