require 'mime/types' require 'ostruct' module RailsConnector # The page related and custom data belonging to a CMS object # # [editor] The login of the current editor of the edited content, if set # # Any custom Attribute can be accessed directly or via []. class AttrDict def initialize(object, keys_and_values = {}, defs = {}) @object = object @blob_dict = keys_and_values.symbolize_keys @attr_defs = defs.symbolize_keys @attr_cache = {} end def empty? @blob_dict.empty? && @attr_defs.empty? end # Returns the title of the content - an HtmlString def title raw = @blob_dict[:title] StringTagging.tag_as_html(raw, self) end def sort_keys [sort_key1, sort_key2, sort_key3].compact end # The body attribute may contain binary data for Obj.binary? or be an HtmlString. def body if object.binary? binary_body.data if binary_body else StringTagging.tag_as_html(textual_body, self) end end def body_length if binary_body binary_body.length elsif body body.length else 0 end end # Ensures the body data is in a file and returns its file system path. def body_data_path # TODO: Braucht/will jemand Text gestreamt? return nil unless object.binary? binary_body.path_of_stored_data(object.last_changed) if binary_body end def [](key) send key end def permitted_groups permission_live_server_read rescue NoMethodError [] end def permissions @permissions ||= OpenStruct.new({ :live => permitted_groups }) end def respond_to?(method_id, include_private=false) super || has_attribute(method_id) end private attr_reader :object, :blob_dict, :attr_defs delegate :obj_class_def, to: :object, allow_nil: true def textual_body return nil if object.binary? blob_dict[:blob] end def binary_body return nil unless object.binary? && has_attribute(:blob) @binary_body ||= Blob.find(blob) rescue RailsConnector::ResourceNotFound nil end def method_missing(method_id, *args) raise NoMethodError.new("missing method - #{method_id}") unless args.empty? return attribute_value(method_id.to_s) rescue UnknownAttributeError raise NoMethodError.new("missing method - #{method_id}") end def attribute_value(key) raise UnknownAttributeError.new unless has_attribute(key) key = key.to_sym raw = blob_dict[key] @attr_cache[key] ||= case type_of(key) when :markdown StringTagging.tag_as_markdown(raw, self) when :html StringTagging.tag_as_html(raw.to_s, self) when :string, :text raw.to_s when :date DateAttribute.parse(raw) if raw when :linklist LinkList.new(raw) when :multienum raw || [] else raw end end # this attributes are defined by cms # but if not set, are not existend in attr_defs def predefined_attribute?(key) [:channels, :sort_key1, :sort_key2, :sort_key3].include?(key.to_sym) end def has_attribute(key) key = key.to_sym return true if predefined_attribute?(key) blob_dict.key?(key) || attr_defs.key?(key) || class_defined_attributes.key?(key) end def type_of(key) key = key.to_sym return :linklist if key == :text_links return :multienum if key == :channels type_from_attr_defs(key) || type_from_class_defined_attributes(key) end def type_from_attr_defs(key) attr_defs[key]['type'].to_sym rescue nil end def type_from_class_defined_attributes(key) class_defined_attributes[key].type.to_sym rescue nil end def class_defined_attributes obj_class_def.try(:custom_attributes) || {} end end class UnknownAttributeError < StandardError end end