lib/wcc/contentful/link_visitor.rb in wcc-contentful-1.0.8 vs lib/wcc/contentful/link_visitor.rb in wcc-contentful-1.1.0
- old
+ new
@@ -3,36 +3,25 @@
# The LinkVisitor is a utility class for walking trees of linked entries.
# It is used internally by the Store layer to compose the resulting resolved hashes.
# But you can use it too!
class WCC::Contentful::LinkVisitor
attr_reader :entry
- attr_reader :type
attr_reader :fields
attr_reader :depth
# @param [Hash] entry The entry hash (resolved or unresolved) to walk
- # @param [Array<String, Symbol>] The fields to select from the entry tree.
- # Use `:Link` to select only links, or `'slug'` to select all slugs in the tree.
+ # @param [Array<Symbol>] The type of fields to select from the entry tree.
+ # Must be one of `:Link`, `:Entry`, `:Asset`.
# @param [Fixnum] depth (optional) How far to walk down the tree of links. Be careful of
# recursive trees!
- # @example
- # entry = store.find_by(id: id, include: 3)
- # WCC::Contentful::LinkVisitor.new(entry, 'slug', depth: 3)
- # .map { |slug| 'https://mirror-site' + slug }
def initialize(entry, *fields, depth: 0)
- unless entry.is_a?(Hash) && entry.dig('sys', 'id')
+ unless entry.is_a?(Hash) && entry.dig('sys', 'type') == 'Entry'
raise ArgumentError, "Please provide an entry as a hash value (got #{entry})"
end
- unless ct = entry.dig('sys', 'contentType', 'sys', 'id')
- raise ArgumentError, 'Entry has no content type!'
- end
- @type = WCC::Contentful.types[ct]
- raise ArgumentError, "Unknown content type '#{ct}'" unless @type
-
@entry = entry
- @fields = fields
+ @fields = fields.map(&:to_s)
@depth = depth
end
# Walks an entry and its resolved links, without transforming the entry.
# @yield [value, field, locale]
@@ -40,11 +29,11 @@
# @yieldparam [WCC::Contentful::IndexedRepresentation::Field] field The type of the selected field
# @yieldparam [String] locale The locale of the current field value
# @returns nil
def each(&block)
_each do |val, field, locale, index|
- yield(val, field, locale, index) if should_yield_field?(field)
+ yield(val, field, locale, index) if should_yield_field?(field, val)
next unless should_walk_link?(field, val)
self.class.new(val, *fields, depth: depth - 1).each(&block)
end
@@ -52,11 +41,11 @@
nil
end
def map!(&block)
_each do |val, field, locale, index|
- if should_yield_field?(field)
+ if should_yield_field?(field, val)
val = yield(val, field, locale, index)
set_field(field, locale, index, val)
end
next unless should_walk_link?(field, val)
@@ -68,29 +57,29 @@
end
private
def _each(&block)
- type.fields.each_value do |f|
- each_field(f, &block)
+ (entry['fields'] || {}).each do |(k, _v)|
+ each_field(k, &block)
end
end
def each_field(field)
each_locale(field) do |val, locale|
- if field.array
- val&.each_with_index do |v, index|
+ if val&.is_a?(Array)
+ val.each_with_index do |v, index|
yield(v, field, locale, index) unless v.nil?
end
else
yield(val, field, locale) unless val.nil?
end
end
end
def each_locale(field)
- raw_value = entry.dig('fields', field.name)
+ raw_value = entry.dig('fields', field)
if locale = entry.dig('sys', 'locale')
if raw_value.is_a?(Hash) && raw_value[locale]
# it's a locale=* entry, but they've added sys.locale to those now
raw_value = raw_value[locale]
end
@@ -100,23 +89,30 @@
h[l] = yield(val, l)
end
end
end
- def should_yield_field?(field)
- fields.empty? || fields.include?(field.type) || fields.include?(field.name)
+ def should_yield_field?(_field, value)
+ return true if fields.empty?
+
+ case value
+ when Hash
+ fields.include?(value.dig('sys', 'type'))
+ when Array
+ value.any? { |v| v.is_a?(Hash) && fields.include?(v.dig('sys', 'type')) }
+ end
end
- def should_walk_link?(field, val, dep = depth)
- dep > 0 && field.type == :Link && val.dig('sys', 'type') == 'Entry'
+ def should_walk_link?(_field, val, dep = depth)
+ dep > 0 && val.is_a?(Hash) && val.dig('sys', 'type') == 'Entry'
end
def set_field(field, locale, index, val)
- current_field = (entry['fields'][field.name] ||= {})
+ current_field = (entry['fields'][field] ||= {})
- if field.array
- (current_field[locale] ||= [])[index] = val
- else
+ if index.nil?
current_field[locale] = val
+ else
+ (current_field[locale] ||= [])[index] = val
end
end
end