tag.rb 6.4 KB

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