item.rb 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Tag::Item < ApplicationModel
  3. validates :name, presence: true, format: { without: %r{,|\*} }
  4. before_save :fill_namedowncase
  5. has_many :tags, foreign_key: 'tag_item_id',
  6. inverse_of: :tag_item,
  7. dependent: :destroy
  8. scope :recommended, lambda {
  9. left_outer_joins(:tags)
  10. .group(:id)
  11. .reorder('COUNT(tags.tag_item_id) DESC, name ASC')
  12. }
  13. scope :filter_by_name, lambda { |query|
  14. where('name_downcase LIKE ?', "%#{SqlHelper.quote_like(query.strip.downcase)}%")
  15. .reorder(name: :asc)
  16. }
  17. scope :filter_or_recommended, lambda { |query|
  18. query.blank? ? recommended : filter_by_name(query)
  19. }
  20. =begin
  21. lookup by name and create tag item
  22. tag_item = Tag::Item.lookup_by_name_and_create('some tag')
  23. =end
  24. def self.lookup_by_name_and_create(name)
  25. name.strip!
  26. tag_item = Tag::Item.lookup(name: name)
  27. return tag_item if tag_item
  28. Tag::Item.create(name: name)
  29. end
  30. =begin
  31. rename tag items
  32. Tag::Item.rename(
  33. id: existing_tag_item_to_rename,
  34. name: 'new tag item name',
  35. updated_by_id: current_user.id,
  36. )
  37. =end
  38. def self.rename(data)
  39. new_tag_name = data[:name].strip
  40. old_tag_item = Tag::Item.find(data[:id])
  41. already_existing_tag = Tag::Item.lookup(name: new_tag_name)
  42. # check if no rename is needed
  43. return true if new_tag_name == old_tag_item.name
  44. # merge old with new tag if already existing
  45. if already_existing_tag
  46. # re-assign old tag to already existing tag
  47. Tag.where(tag_item_id: old_tag_item.id).each do |tag|
  48. # check if tag already exists on object
  49. if Tag.exists?(tag_object_id: tag.tag_object_id, o_id: tag.o_id, tag_item_id: already_existing_tag.id)
  50. Tag.tag_remove(
  51. tag_object_id: tag.tag_object_id,
  52. o_id: tag.o_id,
  53. tag_item_id: old_tag_item.id,
  54. )
  55. next
  56. end
  57. # re-assign
  58. tag_object = Tag::Object.lookup(id: tag.tag_object_id)
  59. tag.tag_item_id = already_existing_tag.id
  60. tag.save
  61. # touch reference objects
  62. Tag.touch_reference_by_params(
  63. object: tag_object.name,
  64. o_id: tag.o_id,
  65. )
  66. end
  67. # delete not longer used tag
  68. old_tag_item.destroy
  69. return true
  70. end
  71. update_referenced_objects(old_tag_item.name, new_tag_name)
  72. # update new tag name
  73. old_tag_item.name = new_tag_name
  74. old_tag_item.save
  75. # touch reference objects
  76. Tag.where(tag_item_id: old_tag_item.id).each do |tag|
  77. tag_object = Tag::Object.lookup(id: tag.tag_object_id)
  78. Tag.touch_reference_by_params(
  79. object: tag_object.name,
  80. o_id: tag.o_id,
  81. )
  82. end
  83. true
  84. end
  85. =begin
  86. remove tag item (destroy with reverences)
  87. Tag::Item.remove(id)
  88. =end
  89. def self.remove(id)
  90. # search for references, destroy and touch
  91. Tag.where(tag_item_id: id).each do |tag|
  92. tag_object = Tag::Object.lookup(id: tag.tag_object_id)
  93. tag.destroy
  94. Tag.touch_reference_by_params(
  95. object: tag_object.name,
  96. o_id: tag.o_id,
  97. )
  98. end
  99. Tag::Item.find(id).destroy
  100. true
  101. end
  102. def fill_namedowncase
  103. self.name_downcase = name.downcase
  104. true
  105. end
  106. =begin
  107. Update referenced objects such as triggers, overviews, schedulers, and postmaster filters
  108. Specifically, the following fields are updated:
  109. Overview.condition
  110. Trigger.condition Trigger.perform
  111. Job.condition Job.perform
  112. PostmasterFilter.perform
  113. =end
  114. def self.update_referenced_objects(old_name, new_name)
  115. objects = Overview.all + Trigger.all + Job.all + PostmasterFilter.all
  116. objects.each do |object|
  117. changed = false
  118. if object.has_attribute?(:condition)
  119. changed |= update_condition_hash object.condition, old_name, new_name
  120. end
  121. if object.has_attribute?(:perform)
  122. changed |= update_condition_hash object.perform, old_name, new_name
  123. end
  124. object.save if changed
  125. end
  126. end
  127. def self.update_condition_hash(hash, old_name, new_name)
  128. changed = false
  129. hash.each do |key, condition|
  130. next if %w[ticket.tags x-zammad-ticket-tags].exclude? key
  131. next if condition[:value].split(', ').exclude? old_name
  132. condition[:value] = update_name(condition[:value], old_name, new_name)
  133. changed = true
  134. end
  135. changed
  136. end
  137. def self.update_name(condition, old_name, new_name)
  138. tags = condition.split(', ')
  139. return new_name if tags.size == 1
  140. tags = tags.map { |t| t == old_name ? new_name : t }
  141. tags.join(', ')
  142. end
  143. end