Class: AdditionalTags::Tags

Inherits:
Object
  • Object
show all
Defined in:
lib/additional_tags/tags.rb

Class Method Summary collapse

Class Method Details

.all_type_tags(klass, without_projects: false) ⇒ Object



41
42
43
44
45
46
# File 'lib/additional_tags/tags.rb', line 41

def all_type_tags(klass, without_projects: false)
  ActsAsTaggableOn::Tag.all
                       .joins(tag_for_joins(klass, without_projects: without_projects))
                       .distinct
                       .order(:name)
end

.available_tags(klass, **options) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/additional_tags/tags.rb', line 13

def available_tags(klass, **options)
  user = options[:user].presence || User.current

  scope = ActsAsTaggableOn::Tag.where({})
  if options[:project]
    scope = if Setting.display_subprojects_issues?
              scope.where subproject_sql(options[:project])
            else
              scope.where projects: { id: options[:project] }
            end
  end

  if options[:permission]
    scope = scope.where tag_access(options[:permission], user, skip_pre_condition: options[:skip_pre_condition])
  elsif options[:visible_condition]
    scope = scope.where klass.visible_condition(user)
  end
  scope = scope.where "LOWER(#{TAG_TABLE_NAME}.name) LIKE ?", "%#{options[:name_like].downcase}%" if options[:name_like]
  scope = scope.where "#{TAG_TABLE_NAME}.name=?", options[:name] if options[:name]
  scope = scope.where "#{TAGGING_TABLE_NAME}.taggable_id!=?", options[:exclude_id] if options[:exclude_id]
  scope = scope.where options[:where_field] => options[:where_value] if options[:where_field].present? && options[:where_value]

  scope.select(table_columns(options[:sort_by]))
       .joins(tag_for_joins(klass, **options.slice(:project_join, :project, :without_projects)))
       .group("#{TAG_TABLE_NAME}.id, #{TAG_TABLE_NAME}.name, #{TAG_TABLE_NAME}.taggings_count").having('COUNT(*) > 0')
       .order(build_order_sql(options[:sort_by], options[:order]))
end

.build_relation_tags(entries) ⇒ Object



96
97
98
99
100
101
102
103
104
# File 'lib/additional_tags/tags.rb', line 96

def build_relation_tags(entries)
  entries = Array entries
  return [] if entries.none?

  tags = entries.map(&:tags)
  tags.flatten!

  tags.uniq
end

.entity_group_by(scope:, tags:, statuses: nil, sub_groups: nil, group_id_is_bool: false) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/additional_tags/tags.rb', line 106

def entity_group_by(scope:, tags:, statuses: nil, sub_groups: nil, group_id_is_bool: false)
  counts = {}
  tags.each do |tag|
    values = { tag: tag, total: 0, total_sub_groups: 0, groups: [] }

    if statuses
      statuses.each do |status|
        group_id = status.first
        group = status.second
        values[group] = status_for_tag_value scope: scope,
                                             tag_id: tag.id,
                                             group_id: group_id,
                                             group_id_is_bool: group_id_is_bool
        values[:groups] << { id: group_id, group: group, count: values[group] }
        values[:total] += values[group]
        values[:total_sub_groups] += values[group] if sub_groups&.include? group_id
      end
    else
      values[:total] += status_for_tag_value scope: scope, tag_id: tag.id
    end

    values[:total_without_sub_groups] = values[:total] - values[:total_sub_groups]

    counts[tag.name] = values
  end

  counts
end

.merge(tag_name, tags_to_merge) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/additional_tags/tags.rb', line 63

def merge(tag_name, tags_to_merge)
  return if tag_name.blank? || tags_to_merge.none?

  ActsAsTaggableOn::Tagging.transaction do
    tag = ActsAsTaggableOn::Tag.find_by(name: tag_name) || ActsAsTaggableOn::Tag.create(name: tag_name)
    # Update old tagging with new tag
    ActsAsTaggableOn::Tagging.where(tag_id: tags_to_merge.map(&:id)).update_all tag_id: tag.id
    # remove old (merged) tags
    tags_to_merge.reject { |t| t.id == tag.id }.each(&:destroy)
    # remove duplicate taggings
    dup_scope = ActsAsTaggableOn::Tagging.where tag_id: tag.id
    valid_ids = dup_scope.group(:tag_id, :taggable_id, :taggable_type, :tagger_id, :tagger_type, :context)
                         .pluck(Arel.sql('MIN(id)'))
    dup_scope.where.not(id: valid_ids).destroy_all if valid_ids.any?
    # recalc count for new tag
    ActsAsTaggableOn::Tag.reset_counters tag.id, :taggings
  end
end

.remove_unused_tagsObject



58
59
60
61
# File 'lib/additional_tags/tags.rb', line 58

def remove_unused_tags
  ActsAsTaggableOn::Tag.where.missing(:taggings)
                       .each(&:destroy)
end

.sort_tag_list(tag_list) ⇒ Object

sort tag_list alphabetically with special characters support



90
91
92
93
94
# File 'lib/additional_tags/tags.rb', line 90

def sort_tag_list(tag_list)
  tag_list.to_a.sort! do |a, b|
    ActiveSupport::Inflector.transliterate(a.name.downcase) <=> ActiveSupport::Inflector.transliterate(b.name.downcase)
  end
end

.sort_tags(tags) ⇒ Object

sort tags alphabetically with special characters support



83
84
85
86
87
# File 'lib/additional_tags/tags.rb', line 83

def sort_tags(tags)
  tags.sort! do |a, b|
    ActiveSupport::Inflector.transliterate(a.downcase) <=> ActiveSupport::Inflector.transliterate(b.downcase)
  end
end

.subproject_sql(project) ⇒ Object



135
136
137
138
# File 'lib/additional_tags/tags.rb', line 135

def subproject_sql(project)
  "#{Project.table_name}.lft >= #{project.lft} " \
    "AND #{Project.table_name}.rgt <= #{project.rgt}"
end

.tag_to_joins(klass) ⇒ Object



48
49
50
51
52
53
54
55
56
# File 'lib/additional_tags/tags.rb', line 48

def tag_to_joins(klass)
  table_name = klass.table_name

  joins = ["JOIN #{TAGGING_TABLE_NAME} ON #{TAGGING_TABLE_NAME}.taggable_id = #{table_name}.id" \
           " AND #{TAGGING_TABLE_NAME}.taggable_type = '#{klass}'"]
  joins << "JOIN #{TAG_TABLE_NAME} ON #{TAGGING_TABLE_NAME}.tag_id = #{TAG_TABLE_NAME}.id"

  joins
end

.visible_condition(user, **options) ⇒ Object



6
7
8
9
10
11
# File 'lib/additional_tags/tags.rb', line 6

def visible_condition(user, **options)
  permission = options[:permission] || :view_issue_tags
  skip_pre_condition = options[:skip_pre_condition] || true

  tag_access permission, user, skip_pre_condition: skip_pre_condition
end