OSDN Git Service

Makes visible scopes accept projects option and deprecate Project.visible_by.
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Tue, 5 Apr 2011 12:50:19 +0000 (12:50 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Tue, 5 Apr 2011 12:50:19 +0000 (12:50 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@5324 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/changeset.rb
app/models/document.rb
app/models/issue.rb
app/models/journal.rb
app/models/message.rb
app/models/news.rb
app/models/project.rb
app/models/time_entry.rb
test/unit/issue_test.rb

index 7195408..59b2302 100644 (file)
@@ -42,7 +42,7 @@ class Changeset < ActiveRecord::Base
   validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
   
   named_scope :visible, lambda {|*args| { :include => {:repository => :project},
-                                          :conditions => Project.allowed_to_condition(args.first || User.current, :view_changesets) } }
+                                          :conditions => Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args) } }
                                           
   def revision=(r)
     write_attribute :revision, (r.nil? ? nil : r.to_s)
index 21232a2..d51f2d3 100644 (file)
@@ -30,7 +30,7 @@ class Document < ActiveRecord::Base
   validates_length_of :title, :maximum => 60
   
   named_scope :visible, lambda {|*args| { :include => :project,
-                                          :conditions => Project.allowed_to_condition(args.first || User.current, :view_documents) } }
+                                          :conditions => Project.allowed_to_condition(args.shift || User.current, :view_documents, *args) } }
   
   def visible?(user=User.current)
     !user.nil? && user.allowed_to?(:view_documents, project)
index 24258b4..9436266 100644 (file)
@@ -60,7 +60,7 @@ class Issue < ActiveRecord::Base
   validates_numericality_of :estimated_hours, :allow_nil => true
 
   named_scope :visible, lambda {|*args| { :include => :project,
-                                          :conditions => Issue.visible_condition(args.first || User.current) } }
+                                          :conditions => Issue.visible_condition(args.shift || User.current, *args) } }
   
   named_scope :open, :conditions => ["#{IssueStatus.table_name}.is_closed = ?", false], :include => :status
 
index 7a36b12..39eb338 100644 (file)
@@ -40,7 +40,7 @@ class Journal < ActiveRecord::Base
   
   named_scope :visible, lambda {|*args| {
     :include => {:issue => :project},
-    :conditions => Issue.visible_condition(args.first || User.current)
+    :conditions => Issue.visible_condition(args.shift || User.current, *args)
   }}
   
   def save(*args)
index 77c9ff5..776af6e 100644 (file)
@@ -24,7 +24,7 @@ class Message < ActiveRecord::Base
   
   acts_as_searchable :columns => ['subject', 'content'],
                      :include => {:board => :project},
-                     :project_key => 'project_id',
+                     :project_key => "#{Board.table_name}.project_id",
                      :date_column => "#{table_name}.created_on"
   acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
                 :description => :content,
@@ -43,7 +43,7 @@ class Message < ActiveRecord::Base
   after_create :add_author_as_watcher
   
   named_scope :visible, lambda {|*args| { :include => {:board => :project},
-                                          :conditions => Project.allowed_to_condition(args.first || User.current, :view_messages) } }
+                                          :conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } }
   
   def visible?(user=User.current)
     !user.nil? && user.allowed_to?(:view_messages, project)
index 7f8c731..9e7cb1e 100644 (file)
@@ -34,7 +34,7 @@ class News < ActiveRecord::Base
   
   named_scope :visible, lambda {|*args| { 
     :include => :project,
-    :conditions => Project.allowed_to_condition(args.first || User.current, :view_news) 
+    :conditions => Project.allowed_to_condition(args.shift || User.current, :view_news, *args) 
   }}
   
   def visible?(user=User.current)
index 58839a6..2d6e2ef 100644 (file)
@@ -84,7 +84,7 @@ class Project < ActiveRecord::Base
   named_scope :has_module, lambda { |mod| { :conditions => ["#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s] } }
   named_scope :active, { :conditions => "#{Project.table_name}.status = #{STATUS_ACTIVE}"}
   named_scope :all_public, { :conditions => { :is_public => true } }
-  named_scope :visible, lambda { { :conditions => Project.visible_by(User.current) } }
+  named_scope :visible, lambda {|*args| {:conditions => Project.visible_condition(args.shift || User.current, *args) }}
   
   def initialize(attributes = nil)
     super
@@ -115,25 +115,30 @@ class Project < ActiveRecord::Base
   # returns latest created projects
   # non public projects will be returned only if user is a member of those
   def self.latest(user=nil, count=5)
-    find(:all, :limit => count, :conditions => visible_by(user), :order => "created_on DESC")  
+    visible(user).find(:all, :limit => count, :order => "created_on DESC")     
   end  
 
-  # Returns a SQL :conditions string used to find all active projects for the specified user.
+  def self.visible_by(user=nil)
+    ActiveSupport::Deprecation.warn "Project.visible_by is deprecated and will be removed in Redmine 1.3.0. Use Project.visible_condition instead."
+    visible_condition(user || User.current)
+  end
+  
+  # Returns a SQL conditions string used to find all projects visible by the specified user.
   #
   # Examples:
-  #     Projects.visible_by(admin)        => "projects.status = 1"
-  #     Projects.visible_by(normal_user)  => "projects.status = 1 AND projects.is_public = 1"
-  def self.visible_by(user=nil)
-    user ||= User.current
-    if user && user.admin?
-      return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"
-    elsif user && user.memberships.any?
-      return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE} AND (#{Project.table_name}.is_public = #{connection.quoted_true} or #{Project.table_name}.id IN (#{user.memberships.collect{|m| m.project_id}.join(',')}))"
-    else
-      return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE} AND #{Project.table_name}.is_public = #{connection.quoted_true}"
-    end
+  #   Project.visible_condition(admin)        => "projects.status = 1"
+  #   Project.visible_condition(normal_user)  => "((projects.status = 1) AND (projects.is_public = 1 OR projects.id IN (1,3,4)))"
+  #   Project.visible_condition(anonymous)    => "((projects.status = 1) AND (projects.is_public = 1))"
+  def self.visible_condition(user, options={})
+    allowed_to_condition(user, :view_project, options)
   end
   
+  # Returns a SQL conditions string used to find all projects for which +user+ has the given +permission+
+  #
+  # Valid options:
+  # * :project => limit the condition to project
+  # * :with_subprojects => limit the condition to project and its subprojects
+  # * :member => limit the condition to the user projects
   def self.allowed_to_condition(user, permission, options={})
     base_statement = "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"
     if perm = Redmine::AccessControl.permission(permission)
index c89ead3..a513999 100644 (file)
@@ -41,7 +41,7 @@ class TimeEntry < ActiveRecord::Base
   
   named_scope :visible, lambda {|*args| { 
     :include => :project,
-    :conditions => Project.allowed_to_condition(args.first || User.current, :view_time_entries) 
+    :conditions => Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args)
   }}
 
   def after_initialize
index f4dcf66..5f61d61 100644 (file)
@@ -106,6 +106,22 @@ class IssueTest < ActiveSupport::TestCase
     assert issues.detect {|issue| !issue.project.is_public?}
   end
   
+  def test_visible_scope_with_project
+    project = Project.find(1)
+    issues = Issue.visible(User.find(2), :project => project).all
+    projects = issues.collect(&:project).uniq
+    assert_equal 1, projects.size
+    assert_equal project, projects.first
+  end
+  
+  def test_visible_scope_with_project_and_subprojects
+    project = Project.find(1)
+    issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all
+    projects = issues.collect(&:project).uniq
+    assert projects.size > 1
+    assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
+  end
+  
   def test_errors_full_messages_should_include_custom_fields_errors
     field = IssueCustomField.find_by_name('Database')