scrivito_sdk 0.17.0 → 0.18.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.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/app/controllers/scrivito/default_cms_controller.rb +15 -3
- data/app/controllers/scrivito/objs_controller.rb +61 -25
- data/app/controllers/scrivito/users_controller.rb +7 -0
- data/app/controllers/scrivito/webservice_controller.rb +17 -7
- data/app/controllers/scrivito/workspaces_controller.rb +85 -17
- data/app/helpers/scrivito/default_cms_routing_helper.rb +3 -3
- data/config/routes.rb +4 -1
- data/lib/assets/javascripts/scrivito_editing.js +4182 -508
- data/lib/assets/stylesheets/scrivito_editing.css +489 -13
- data/lib/generators/cms/migration/templates/migration.erb +4 -4
- data/lib/scrivito/attribute_collection.rb +1 -6
- data/lib/scrivito/attribute_content.rb +29 -7
- data/lib/scrivito/basic_obj.rb +91 -61
- data/lib/scrivito/basic_widget.rb +0 -11
- data/lib/scrivito/client_config.rb +40 -25
- data/lib/scrivito/cms_backend.rb +54 -0
- data/lib/scrivito/cms_cache_storage.rb +8 -0
- data/lib/scrivito/cms_field_tag.rb +2 -1
- data/lib/scrivito/cms_rest_api.rb +9 -0
- data/lib/scrivito/configuration.rb +4 -2
- data/lib/scrivito/content_state.rb +8 -0
- data/lib/scrivito/content_state_caching.rb +20 -0
- data/lib/scrivito/editing_context.rb +35 -34
- data/lib/scrivito/membership.rb +22 -3
- data/lib/scrivito/memberships_collection.rb +8 -4
- data/lib/scrivito/obj_class.rb +45 -100
- data/lib/scrivito/obj_class_collection.rb +53 -0
- data/lib/scrivito/obj_class_data.rb +33 -0
- data/lib/scrivito/obj_data.rb +26 -48
- data/lib/scrivito/obj_data_from_hash.rb +5 -5
- data/lib/scrivito/obj_data_from_service.rb +9 -3
- data/lib/scrivito/obj_search_builder.rb +0 -5
- data/lib/scrivito/obj_search_enumerator.rb +3 -20
- data/lib/scrivito/objs_collection.rb +7 -0
- data/lib/scrivito/restriction_set.rb +2 -2
- data/lib/scrivito/user.rb +89 -23
- data/lib/scrivito/user_definition.rb +73 -70
- data/lib/scrivito/workspace.rb +52 -8
- data/lib/scrivito/workspace/publish_checker.rb +126 -0
- metadata +6 -2
@@ -0,0 +1,53 @@
|
|
1
|
+
module Scrivito
|
2
|
+
# This class allows you to retrieve obj classes from a specific working copy. It behaves almost
|
3
|
+
# exactly as an Array, so methods like +#each+, +#select+ etc. are available. You can get an
|
4
|
+
# instance by accessing {Workspace#obj_classes}.
|
5
|
+
#
|
6
|
+
# @api public
|
7
|
+
class ObjClassCollection
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
# Initializes an obj class collection for a workspace.
|
11
|
+
#
|
12
|
+
# @param [Workspace] workspace
|
13
|
+
# @return [ObjClassCollection]
|
14
|
+
def initialize(workspace)
|
15
|
+
@workspace = workspace
|
16
|
+
end
|
17
|
+
|
18
|
+
# Finds an obj class by its name in the working copy of the collection.
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
#
|
22
|
+
# @example Find the obj class named "Homepage" in the "rtc" {Workspace}.
|
23
|
+
# Workspace.find('rtc').obj_classes['Homepage']
|
24
|
+
#
|
25
|
+
# @param [String] name The name of the obj class.
|
26
|
+
# @return [ObjClass, nil] Returns the obj class or nil when no obj class with the given +name+ can be found in the working copy.
|
27
|
+
def [](name)
|
28
|
+
if obj_class_data = CmsBackend.instance.find_obj_class_data_by_name(workspace.revision, name)
|
29
|
+
ObjClass.new(obj_class_data, workspace)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @!method each
|
34
|
+
# Yields successive obj classes of the collection. Implements the +Enumerable+ interface.
|
35
|
+
# @api public
|
36
|
+
# @yield [ObjClass] Successive obj classes of the collection.
|
37
|
+
# @example Find all obj classes in the "rtc" {Workspace} and print their name.
|
38
|
+
# Workspace.find('rtc').obj_classes.each do |obj_class|
|
39
|
+
# puts obj_class.name
|
40
|
+
# end
|
41
|
+
delegate :each, to: :obj_classes
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def obj_classes
|
46
|
+
CmsBackend.instance.find_all_obj_class_data(workspace.revision).map do |obj_class_data|
|
47
|
+
ObjClass.new(obj_class_data, workspace)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_reader :workspace
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
class ObjClassData
|
4
|
+
def initialize(raw_data)
|
5
|
+
raw_data = raw_data.deep_stringify_keys
|
6
|
+
if type = raw_data['type']
|
7
|
+
raw_data['is_binary'] = %w[image generic].include?(type)
|
8
|
+
end
|
9
|
+
@raw_data = raw_data
|
10
|
+
end
|
11
|
+
|
12
|
+
def id
|
13
|
+
@raw_data['id']
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
@raw_data['name']
|
18
|
+
end
|
19
|
+
|
20
|
+
def is_active
|
21
|
+
!!@raw_data['is_active']
|
22
|
+
end
|
23
|
+
|
24
|
+
def is_binary
|
25
|
+
!!@raw_data['is_binary']
|
26
|
+
end
|
27
|
+
|
28
|
+
def attributes
|
29
|
+
@raw_data['attributes'] || []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/lib/scrivito/obj_data.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Scrivito
|
2
2
|
|
3
3
|
class ObjData
|
4
|
-
MissingAttribute = Class.new
|
5
|
-
|
6
4
|
internal_key_list = %w[
|
7
5
|
last_changed
|
8
6
|
modification
|
@@ -21,8 +19,6 @@ module Scrivito
|
|
21
19
|
|
22
20
|
INTERNAL_COMPARISON_KEYS = Set.new(internal_comparison_key_list.map { |name| "_#{name}" })
|
23
21
|
|
24
|
-
SPECIAL_KEYS = Set.new(%w[ body title blob ])
|
25
|
-
|
26
22
|
ATTRIBUTE_DEFAULT_VALUES = {
|
27
23
|
"string" => "",
|
28
24
|
"text" => "",
|
@@ -46,27 +42,23 @@ module Scrivito
|
|
46
42
|
value_and_type_of(attribute_name).second
|
47
43
|
end
|
48
44
|
|
49
|
-
def
|
50
|
-
|
45
|
+
def value_without_default_of(attribute_name)
|
46
|
+
value_and_type_without_default_of(attribute_name).first
|
51
47
|
end
|
52
48
|
|
53
49
|
def value_and_type_of(attribute_name)
|
54
|
-
|
55
|
-
|
56
|
-
if value_and_type.first.is_a?(MissingAttribute)
|
57
|
-
raise ScrivitoError.new("Illegal attribute name #{attribute_name}")
|
50
|
+
if internal_attribute?(attribute_name)
|
51
|
+
internal_value_and_type(attribute_name)
|
58
52
|
else
|
59
|
-
|
53
|
+
custom_value_and_type_with_default(attribute_name)
|
60
54
|
end
|
61
55
|
end
|
62
56
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
if value_and_type.first.is_a?(MissingAttribute)
|
67
|
-
[nil, nil]
|
57
|
+
def value_and_type_without_default_of(attribute_name)
|
58
|
+
if internal_attribute?(attribute_name)
|
59
|
+
internal_value_and_type(attribute_name)
|
68
60
|
else
|
69
|
-
|
61
|
+
raw_value_and_type_of(attribute_name)
|
70
62
|
end
|
71
63
|
end
|
72
64
|
|
@@ -76,6 +68,10 @@ module Scrivito
|
|
76
68
|
end
|
77
69
|
end
|
78
70
|
|
71
|
+
def to_h
|
72
|
+
raise NotImplementedError, 'implement in subclass'
|
73
|
+
end
|
74
|
+
|
79
75
|
def raw_value_and_type_of(attribute_name)
|
80
76
|
raise NotImplementedError, "implement in subclass"
|
81
77
|
end
|
@@ -95,7 +91,7 @@ module Scrivito
|
|
95
91
|
|
96
92
|
next if attr.start_with?('_') && !INTERNAL_COMPARISON_KEYS.include?(attr)
|
97
93
|
|
98
|
-
if
|
94
|
+
if value_without_default_of(attr) != other.value_without_default_of(attr)
|
99
95
|
return false
|
100
96
|
end
|
101
97
|
end
|
@@ -108,24 +104,20 @@ module Scrivito
|
|
108
104
|
|
109
105
|
private
|
110
106
|
|
111
|
-
def
|
112
|
-
|
107
|
+
def custom_value_and_type_with_default(attribute_name)
|
108
|
+
value, type = raw_value_and_type_of(attribute_name)
|
109
|
+
value = ATTRIBUTE_DEFAULT_VALUES[type] if value.nil?
|
110
|
+
[value, type]
|
111
|
+
end
|
113
112
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
[ObjData::MissingAttribute.new, nil]
|
120
|
-
end
|
121
|
-
else
|
122
|
-
value, type = value_and_type
|
123
|
-
if value.nil? && has_custom_attribute?(attribute_name)
|
124
|
-
value = ATTRIBUTE_DEFAULT_VALUES[type]
|
125
|
-
end
|
113
|
+
def internal_value_and_type(attribute_name)
|
114
|
+
value, type = raw_value_and_type_of(attribute_name)
|
115
|
+
type = type_of_internal(attribute_name)
|
116
|
+
[value, type]
|
117
|
+
end
|
126
118
|
|
127
|
-
|
128
|
-
|
119
|
+
def internal_attribute?(attribute_name)
|
120
|
+
attribute_name.starts_with?('_')
|
129
121
|
end
|
130
122
|
|
131
123
|
def type_of_internal(key)
|
@@ -136,24 +128,10 @@ module Scrivito
|
|
136
128
|
"linklist"
|
137
129
|
when "_last_changed"
|
138
130
|
"date"
|
139
|
-
when "title", "body"
|
140
|
-
"html"
|
141
|
-
when "blob"
|
142
|
-
"binary"
|
143
131
|
else
|
144
132
|
nil
|
145
133
|
end
|
146
134
|
end
|
147
|
-
|
148
|
-
def default_attribute_value(attribute_name)
|
149
|
-
case attribute_name
|
150
|
-
when "_text_links"
|
151
|
-
[]
|
152
|
-
else
|
153
|
-
nil
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
135
|
end
|
158
136
|
|
159
137
|
end
|
@@ -7,9 +7,7 @@ module Scrivito
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def raw_value_and_type_of(attribute_name)
|
10
|
-
|
11
|
-
[@hash[attribute_name], @type_hash[attribute_name]]
|
12
|
-
end
|
10
|
+
[@hash[attribute_name], @type_hash[attribute_name]]
|
13
11
|
end
|
14
12
|
|
15
13
|
def has_custom_attribute?(name)
|
@@ -20,12 +18,14 @@ module Scrivito
|
|
20
18
|
@all_attributes ||= begin
|
21
19
|
@hash.keys |
|
22
20
|
INTERNAL_KEYS.to_a |
|
23
|
-
SPECIAL_KEYS.to_a |
|
24
21
|
%w[_id]
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
25
|
+
def to_h
|
26
|
+
@hash
|
27
|
+
end
|
28
|
+
|
28
29
|
end
|
29
30
|
|
30
31
|
end
|
31
|
-
|
@@ -9,7 +9,7 @@ module Scrivito
|
|
9
9
|
if attribute_name == '_widget_pool'
|
10
10
|
[value_of_widget_pool, nil]
|
11
11
|
else
|
12
|
-
type_and_value = @data[
|
12
|
+
type_and_value = @data.fetch(attribute_name, [nil, nil])
|
13
13
|
|
14
14
|
if type_and_value.present?
|
15
15
|
type = if type_and_value.length == 1
|
@@ -28,7 +28,13 @@ module Scrivito
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def all_attributes
|
31
|
-
@all_attributes ||= (@data.keys | INTERNAL_KEYS.to_a
|
31
|
+
@all_attributes ||= (@data.keys | INTERNAL_KEYS.to_a)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_h
|
35
|
+
@data.dup.tap do |h|
|
36
|
+
h.each_pair { |k, v| h[k] = v.first }
|
37
|
+
end
|
32
38
|
end
|
33
39
|
|
34
40
|
private
|
@@ -76,7 +82,7 @@ module Scrivito
|
|
76
82
|
end
|
77
83
|
|
78
84
|
def is_custom_attribute?(attribute_name)
|
79
|
-
!
|
85
|
+
!internal_attribute?(attribute_name)
|
80
86
|
end
|
81
87
|
|
82
88
|
end
|
@@ -9,7 +9,6 @@ class ObjSearchBuilder < Struct.new(:query)
|
|
9
9
|
set_offset
|
10
10
|
set_order
|
11
11
|
set_batch_size
|
12
|
-
set_format
|
13
12
|
set_include_deleted
|
14
13
|
|
15
14
|
enumerator
|
@@ -48,10 +47,6 @@ class ObjSearchBuilder < Struct.new(:query)
|
|
48
47
|
enumerator.batch_size(query[:batch_size]) if query[:batch_size]
|
49
48
|
end
|
50
49
|
|
51
|
-
def set_format
|
52
|
-
enumerator.format(query[:format]) if query[:format]
|
53
|
-
end
|
54
|
-
|
55
50
|
def set_include_deleted
|
56
51
|
enumerator.include_deleted if query[:include_deleted]
|
57
52
|
end
|
@@ -106,8 +106,6 @@ module Scrivito
|
|
106
106
|
#
|
107
107
|
# @api public
|
108
108
|
class ObjSearchEnumerator
|
109
|
-
class UnregisteredObjFormat < StandardError; end
|
110
|
-
|
111
109
|
include Enumerable
|
112
110
|
|
113
111
|
attr_reader :workspace
|
@@ -271,7 +269,7 @@ module Scrivito
|
|
271
269
|
}
|
272
270
|
end
|
273
271
|
|
274
|
-
@size ||=
|
272
|
+
@size ||= CmsBackend.instance.search_objs(workspace, size_query)['total'].to_i
|
275
273
|
end
|
276
274
|
|
277
275
|
# load a single batch of search results from the backend.
|
@@ -282,18 +280,7 @@ module Scrivito
|
|
282
280
|
def load_batch
|
283
281
|
next_batch = fetch_next_batch(options[:offset] || 0)
|
284
282
|
|
285
|
-
|
286
|
-
next_batch.first.map { |obj| formatter.call(obj) }
|
287
|
-
end
|
288
|
-
|
289
|
-
def format(name)
|
290
|
-
@formatter = Configuration.obj_formats[name]
|
291
|
-
|
292
|
-
unless @formatter
|
293
|
-
raise UnregisteredObjFormat, "The format with name '#{name}' is not registered."
|
294
|
-
end
|
295
|
-
|
296
|
-
self
|
283
|
+
next_batch.first
|
297
284
|
end
|
298
285
|
|
299
286
|
# @api public
|
@@ -342,7 +329,7 @@ module Scrivito
|
|
342
329
|
end
|
343
330
|
|
344
331
|
def fetch_next_batch(offset)
|
345
|
-
request_result =
|
332
|
+
request_result = CmsBackend.instance.search_objs(workspace, search_dsl(offset))
|
346
333
|
|
347
334
|
obj_ids = request_result['results'].map { |result| result['id'] || result['_id'] }
|
348
335
|
objs = workspace.objs.find_including_deleted(obj_ids)
|
@@ -352,10 +339,6 @@ module Scrivito
|
|
352
339
|
[objs, @size]
|
353
340
|
end
|
354
341
|
|
355
|
-
def resource_path
|
356
|
-
"workspaces/#{workspace.id}/objs/search"
|
357
|
-
end
|
358
|
-
|
359
342
|
def search_dsl(offset)
|
360
343
|
patches = {
|
361
344
|
offset: offset,
|
@@ -89,6 +89,13 @@ module Scrivito
|
|
89
89
|
find_by(:path, paths).map(&:first)
|
90
90
|
end
|
91
91
|
|
92
|
+
def changes(offset, batch_size)
|
93
|
+
where('_modification', 'equals', ['new', 'edited', 'deleted'])
|
94
|
+
.batch_size(batch_size)
|
95
|
+
.offset(offset)
|
96
|
+
.include_deleted
|
97
|
+
end
|
98
|
+
|
92
99
|
private
|
93
100
|
|
94
101
|
def find_filtering_deleted(id_or_list, include_deleted)
|
@@ -20,8 +20,8 @@ module Scrivito
|
|
20
20
|
|
21
21
|
def add(options, &block)
|
22
22
|
options = options.with_indifferent_access
|
23
|
-
attribute = options.fetch(:
|
24
|
-
raise ScrivitoError, 'No "
|
23
|
+
attribute = options.fetch(:using) do
|
24
|
+
raise ScrivitoError, 'No "using" option given when adding a publish restriction'
|
25
25
|
end
|
26
26
|
|
27
27
|
unless block_given?
|
data/lib/scrivito/user.rb
CHANGED
@@ -1,40 +1,66 @@
|
|
1
1
|
module Scrivito
|
2
|
-
# @api
|
3
|
-
class User
|
2
|
+
# @api public
|
3
|
+
class User
|
4
|
+
# Valid action verbs for the explicit rules.
|
5
|
+
# @api public
|
6
|
+
VERBS = [
|
7
|
+
:create,
|
8
|
+
:delete,
|
9
|
+
:invite_to,
|
10
|
+
:publish,
|
11
|
+
:read,
|
12
|
+
:write,
|
13
|
+
].freeze
|
14
|
+
|
4
15
|
class << self
|
5
16
|
# Defines a new user.
|
6
|
-
# @api
|
17
|
+
# @api public
|
7
18
|
# @param [String] id the unique, unalterable id of the user.
|
8
19
|
# The user id is used to associate the user with the corresponding CMS resources.
|
9
20
|
# It will be persisted in the CMS.
|
10
21
|
# @raise [Scrivito::ScrivitoError] if id is blank
|
11
22
|
# @raise [Scrivito::ScrivitoError] if id is more than 64 characters long
|
12
|
-
# @yieldparam [Scrivito::UserDefinition] user object to define
|
13
|
-
# @see Scrivito::UserDefinition#
|
23
|
+
# @yieldparam [Scrivito::UserDefinition] user object to define rules on
|
24
|
+
# @see Scrivito::UserDefinition#can_always
|
25
|
+
# @see Scrivito::UserDefinition#can_never
|
14
26
|
# @see Scrivito::UserDefinition#description
|
27
|
+
# @see Scrivito::UserDefinition#restrict_obj_publish
|
28
|
+
# @see Scrivito::UserDefinition#suggest_users
|
15
29
|
# @example
|
16
30
|
# Scrivito::User.define('alice') do |user|
|
17
|
-
# user.
|
31
|
+
# user.description { 'Alice Almighty' }
|
32
|
+
# user.can_always(:read, :workspace)
|
33
|
+
# user.can_always(:write, :workspace)
|
34
|
+
# user.can_always(:publish, :workspace, 'You can always publish workspaces.')
|
18
35
|
# end
|
19
36
|
#
|
20
37
|
# Scrivito::User.define('bob') do |user|
|
21
38
|
# user.description { 'Bob Doe' }
|
22
|
-
# user.
|
39
|
+
# user.can_never(:create, :workspace, 'You are not allowed to create workspaces.')
|
40
|
+
# user.can_always(:read, :workspace)
|
41
|
+
# user.restrict_obj_publish(using: :_obj_class) do |obj_class|
|
42
|
+
# if obj_class.name == 'BlogPost'
|
43
|
+
# false
|
44
|
+
# else
|
45
|
+
# 'You are not allowed to publish blog posts.'
|
46
|
+
# end
|
47
|
+
# end
|
23
48
|
# end
|
24
|
-
def define(id
|
49
|
+
def define(id)
|
25
50
|
assert_valid_id(id)
|
26
51
|
user_definition = UserDefinition.new(id)
|
27
|
-
yield user_definition
|
52
|
+
yield user_definition if block_given?
|
28
53
|
user_definition.user
|
29
54
|
end
|
30
55
|
|
31
56
|
def anonymous_admin
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
57
|
+
explicit_rules = {}
|
58
|
+
VERBS.each { |verb| explicit_rules[[:can_always, verb, :workspace]] = nil }
|
59
|
+
new(id: nil, explicit_rules: explicit_rules)
|
60
|
+
end
|
61
|
+
|
62
|
+
def unknown_user(id)
|
63
|
+
new(id: id, explicit_rules: {})
|
38
64
|
end
|
39
65
|
|
40
66
|
def find(id)
|
@@ -59,18 +85,41 @@ module Scrivito
|
|
59
85
|
end
|
60
86
|
end
|
61
87
|
|
88
|
+
attr_reader :id, :explicit_rules, :description_proc, :suggest_users_proc, :restriction_set
|
89
|
+
|
62
90
|
def initialize(options)
|
63
|
-
|
64
|
-
|
91
|
+
@id = options[:id]
|
92
|
+
@explicit_rules = options[:explicit_rules]
|
93
|
+
@description_proc = options[:description_proc]
|
94
|
+
@suggest_users_proc = options[:suggest_users_proc]
|
95
|
+
@restriction_set = options[:restriction_set]
|
96
|
+
|
97
|
+
@explicit_rules.each_key { |rule| assert_valid_verb(rule.second) }
|
98
|
+
end
|
99
|
+
|
100
|
+
def can?(verb, workspace)
|
101
|
+
assert_valid_verb(verb)
|
102
|
+
can_always?(verb, :workspace) || owner_of?(workspace) && !can_never?(verb, :workspace)
|
103
|
+
end
|
104
|
+
|
105
|
+
def can_always?(verb, subject)
|
106
|
+
assert_valid_verb(verb)
|
107
|
+
@explicit_rules.has_key?([:can_always, verb, subject])
|
65
108
|
end
|
66
109
|
|
67
|
-
def
|
68
|
-
|
110
|
+
def can_never?(verb, subject)
|
111
|
+
assert_valid_verb(verb)
|
112
|
+
@explicit_rules.has_key?([:can_never, verb, subject])
|
113
|
+
end
|
114
|
+
|
115
|
+
def owner_of?(workspace)
|
116
|
+
membership = workspace.memberships[self]
|
117
|
+
membership ? membership.role == 'owner' : false
|
69
118
|
end
|
70
119
|
|
71
120
|
# Verfies if the User is able to publish changes to a certain {BasicObj Obj}
|
72
121
|
#
|
73
|
-
# @api
|
122
|
+
# @api public
|
74
123
|
# @param [BasicObj] obj the obj that should be published
|
75
124
|
# @return [Boolean] true if the user is allowed to publish otherwise false
|
76
125
|
def can_publish?(obj)
|
@@ -81,11 +130,11 @@ module Scrivito
|
|
81
130
|
# specified in a {UserDefinition#restrict_obj_publish} callback if they are not
|
82
131
|
# If the user can publish the obj an empty array is returned
|
83
132
|
#
|
84
|
-
# @api
|
133
|
+
# @api public
|
85
134
|
# @param [BasicObj] obj the obj that should be published
|
86
135
|
# @return [Array<String>] Hints why the user can't publish
|
87
136
|
def restriction_messages_for(obj)
|
88
|
-
return [] if
|
137
|
+
return [] if can_always?(:publish, :workspace)
|
89
138
|
|
90
139
|
if obj.modification == Modification::EDITED
|
91
140
|
base_revision_obj = obj.in_revision(obj.revision.workspace.base_revision)
|
@@ -102,7 +151,20 @@ module Scrivito
|
|
102
151
|
end
|
103
152
|
|
104
153
|
def suggest_users(input)
|
105
|
-
|
154
|
+
if suggest_users_proc
|
155
|
+
suggested_users = suggest_users_proc.call(input)
|
156
|
+
suggested_users.nil? ? [] : suggested_users
|
157
|
+
else
|
158
|
+
user = self.class.find(input)
|
159
|
+
user ? [user] : []
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def as_json(options = nil)
|
164
|
+
{
|
165
|
+
id: id,
|
166
|
+
description: description,
|
167
|
+
}
|
106
168
|
end
|
107
169
|
|
108
170
|
private
|
@@ -110,5 +172,9 @@ module Scrivito
|
|
110
172
|
def calculate_description
|
111
173
|
description_proc ? description_proc.call : id
|
112
174
|
end
|
175
|
+
|
176
|
+
def assert_valid_verb(verb)
|
177
|
+
raise ScrivitoError.new("Invalid verb '#{verb}'") unless VERBS.include?(verb)
|
178
|
+
end
|
113
179
|
end
|
114
180
|
end
|