updater.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class FormUpdater::Updater
  3. include Mixin::RequiredSubPaths
  4. # Context from GraphQL or possibly other environments.
  5. # It must respond to :current_user and :current_user? for session information (see Gql::Context::CurrentUserAware).
  6. # It may respond to :schema with an object providing :id_for_object to perform ID mappings like in Gql::ZammadSchema.
  7. attr_reader :context, :current_user, :relation_fields, :meta, :data, :id, :object, :result, :flags
  8. def initialize(context:, relation_fields:, meta:, data:, id: nil)
  9. @context = context
  10. @meta = meta
  11. @data = data
  12. @id = id
  13. @current_user = context[:current_user]
  14. @result = {}
  15. @flags = {}
  16. # Build lookup for relation fields for better usage.
  17. @relation_fields = relation_fields.each_with_object({}) do |relation_field, lookup|
  18. lookup[relation_field[:name]] = relation_field.to_h
  19. end
  20. end
  21. def object_type
  22. raise NotImplementedError
  23. end
  24. def self.updaters
  25. descendants
  26. end
  27. def self.requires_authentication
  28. true
  29. end
  30. def authorized?
  31. # The authorized function needs to be implemented for any updaters which have a `id`.
  32. if id
  33. @object = Gql::ZammadSchema.authorized_object_from_id id, type: object_type, user: current_user
  34. end
  35. true
  36. end
  37. def resolve
  38. validate_workflows if self.class.included_modules.include?(FormUpdater::Concerns::ChecksCoreWorkflow)
  39. resolve_relation_fields if relation_fields.present?
  40. handle_updater_flags if self.class.method_defined?(:handle_updater_flags)
  41. {
  42. fields: result,
  43. flags: flags
  44. }
  45. end
  46. private
  47. def resolve_relation_fields
  48. relation_fields.each do |name, relation_field|
  49. relation_resolver = get_relation_resolver(relation_field)
  50. result_initialize_field(name)
  51. result[relation_field[:name]][:options] = relation_resolver.options
  52. ensure_field_value_int(result[relation_field[:name]])
  53. end
  54. end
  55. def ensure_field_value_int(field)
  56. return if field[:value].blank?
  57. field[:value] = field[:value].to_i
  58. end
  59. RELATION_CLASS_PREFIX = 'FormUpdater::Relation::'.freeze
  60. def get_relation_resolver(relation_field)
  61. relation_class = "#{RELATION_CLASS_PREFIX}#{relation_field[:name].humanize}".safe_constantize
  62. if !relation_class
  63. relation_class = "#{RELATION_CLASS_PREFIX}#{relation_field[:relation]}".constantize
  64. end
  65. relation_class.new(
  66. context: context,
  67. current_user: current_user,
  68. data: data,
  69. filter_ids: relation_field[:filter_ids],
  70. )
  71. rescue
  72. raise "Cannot resolve relation type #{relation_field[:relation]} (#{relation_field[:name]})."
  73. end
  74. def result_initialize_field(name)
  75. result[name] ||= {}
  76. end
  77. end