infopark_fiona7 1.2.0.2.3 → 1.5.2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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) ||