Skip to content

Instantly share code, notes, and snippets.

@Casual3498
Created September 16, 2019 20:20
Show Gist options
  • Save Casual3498/8b196a8782d61b9f6fccc993ec891e9b to your computer and use it in GitHub Desktop.
Save Casual3498/8b196a8782d61b9f6fccc993ec891e9b to your computer and use it in GitHub Desktop.
Redmine issues optimization
require_dependency 'issue'
module MosregJoinEnabledModules
module Patches
module IssuePatch
def self.included(base)
base.class_eval do
scope :visible, lambda {|*args|
joins(project: :enabled_modules).
where(Issue.visible_condition(args.shift || User.current, *(args << {join_enabled_modules: true})))
}
end
end
end
end
end
Issue.send(:include, MosregJoinEnabledModules::Patches::IssuePatch)
require_dependency 'project'
module MosregJoinEnabledModules
module Patches
module ProjectPatch
def self.included(base)
base.class_eval do
# 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
# * :join_enabled_modules => if query joined enabled_modules and can use #{EnabledModule.table_name}.name
def self.allowed_to_condition(user, permission, options={})
perm = Redmine::AccessControl.permission(permission)
base_statement = (perm && perm.read? ? "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED}" : "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}")
if perm && perm.project_module
# If the permission belongs to a project module, make sure the module is enabled
if options[:join_enabled_modules]
base_statement << " AND #{EnabledModule.table_name}.name='#{perm.project_module}'"
else
base_statement << " AND #{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.project_module}')"
end
end
if project = options[:project]
project_statement = project.project_condition(options[:with_subprojects])
base_statement = "(#{project_statement}) AND (#{base_statement})"
end
if user.admin?
base_statement
else
statement_by_role = {}
unless options[:member]
role = user.builtin_role
if role.allowed_to?(permission)
s = "#{Project.table_name}.is_public = #{connection.quoted_true}"
if user.id
group = role.anonymous? ? Group.anonymous : Group.non_member
principal_ids = [user.id, group.id].compact
s = "(#{s} AND #{Project.table_name}.id NOT IN (SELECT project_id FROM #{Member.table_name} WHERE user_id IN (#{principal_ids.join(',')})))"
end
statement_by_role[role] = s
end
end
user.projects_by_role.each do |role, projects|
if role.allowed_to?(permission) && projects.any?
statement_by_role[role] = "#{Project.table_name}.id IN (#{projects.collect(&:id).join(',')})"
end
end
if statement_by_role.empty?
"1=0"
else
if block_given?
statement_by_role.each do |role, statement|
if s = yield(role, user)
statement_by_role[role] = "(#{statement} AND (#{s}))"
end
end
end
"((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))"
end
end
end
end
end
end
end
end
Project.send(:include, MosregJoinEnabledModules::Patches::ProjectPatch)
require_dependency 'tracker'
module MosregJoinEnabledModules
module Patches
module TrackerPatch
def self.included(base)
base.class_eval do
# Returns the trackers that are visible by the user.
#
# Examples:
# project.trackers.visible(user)
# => returns the trackers that are visible by the user in project
#
# Tracker.visible(user)
# => returns the trackers that are visible by the user in at least on project
scope :visible, lambda {|*args|
user = args.shift || User.current
condition = Project.allowed_to_condition(user, :view_issues, join_enabled_modules: true) do |role, user|
unless role.permissions_all_trackers?(:view_issues)
tracker_ids = role.permissions_tracker_ids(:view_issues)
if tracker_ids.any?
"#{Tracker.table_name}.id IN (#{tracker_ids.join(',')})"
else
'1=0'
end
end
end
joins(projects: :enabled_modules).
where(condition).uniq
}
end
end
end
end
end
Tracker.send(:include, MosregJoinEnabledModules::Patches::TrackerPatch)
require_dependency 'version'
module MosregJoinEnabledModules
module Patches
module VersionPatch
def self.included(base)
base.class_eval do
scope :visible, lambda {|*args|
joins(project: :enabled_modules).
where(Project.allowed_to_condition(args.first || User.current, :view_issues, join_enabled_modules: true))
}
end
end
end
end
end
Version.send(:include, MosregJoinEnabledModules::Patches::VersionPatch)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment