infopark_fiona7 0.71.1.12 → 1.1.0.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/fiona7_ui.js +67 -0
  3. data/app/assets/stylesheets/fiona7_ui.css.scss +29 -0
  4. data/app/controllers/fiona7/release_controller.rb +37 -75
  5. data/app/controllers/scrivito/cms_dispatch_controller.rb +2 -12
  6. data/app/controllers/scrivito/objs_controller.rb +41 -13
  7. data/app/controllers/scrivito/webservice_controller.rb +4 -3
  8. data/app/views/fiona7/release/preview.html.erb +73 -0
  9. data/config/routes.rb +3 -1
  10. data/infopark_fiona7.gemspec +1 -1
  11. data/lib/fiona7/assert.rb +4 -0
  12. data/lib/fiona7/attribute_name_mangler.rb +19 -0
  13. data/lib/fiona7/attribute_names_from_cms.rb +17 -0
  14. data/lib/fiona7/attribute_names_from_queries.rb +17 -0
  15. data/lib/fiona7/builder/obj_builder.rb +3 -2
  16. data/lib/fiona7/builder/obj_updater.rb +2 -2
  17. data/lib/fiona7/builder/widget_builder.rb +1 -1
  18. data/lib/fiona7/builder/widget_updater.rb +2 -2
  19. data/lib/fiona7/complex_object.rb +24 -0
  20. data/lib/fiona7/controllers/rest_api/obj_controller.rb +96 -24
  21. data/lib/fiona7/controllers/rest_api/workspace_controller.rb +23 -2
  22. data/lib/fiona7/engine.rb +11 -23
  23. data/lib/fiona7/facet_builder.rb +136 -0
  24. data/lib/fiona7/json/reverse_obj_decorator.rb +2 -0
  25. data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk.rb +68 -10
  26. data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk_slave.rb +66 -14
  27. data/lib/fiona7/mode_switch/views.rb +2 -2
  28. data/lib/fiona7/naive_search_engine.rb +40 -5
  29. data/lib/fiona7/obj_class_name_demangler.rb +11 -0
  30. data/lib/fiona7/obj_class_name_mangler.rb +11 -0
  31. data/lib/fiona7/obj_classes_from_cms.rb +14 -0
  32. data/lib/fiona7/obj_classes_from_queries.rb +11 -0
  33. data/lib/fiona7/recursive_object_finder.rb +149 -0
  34. data/lib/fiona7/routers/rest_api.rb +14 -1
  35. data/lib/fiona7/routing_monkey_patch.rb +5 -2
  36. data/lib/fiona7/scrivito_patches/attribute_serializer.rb +1 -1
  37. data/lib/fiona7/scrivito_patches/basic_obj.rb +4 -9
  38. data/lib/fiona7/scrivito_patches/basic_widget.rb +0 -9
  39. data/lib/fiona7/scrivito_patches/cms_backend.rb +11 -16
  40. data/lib/fiona7/scrivito_patches/cms_rest_api.rb +1 -1
  41. data/lib/fiona7/scrivito_patches/cms_routing.rb +50 -33
  42. data/lib/fiona7/scrivito_patches/link_parser.rb +6 -13
  43. data/lib/fiona7/scrivito_patches/log_subscriber.rb +18 -0
  44. data/lib/fiona7/scrivito_patches/preset_routes.rb +47 -0
  45. data/lib/fiona7/scrivito_patches/routing_extensions.rb +48 -0
  46. data/lib/fiona7/search_engine.rb +4 -0
  47. data/lib/fiona7/type_loader.rb +5 -4
  48. data/lib/fiona7/type_register.rb +13 -27
  49. data/lib/fiona7/type_synchronizer.rb +8 -6
  50. data/lib/fiona7/verity_search_engine.rb +77 -30
  51. data/lib/fiona7/version.rb +1 -1
  52. metadata +18 -13
  53. data/app/models/rails_connector/abstract_obj.rb +0 -24
  54. data/lib/fiona7/controllers/content_service/obj_controller.rb +0 -121
  55. data/lib/fiona7/controllers/content_service/workspace_controller.rb +0 -19
  56. data/lib/fiona7/recursive_link_resolver.rb +0 -93
  57. data/lib/fiona7/routers/content_service.rb +0 -19
  58. data/lib/fiona7/scrivito_patches/client_config.rb +0 -0
  59. data/lib/fiona7/scrivito_patches/controller_actions.rb +0 -6
  60. data/lib/fiona7/scrivito_patches/obj_class.rb +0 -16
  61. data/lib/fiona7/scrivito_patches/obj_data_from_rest.rb +0 -30
@@ -2,21 +2,14 @@ require 'scrivito/link_parser'
2
2
 
3
3
  module Scrivito
4
4
  class LinkParser
5
- alias_method :original_parse, :parse
6
-
7
- # Patch parse to handle numerical ids
8
- def parse(url)
9
- url = url.to_s if url
10
- original_parse(url)
11
- end
12
-
13
5
  # Patch to handle legacy mode
14
- def application_route?(uri)
15
- route_params = route(uri)
16
- route_params && (
17
- route_params[:controller] == 'scrivito/cms_dispatch' ||
18
- route_params[:controller] == 'rails_connector/cms_dispatch'
6
+ def dispatch_route_for(route_params)
7
+ if route_params && (
8
+ (route_params[:controller] == 'scrivito/cms_dispatch') ||
9
+ (route_params[:controller] == 'rails_connector/cms_dispatch')
19
10
  )
11
+ route_params
12
+ end
20
13
  end
21
14
  end
22
15
  end
@@ -0,0 +1,18 @@
1
+ module Scrivito
2
+ class LogSubscriber < ActiveSupport::LogSubscriber
3
+ def backend_request(event)
4
+ self.class.runtime += event.duration
5
+ return unless logger.debug?
6
+
7
+ duration = '(%.1fms)' % [event.duration]
8
+
9
+ param = event.payload[:params]
10
+ param_text = " #{param}" if param
11
+
12
+ verb_text = event.payload[:verb].upcase
13
+ path_text = event.payload[:path]
14
+
15
+ debug " Fiona7 #{verb_text} #{path_text}#{param_text} #{duration}"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,47 @@
1
+ module Scrivito
2
+ module PresetRoutes
3
+ def self.install_into(route_set)
4
+ return if Scrivito::Configuration.scrivito_route_enabled?
5
+
6
+ Scrivito::Configuration.with_scrivito_route_enabled do
7
+ route_set.draw do
8
+ scrivito_route '/', using: "homepage", via: :all
9
+
10
+ if Scrivito::Configuration.legacy_routing
11
+ scrivito_route ':id(/*slug)', using: "slug_id", via: :all
12
+ else
13
+ scrivito_route '(/)(*slug-):id', using: "slug_id", via: :all
14
+
15
+ match ':id(/*slug)', to: 'scrivito/legacy_redirect#index', via: :all, constraints: {
16
+ id: /[0-9]{4,}/
17
+ }
18
+ end
19
+
20
+ scrivito_route '/*permalink', using: "permalink", format: false, via: :all
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.install_slave_into(route_set)
26
+ return if Scrivito::Configuration.scrivito_route_enabled?
27
+
28
+ Scrivito::Configuration.with_scrivito_route_enabled do
29
+ route_set.draw do
30
+ scrivito_route '/f7(/)', using: "homepage", via: :all
31
+
32
+ if Scrivito::Configuration.legacy_routing
33
+ scrivito_route '/f7/:id(/*slug)', using: "slug_id", via: :all
34
+ else
35
+ scrivito_route '/f7/(*slug-):id', using: "slug_id", via: :all
36
+
37
+ match '/f7/:id(/*slug)', to: 'scrivito/legacy_redirect#index', via: :all, constraints: {
38
+ id: /[0-9]{4,}/
39
+ }
40
+ end
41
+
42
+ scrivito_route '/f7/*permalink', using: "permalink", format: false, via: :all
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,48 @@
1
+ module Scrivito
2
+
3
+ module RoutingExtensions
4
+
5
+ def scrivito_route(path, using:, format: nil, via: :get)
6
+ assert_scrivito_route_enabled
7
+ # @set is a ActionDispatch::Routing::RouteSet
8
+ # see: http://git.io/v4UYF and http://git.io/v4UOI
9
+ route_set = @set
10
+
11
+ route_name = using.to_sym
12
+
13
+ route = Route.register(route_set, route_name)
14
+
15
+ options = {
16
+ to: 'scrivito/cms_dispatch#index',
17
+ via: via,
18
+ format: format,
19
+ as: route.helper_name,
20
+ }
21
+
22
+ # removed fixed length constraint on ids
23
+ options[:constraints] = {id: /[0-9]{4,}/} if route_name == :slug_id
24
+
25
+ begin
26
+ match(path, options)
27
+ rescue ArgumentError => error
28
+ if error.message.include?(route.helper_name)
29
+ raise ScrivitoError,
30
+ %(You have already defined a Scrivito route with the name "#{route_name}".)
31
+ else
32
+ raise error
33
+ end
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def assert_scrivito_route_enabled
40
+ unless Scrivito::Configuration.scrivito_route_enabled?
41
+ raise ScrivitoError, 'The preset routes are still enabled. Please disable them by ' \
42
+ 'setting the configuration "inject_preset_routes" to false before using scrivito_route'
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -16,5 +16,9 @@ module Fiona7
16
16
  def results
17
17
  raise "Not implemented"
18
18
  end
19
+
20
+ def objects
21
+ raise "Not implemented"
22
+ end
19
23
  end
20
24
  end
@@ -1,3 +1,6 @@
1
+ require "fiona7/obj_class_name_mangler"
2
+ require "fiona7/obj_class_name_demangler"
3
+
1
4
  module Fiona7
2
5
  class TypeLoader
3
6
  class AttributeTypeHelper
@@ -20,8 +23,7 @@ module Fiona7
20
23
 
21
24
  def initialize(obj_class)
22
25
  self.obj_class = obj_class
23
- self.name_aliaser = TypeRegister::NameAliaser.new(virtual: obj_class)
24
- self.rc_obj_class = RailsConnector::Meta::EagerLoader.instance.obj_class(self.name_aliaser.real_obj_class)
26
+ self.rc_obj_class = RailsConnector::Meta::EagerLoader.instance.obj_class(Fiona7::ObjClassNameMangler.new(self.obj_class).mangle)
25
27
 
26
28
  end
27
29
 
@@ -43,7 +45,7 @@ module Fiona7
43
45
  self.rc_obj_class.custom_attributes.each do |real_name, cms_attribute|
44
46
  next if Fiona7::Initializer::ATTRIBUTES_MAP.key?(real_name)
45
47
 
46
- # TODO: move this to a better place
48
+ # TODO: move this to a better place ~> AttributeNameDemangler
47
49
  if Fiona7.mode == :standalone
48
50
  virtual_name = real_name.sub("s_#{self.rc_obj_class.name}__", "")
49
51
  else
@@ -60,7 +62,6 @@ module Fiona7
60
62
  end
61
63
 
62
64
  protected
63
- attr_accessor :name_aliaser
64
65
  attr_writer :obj_class, :rc_obj_class
65
66
 
66
67
  end
@@ -2,6 +2,10 @@ require 'set'
2
2
  require 'singleton'
3
3
  require 'fiona7/type_loader'
4
4
  require 'fiona7/type_synchronizer'
5
+ require "fiona7/obj_class_name_mangler"
6
+ require "fiona7/obj_class_name_demangler"
7
+ require "fiona7/attribute_name_mangler"
8
+
5
9
 
6
10
  module Fiona7
7
11
  class TypeRegister
@@ -16,21 +20,6 @@ module Fiona7
16
20
  stringlist: :text
17
21
  }.freeze
18
22
 
19
- class NameAliaser
20
- attr_accessor :virtual_obj_class, :real_obj_class
21
-
22
- def initialize(input={})
23
- if input[:virtual]
24
- self.virtual_obj_class = input[:virtual]
25
- self.real_obj_class = input[:virtual].gsub('::', '__')
26
- elsif input[:real]
27
- self.real_obj_class = input[:real]
28
- self.virtual_obj_class = input[:real].gsub('__','::')
29
- else
30
- raise "Invalid input for NameAliaser"
31
- end
32
- end
33
- end
34
23
  class TypeDefinition
35
24
  class Attribute < Struct.new(:name, :type, :real_name, :real_type, :values)
36
25
  class Core < Struct.new(:name, :type)
@@ -49,31 +38,24 @@ module Fiona7
49
38
  end
50
39
 
51
40
  attr_accessor :name
41
+ attr_accessor :real_name
52
42
  attr_accessor :attrs
53
43
  attr_accessor :aliaser
54
44
 
55
45
  def initialize(name)
56
46
  self.name = name
47
+ self.real_name = Fiona7::ObjClassNameMangler.new(name).mangle
57
48
  self.attrs = Set.new
58
- self.aliaser = NameAliaser.new(virtual: name)
59
49
  end
60
50
 
61
- def real_name
62
- self.aliaser.real_obj_class
63
- end
64
51
 
65
52
  def virtual_name
66
- self.aliaser.virtual_obj_class
53
+ self.name
67
54
  end
68
55
 
69
56
  def add_attr(name, type, real_name=nil, real_type=nil, values=nil)
70
57
  real_type ||= TYPE_MAP[type.to_sym] || type
71
- # TODO: move this to a better place
72
- if Fiona7.mode == :standalone
73
- real_name ||= "s_#{self.real_name}__#{name}"
74
- else
75
- real_name ||= name
76
- end
58
+ real_name = Fiona7::AttributeNameMangler.new(name, self.name).mangle
77
59
  self.attrs << Attribute.new(name.to_s, type.to_sym, real_name.to_s, real_type.to_sym, values)
78
60
  end
79
61
 
@@ -125,6 +107,10 @@ module Fiona7
125
107
  self.cms_def_present?(obj_class)
126
108
  end
127
109
 
110
+ def read_all
111
+ self.cms_defs.values
112
+ end
113
+
128
114
  def write?(obj_class)
129
115
  true &&
130
116
  self.usr_def_present?(obj_class) &&
@@ -133,7 +119,7 @@ module Fiona7
133
119
  end
134
120
 
135
121
  def read_mangled(obj_class)
136
- read(NameAliaser.new(real: obj_class).virtual_obj_class)
122
+ read(Fiona7::ObjClassNameDemangler.new(obj_class).demangle)
137
123
  end
138
124
 
139
125
  def read(obj_class)
@@ -1,31 +1,33 @@
1
1
  require 'fiona7/builder/obj_class_builder'
2
2
  require 'fiona7/builder/obj_class_updater'
3
+ require 'fiona7/obj_class_name_mangler'
3
4
 
4
5
  module Fiona7
5
6
  class TypeSynchronizer
6
- attr_reader :type_definition, :name_aliaser
7
+ attr_reader :type_definition
7
8
 
8
9
  def initialize(type_definition)
9
10
  self.type_definition = type_definition
10
- self.name_aliaser = TypeRegister::NameAliaser.new(virtual: type_definition.name)
11
+ self.real_obj_class = Fiona7::ObjClassNameMangler.new(type_definition.name).mangle
11
12
  end
12
13
 
13
14
  def synchronize
14
15
  return if skip_this_class?
15
16
 
16
17
  Reactor::Sudo.su(Fiona7.root) do
17
- if RailsConnector::ObjClass.exists?(:obj_class_name => self.name_aliaser.real_obj_class)
18
+ if RailsConnector::ObjClass.exists?(:obj_class_name => self.real_obj_class)
18
19
  Fiona7::Builder::ObjClassUpdater.new(self.builder_values).build
19
20
  else
20
21
  Fiona7::Builder::ObjClassBuilder.new(self.builder_values).build
21
22
  end
22
23
 
23
- RailsConnector::Meta::EagerLoader.instance.forget_obj_class(self.name_aliaser.real_obj_class)
24
+ RailsConnector::Meta::EagerLoader.instance.forget_obj_class(self.real_obj_class)
24
25
  end
25
26
  end
26
27
 
27
28
  protected
28
- attr_writer :type_definition, :name_aliaser
29
+ attr_writer :type_definition
30
+ attr_accessor :real_obj_class
29
31
 
30
32
  def skip_this_class?
31
33
  case self.type_definition.name
@@ -38,7 +40,7 @@ module Fiona7
38
40
 
39
41
  def builder_values
40
42
  {
41
- name: self.name_aliaser.real_obj_class,
43
+ name: self.real_obj_class,
42
44
  attributes: self.builder_attributes
43
45
  }
44
46
  end
@@ -2,18 +2,29 @@ require "fiona7/search_engine"
2
2
  require "rails_connector/verity_search_request"
3
3
  require "fiona7/custom_verity_accessor"
4
4
 
5
+ require "fiona7/attribute_names_from_queries"
6
+ require "fiona7/attribute_names_from_cms"
7
+
5
8
  module Fiona7
6
9
  class VeritySearchEngine < SearchEngine
7
- def results
10
+ def initialize(*args)
11
+ super
8
12
  # scrivito sdk likes to send a query with limit 0
9
13
  # just to fetch the total count of results
10
14
  # but verity does not like limit 0 very much
11
15
  if @limit == 0
12
16
  @limit = 1
13
17
  end
18
+ end
19
+
20
+ def results
21
+ @results || fetch_results
22
+ end
23
+
24
+ def objects
25
+ return @objects if @objects
14
26
 
15
- construct_search_request
16
- fetch_results
27
+ @results || fetch_results
17
28
  fetch_objects
18
29
  end
19
30
 
@@ -24,12 +35,14 @@ module Fiona7
24
35
  options[:sort_order] = [["score", "desc"], ["lastChanged", "desc"]]
25
36
  options[:limit] = @limit.to_i if @limit
26
37
  options[:offset] = @offset.to_i if @offset.to_i > 0
27
- @search_request = VeritySearchRequest.new(@query, options, @klass == Fiona7::ReleasedObj)
38
+ VeritySearchRequest.new(@query, options, @klass == Fiona7::ReleasedObj)
28
39
  end
29
40
 
30
41
  def fetch_results
31
- @results = @search_request.fetch_hits
32
- @count = @results.total_hits
42
+ @search_request = construct_search_request
43
+ @search_response = @search_request.fetch_hits
44
+ @count = @search_response.total_hits
45
+ @results = @search_response.map(&:id)
33
46
  end
34
47
 
35
48
  def fetch_objects
@@ -39,7 +52,9 @@ module Fiona7
39
52
 
40
53
  class VeritySearchRequest < ::RailsConnector::VeritySearchRequest
41
54
  def initialize(query, options={}, use_released=false)
55
+ @query = query
42
56
  @query_string = build_query_string(query)
57
+ puts "VERITY QUERY:\n#{@query_string}"
43
58
  @options = default_search_options.merge(options)
44
59
  @use_released ||= use_released
45
60
  end
@@ -69,39 +84,44 @@ module Fiona7
69
84
 
70
85
  def complex_query_string(query)
71
86
  conditions = query.map do |q|
72
- unresolved_field = q[:field]
73
- resolved_field = resolve_field_name(unresolved_field)
87
+ field = resolve_field_name(q[:field])
74
88
 
75
- # paths are sadly not in the search index.
76
- next if resolved_field == :visiblePath
89
+ # paths are sadly not in the search index by default.
90
+ next if field == :visiblePath
77
91
 
78
92
  case q[:operator]
79
93
  when :equal
80
- if unresolved_field == :_modification
94
+ if field == :__dummy__
81
95
  '("edited" <#IN> state)'
82
96
  else
83
- field_operator_value(resolved_field, "=", q[:value])
97
+ search_in(field, q[:value])
84
98
  end
85
99
  when :search
86
- if unresolved_field == :'*'
100
+ if field == :'*'
87
101
  full_text_query_string(as_values_array(q[:value]))
88
102
  else
89
- field_operator_value(resolved_field, "<#CONTAINS>", q[:value])
103
+ values = as_values_array(q[:value])
104
+ values = values.map {|v| "*#{v}*" }
105
+ search_in(field, values)
90
106
  end
91
107
  when :greater_than
92
- field_operator_value(resolved_field, ">", q[:value])
108
+ search_term(field, ">", q[:value])
93
109
  when :less_than
94
- field_operator_value(resolved_field, "<", q[:value])
110
+ search_term(field, "<", q[:value])
95
111
  when :prefix, :prefix_search
96
- if unresolved_field == :'*'
112
+ if field == :'*'
97
113
  values = as_values_array(q[:value])
98
114
  values = values.map {|v| "#{v}*" }
99
115
  full_text_query_string(values)
100
116
  else
101
117
  values = as_values_array(q[:value])
102
118
  values = values.map {|v| "#{v}*" }
103
- values_operator_field(values, "<#IN>", resolved_field)
119
+ search_in(field, values)
104
120
  end
121
+ when :__in__
122
+ search_in(field, q[:value])
123
+ when :__not_in__
124
+ search_not_in(field, q[:value])
105
125
  else
106
126
  raise "Operator: #{q[:operator]} not supported"
107
127
  end
@@ -114,31 +134,40 @@ module Fiona7
114
134
  end
115
135
  end
116
136
 
117
- def field_operator_value(field, operator, values)
137
+ def search_in(field, values)
118
138
  values = [values] unless values.kind_of?(Array)
139
+ if [:objClass, :obj_id, :permalink, :lastChanged, :name].include?(field)
140
+ fields = [field.to_s]
141
+ else
142
+ fields = Fiona7::AttributeNamesFromQueries.new(field.to_s, @query).attributes || Fiona7::AttributeNamesFromCms.new(field.to_s).attributes || [field.to_s]
143
+ end
119
144
 
120
- condition = values.map do |value|
121
- %|(#{field} #{operator} "#{self.class.sanitize(value)}")|
122
- end.join(", ")
145
+ sanitized_values = values.map {|v| "`#{self.class.sanitize(v)}`" }
146
+ %|(<#OR> ((#{sanitized_values.join(', ')}) <#IN> (#{fields.join(', ')})))|
147
+ end
123
148
 
124
- %|(<#OR> #{condition})|
149
+ def search_not_in(field, values)
150
+ %|(<#NOT> (#{search_in(field, values)}))|
125
151
  end
126
152
 
127
- def values_operator_field(values, operator, field)
153
+ def search_term(field, operator, values, options={})
128
154
  values = [values] unless values.kind_of?(Array)
155
+ join_op = options[:join] || "OR"
156
+ negate = options[:negate] ? "<#NOT> " : ""
157
+ reverse = options[:reverse]
129
158
 
130
159
  condition = values.map do |value|
131
- %|("#{self.class.sanitize(value)}" #{operator} #{field})|
160
+ if reverse
161
+ %|(#{negate}`#{self.class.sanitize(value)}` #{operator} #{field})|
162
+ else
163
+ %|(#{negate}#{field} #{operator} `#{self.class.sanitize(value)}`)|
164
+ end
132
165
  end.join(", ")
133
166
 
134
- %|(<#OR> #{condition})|
167
+ %|(<##{join_op}> #{condition})|
135
168
  end
136
169
 
137
170
  def resolve_field_name(field)
138
- if Fiona7.mode != :legacy
139
- Rails.logger.error("This method is not compatible with modes other than legacy")
140
- end
141
-
142
171
  case field
143
172
  when :_obj_class
144
173
  :objClass
@@ -212,6 +241,24 @@ module Fiona7
212
241
  conditions[:notWidget] = '(objClass <#ENDS/NOT> "Widget")'
213
242
  conditions
214
243
  end
244
+
245
+ def find_obj_class_in_query(query)
246
+ obj_class_q = query.find {|q| q[:operator] == :equal && q[:field] == :_obj_class && !q[:value].kind_of?(Array) }
247
+ obj_class_q[:value] if obj_class_q
248
+ end
249
+
250
+ def real_field_name_in_obj_class(obj_class, field)
251
+ type_def = Fiona7::TypeRegister.instance.read(obj_class)
252
+ if type_def
253
+ attribute = type_def.find_attribute(field)
254
+ if attribute
255
+ field = attribute.real_name
256
+ end
257
+ end
258
+
259
+ field
260
+ end
215
261
  end
262
+
216
263
  end
217
264
  end