infopark_fiona7 0.71.1.12 → 1.1.0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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