updater.rb 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. # Copyright (C) 2012-2023 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
  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. # Build lookup for relation fields for better usage.
  16. @relation_fields = relation_fields.each_with_object({}) do |relation_field, lookup|
  17. lookup[relation_field[:name]] = relation_field.to_h
  18. end
  19. end
  20. def object_type
  21. raise NotImplementedError
  22. end
  23. def self.updaters
  24. descendants
  25. end
  26. def self.requires_authentication
  27. true
  28. end
  29. def authorized?
  30. # The authorized function needs to be implemented for any updaters which have a `id`.
  31. if id
  32. @object = Gql::ZammadSchema.authorized_object_from_id id, type: object_type, user: current_user
  33. end
  34. true
  35. end
  36. def resolve
  37. if self.class.included_modules.include?(FormUpdater::Concerns::ChecksCoreWorkflow)
  38. validate_workflows
  39. end
  40. if relation_fields.present?
  41. resolve_relation_fields
  42. end
  43. result
  44. end
  45. private
  46. def resolve_relation_fields
  47. relation_fields.each do |name, relation_field|
  48. relation_resolver = get_relation_resolver(relation_field)
  49. result_initialize_field(name)
  50. result[relation_field[:name]][:options] = relation_resolver.options
  51. end
  52. end
  53. RELATION_CLASS_PREFIX = 'FormUpdater::Relation::'.freeze
  54. def get_relation_resolver(relation_field)
  55. relation_class = "#{RELATION_CLASS_PREFIX}#{relation_field[:name].humanize}".safe_constantize
  56. if !relation_class
  57. relation_class = "#{RELATION_CLASS_PREFIX}#{relation_field[:relation]}".constantize
  58. end
  59. relation_class.new(
  60. context: context,
  61. current_user: current_user,
  62. data: data,
  63. filter_ids: relation_field[:filter_ids],
  64. )
  65. rescue
  66. raise "Cannot resolve relation type #{relation_field[:relation]} (#{relation_field[:name]})."
  67. end
  68. def result_initialize_field(name)
  69. result[name] ||= {}
  70. end
  71. end