scrivito_sdk 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +5 -0
- data/README +6 -0
- data/app/controllers/cms_controller.rb +7 -0
- data/app/controllers/scrivito/blobs_controller.rb +10 -0
- data/app/controllers/scrivito/default_cms_controller.rb +61 -0
- data/app/controllers/scrivito/objs_controller.rb +200 -0
- data/app/controllers/scrivito/tasks_controller.rb +11 -0
- data/app/controllers/scrivito/webservice_controller.rb +36 -0
- data/app/controllers/scrivito/workspaces_controller.rb +41 -0
- data/app/helpers/cms_helper.rb +7 -0
- data/app/helpers/cms_routing_helper.rb +7 -0
- data/app/helpers/scrivito/cms_asset_helper.rb +103 -0
- data/app/helpers/scrivito/cms_tag_helper.rb +231 -0
- data/app/helpers/scrivito/default_cms_helper.rb +21 -0
- data/app/helpers/scrivito/default_cms_routing_helper.rb +130 -0
- data/app/helpers/scrivito/display_helper.rb +71 -0
- data/app/helpers/scrivito/editing_helper.rb +26 -0
- data/app/helpers/scrivito/layout_helper.rb +28 -0
- data/app/models/named_link.rb +2 -0
- data/app/views/cms/_index.html.erb +7 -0
- data/app/views/cms/index.html.erb +1 -0
- data/app/views/scrivito/_editing_javascript.html.erb +7 -0
- data/app/views/scrivito/default_cms/show_widget.html.erb +1 -0
- data/app/views/scrivito/objs/copy_widget.html.erb +1 -0
- data/app/views/scrivito/objs/create_widget.html.erb +1 -0
- data/app/views/scrivito/widget_thumbnail.html.erb +9 -0
- data/config/ca-bundle.crt +3509 -0
- data/config/cms_routes.rb +17 -0
- data/config/locales/de.scrivito.errors.yml +7 -0
- data/config/locales/de.scrivito.lib.yml +6 -0
- data/config/locales/de.scrivito.models.yml +6 -0
- data/config/locales/en.scrivito.errors.yml +7 -0
- data/config/locales/en.scrivito.lib.yml +6 -0
- data/config/locales/en.scrivito.models.yml +6 -0
- data/config/routes.rb +37 -0
- data/lib/assets/images/180x120.gif +0 -0
- data/lib/assets/images/scrivito/image_placeholder.png +0 -0
- data/lib/assets/javascripts/scrivito_editing.js +14642 -0
- data/lib/assets/stylesheets/scrivito.css +180 -0
- data/lib/assets/stylesheets/scrivito_editing.css +2213 -0
- data/lib/generators/cms/migration/USAGE +9 -0
- data/lib/generators/cms/migration/migration_generator.rb +21 -0
- data/lib/generators/cms/migration/templates/migration.erb +10 -0
- data/lib/obj.rb +3 -0
- data/lib/scrivito/access_denied.rb +6 -0
- data/lib/scrivito/attribute_content.rb +194 -0
- data/lib/scrivito/backend_error.rb +4 -0
- data/lib/scrivito/basic_obj.rb +840 -0
- data/lib/scrivito/basic_widget.rb +238 -0
- data/lib/scrivito/blob.rb +48 -0
- data/lib/scrivito/cache.rb +41 -0
- data/lib/scrivito/cache_garbage_collector.rb +83 -0
- data/lib/scrivito/cache_middleware.rb +17 -0
- data/lib/scrivito/client_config.rb +62 -0
- data/lib/scrivito/client_error.rb +12 -0
- data/lib/scrivito/cms_accessible.rb +30 -0
- data/lib/scrivito/cms_backend.rb +238 -0
- data/lib/scrivito/cms_cache_storage.rb +51 -0
- data/lib/scrivito/cms_dispatch_controller.rb +46 -0
- data/lib/scrivito/cms_env.rb +63 -0
- data/lib/scrivito/cms_field_tag.rb +112 -0
- data/lib/scrivito/cms_rest_api.rb +151 -0
- data/lib/scrivito/cms_rest_api/attribute_serializer.rb +98 -0
- data/lib/scrivito/cms_rest_api/blob_uploader.rb +18 -0
- data/lib/scrivito/cms_rest_api/widget_extractor.rb +42 -0
- data/lib/scrivito/cms_test_request.rb +23 -0
- data/lib/scrivito/communication_error.rb +17 -0
- data/lib/scrivito/comparison.rb +67 -0
- data/lib/scrivito/configuration.rb +221 -0
- data/lib/scrivito/connection_manager.rb +100 -0
- data/lib/scrivito/content_conversion.rb +43 -0
- data/lib/scrivito/content_service.rb +118 -0
- data/lib/scrivito/content_state.rb +109 -0
- data/lib/scrivito/content_state_caching.rb +47 -0
- data/lib/scrivito/content_state_visitor.rb +19 -0
- data/lib/scrivito/controller_runtime.rb +35 -0
- data/lib/scrivito/date_attribute.rb +16 -0
- data/lib/scrivito/deprecation.rb +21 -0
- data/lib/scrivito/diff.rb +110 -0
- data/lib/scrivito/editing_context.rb +106 -0
- data/lib/scrivito/editing_context_middleware.rb +60 -0
- data/lib/scrivito/engine.rb +65 -0
- data/lib/scrivito/errors.rb +11 -0
- data/lib/scrivito/html_string.rb +18 -0
- data/lib/scrivito/link.rb +187 -0
- data/lib/scrivito/link_parser.rb +81 -0
- data/lib/scrivito/log_subscriber.rb +29 -0
- data/lib/scrivito/migration.rb +2 -0
- data/lib/scrivito/migrations.rb +12 -0
- data/lib/scrivito/migrations/cms_backend.rb +94 -0
- data/lib/scrivito/migrations/installer.rb +45 -0
- data/lib/scrivito/migrations/migration.rb +93 -0
- data/lib/scrivito/migrations/migration_dsl.rb +143 -0
- data/lib/scrivito/migrations/migration_store.rb +23 -0
- data/lib/scrivito/migrations/migrator.rb +135 -0
- data/lib/scrivito/migrations/workspace_lock.rb +39 -0
- data/lib/scrivito/model_identity.rb +13 -0
- data/lib/scrivito/modification.rb +8 -0
- data/lib/scrivito/named_link.rb +75 -0
- data/lib/scrivito/network_error.rb +11 -0
- data/lib/scrivito/obj_data.rb +140 -0
- data/lib/scrivito/obj_data_from_hash.rb +31 -0
- data/lib/scrivito/obj_data_from_service.rb +84 -0
- data/lib/scrivito/obj_params_parser.rb +61 -0
- data/lib/scrivito/obj_search_builder.rb +62 -0
- data/lib/scrivito/obj_search_enumerator.rb +374 -0
- data/lib/scrivito/rate_limit_exceeded.rb +5 -0
- data/lib/scrivito/revision.rb +9 -0
- data/lib/scrivito/string_tagging.rb +18 -0
- data/lib/scrivito/text_link.rb +52 -0
- data/lib/scrivito/text_link_conversion.rb +52 -0
- data/lib/scrivito/type_computer.rb +34 -0
- data/lib/scrivito/widget_field_params.rb +61 -0
- data/lib/scrivito/widget_garbage_collection.rb +97 -0
- data/lib/scrivito/workspace.rb +222 -0
- data/lib/scrivito/workspace_data_from_service.rb +80 -0
- data/lib/scrivito/workspace_selection_middleware.rb +23 -0
- data/lib/scrivito_sdk.rb +19 -0
- data/lib/tasks/cache.rake +12 -0
- data/lib/tasks/migration.rake +35 -0
- data/lib/widget.rb +3 -0
- metadata +291 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
# this class is the server-side equivalent of the JavaScript class `cms_field_element`
|
4
|
+
class CmsFieldTag < Struct.new(
|
5
|
+
:view_context, :editing_context, :obj_or_widget, :field_name
|
6
|
+
)
|
7
|
+
|
8
|
+
def options
|
9
|
+
formatted_options = {}
|
10
|
+
raw_options.each do |key, value|
|
11
|
+
formatted_options["data-scrivito-#{key}"] = value
|
12
|
+
end
|
13
|
+
|
14
|
+
formatted_options
|
15
|
+
end
|
16
|
+
|
17
|
+
def field_type
|
18
|
+
@field_type ||= obj_or_widget.type_of_attribute(field_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_content
|
22
|
+
calculate_content_and_modification
|
23
|
+
@content_and_modification.first
|
24
|
+
end
|
25
|
+
|
26
|
+
def modification_info
|
27
|
+
calculate_content_and_modification
|
28
|
+
@content_and_modification.second
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def calculate_content_and_modification
|
34
|
+
@content_and_modification ||=
|
35
|
+
comparison.diff_for(obj_or_widget, field_name) || [current_value, nil]
|
36
|
+
end
|
37
|
+
|
38
|
+
def raw_options
|
39
|
+
return {} unless inplace_editing_allowed?
|
40
|
+
|
41
|
+
options = {
|
42
|
+
'private-field-workspace-id' => current_workspace_id,
|
43
|
+
'field-name' => field_name,
|
44
|
+
'field-obj-class' => obj_or_widget.obj_class_name,
|
45
|
+
'field-type' => field_type,
|
46
|
+
}
|
47
|
+
|
48
|
+
modification = comparison.modification_for_attribute(obj_or_widget, field_name)
|
49
|
+
if modification == Modification::EDITED && field_type != 'widget'
|
50
|
+
options['field-modification'] = modification
|
51
|
+
end
|
52
|
+
|
53
|
+
if obj_or_widget.kind_of?(BasicWidget)
|
54
|
+
options['private-field-id'] = obj_or_widget.obj.id
|
55
|
+
options['private-field-widget-id'] = obj_or_widget.id
|
56
|
+
else
|
57
|
+
options['private-field-id'] = obj_or_widget.id
|
58
|
+
end
|
59
|
+
|
60
|
+
if FIELD_TYPES_WITH_ORIGINAL_CONTENT.include?(field_type)
|
61
|
+
original_value = view_context.display_original_value(current_value)
|
62
|
+
original_content = original_content(field_type, original_value)
|
63
|
+
options['private-field-original-content'] = MultiJson.encode(original_content)
|
64
|
+
end
|
65
|
+
|
66
|
+
if field_type == 'widget'
|
67
|
+
valid_widget_classes = obj_or_widget.valid_widget_classes_for(field_name.to_s)
|
68
|
+
if valid_widget_classes
|
69
|
+
options['private-field-widget-allowed-classes'] = valid_widget_classes.to_json
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
options
|
74
|
+
end
|
75
|
+
|
76
|
+
def comparison
|
77
|
+
editing_context.comparison
|
78
|
+
end
|
79
|
+
|
80
|
+
def current_value
|
81
|
+
obj_or_widget[field_name]
|
82
|
+
end
|
83
|
+
|
84
|
+
def current_workspace_id
|
85
|
+
Workspace.current.id
|
86
|
+
end
|
87
|
+
|
88
|
+
FIELD_TYPES_WITH_ORIGINAL_CONTENT = %w[
|
89
|
+
enum
|
90
|
+
html
|
91
|
+
multienum
|
92
|
+
reference
|
93
|
+
referencelist
|
94
|
+
string
|
95
|
+
text
|
96
|
+
]
|
97
|
+
|
98
|
+
def inplace_editing_allowed?
|
99
|
+
editing_context.authenticated_editor?
|
100
|
+
end
|
101
|
+
|
102
|
+
def original_content(field_type, field_value)
|
103
|
+
case field_type
|
104
|
+
when 'reference' then field_value.try(:id)
|
105
|
+
when 'referencelist' then field_value.map(&:id)
|
106
|
+
else field_value
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'restclient'
|
2
|
+
require 'active_support/all'
|
3
|
+
|
4
|
+
module Scrivito
|
5
|
+
|
6
|
+
# Provides a simple wrapper for the CMS Rest API.
|
7
|
+
#
|
8
|
+
# @example Request the published workspace:
|
9
|
+
# Scrivito::CmsRestApi.get('workspaces/published')
|
10
|
+
#
|
11
|
+
# @example Create a new Obj:
|
12
|
+
# Scrivito::CmsRestApi.post('workspaces/001384beff9e5845/objs',
|
13
|
+
# {'obj' => {'_path' => '/new_obj', '_obj_class' => 'Publication'}})
|
14
|
+
#
|
15
|
+
# @example Update an Obj:
|
16
|
+
# Scrivito::CmsRestApi.put('workspaces/001384beff9e5845/objs/9e432077f0412a63',
|
17
|
+
# {'obj' => {'title' => 'new title'}})
|
18
|
+
#
|
19
|
+
# @example Delete an Obj:
|
20
|
+
# Scrivito::CmsRestApi.delete('workspaces/001384beff9e5845/objs/f4123622ff07b70b')
|
21
|
+
#
|
22
|
+
# @example Specify a poll interval (in seconds; default: 2) to use in case the response
|
23
|
+
# is a task reference response and the final response is polled for:
|
24
|
+
# Scrivito::CmsRestApi.put('workspace/rtc/publish', nil, :interval => 10)
|
25
|
+
#
|
26
|
+
# @example Return immediately with the first response (without polling in case it is a
|
27
|
+
# task reference response):
|
28
|
+
# Scrivito::CmsRestApi.task_unaware_request(:put, 'workspace/rtc/publish', nil)
|
29
|
+
#
|
30
|
+
class CmsRestApi
|
31
|
+
METHOD_TO_NET_HTTP_CLASS = {
|
32
|
+
:get => Net::HTTP::Get,
|
33
|
+
:put => Net::HTTP::Put,
|
34
|
+
:post => Net::HTTP::Post,
|
35
|
+
:delete => Net::HTTP::Delete,
|
36
|
+
}.freeze
|
37
|
+
|
38
|
+
def self.get(resource_path, payload = nil, options = nil)
|
39
|
+
request_cms_api(:get, resource_path, payload, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.put(resource_path, payload, options = nil)
|
43
|
+
request_cms_api(:put, resource_path, payload, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.post(resource_path, payload, options = nil)
|
47
|
+
request_cms_api(:post, resource_path, payload, options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.delete(resource_path, payload = nil, options = nil)
|
51
|
+
request_cms_api(:delete, resource_path, payload, options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.task_unaware_request(method, resource_path, payload = nil)
|
55
|
+
raise "Unexpected method #{method}" unless [:delete, :get, :post, :put].include?(method)
|
56
|
+
response_for_request_cms_api(method, resource_path, payload)
|
57
|
+
end
|
58
|
+
|
59
|
+
class << self
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def request_cms_api(action, resource_path, payload, options)
|
64
|
+
decoded = response_for_request_cms_api(action, resource_path, payload)
|
65
|
+
return decoded unless Hash === decoded
|
66
|
+
return decoded unless decoded.keys == ["task"]
|
67
|
+
task_data = decoded["task"]
|
68
|
+
return decoded unless Hash === task_data
|
69
|
+
task_path = "tasks/#{task_data["id"]}"
|
70
|
+
final_response(task_path, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
def response_for_request_cms_api(method, resource_path, payload = nil)
|
74
|
+
request = method_to_net_http_class(method).new(path(resource_path))
|
75
|
+
set_headers(request)
|
76
|
+
request.body = MultiJson.encode(payload) if payload.present?
|
77
|
+
|
78
|
+
response = nil
|
79
|
+
retried = false
|
80
|
+
begin
|
81
|
+
# lower timeout back to DEFAULT_TIMEOUT once the backend has been fixed
|
82
|
+
response = connection_manager.request(request, 25)
|
83
|
+
rescue NetworkError => e
|
84
|
+
if method == :post || retried
|
85
|
+
raise e
|
86
|
+
else
|
87
|
+
retried = true
|
88
|
+
retry
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
handle_response(response)
|
93
|
+
end
|
94
|
+
|
95
|
+
def handle_response(response)
|
96
|
+
code = response.code.to_i
|
97
|
+
if response.code.start_with?('2')
|
98
|
+
MultiJson.load(response.body)
|
99
|
+
elsif response.code == '403'
|
100
|
+
raise AccessDenied.new(response.body)
|
101
|
+
else
|
102
|
+
begin
|
103
|
+
specific_output = MultiJson.decode(response.body)['error']
|
104
|
+
|
105
|
+
if response.code.start_with?('4')
|
106
|
+
raise ClientError.new(specific_output, code)
|
107
|
+
elsif response.code == '500' && specific_output
|
108
|
+
raise BackendError.new(specific_output, code)
|
109
|
+
else # 3xx and >500 are treated as NetworkErrors
|
110
|
+
raise NetworkError.new(response.body, code)
|
111
|
+
end
|
112
|
+
rescue MultiJson::DecodeError
|
113
|
+
raise NetworkError.new(response.body, code)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def final_response(task_path, options)
|
119
|
+
options ||= {}
|
120
|
+
wait = options[:interval].presence.try(:to_f) || 2
|
121
|
+
task_data = response = nil
|
122
|
+
loop do
|
123
|
+
sleep wait
|
124
|
+
task_data = response_for_request_cms_api(:get, task_path, nil)
|
125
|
+
break unless task_data["status"] == "open"
|
126
|
+
end
|
127
|
+
return task_data["result"] if task_data["status"] == "success"
|
128
|
+
message = task_data["message"] || "Missing error message in task response #{task_data}"
|
129
|
+
raise ClientError.new(message, 400)
|
130
|
+
end
|
131
|
+
|
132
|
+
def set_headers(request)
|
133
|
+
request.basic_auth('api_token', Configuration.api_key)
|
134
|
+
request['Content-type'] = 'application/json'
|
135
|
+
request['Accept'] = 'application/json'
|
136
|
+
end
|
137
|
+
|
138
|
+
def path(path)
|
139
|
+
"/#{Configuration.endpoint_uri.path}/#{path}".squeeze('/')
|
140
|
+
end
|
141
|
+
|
142
|
+
def connection_manager
|
143
|
+
ConnectionManager.instance
|
144
|
+
end
|
145
|
+
|
146
|
+
def method_to_net_http_class(method)
|
147
|
+
METHOD_TO_NET_HTTP_CLASS.fetch(method)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Scrivito
|
2
|
+
class CmsRestApi
|
3
|
+
module AttributeSerializer
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def generate_widget_pool_changes(widget_hash)
|
7
|
+
widget_pool_changes = {}
|
8
|
+
|
9
|
+
widget_hash.each do |widget, attributes|
|
10
|
+
if attributes.present?
|
11
|
+
widget_pool_changes[widget.id] =
|
12
|
+
self.convert(attributes)
|
13
|
+
else # Empty hash or nil
|
14
|
+
widget_pool_changes[widget.id] = attributes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
widget_pool_changes
|
19
|
+
end
|
20
|
+
|
21
|
+
def convert(attributes)
|
22
|
+
Hash[
|
23
|
+
attributes.map do |attribute_name, value|
|
24
|
+
attribute_name = attribute_name.to_s
|
25
|
+
|
26
|
+
converted_value = if value.nil? || value == []
|
27
|
+
nil
|
28
|
+
elsif link_array?(value)
|
29
|
+
convert_links(value)
|
30
|
+
elsif value.is_a?(BasicObj)
|
31
|
+
value.id
|
32
|
+
elsif widget_array?(value)
|
33
|
+
convert_widgets(value)
|
34
|
+
elsif obj_array?(value)
|
35
|
+
value.map(&:id)
|
36
|
+
elsif value.is_a?(Time) || value.is_a?(Date)
|
37
|
+
convert_time(value)
|
38
|
+
elsif value.is_a?(Array)
|
39
|
+
value.map(&:to_s)
|
40
|
+
elsif value.is_a?(File)
|
41
|
+
Scrivito::CmsRestApi::BlobUploader.upload_file(value)
|
42
|
+
else
|
43
|
+
value.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
[attribute_name, converted_value]
|
47
|
+
end
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
def convert_time(point_in_time)
|
52
|
+
time_object = if point_in_time.instance_of?(Date)
|
53
|
+
point_in_time.to_time
|
54
|
+
else
|
55
|
+
point_in_time.to_time.utc
|
56
|
+
end
|
57
|
+
|
58
|
+
time_object.strftime("%Y%m%d%H%M%S")
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def widget_array?(value)
|
64
|
+
value.is_a?(Array) && value.all? do |element|
|
65
|
+
element.is_a?(BasicWidget)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def convert_widgets(value)
|
70
|
+
converted_widgets = value.map do |widget|
|
71
|
+
{ 'widget' => widget.id }
|
72
|
+
end
|
73
|
+
|
74
|
+
{ 'list' => converted_widgets }
|
75
|
+
end
|
76
|
+
|
77
|
+
def link_array?(value)
|
78
|
+
value.is_a?(Array) && value.all? do |element|
|
79
|
+
element.is_a?(Link)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def obj_array?(value)
|
84
|
+
value.is_a?(Array) && value.all? do |element|
|
85
|
+
element.is_a?(BasicObj)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def convert_links(links)
|
90
|
+
links.map do |link|
|
91
|
+
link.to_cms_api_linklist_params
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Scrivito
|
2
|
+
class CmsRestApi
|
3
|
+
module BlobUploader
|
4
|
+
class << self
|
5
|
+
def upload_file(file)
|
6
|
+
upload_permission = CmsRestApi.get('blobs/upload_permission')
|
7
|
+
|
8
|
+
fields = upload_permission['fields'].to_a + [[:file, file]]
|
9
|
+
|
10
|
+
# Net/HTTP does not support multipart forms
|
11
|
+
RestClient.post(upload_permission['url'], fields)
|
12
|
+
|
13
|
+
upload_permission['blob']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Scrivito
|
2
|
+
class CmsRestApi
|
3
|
+
class WidgetExtractor
|
4
|
+
|
5
|
+
# Extract widgets from a given attribute tree and return them as a flat
|
6
|
+
# hash of widget_like => updated_attributes
|
7
|
+
def self.call(updated_attributes, obj=nil)
|
8
|
+
extracted_widgets = {}
|
9
|
+
|
10
|
+
updated_attributes.each do |attribute_name, value|
|
11
|
+
if value.is_a?(Array) && value.all? {|w| w.is_a?(BasicWidget)}
|
12
|
+
value.each do |widget|
|
13
|
+
unless widget.persisted?
|
14
|
+
widget.id = if obj.present?
|
15
|
+
obj.generate_widget_pool_id
|
16
|
+
else
|
17
|
+
BasicObj.generate_widget_pool_id
|
18
|
+
end
|
19
|
+
|
20
|
+
widget.obj = obj
|
21
|
+
|
22
|
+
extracted_widgets[widget] = widget.attributes_to_be_saved
|
23
|
+
extracted_widgets.merge!(self.call(widget.attributes_to_be_saved, obj))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
extracted_widgets
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.notify_persisted_widgets(obj, widget_hash)
|
33
|
+
widget_hash.each do |widget, attributes|
|
34
|
+
if attributes.present?
|
35
|
+
widget.obj = obj
|
36
|
+
widget.forget_unsaved_attribtues
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Scrivito
|
2
|
+
module CmsTestRequest
|
3
|
+
def for_cms_object(test_obj=nil)
|
4
|
+
# prepare the env as if the given obj was loaded by CmsEnv
|
5
|
+
env[Scrivito::CmsEnv::OBJ_ENV_KEY] = test_obj if test_obj
|
6
|
+
class << self
|
7
|
+
# This special behaviour is necessary for testing controllers that descend from DefaultCmsController.
|
8
|
+
# These controllers do not have explicit routes by default.
|
9
|
+
# Instead, they are reached via the CmsDispatchController.
|
10
|
+
# The TestRequest must therefore use CmsDispatchController as a fallback route.
|
11
|
+
def assign_parameters(routes, controller_path, action, parameters = {})
|
12
|
+
super(routes, controller_path, action, parameters)
|
13
|
+
rescue ActionController::RoutingError, AbstractController::ActionNotFound => e
|
14
|
+
begin
|
15
|
+
super(routes, "scrivito/cms_dispatch", action, parameters)
|
16
|
+
rescue ActionController::RoutingError, AbstractController::ActionNotFound
|
17
|
+
raise e
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|