tag.rb 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. class Tag < ApplicationModel
  3. belongs_to :tag_object, class_name: 'Tag::Object'
  4. belongs_to :tag_item, class_name: 'Tag::Item'
  5. =begin
  6. add tags for certain object
  7. Tag.tag_add(
  8. object: 'Ticket',
  9. o_id: ticket.id,
  10. item: 'some tag',
  11. created_by_id: current_user.id,
  12. )
  13. =end
  14. def self.tag_add(data)
  15. data[:item].strip!
  16. # lookups
  17. if data[:object]
  18. tag_object_id = Tag::Object.lookup_by_name_and_create(data[:object]).id
  19. end
  20. if data[:item]
  21. tag_item_id = Tag::Item.lookup_by_name_and_create(data[:item]).id
  22. end
  23. # return if duplicate
  24. current_tags = tag_list(data)
  25. return true if current_tags.include?(data[:item])
  26. # create history
  27. Tag.create(
  28. tag_object_id: tag_object_id,
  29. tag_item_id: tag_item_id,
  30. o_id: data[:o_id],
  31. created_by_id: data[:created_by_id],
  32. )
  33. # touch reference
  34. touch_reference_by_params(data)
  35. true
  36. end
  37. =begin
  38. remove tags of certain object
  39. Tag.tag_remove(
  40. object: 'Ticket',
  41. o_id: ticket.id,
  42. item: 'some tag',
  43. created_by_id: current_user.id,
  44. )
  45. or by ids
  46. Tag.tag_remove(
  47. tag_object_id: 123,
  48. o_id: ticket.id,
  49. tag_item_id: 123,
  50. created_by_id: current_user.id,
  51. )
  52. =end
  53. def self.tag_remove(data)
  54. # lookups
  55. if data[:object]
  56. data[:tag_object_id] = Tag::Object.lookup_by_name_and_create(data[:object]).id
  57. else
  58. data[:object] = Tag::Object.lookup(id: data[:tag_object_id]).name
  59. end
  60. if data[:item]
  61. data[:item].strip!
  62. data[:tag_item_id] = Tag::Item.lookup_by_name_and_create(data[:item]).id
  63. end
  64. # create history
  65. result = Tag.where(
  66. tag_object_id: data[:tag_object_id],
  67. tag_item_id: data[:tag_item_id],
  68. o_id: data[:o_id],
  69. )
  70. result.each(&:destroy)
  71. # touch reference
  72. touch_reference_by_params(data)
  73. true
  74. end
  75. =begin
  76. tag list for certain object
  77. tags = Tag.tag_list(
  78. object: 'Ticket',
  79. o_id: ticket.id,
  80. )
  81. returns
  82. ['tag 1', 'tag2', ...]
  83. =end
  84. def self.tag_list(data)
  85. tag_object_id_requested = Tag::Object.lookup(name: data[:object])
  86. return [] if !tag_object_id_requested
  87. tag_search = Tag.where(
  88. tag_object_id: tag_object_id_requested,
  89. o_id: data[:o_id],
  90. )
  91. tags = []
  92. tag_search.each { |tag|
  93. tag_item = Tag::Item.lookup(id: tag.tag_item_id)
  94. next if !tag_item
  95. tags.push tag_item.name
  96. }
  97. tags
  98. end
  99. class Object < ApplicationModel
  100. validates :name, presence: true
  101. =begin
  102. lookup by name and create tag item
  103. tag_object = Tag::Object.lookup_by_name_and_create('some tag')
  104. =end
  105. def self.lookup_by_name_and_create(name)
  106. name.strip!
  107. tag_object = Tag::Object.lookup(name: name)
  108. return tag_object if tag_object
  109. Tag::Object.create(name: name)
  110. end
  111. end
  112. class Item < ApplicationModel
  113. validates :name, presence: true
  114. before_save :fill_namedowncase
  115. =begin
  116. lookup by name and create tag item
  117. tag_item = Tag::Item.lookup_by_name_and_create('some tag')
  118. =end
  119. def self.lookup_by_name_and_create(name)
  120. name.strip!
  121. tag_item = Tag::Item.lookup(name: name)
  122. return tag_item if tag_item
  123. Tag::Item.create(name: name)
  124. end
  125. =begin
  126. rename tag items
  127. Tag::Item.rename(
  128. id: existing_tag_item_to_rename,
  129. name: 'new tag item name',
  130. updated_by_id: current_user.id,
  131. )
  132. =end
  133. def self.rename(data)
  134. new_tag_name = data[:name].strip
  135. old_tag_item = Tag::Item.find(data[:id])
  136. already_existing_tag = Tag::Item.lookup(name: new_tag_name)
  137. # merge old with new tag if already existing
  138. if already_existing_tag
  139. # re-assign old tag to already existing tag
  140. Tag.where(tag_item_id: old_tag_item.id).each { |tag|
  141. # check if tag already exists on object
  142. if Tag.find_by(tag_object_id: tag.tag_object_id, o_id: tag.o_id, tag_item_id: already_existing_tag.id)
  143. Tag.tag_remove(
  144. tag_object_id: tag.tag_object_id,
  145. o_id: tag.o_id,
  146. tag_item_id: old_tag_item.id,
  147. )
  148. next
  149. end
  150. # re-assign
  151. tag_object = Tag::Object.lookup(id: tag.tag_object_id)
  152. tag.tag_item_id = already_existing_tag.id
  153. tag.save
  154. # touch reference objects
  155. Tag.touch_reference_by_params(
  156. object: tag_object.name,
  157. o_id: tag.o_id,
  158. )
  159. }
  160. # delete not longer used tag
  161. old_tag_item.destroy
  162. # update new tag name
  163. else
  164. old_tag_item.name = new_tag_name
  165. old_tag_item.save
  166. # touch reference objects
  167. Tag.where(tag_item_id: old_tag_item.id).each { |tag|
  168. tag_object = Tag::Object.lookup(id: tag.tag_object_id)
  169. Tag.touch_reference_by_params(
  170. object: tag_object.name,
  171. o_id: tag.o_id,
  172. )
  173. }
  174. end
  175. true
  176. end
  177. =begin
  178. remove tag item (destroy with reverences)
  179. Tag::Item.remove(id)
  180. =end
  181. def self.remove(id)
  182. # search for references, destroy and touch
  183. Tag.where(tag_item_id: id).each { |tag|
  184. tag_object = Tag::Object.lookup(id: tag.tag_object_id)
  185. tag.destroy
  186. Tag.touch_reference_by_params(
  187. object: tag_object.name,
  188. o_id: tag.o_id,
  189. )
  190. }
  191. Tag::Item.find(id).destroy
  192. true
  193. end
  194. def fill_namedowncase
  195. self.name_downcase = name.downcase
  196. end
  197. end
  198. end