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