diff app/helpers/application_helper.rb @ 210:0579821a129a

Update to Redmine trunk rev 4802
author Chris Cannam
date Tue, 08 Feb 2011 13:51:46 +0000
parents 8661b858af72
children 051f544170fe
line wrap: on
line diff
--- a/app/helpers/application_helper.rb	Wed Jan 19 15:04:22 2011 +0000
+++ b/app/helpers/application_helper.rb	Tue Feb 08 13:51:46 2011 +0000
@@ -109,6 +109,20 @@
     link_to(text, {:controller => 'repositories', :action => 'revision', :id => project, :rev => rev},
             :title => l(:label_revision_id, format_revision(revision)))
   end
+  
+  # Generates a link to a message
+  def link_to_message(message, options={}, html_options = nil)
+    link_to(
+      h(truncate(message.subject, :length => 60)),
+      { :controller => 'messages', :action => 'show',
+        :board_id => message.board_id,
+        :id => message.root,
+        :r => (message.parent_id && message.id),
+        :anchor => (message.parent_id ? "message-#{message.id}" : nil)
+      }.merge(options),
+      html_options
+    )
+  end
 
   # Generates a link to a project if active
   # Examples:
@@ -588,16 +602,26 @@
   #     source:some/file#L120 -> Link to line 120 of the file
   #     source:some/file@52#L120 -> Link to line 120 of the file's revision 52
   #     export:some/file -> Force the download of the file
-  #  Forum messages:
+  #   Forum messages:
   #     message#1218 -> Link to message with id 1218
+  #
+  #   Links can refer other objects from other projects, using project identifier:
+  #     identifier:r52
+  #     identifier:document:"Some document"
+  #     identifier:version:1.0.0
+  #     identifier:source:some/file
   def parse_redmine_links(text, project, obj, attr, only_path, options)
-    text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(attachment|document|version|commit|source|export|message|project)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|,|\s|\]|<|$)}) do |m|
-      leading, esc, prefix, sep, identifier = $1, $2, $3, $5 || $7, $6 || $8
+    text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-]+):)?(attachment|document|version|commit|source|export|message|project)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|,|\s|\]|<|$)}) do |m|
+      leading, esc, project_prefix, project_identifier, prefix, sep, identifier = $1, $2, $3, $4, $5, $7 || $9, $8 || $10
       link = nil
+      if project_identifier
+        project = Project.visible.find_by_identifier(project_identifier)
+      end
       if esc.nil?
         if prefix.nil? && sep == 'r'
-          if project && (changeset = project.changesets.find_by_revision(identifier))
-            link = link_to("r#{identifier}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
+          # project.changesets.visible raises an SQL error because of a double join on repositories
+          if project && project.repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(project.repository.id, identifier))
+            link = link_to("#{project_prefix}r#{identifier}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
                                       :class => 'changeset',
                                       :title => truncate_single_line(changeset.comments, :length => 100))
           end
@@ -611,24 +635,18 @@
                                         :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})")
             end
           when 'document'
-            if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
+            if document = Document.visible.find_by_id(oid)
               link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
                                                 :class => 'document'
             end
           when 'version'
-            if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
+            if version = Version.visible.find_by_id(oid)
               link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
                                               :class => 'version'
             end
           when 'message'
-            if message = Message.find_by_id(oid, :include => [:parent, {:board => :project}], :conditions => Project.visible_by(User.current))
-              link = link_to h(truncate(message.subject, :length => 60)), {:only_path => only_path,
-                                                                :controller => 'messages',
-                                                                :action => 'show',
-                                                                :board_id => message.board,
-                                                                :id => message.root,
-                                                                :anchor => (message.parent ? "message-#{message.id}" : nil)},
-                                                 :class => 'message'
+            if message = Message.visible.find_by_id(oid, :include => :parent)
+              link = link_to_message(message, {:only_path => only_path}, :class => 'message')
             end
           when 'project'
             if p = Project.visible.find_by_id(oid)
@@ -640,26 +658,26 @@
           name = identifier.gsub(%r{^"(.*)"$}, "\\1")
           case prefix
           when 'document'
-            if project && document = project.documents.find_by_title(name)
+            if project && document = project.documents.visible.find_by_title(name)
               link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
                                                 :class => 'document'
             end
           when 'version'
-            if project && version = project.versions.find_by_name(name)
+            if project && version = project.versions.visible.find_by_name(name)
               link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
                                               :class => 'version'
             end
           when 'commit'
-            if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
-              link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.identifier},
+            if project && project.repository && (changeset = Changeset.visible.find(:first, :conditions => ["repository_id = ? AND scmid LIKE ?", project.repository.id, "#{name}%"]))
+              link = link_to h("#{project_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.identifier},
                                            :class => 'changeset',
                                            :title => truncate_single_line(changeset.comments, :length => 100)
             end
           when 'source', 'export'
-            if project && project.repository
+            if project && project.repository && User.current.allowed_to?(:browse_repository, project)
               name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
               path, rev, anchor = $1, $3, $5
-              link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project,
+              link = link_to h("#{project_prefix}#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project,
                                                       :path => to_path_param(path),
                                                       :rev => rev,
                                                       :anchor => anchor,
@@ -679,7 +697,7 @@
           end
         end
       end
-      leading + (link || "#{prefix}#{sep}#{identifier}")
+      leading + (link || "#{project_prefix}#{prefix}#{sep}#{identifier}")
     end
   end