infopark_fiona7 1.5.5.5.1 → 1.6.1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +17 -0
  3. data/app/assets/javascripts/fiona7/task_list_dialog.js +2 -2
  4. data/app/assets/javascripts/fiona7/templates.js +1 -16
  5. data/app/assets/javascripts/fiona7/translations.js +22 -23
  6. data/app/assets/javascripts/fiona7_ui.js +56 -59
  7. data/app/assets/javascripts/scrivito_patches/base_obj_path.js +11 -5
  8. data/app/assets/javascripts/scrivito_patches/binary_request.js +53 -0
  9. data/app/assets/javascripts/scrivito_patches/client/ajax.js +122 -0
  10. data/app/assets/javascripts/scrivito_patches/{models/api → client}/basic_obj.js +150 -243
  11. data/app/assets/javascripts/scrivito_patches/client/cms_rest_api.js +209 -0
  12. data/app/assets/javascripts/scrivito_patches/components/sidebar/workspaces_panel.js +325 -0
  13. data/app/assets/javascripts/scrivito_patches/components/sidebar/workspaces_panel.js.jsx +294 -0
  14. data/app/assets/javascripts/scrivito_patches/models/{obj.js → legacy_obj.js} +27 -54
  15. data/app/assets/stylesheets/fiona7_ui.css.scss +2 -0
  16. data/app/controllers/fiona7/release_controller.rb +7 -6
  17. data/app/controllers/fiona7/sessions_controller.rb +10 -2
  18. data/app/controllers/fiona7/uploads_controller.rb +22 -0
  19. data/app/controllers/fiona7_login_page_controller.rb +3 -0
  20. data/app/controllers/scrivito/obj_class_controller.rb +28 -5
  21. data/app/views/fiona7/release/preview.html.erb +5 -38
  22. data/app/views/fiona7_login_page/index.html.erb +6 -0
  23. data/config/precedence_routes.rb +7 -7
  24. data/infopark_fiona7.gemspec +2 -2
  25. data/lib/fiona7/attribute_readers/number_as_string.rb +6 -1
  26. data/lib/fiona7/attribute_writers/binary_as_binary.rb +4 -2
  27. data/lib/fiona7/attribute_writers/binary_as_linklist.rb +4 -2
  28. data/lib/fiona7/builder/container_chain_builder.rb +50 -0
  29. data/lib/fiona7/builder/indirect_blob_builder.rb +7 -47
  30. data/lib/fiona7/builder/indirect_blob_builder_for_obj.rb +14 -0
  31. data/lib/fiona7/builder/lazy_blob_copier.rb +68 -14
  32. data/lib/fiona7/builder/obj_builder.rb +6 -32
  33. data/lib/fiona7/builder/obj_updater.rb +12 -4
  34. data/lib/fiona7/builder/widget_builder.rb +1 -1
  35. data/lib/fiona7/controllers/rest_api/blob_controller.rb +8 -2
  36. data/lib/fiona7/controllers/rest_api/obj_controller.rb +12 -8
  37. data/lib/fiona7/controllers/rest_api/workspace_controller.rb +6 -0
  38. data/lib/fiona7/engine.rb +49 -3
  39. data/lib/fiona7/forbidden_obj_classes.rb +14 -3
  40. data/lib/fiona7/linked_id_finder.rb +44 -0
  41. data/lib/fiona7/name_and_parent_from_path.rb +11 -0
  42. data/lib/fiona7/referenced_id_finder.rb +24 -0
  43. data/lib/fiona7/release_collector.rb +85 -0
  44. data/lib/fiona7/routers/rest_api.rb +2 -0
  45. data/lib/fiona7/scrivito_patches/cms_field_tag.rb +1 -0
  46. data/lib/fiona7/scrivito_patches/cms_rest_api.rb +16 -16
  47. data/lib/fiona7/scrivito_patches/cms_routing.rb +1 -0
  48. data/lib/fiona7/scrivito_patches/link_parser.rb +10 -7
  49. data/lib/fiona7/scrivito_patches/workspace.rb +0 -5
  50. data/lib/fiona7/super_id_finder.rb +68 -0
  51. data/lib/fiona7/super_object_finder.rb +5 -20
  52. data/lib/fiona7/temporary_uploader.rb +33 -0
  53. data/lib/fiona7/upload_path_selector.rb +17 -0
  54. data/lib/fiona7/verity_search_engine.rb +25 -12
  55. data/lib/fiona7/version.rb +1 -1
  56. metadata +23 -19
  57. data/app/assets/javascripts/fiona7/task_list_command.js +0 -15
  58. data/app/assets/javascripts/fiona7/task_list_menu_item.js +0 -30
  59. data/app/assets/javascripts/scrivito_patches/ajax.js +0 -225
  60. data/app/assets/javascripts/scrivito_patches/attribute_serializer.js +0 -259
  61. data/app/assets/javascripts/scrivito_patches/binary_utils.js +0 -33
  62. data/app/assets/javascripts/scrivito_patches/cms_rest_api.js +0 -371
  63. data/app/assets/javascripts/scrivito_patches/models/binary_field_element.js +0 -53
  64. data/app/assets/javascripts/scrivito_patches/obj_serializer.js +0 -91
  65. data/lib/fiona7/scrivito_patches/attribute_serializer.rb +0 -37
  66. data/lib/fiona7/scrivito_patches/model_library.rb +0 -19
  67. data/lib/fiona7/scrivito_patches/obj_params_parser.rb +0 -20
@@ -1,6 +1,8 @@
1
1
  require 'fiona7/super_object_finder'
2
2
  require 'fiona7/blob_id_generator'
3
- require 'fiona7/builder/indirect_blob_builder'
3
+ require 'fiona7/builder/indirect_blob_builder_for_obj'
4
+ require 'fiona7/builder/container_chain_builder'
5
+ require 'fiona7/upload_path_selector'
4
6
 
5
7
  module Fiona7
6
8
  module Builder
@@ -22,7 +24,7 @@ module Fiona7
22
24
  class LazyBlobCopier
23
25
  def initialize(attrs={})
24
26
  @destination_obj = attrs[:destination_obj]
25
- @attribute = attrs[:attr_name] || 'blob'
27
+ @attribute = attrs[:attr_name]
26
28
  @source_blob_id = attrs[:source_blob_id]
27
29
  @filename = attrs[:filename]
28
30
  @content_type = attrs[:content_type]
@@ -36,8 +38,10 @@ module Fiona7
36
38
  @blob_obj = Fiona7::WriteObj.find(@source_blob_id.to_i)
37
39
  @source_obj = find_unique_source_obj
38
40
 
39
- if @destination_obj == @source_obj
40
- rename
41
+ if @source_obj == nil
42
+ link_orphaned_blob
43
+ elsif @destination_obj == @source_obj
44
+ rename_or_assign
41
45
  else
42
46
  copy
43
47
  end
@@ -47,13 +51,54 @@ module Fiona7
47
51
 
48
52
  protected
49
53
 
50
- def rename
51
- return unless @basename.present? && @ext.present?
54
+ def rename_or_assign
55
+ if @basename.present? && @ext.present?
56
+ if Fiona7.mode == :legacy
57
+ direct_rename
58
+ else
59
+ indirect_rename
60
+ end
61
+ else
62
+ if Fiona7.mode == :legacy
63
+ # no assignment required
64
+ else
65
+ # assign the new blob
66
+ @destination_obj.set(@attribute, {
67
+ title: @source_blob_id,
68
+ destination_object: @blob_obj
69
+ }) if @attribute
70
+ end
71
+ end
72
+ end
52
73
 
74
+ def link_orphaned_blob
53
75
  if Fiona7.mode == :legacy
54
- direct_rename
76
+ # NOTE: orphaned blobs in legacy are probably temporary files
77
+ direct_copy
78
+ if is_a_tempfile?(@blob_obj)
79
+ begin
80
+ # NOTE: this is a very ugly hack to clean up temporary
81
+ blob_obj = @blob_obj
82
+ @destination_obj.singleton_class.after_save { blob_obj.destroy rescue nil }
83
+ rescue
84
+ end
85
+ end
55
86
  else
56
- indirect_rename
87
+ # move source blob to a proper location
88
+ parent = ContainerChainBuilder.new(UploadPathSelector.new(@destination_obj).call).call
89
+ if parent.obj_id != @blob_obj.parent_obj_id
90
+ @blob_obj.reload_attributes
91
+ @blob_obj.update_attributes!({
92
+ parent: parent
93
+ })
94
+ end
95
+
96
+ # link the orphaned blob
97
+ @destination_blob_id = @source_blob_id
98
+ @destination_obj.set(@attribute, {
99
+ title: @destination_blob_id,
100
+ destination_object: @blob_obj
101
+ }) if @attribute
57
102
  end
58
103
  end
59
104
 
@@ -66,6 +111,7 @@ module Fiona7
66
111
  end
67
112
 
68
113
  def direct_rename
114
+ # TODO: move source blob
69
115
  @destination_obj.set(:name, @basename)
70
116
  # CM stores the file extension as :contentType and not the mimetype
71
117
  @destination_obj.set(:content_type, @ext)
@@ -94,7 +140,7 @@ module Fiona7
94
140
  @destination_obj.set(@attribute, {
95
141
  title: @destination_blob_id,
96
142
  destination_object: @blob_obj
97
- })
143
+ }) if @attribute
98
144
  end
99
145
 
100
146
  def direct_copy
@@ -148,7 +194,7 @@ module Fiona7
148
194
 
149
195
  @destination_obj.set(@attribute, {
150
196
  title: @destination_blob_id, destination_object: destination_blob
151
- })
197
+ }) if @attribute
152
198
  end
153
199
 
154
200
  def split_filename(filename)
@@ -161,7 +207,7 @@ module Fiona7
161
207
  end
162
208
 
163
209
  def validate_input!
164
- if Fiona7.mode == :legacy && @attribute != 'blob'
210
+ if Fiona7.mode == :legacy && @attribute && @attribute != 'blob'
165
211
  raise Scrivito::ClientError.new("Blob attributes other than :blob are unsupported in :legacy mode")
166
212
  end
167
213
  if !extension_and_content_type_match?
@@ -177,13 +223,16 @@ module Fiona7
177
223
  return false if @ext.blank?
178
224
 
179
225
  return MIME::Types.type_for(@ext).any? {|m| m.content_type == @content_type }
180
- #rescue
181
226
  return false
182
227
  end
183
228
 
184
229
  def find_unique_source_obj
185
230
  if Fiona7.mode == :legacy
186
- return @blob_obj
231
+ if is_a_temporary_upload?(@blob_obj)
232
+ nil
233
+ else
234
+ @blob_obj
235
+ end
187
236
  end
188
237
 
189
238
  linking = Fiona7::SuperObjectFinder.new.find(@blob_obj)
@@ -199,8 +248,13 @@ module Fiona7
199
248
 
200
249
  def construct_destination_blob
201
250
  filename = @filename || (@source_obj.name + "." + @source_obj.file_extension)
202
- Fiona7::Builder::IndirectBlobBuilder.new(@destination_obj, filename).call
251
+ Fiona7::Builder::IndirectBlobBuilderForObj.new(@destination_obj, filename).call
252
+
253
+ end
203
254
 
255
+ def is_a_tempfile?(blob_obj)
256
+ Fiona7.mode == :legacy &&
257
+ ['X_Generic', 'X_Image'].include?(blob_obj.obj_class)
204
258
  end
205
259
  end
206
260
  end
@@ -18,6 +18,10 @@ require 'fiona7/attribute_writers/factory'
18
18
 
19
19
  require 'fiona7/widget_gc/garbage_collector'
20
20
 
21
+ require 'fiona7/name_and_parent_from_path'
22
+
23
+ require 'fiona7/builder/container_chain_builder'
24
+
21
25
 
22
26
  module Fiona7
23
27
  module Builder
@@ -65,6 +69,7 @@ module Fiona7
65
69
  end
66
70
 
67
71
  class ObjBuilder
72
+ include NameAndParentFromPath
68
73
 
69
74
  def initialize(values)
70
75
  @values = ParamPreprocessor.call(values)
@@ -108,7 +113,7 @@ module Fiona7
108
113
 
109
114
  @path = "/#{@path}" unless @path.start_with?('/')
110
115
  @name, parent_path = name_and_parent_path_from_path(@path)
111
- @parent = ensure_parent_exists(parent_path) if parent_path
116
+ @parent = ContainerChainBuilder.new(parent_path).call
112
117
 
113
118
  ensure_obj_class_exists
114
119
 
@@ -229,37 +234,6 @@ module Fiona7
229
234
  end.as_json
230
235
  end
231
236
 
232
- def name_and_parent_path_from_path(path)
233
- components = path.split('/')
234
- name = components.pop.presence
235
- parent_path= components.join('/').presence || '/'
236
-
237
- return name, parent_path
238
- end
239
-
240
- def ensure_parent_exists(path)
241
- remaining = path.split("/")
242
- current = []
243
- paths = []
244
- original = path
245
-
246
- while !remaining.empty?
247
- current.push(remaining.shift)
248
-
249
- path = current.join('/').presence || '/'
250
- paths.push(path)
251
- end
252
-
253
- paths.each do |path|
254
- if !WriteObj.exists?(path: path)
255
- name, parent_path = name_and_parent_path_from_path(path)
256
- WriteObj.create!(name: name, parent_obj_id: WriteObj.find_by_path(parent_path).id, obj_class: 'X_Container')
257
- end
258
- end
259
-
260
- WriteObj.find_by_path(original) || (raise "Tried to make sure that the parent under '#{original}' exist, but it does not :(")
261
- end
262
-
263
237
  def generate_orphaned_path
264
238
  return nil if update?
265
239
  "_orphaned/#{SecureRandom.hex(16)}"
@@ -20,11 +20,12 @@ module Fiona7
20
20
  @widget_pool = @values.delete(:_widget_pool)
21
21
  @permalink = @values.key?(:_permalink) ? (@values.delete(:_permalink) || "") : nil
22
22
 
23
-
24
- # revert command sends this info. which is silly.
23
+ # revert command sends this info. we cannot do anything useful with it.
25
24
  @values.delete(:_last_changed)
26
25
 
27
- @name, parent_path = name_and_parent_path_from_path(@path) if (@path)
26
+ @name, parent_path = name_and_parent_path_from_path(@path) if (@path)
27
+ old_name, old_parent_path = name_and_parent_path_from_path(@obj.path)
28
+
28
29
  if obj_class = @values.delete(:_obj_class)
29
30
  @obj_class = obj_class
30
31
  @real_obj_class = Fiona7::ObjClassNameMangler.new(@obj_class).mangle
@@ -42,7 +43,14 @@ module Fiona7
42
43
  # setting the name without changing the value counts
43
44
  # as changing the name attribute for the CM
44
45
  @obj.name = @name if !@name.blank? && @name != @obj.name
45
- # TODO: move (parent change)
46
+
47
+ # this is a obj move operation
48
+ if parent_path && old_parent_path != parent_path
49
+ # we first have to make sure that the new parent exists
50
+ # FIXME: moving the object and changing the obj class
51
+ # will not move the object
52
+ @obj.parent = ContainerChainBuilder.new(parent_path).call
53
+ end
46
54
  end
47
55
 
48
56
  end
@@ -29,7 +29,7 @@ module Fiona7
29
29
 
30
30
  @path = "/#{@path}" unless @path.start_with?('/')
31
31
  @name, parent_path = name_and_parent_path_from_path(@path)
32
- @parent = ensure_parent_exists(parent_path) if parent_path
32
+ @parent = ContainerChainBuilder.new(parent_path).call
33
33
 
34
34
  ensure_obj_class_exists
35
35
 
@@ -56,18 +56,24 @@ module Fiona7
56
56
 
57
57
  def copy(blob_id, params)
58
58
  input = params.symbolize_keys
59
- blob_id = blob_id.to_i
59
+ blob_id = blob_id
60
60
  destination_obj_id = input[:destination_obj_id]
61
61
  filename = input[:filename]
62
62
  content_type = input[:content_type]
63
63
  destination_obj = Fiona7::WriteObj.find(destination_obj_id)
64
64
 
65
- Fiona7::Builder::LazyBlobCopier.new({
65
+ destination_obj.reload_attributes
66
+
67
+ binary_spec = Fiona7::Builder::LazyBlobCopier.new({
66
68
  destination_obj: destination_obj,
67
69
  source_blob_id: blob_id,
68
70
  filename: filename,
69
71
  content_type: content_type
70
72
  }).call.stringify_keys
73
+
74
+ destination_obj.save!
75
+
76
+ return binary_spec
71
77
  end
72
78
  end
73
79
  end
@@ -279,8 +279,12 @@ module Fiona7
279
279
  result = []
280
280
  query_params.each do |query_param|
281
281
  new_query_param = query_param.symbolize_keys
282
- new_query_param[:operator] = query_param[:operator].to_sym
283
- new_query_param[:field] = query_param[:field].to_sym
282
+ new_query_param[:operator] = new_query_param[:operator].to_sym
283
+ if new_query_param[:field].is_a?(Array)
284
+ new_query_param[:field] = new_query_param[:field].map(&:to_sym)
285
+ else
286
+ new_query_param[:field] = new_query_param[:field].to_sym
287
+ end
284
288
 
285
289
  case query_param[:operator]
286
290
  when :contains
@@ -306,12 +310,12 @@ module Fiona7
306
310
  def use_naive_search_engine?(query)
307
311
  false ||
308
312
  query.empty? ||
309
- 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)} ||
310
- query.any? {|q| q[:field].to_sym == :_parent_path && (q[:operator].to_sym == :equal || query.length == 1)} ||
311
- (query.length == 1 && query.first[:field].to_sym == :_modification) ||
312
- (query.length == 1 && query.first[:field].to_sym == :_obj_class) ||
313
- (query.length == 1 && query.first[:field].to_sym == :id) ||
314
- (query.length == 1 && query.first[:field].to_sym == :_permalink) ||
313
+ query.any? {|q| (q[:field] == :_path || q[:field] == :_name)&& (q[:operator] == :equal || q[:operator] == :prefix || query.length == 1)} ||
314
+ query.any? {|q| q[:field] == :_parent_path && (q[:operator] == :equal || query.length == 1)} ||
315
+ (query.length == 1 && query.first[:field] == :_modification) ||
316
+ (query.length == 1 && query.first[:field] == :_obj_class) ||
317
+ (query.length == 1 && query.first[:field] == :id) ||
318
+ (query.length == 1 && query.first[:field] == :_permalink) ||
315
319
  false
316
320
  end
317
321
  end
@@ -50,12 +50,18 @@ module Fiona7
50
50
  Assert.contraint(false, "Workspaces cannot be deleted")
51
51
  end
52
52
 
53
+ def by_modified_obj
54
+ ['rtc']
55
+ end
56
+
53
57
  def update(id)
54
58
  # DUMMY NO OP
55
59
  {}
56
60
  end
57
61
 
58
62
  def create(values)
63
+ values ||= {}
64
+ values[:workspace] ||= {}
59
65
  id = (values[:workspace][:id] || values[:workspace]["id"])
60
66
  id = (id || :no_id_provided).to_sym
61
67
  Assert.constraint(
@@ -17,7 +17,6 @@ require "fiona7/initializer"
17
17
  require "fiona7/mode_switch"
18
18
  require "fiona7/controller_helper"
19
19
  require "fiona7/scrivito_patches/attribute_content"
20
- require "fiona7/scrivito_patches/attribute_serializer"
21
20
  require "fiona7/scrivito_patches/basic_obj"
22
21
  require "fiona7/scrivito_patches/basic_widget"
23
22
  require "fiona7/scrivito_patches/binary"
@@ -32,8 +31,6 @@ require "fiona7/scrivito_patches/layout_tags"
32
31
  require "fiona7/scrivito_patches/log_subscriber"
33
32
  require "fiona7/scrivito_patches/link_parser"
34
33
  require "fiona7/scrivito_patches/migrator"
35
- require "fiona7/scrivito_patches/model_library"
36
- require "fiona7/scrivito_patches/obj_params_parser"
37
34
  require "fiona7/scrivito_patches/page_config"
38
35
  require "fiona7/scrivito_patches/preset_routes"
39
36
  require "fiona7/scrivito_patches/routing_extensions"
@@ -47,6 +44,7 @@ require "fiona7/middleware/server_detection_middleware"
47
44
 
48
45
  # components
49
46
  require "fiona7/recursive_object_finder"
47
+ require "fiona7/release_collector"
50
48
  require "fiona7/complex_object"
51
49
 
52
50
  require "fiona7/routers/rest_api"
@@ -77,6 +75,54 @@ module Fiona7
77
75
  :release_obj => []
78
76
  }
79
77
 
78
+ # Allows to specify custom release patterns for objects
79
+ # So for example if releasing a page should release some other
80
+ # (for example unreferenced) page, then this can be used
81
+ # to achieve the desired behavior.
82
+ #
83
+ # This parameter accepts anything responding to .call method
84
+ # and receiveing one parameter: obj_id.
85
+ #
86
+ # Thus it is possible to use a lambda like this:
87
+ #
88
+ # release_collector = lambda do |obj_id|
89
+ # # ...
90
+ # end
91
+ #
92
+ # or a class based implementation.
93
+ #
94
+ # It is expected that the release collector returns an Array
95
+ # of Hashes with the following format:
96
+ #
97
+ # [
98
+ # {
99
+ # # this is a title for a group of objects
100
+ # title: 'This title will be shown in the dialog',
101
+ # # this is the list of objects presented underneath
102
+ # objs: [
103
+ # {
104
+ # # the ID of the object to be released
105
+ # id: 2001,
106
+ # # "Title" of the object which will be displayed
107
+ # title: 'Root',
108
+ # # "Description" of the object, typically obj_class
109
+ # description: 'RootObj',
110
+ # # If true, then release checkbox will be checked
111
+ # # i.e. without additional input from the user it will
112
+ # # get released automatically
113
+ # checked: true
114
+ # }
115
+ # ]
116
+ # ]
117
+ #
118
+ # Obviously it possible to define multiple groups and multiple
119
+ # objects in each group.
120
+ #
121
+ # It is recommended that custom implementations inherit
122
+ # or delegate to Fiona7::ReleaseCollector which is the
123
+ # default implementation.
124
+ mattr_accessor :release_collector
125
+
80
126
  # Allows to specify custom typing for virtual attribute types
81
127
  # Besides the built in mapping:
82
128
  # link: :linklist,
@@ -5,13 +5,24 @@ module Fiona7
5
5
  SYSTEM_CLASSES = ['X_Generic', 'X_Image', 'X_Container'].freeze
6
6
 
7
7
  def call
8
+ self.system_obj_classes +
9
+ self.widget_obj_classes
10
+ end
11
+
12
+ def all
13
+ self.call
14
+ end
15
+
16
+ def system_obj_classes
17
+ SYSTEM_CLASSES
18
+ end
19
+
20
+ def widget_obj_classes
8
21
  # NOTE: to_s handles shadow classes properly
9
22
  widget_classes = Scrivito.models.widgets.map(&:to_s)
10
- widget_obj_classes = widget_classes.map do |obj_class|
23
+ widget_classes.map do |obj_class|
11
24
  Fiona7::ObjClassNameMangler.new(obj_class).mangle
12
25
  end
13
-
14
- SYSTEM_CLASSES + widget_obj_classes
15
26
  end
16
27
  end
17
28
  end