item_attributes.rb 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. module Import
  3. class Exchange
  4. class ItemAttributes
  5. def self.extract(resource)
  6. new(resource).extract
  7. end
  8. def initialize(resource)
  9. @resource = resource
  10. end
  11. def extract
  12. @extract ||= begin
  13. properties = @resource.get_all_properties!
  14. result = normalize(properties)
  15. flattened = flatten(result)
  16. booleanize_values(flattened)
  17. end
  18. end
  19. private
  20. def booleanize_values(properties)
  21. booleans = %w[true false]
  22. properties.each do |key, value|
  23. case value
  24. when String
  25. next if booleans.exclude?(value)
  26. properties[key] = value == 'true'
  27. when Hash
  28. properties[key] = booleanize_values(value)
  29. end
  30. end
  31. end
  32. def normalize(properties)
  33. properties.each_with_object({}) do |(key, value), result|
  34. next if key == :body
  35. if value[:text]
  36. result[key] = value[:text]
  37. elsif value[:attribs]
  38. result[key] = value[:attribs]
  39. elsif value[:elems]
  40. result[key] = sub_elems(value[:elems])
  41. end
  42. end
  43. end
  44. def sub_elems(elems)
  45. elems.each_with_object({}) do |elem, result|
  46. if elem[:entry]
  47. result.merge!(sub_elem_entry(elem[:entry]))
  48. else
  49. result.merge!(normalize(elem))
  50. end
  51. end
  52. end
  53. def sub_elem_entry(entry)
  54. entry_value = {}
  55. if entry[:elems]
  56. entry_value = sub_elems(entry[:elems])
  57. end
  58. if entry[:text]
  59. entry_value[:text] = entry[:text]
  60. end
  61. if entry[:attribs].present?
  62. entry_value.merge!(entry[:attribs])
  63. end
  64. entry_key = entry_value.delete(:key)
  65. {
  66. entry_key => entry_value
  67. }
  68. end
  69. def flatten(properties, prefix: nil)
  70. keys = %i[text id]
  71. properties.each_with_object({}) do |(key, value), result|
  72. result_key = key
  73. if prefix
  74. result_key = if keys.include?(key) && (!result[result_key] || result[result_key] == value)
  75. prefix
  76. else
  77. :"#{prefix}.#{key}"
  78. end
  79. end
  80. result_key = result_key.to_s.downcase
  81. if value.is_a?(Hash)
  82. sub_result = flatten(value, prefix: result_key)
  83. result.merge!(sub_result)
  84. else
  85. result[result_key] = value.to_s
  86. end
  87. end
  88. end
  89. end
  90. end
  91. end