module Scrivito # This class allows you to retrieve CMS objects from a specific working copy. # You can get an instance by accessing {Workspace#objs}. # @api public class ObjCollection attr_reader :workspace def initialize(workspace) @workspace = workspace end # Find an {BasicObj Obj} by its id. # If the parameter is an Array containing ids, return a list of the # corresponding {Scrivito::BasicObj Obj}s. # @param [String, Integer, Array]id_or_list # @return [Obj, Array] # @api public def find(id_or_list) find_using(id_or_list, :find_by) end # Find a {BasicObj Obj} by its id. # If the parameter is an Array containing ids, return a list of the # corresponding {Scrivito::BasicObj Obj}s. The results include deleted objects as well. # @param [String, Integer, Array]id_or_list # @return [Obj, Array] # @api public def find_including_deleted(id_or_list) find_using(id_or_list, :find_by_including_deleted) end # # Find the {Scrivito::BasicObj Obj} that has the given +path+. # # @api public # # @note If there is more than one {Scrivito::BasicObj Obj} with the given +path+, # then the {Scrivito::BasicObj Obj} with the smallest +id+ will be returned. # # @param [String] path Path of the {Scrivito::BasicObj Obj}. # # @return [Scrivito::BasicObj] if an {Scrivito::BasicObj Obj} with the given +path+ exists. # @return [NilClass] if no {Scrivito::BasicObj Obj} with the given +path+ exists. # def find_by_path(path) find_one_by(:path, path) end # # Returns the {Scrivito::BasicObj Obj} that has the given +permalink+. # # @api public # # @note If there is more than one {Scrivito::BasicObj Obj} with the given +permalink+, # then the {Scrivito::BasicObj Obj} with the smallest +id+ will be returned. # # @param [String] permalink The permalink of the {BasicObj Obj}. # # @return [Scrivito::BasicObj] if an {Scrivito::BasicObj Obj} with the given +permalink+ exists. # @return [NilClass] if no {Scrivito::BasicObj Obj} with the given +permalink+ exists. # def find_by_permalink(permalink) find_one_by(:permalink, permalink) end # Returns an {ObjSearchEnumerator} with the given initial subquery consisting of the # four arguments. # # Note that +field+ and +value+ may also be arrays for searching several fields or searching # for several values. # # {ObjSearchEnumerator}s can be chained using one of the chainable methods # (e.g. {ObjSearchEnumerator#and} and {ObjSearchEnumerator#and_not}). # # @param [Symbol, String, Array] field See {ObjSearchEnumerator#and} for details # @param [Symbol, String] operator See {ObjSearchEnumerator#and} for details # @param [String, Array] value See {ObjSearchEnumerator#and} for details # @param [Hash] boost See {ObjSearchEnumerator#and} for details # @return [ObjSearchEnumerator] # @api public def where(field, operator, value, boost = nil) ObjSearchEnumerator.new(workspace) .and(field, operator, value, boost) end # Returns an {ObjSearchEnumerator} of all {BasicObj Obj}s. # @return [ObjSearchEnumerator] # @api public def all ObjSearchEnumerator.new(workspace, 1000) end # Returns an {ObjSearchEnumerator} of all {BasicObj Obj}s with the given +obj_class+. # @param [String] obj_class name of the object class. # @return [ObjSearchEnumerator] # @api public def find_all_by_obj_class(obj_class) all.and(:_obj_class, :equals, obj_class) end def find_one_by(view, value, obj_class_name = nil) find_by(view, [value], obj_class_name).first.min_by(&:id) end def find_by_parent_path(path) find_by(:ppath, [path]).first end def find_by_parent_path_including_deleted(path) find_by_including_deleted(:ppath, [path]).first end def find_by_id(id) find_by(:id, [id]).first.first end def find_by_paths(paths) find_by(:path, paths).map(&:first) end def changes(offset, batch_size) where('_modification', 'equals', ['new', 'edited', 'deleted']) .batch_size(batch_size) .offset(offset) .include_deleted end private def find_using(id_or_list, method) case id_or_list when Array send(method, :id, id_or_list).map(&:first).compact else obj = send(method, :id, [id_or_list.to_s]).first.first obj or raise ResourceNotFound, "Could not find Obj with id #{id_or_list}" end end def find_by(view, keys, obj_class_name = nil) find_by_including_deleted(view, keys, obj_class_name).each { |objs| objs.reject!(&:deleted?) } end # Accepts the name of an "obj_by" view, a list of keys. # Returns a list of lists of Objs: a list of Objs for each given key. def find_by_including_deleted(view, keys, obj_class_name = nil) revision = workspace.revision CmsBackend.find_obj_data_by(revision, view, keys).map do |obj_datas| if obj_class_name obj_datas = obj_datas.select do |obj_data| obj_class_name == obj_data.value_of('_obj_class') end end obj_datas.map do |obj_data| obj = BasicObj.instantiate(obj_data) obj.revision = revision obj end end end end end