base.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class Selector::Base
  3. attr_accessor :selector, :options, :changed_attributes, :target_class, :target_table, :target_name
  4. def initialize(selector:, options:, target_class: Ticket)
  5. if selector.respond_to?(:permit!)
  6. selector = selector.permit!.to_h
  7. end
  8. @selector = Marshal.load(Marshal.dump(selector)).deep_symbolize_keys
  9. @options = options
  10. @target_class = target_class
  11. @target_table = target_class.table_name
  12. @target_name = target_table.delete_suffix('s')
  13. @changed_attributes = {}
  14. @options[:changes] ||= {}
  15. migrate
  16. set_static_conditions
  17. check_changes
  18. end
  19. def migrate
  20. @selector = self.class.migrate_selector(selector)
  21. end
  22. def self.migrate_selector(value)
  23. return value if !value[:conditions].nil?
  24. result = {
  25. operator: 'AND',
  26. conditions: [],
  27. }
  28. value.each_key do |key|
  29. result[:conditions] << {
  30. name: key.to_s,
  31. }.merge(value[key])
  32. end
  33. result
  34. end
  35. def set_static_conditions
  36. conditions = static_conditions_ticket + static_conditions_article + static_conditions_ticket_update + static_conditions_user_one
  37. return if conditions.blank?
  38. @selector = {
  39. operator: 'AND',
  40. conditions: conditions + [@selector]
  41. }
  42. end
  43. def static_conditions_ticket
  44. return [] if options[:ticket_id].blank?
  45. [
  46. {
  47. name: 'ticket.id',
  48. operator: 'is',
  49. value: options[:ticket_id]
  50. }
  51. ]
  52. end
  53. def static_conditions_article
  54. return [] if options[:article_id].blank?
  55. [
  56. {
  57. name: 'article.id',
  58. operator: 'is',
  59. value: options[:article_id]
  60. }
  61. ]
  62. end
  63. # https://github.com/zammad/zammad/issues/4550
  64. def static_conditions_ticket_update
  65. return [] if options[:ticket_action] != 'update' || options[:changes_required].blank?
  66. [
  67. {
  68. name: 'ticket.action',
  69. operator: 'is',
  70. value: 'update'
  71. }
  72. ]
  73. end
  74. def static_conditions_user_one
  75. return [] if target_class != User
  76. [
  77. {
  78. name: 'user.id',
  79. operator: 'is not',
  80. value: '1'
  81. }
  82. ]
  83. end
  84. def check_changes
  85. if options[:article_id].present? && attribute_exists?('article.id')
  86. @changed_attributes['article'] = true
  87. end
  88. options[:changes].each_key do |key|
  89. next if !attribute_exists?("ticket.#{key}")
  90. @changed_attributes["ticket.#{key}"] = true
  91. end
  92. end
  93. def attribute_exists?(attribute, check_condition = @selector[:conditions])
  94. result = false
  95. check_condition.each do |condition|
  96. if condition.key?(:conditions)
  97. if attribute_exists?(attribute, condition[:conditions])
  98. result = true
  99. end
  100. elsif condition[:name] == attribute
  101. result = true
  102. end
  103. end
  104. result
  105. end
  106. def get
  107. raise 'NOT_IMPLEMENTED'
  108. end
  109. class InvalidCondition < StandardError
  110. end
  111. end