item.rb 4.2 KB

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