infopark_fiona7 1.2.0.2.3 → 1.5.2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +33 -0
  3. data/app/assets/javascripts/fiona7_ui.js +82 -23
  4. data/app/assets/javascripts/scrivito_patches/ajax.js +222 -0
  5. data/app/assets/javascripts/scrivito_patches/ajax_error_handling.js +24 -0
  6. data/app/assets/javascripts/scrivito_patches/attribute_serializer.js +259 -0
  7. data/app/assets/javascripts/scrivito_patches/base_obj_path.js +17 -0
  8. data/app/assets/javascripts/scrivito_patches/binary_utils.js +33 -0
  9. data/app/assets/javascripts/scrivito_patches/cms_rest_api.js +490 -0
  10. data/app/assets/javascripts/scrivito_patches/models/api/basic_obj.js +650 -0
  11. data/app/assets/javascripts/scrivito_patches/models/binary_field_element.js +53 -0
  12. data/app/assets/javascripts/scrivito_patches/models/obj.js +74 -239
  13. data/app/assets/javascripts/scrivito_patches/obj_serializer.js +91 -0
  14. data/app/assets/stylesheets/fiona7.css.scss +12 -0
  15. data/app/assets/stylesheets/fiona7_ui.css.scss +18 -0
  16. data/app/controllers/fiona7/api_controller.rb +20 -0
  17. data/app/controllers/fiona7/sessions_controller.rb +2 -10
  18. data/app/controllers/fiona7_login_page_controller.rb +0 -3
  19. data/app/controllers/scrivito/obj_class_controller.rb +58 -0
  20. data/app/controllers/scrivito/objs_controller.rb +2 -38
  21. data/app/helpers/fiona7_override_helper.rb +25 -0
  22. data/app/views/fiona7/release/preview.html.erb +1 -1
  23. data/app/views/fiona7_login_page/index.html.erb +0 -6
  24. data/app/views/scrivito/ui/index.html.erb +2 -1
  25. data/app/views/scrivito/webservice/_workspace.json.jbuilder +8 -0
  26. data/config/locales/errors.yml +18 -0
  27. data/config/locales/workflow.yml +24 -0
  28. data/config/precedence_routes.rb +7 -14
  29. data/infopark_fiona7.gemspec +6 -4
  30. data/lib/fiona7/assert.rb +2 -2
  31. data/lib/fiona7/attribute_readers/factory.rb +4 -0
  32. data/lib/fiona7/attribute_type_mapper.rb +4 -1
  33. data/lib/fiona7/attribute_writers/binary_as_binary.rb +2 -2
  34. data/lib/fiona7/attribute_writers/binary_as_linklist.rb +2 -2
  35. data/lib/fiona7/attribute_writers/factory.rb +4 -0
  36. data/lib/fiona7/builder/indirect_blob_builder.rb +2 -2
  37. data/lib/fiona7/builder/lazy_blob_copier.rb +1 -1
  38. data/lib/fiona7/builder/obj_builder.rb +45 -12
  39. data/lib/fiona7/controllers/rest_api/error_handler.rb +49 -0
  40. data/lib/fiona7/controllers/rest_api/obj_controller.rb +34 -20
  41. data/lib/fiona7/controllers/rest_api/session_controller.rb +13 -0
  42. data/lib/fiona7/engine.rb +7 -10
  43. data/lib/fiona7/facet_builder.rb +5 -1
  44. data/lib/fiona7/naive_search_engine.rb +9 -0
  45. data/lib/fiona7/routers/rest_api.rb +17 -0
  46. data/lib/fiona7/scrivito_patches/attribute_content.rb +28 -0
  47. data/lib/fiona7/scrivito_patches/cms_routing.rb +14 -31
  48. data/lib/fiona7/scrivito_patches/page_config.rb +1 -0
  49. data/lib/fiona7/scrivito_user.rb +3 -2
  50. data/lib/fiona7/type_register.rb +4 -0
  51. data/lib/fiona7/verity_search_engine.rb +6 -17
  52. data/lib/fiona7/version.rb +1 -1
  53. data/lib/fiona7/workspace.rb +2 -0
  54. metadata +28 -14
  55. data/app/assets/javascripts/scrivito_patches/models/ajax.js +0 -99
  56. data/app/assets/javascripts/scrivito_patches/models/blob.js +0 -50
@@ -0,0 +1,24 @@
1
+ de:
2
+ fiona7:
3
+ workflow:
4
+ actions: Aktionen
5
+ edit: Bearbeiten
6
+ take: Übernehmen
7
+ forward: Weiterleiten
8
+ commit: Einreichen
9
+ sign: Abzeichnen
10
+ reject: Ablehnen
11
+ release: Freigeben
12
+
13
+
14
+ en:
15
+ fiona7:
16
+ workflow:
17
+ actions: Actions
18
+ edit: Edit
19
+ take: Take
20
+ forward: Forward
21
+ commit: Commit
22
+ sign: Sign
23
+ reject: Reject
24
+ release: Release
@@ -4,6 +4,7 @@ Rails.application.routes.draw do
4
4
  end
5
5
 
6
6
  Fiona7::Engine.routes.draw do
7
+ match '/_f7/tenants/:name/perform', to: 'fiona7/api#perform', via: [:post, :put]
7
8
  get '/_b/:id(/:name)' => 'fiona7/blobs#show', as: :fiona7_blob
8
9
 
9
10
  match '/_b/:id(/:name)' => 'fiona7/blobs#query', as: :fiona7_blob_meta, via: [:head]
@@ -30,7 +31,7 @@ Scrivito::SdkEngine.routes.draw do
30
31
  get 'scrivito/*application_path', to: 'scrivito/ui#index', format: false
31
32
 
32
33
  scope '__scrivito', module: 'scrivito' do
33
- get ':id', to: 'cms_dispatch#index', as: :base_id, constraints: {id: /\h{4,}/}
34
+ get ':id', to: 'cms_dispatch#index', as: :base_id, constraints: {id: /\d+/} # <-- patch here
34
35
 
35
36
  resources :objs, controller: 'objs', only: [:show, :create, :update, :destroy],
36
37
  defaults: {format: :json} do
@@ -44,15 +45,10 @@ Scrivito::SdkEngine.routes.draw do
44
45
  get :widget_class_selection
45
46
  get :widget_modification
46
47
  get :conflicting_workspaces
47
- get :is_outdated
48
48
  get :binary_no_cache
49
49
 
50
- post :copy
51
- post :duplicate
52
-
53
50
  put :revert
54
51
  put :restore
55
- put :mark_resolved
56
52
  put :revert_widget
57
53
  put :restore_widget
58
54
  put :transfer_modifications
@@ -60,20 +56,17 @@ Scrivito::SdkEngine.routes.draw do
60
56
  end
61
57
 
62
58
  resources :tasks, controller: 'tasks', only: [:show], defaults: {format: :json}
59
+ resources :sessions, controller: 'sessions', only: [:update], defaults: {format: :json}
63
60
 
64
- get 'blobs/upload_permission' => 'blobs#upload_permission', defaults: {format: :json}
65
- put 'blobs/activate_upload' => 'blobs#activate_upload', defaults: {format: :json}
66
- put 'blobs/copy' => 'blobs#copy', defaults: {format: :json}
61
+ get 'obj_class/:obj_class_name/defaults', to: 'obj_class#defaults'
62
+ put 'resolve_paths' => 'resolve_paths#resolve', defaults: {format: :json}
67
63
 
68
64
  resources :workspaces,
69
65
  controller: 'workspaces',
70
- only: [:index, :show, :create, :destroy],
66
+ only: [:index, :show],
71
67
  defaults: {format: :json} do
72
68
  member do
73
- put :rename
74
- put :memberships
75
- put :rebase
76
- put :publish
69
+ put :publish_approval
77
70
  get :check
78
71
  end
79
72
  end
@@ -14,15 +14,17 @@ Gem::Specification.new do |s|
14
14
  s.summary = "scrivito-compatible interface for classic Fiona"
15
15
  s.description = "scrivito-compatible interface for classic Fiona"
16
16
 
17
- s.files = Dir["{app,config,db,lib}/**/*", "Rakefile", "README.md", "infopark_fiona7.gemspec"]
17
+ s.files = Dir["{app,config,db,lib}/**/*", "Rakefile", "README.md", "infopark_fiona7.gemspec"].reject do |f|
18
+ /^app\/assets.*\.es6\.js$/ =~ f
19
+ end.sort
18
20
 
19
21
  s.add_dependency "rails", "~> 4.2.2"
20
- s.add_dependency "scrivito", "= 1.2.0"
22
+ s.add_dependency "scrivito", "= 1.5.2"
21
23
  s.add_dependency "scrivito_sdk"
22
24
  s.add_dependency "scrivito_editors"
23
25
  s.add_dependency "infopark_fiona_connector", "= 7.0.1.beta2"
24
- s.add_dependency "infopark_reactor", ">= 1.23.1"
26
+ s.add_dependency "infopark_reactor", ">= 1.22.4"
25
27
  s.add_dependency "mini_magick"
26
- s.add_dependency "jquery-ui-rails", "< 6.0.0"
27
28
  #s.add_development_dependency "ruby-prof"
29
+ s.add_development_dependency "scrivito_development"
28
30
  end
data/lib/fiona7/assert.rb CHANGED
@@ -2,11 +2,11 @@ module Fiona7
2
2
  class Assert
3
3
  class << self
4
4
  def constraint(condition, message, code=418)
5
- raise Scrivito::ClientError.new(message, code) unless condition
5
+ raise Scrivito::ClientError.new(message, http_code: code) unless condition
6
6
  end
7
7
 
8
8
  def input(condition, message, code=422)
9
- raise Scrivito::ClientError.new(message, code) unless condition
9
+ raise Scrivito::ClientError.new(message, http_code: code) unless condition
10
10
  end
11
11
 
12
12
  def success(condition, message)
@@ -49,6 +49,10 @@ module Fiona7
49
49
  Fiona7::AttributeReaders::MultienumAsMultienum
50
50
  when [:number, :string], [:number, :text]
51
51
  Fiona7::AttributeReaders::NumberAsString
52
+ when [:integer, :string], [:integer, :text]
53
+ Fiona7::AttributeReaders::NumberAsString
54
+ when [:float, :string], [:float, :text]
55
+ Fiona7::AttributeReaders::NumberAsString
52
56
  when [:html, :html]
53
57
  Fiona7::AttributeReaders::HtmlAsHtml
54
58
  when [:binary, :linklist]
@@ -6,6 +6,7 @@ module Fiona7
6
6
  def initialize(obj_class, source=Fiona7.custom_attribute_types)
7
7
  self.custom = CustomAttributeTypeMapper.new(obj_class, source)
8
8
  self.built_in = BuiltInTypeMapper.new(obj_class)
9
+ self.obj_class = obj_class
9
10
  end
10
11
 
11
12
  def call(attribute, virtual_type)
@@ -16,7 +17,7 @@ module Fiona7
16
17
  end
17
18
 
18
19
  protected
19
- attr_accessor :custom, :built_in
20
+ attr_accessor :custom, :built_in, :obj_class
20
21
 
21
22
  def validate!(attribute, mapped_type)
22
23
  [:string, :text, :enum, :multienum,
@@ -53,6 +54,8 @@ module Fiona7
53
54
  linklist: :linklist,
54
55
  string: :string,
55
56
  date: :date,
57
+ float: :string,
58
+ integer: :string,
56
59
  html: :html,
57
60
  enum: :enum,
58
61
  multienum: :multienum,
@@ -43,7 +43,7 @@ module Fiona7
43
43
  # standard handling!
44
44
  self.obj.set(attribute_name.to_s, self.upload_file(file))
45
45
  else
46
- ext = ::File.extname(file.path).to_s[1..-1]
46
+ ext = ::File.extname(file.path).to_s[1..-1].to_s.downcase
47
47
  self.obj.upload(file, ext)
48
48
  end
49
49
  end
@@ -53,7 +53,7 @@ module Fiona7
53
53
  # standard handling!
54
54
  self.obj.set(attribute_name.to_s, self.upload_uploaded_file(file))
55
55
  else
56
- ext = ::File.extname(file.original_filename).to_s[1..-1]
56
+ ext = ::File.extname(file.original_filename).to_s[1..-1].to_s.downcase
57
57
  self.obj.upload(file.open, ext)
58
58
  end
59
59
  end
@@ -55,7 +55,7 @@ module Fiona7
55
55
  # standard handling!
56
56
  self.obj.set(attribute_name.to_s, self.upload_file(file))
57
57
  else
58
- ext = ::File.extname(file.path).to_s[1..-1]
58
+ ext = ::File.extname(file.path).to_s[1..-1].to_s.downcase
59
59
  self.obj.upload(file, ext)
60
60
  end
61
61
  end
@@ -65,7 +65,7 @@ module Fiona7
65
65
  # standard handling!
66
66
  self.obj.set(attribute_name.to_s, self.upload_uploaded_file(file))
67
67
  else
68
- ext = ::File.extname(file.original_filename).to_s[1..-1]
68
+ ext = ::File.extname(file.original_filename).to_s[1..-1].to_s.downcase
69
69
  self.obj.upload(file.open, ext)
70
70
  end
71
71
  end
@@ -56,6 +56,10 @@ module Fiona7
56
56
  Fiona7::AttributeWriters::MultienumAsMultienum
57
57
  when [:number, :string], [:number, :text]
58
58
  Fiona7::AttributeWriters::NumberAsString
59
+ when [:integer, :string], [:integer, :text]
60
+ Fiona7::AttributeWriters::NumberAsString
61
+ when [:float, :string], [:float, :text]
62
+ Fiona7::AttributeWriters::NumberAsString
59
63
  when [:html, :html]
60
64
  Fiona7::AttributeWriters::HtmlAsHtml
61
65
  when [:binary, :linklist]
@@ -16,8 +16,8 @@ module Fiona7
16
16
  end
17
17
 
18
18
  parent = ensure_parent_exists(parent_path)
19
- ext = ::File.extname(@filename).to_s[1..-1]
20
- name = ::File.basename(@filename, '.' + ext.to_s)
19
+ ext = ::File.extname(@filename).to_s[1..-1].to_s.downcase
20
+ name = ::File.basename(@filename, '.' + ext)
21
21
  obj_class = if ['jpg', 'jpeg', 'gif', 'png', 'tif', 'tiff'].include?(ext)
22
22
  'X_Image'
23
23
  else
@@ -154,7 +154,7 @@ module Fiona7
154
154
  def split_filename(filename)
155
155
  return unless filename
156
156
 
157
- ext = ::File.extname(filename)[1..-1]
157
+ ext = ::File.extname(filename).to_s[1..-1].to_s.downcase
158
158
  base = ::File.basename(filename, ::File.extname(filename))
159
159
 
160
160
  return base, ext
@@ -19,10 +19,53 @@ require 'fiona7/attribute_writers/factory'
19
19
 
20
20
  module Fiona7
21
21
  module Builder
22
+ class ParamPreprocessor
23
+ def self.call(*args)
24
+ self.new.call(*args)
25
+ end
26
+
27
+ def call(params)
28
+ remove_rack_formdata_workaround(params.symbolize_keys)
29
+ end
30
+
31
+ protected
32
+ # Rack is unable to handle the data format mandated by scrivito:
33
+ # obj[_widget_pool][somewidget][widget_attr][][widgetlist]
34
+ # obj[_widget_pool][somewidget][widget_attr][][]=otherwidget1
35
+ # obj[_widget_pool][somewidget][widget_attr][][]=otherwidget2
36
+ #
37
+ # thus we introduce an extended format to work around this
38
+ # problem and still be able to send API requests through
39
+ # form-data:
40
+ #
41
+ # obj[_widget_pool][somewidget][widget_attr][][widgetlist]
42
+ # obj[_widget_pool][somewidget][widget_attr][formdata$workaround][]=otherwidget1
43
+ # obj[_widget_pool][somewidget][widget_attr][formdata$workaround][]=otherwidget2
44
+ #
45
+ # This method normalizes the extended format to the usual one
46
+ def remove_rack_formdata_workaround(params)
47
+ if params.kind_of?(Hash)
48
+ if params.has_key?("formdata$workaround")
49
+ params["formdata$workaround"]
50
+ else
51
+ Hash[
52
+ params.map { |key, value|
53
+ [key, remove_rack_formdata_workaround(value)]
54
+ }
55
+ ]
56
+ end
57
+ elsif params.kind_of?(Array)
58
+ params.map { |value| remove_rack_formdata_workaround(value) }
59
+ else
60
+ params
61
+ end
62
+ end
63
+ end
64
+
22
65
  class ObjBuilder
23
66
 
24
67
  def initialize(values)
25
- @values = values.symbolize_keys
68
+ @values = ParamPreprocessor.call(values)
26
69
  # garbage
27
70
  @values.delete(:_modification)
28
71
  # revert command sends this info. which is silly.
@@ -138,23 +181,13 @@ module Fiona7
138
181
  full_text = ::YAML.load(@obj.attr_values["X_full_text"]) rescue {}
139
182
  full_text = {} unless full_text.kind_of?(Hash)
140
183
  full_text["_widget_pool"] ||= {}
141
- full_text["_widget_pool"].deep_merge!(filtered_widget_pool)
184
+ full_text["_widget_pool"].deep_merge!(@widget_pool)
142
185
  full_text.to_yaml
143
186
  rescue => e
144
187
  Rails.logger.error("Unable to store information for search engine: #{e.message}")
145
188
  nil
146
189
  end
147
190
 
148
- def filtered_widget_pool
149
- (@widget_pool || {}).deep_dup.tap do |filtered|
150
- filtered.each do |k, values|
151
- if values.kind_of?(Hash)
152
- values.delete_if {|k, v| !(v.respond_to?(:first) && ["string", "enum", "stringlist", "text", "html", "multienum"].include?(v.first)) }
153
- end
154
- end
155
- end.as_json
156
- end
157
-
158
191
  def name_and_parent_path_from_path(path)
159
192
  components = path.split('/')
160
193
  name = components.pop.presence
@@ -0,0 +1,49 @@
1
+ module Fiona7
2
+ class ErrorHandler
3
+ HANDLED_ERRORS = [
4
+ Reactor::Cm::MissingCredentials,
5
+ Reactor::Cm::XmlRequestError,
6
+ Reactor::NoWorkingVersion,
7
+ Reactor::NotPermitted,
8
+ Reactor::AlreadyReleased,
9
+ Fiona7::TypeSystemError
10
+ ]
11
+
12
+ attr_accessor :error, :locale
13
+
14
+ def initialize(error, locale = Scrivito::Configuration.ui_locale || I18n.locale)
15
+ self.error = error
16
+ self.locale = locale
17
+ end
18
+
19
+ def sdk_error
20
+ Scrivito::ApplicationError.new(self.processed_message)
21
+ end
22
+
23
+ def api_error
24
+ self.processed_message
25
+ end
26
+
27
+ def processed_message
28
+ Rails.logger.error(self.error.inspect)
29
+ Rails.logger.error(self.error.backtrace.join("\n"))
30
+
31
+ case self.error
32
+ when Reactor::Cm::XmlRequestError
33
+ self.error.message.gsub(/\[[0-9]+\] /, '')
34
+ when Reactor::Cm::MissingCredentials
35
+ I18n.t(:"fiona7.errors.missing_credentials", locale: self.locale)
36
+ when Reactor::NoWorkingVersion
37
+ I18n.t(:"fiona7.errors.no_working_version", locale: self.locale)
38
+ when Reactor::NotPermitted
39
+ I18n.t(:"fiona7.errors.not_permitted", locale: self.locale)
40
+ when Reactor::AlreadyReleased
41
+ I18n.t(:"fiona7.errors.already_released", locale: self.locale)
42
+ when Fiona7::TypeSystemError
43
+ I18n.t(:"fiona7.errors.type_system", locale: self.locale)
44
+ else
45
+ self.error.message
46
+ end
47
+ end
48
+ end
49
+ end
@@ -28,11 +28,12 @@ module Fiona7
28
28
  # some stupid creators give us an id. fck them
29
29
  values[:obj].delete("_id")
30
30
  values[:obj].delete(:_id)
31
+ path = values[:obj][:_path] || values[:obj]["_path"]
31
32
  # This is a hack to make it seem as if the root obj does not exist
32
- if values[:obj][:_path] != '/' && values[:obj]["_path"] != '/'
33
- obj = Builder::ObjBuilder.new(values[:obj].dup).build
33
+ if (path == "/") || ( obj = Fiona7::WriteObj.where(obj_class: 'X_Container', path: path).first )
34
+ obj = Builder::ObjUpdater.new(values[:obj].merge(_id: ((obj && obj.id) || 2001))).build
34
35
  else
35
- obj = Builder::ObjUpdater.new(values[:obj].merge(_id: 2001)).build
36
+ obj = Builder::ObjBuilder.new(values[:obj].dup).build
36
37
  end
37
38
 
38
39
  klass = EditedObj
@@ -75,6 +76,11 @@ module Fiona7
75
76
  return response
76
77
  end
77
78
 
79
+ def fetch_multiple2(workspace_id, payload)
80
+ revision_id = workspace_id == 'published' ? 'f' : 'b'
81
+ return fetch_multiple(revision_id, payload)
82
+ end
83
+
78
84
  def fetch_by_id(workspace_id, obj_id)
79
85
  klass = matching_class(workspace_id)
80
86
  obj = klass.where(obj_id: obj_id).first
@@ -137,9 +143,7 @@ module Fiona7
137
143
  sort = (conti[:sort_by] || params[:sort_by] || default_sort_by).to_sym
138
144
 
139
145
  if params[:query].present?
140
- normalize_query_params(params[:query])
141
-
142
- query = (params[:query] || []).dup
146
+ query = normalize_query_params(params[:query])
143
147
 
144
148
  Rails.logger.debug "Executing search for: #{query.inspect}"
145
149
  if use_naive_search_engine?(query)
@@ -152,9 +156,6 @@ module Fiona7
152
156
  result = search.results.map {|o_id| {id: o_id} }
153
157
  total = search.total
154
158
 
155
- # TODO: search engine should not destroy query :/
156
- query = (params[:query] || []).dup
157
-
158
159
  response = {
159
160
  total: total,
160
161
  results: result
@@ -185,8 +186,16 @@ module Fiona7
185
186
  def update(workspace_id, values)
186
187
  assert_writable(workspace_id)
187
188
 
188
- obj = Builder::ObjUpdater.new(values[:obj].dup.with_indifferent_access).build
189
189
  klass = EditedObj
190
+ id = (values[:obj]["_id"] || values[:obj][:_id]).to_s.to_i
191
+ # Scrivito SDK does not understand the difference
192
+ # between create and update
193
+ if (id < 2001 || id >= 2**31 || !klass.exists?(id))
194
+ return self.create(workspace_id, values)
195
+ end
196
+
197
+
198
+ obj = Builder::ObjUpdater.new(values[:obj].dup.with_indifferent_access).build
190
199
  decorated = Fiona7::JSON::ReverseObjDecorator.new(klass, obj)
191
200
 
192
201
  ::Fiona7.run_callbacks(:update_obj, obj.id)
@@ -261,32 +270,37 @@ module Fiona7
261
270
  # This is required because the sdk is inconsistent
262
271
  # in its usage of search operators
263
272
  def normalize_query_params(query_params)
273
+ result = []
264
274
  query_params.each do |query_param|
265
- query_param.symbolize_keys!
266
- query_param[:operator] = query_param[:operator].to_sym
267
- query_param[:field] = query_param[:field].to_sym
275
+ new_query_param = query_param.symbolize_keys
276
+ new_query_param[:operator] = query_param[:operator].to_sym
277
+ new_query_param[:field] = query_param[:field].to_sym
268
278
 
269
279
  case query_param[:operator]
270
280
  when :contains
271
- query_param[:operator] = :search
281
+ new_query_param[:operator] = :search
272
282
  when :contains_prefix
273
- query_param[:operator] = :prefix_search
283
+ new_query_param[:operator] = :prefix_search
274
284
  when :equals
275
- query_param[:operator] = :equal
285
+ new_query_param[:operator] = :equal
276
286
  when :starts_with
277
- query_param[:operator] = :prefix
287
+ new_query_param[:operator] = :prefix
278
288
  when :is_greater_than
279
- query_param[:operator] = :greater_than
289
+ new_query_param[:operator] = :greater_than
280
290
  when :is_less_than
281
- query_param[:operator] = :less_than
291
+ new_query_param[:operator] = :less_than
282
292
  end
293
+
294
+ result << new_query_param
283
295
  end
296
+
297
+ result
284
298
  end
285
299
 
286
300
  def use_naive_search_engine?(query)
287
301
  false ||
288
302
  query.empty? ||
289
- query.any? {|q| (q[:field].to_sym == :_path || q[:field].to_sym == :_name)&& (query.length == 1)} ||
303
+ query.any? {|q| (q[:field].to_sym == :_path || q[:field].to_sym == :_name)&& (q[:operator].to_sym == :equal || q[:operator].to_sym == :prefix || query.length == 1)} ||
290
304
  query.any? {|q| q[:field].to_sym == :_parent_path && (q[:operator].to_sym == :equal || query.length == 1)} ||
291
305
  (query.length == 1 && query.first[:field].to_sym == :_modification) ||
292
306
  (query.length == 1 && query.first[:field].to_sym == :_obj_class) ||