scrivito_sdk 0.16.0 → 0.17.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scrivito/default_cms_controller.rb +3 -3
  3. data/app/controllers/scrivito/objs_controller.rb +18 -7
  4. data/app/controllers/scrivito/webservice_controller.rb +13 -1
  5. data/app/controllers/scrivito/workspaces_controller.rb +5 -1
  6. data/app/helpers/scrivito/cms_asset_helper.rb +8 -1
  7. data/app/helpers/scrivito/default_cms_routing_helper.rb +2 -4
  8. data/app/helpers/scrivito/display_helper.rb +0 -7
  9. data/app/helpers/scrivito/editing_helper.rb +10 -8
  10. data/app/helpers/scrivito/layout_helper.rb +4 -11
  11. data/config/ca-bundle.crt +1773 -1416
  12. data/config/cms_routes.rb +2 -2
  13. data/config/routes.rb +1 -0
  14. data/lib/assets/javascripts/scrivito_editing.js +969 -533
  15. data/lib/assets/stylesheets/scrivito_editing.css +99 -9
  16. data/lib/generators/cms/migration/templates/migration.erb +34 -6
  17. data/lib/generators/cms/widget/templates/migration.erb +3 -6
  18. data/lib/scrivito/attribute.rb +158 -0
  19. data/lib/scrivito/attribute_collection.rb +72 -0
  20. data/lib/scrivito/attribute_content.rb +39 -3
  21. data/lib/scrivito/basic_obj.rb +48 -27
  22. data/lib/scrivito/basic_widget.rb +15 -5
  23. data/lib/scrivito/client_config.rb +46 -19
  24. data/lib/scrivito/cms_field_tag.rb +1 -1
  25. data/lib/scrivito/cms_rest_api/attribute_serializer.rb +6 -1
  26. data/lib/scrivito/cms_rest_api/blob_uploader.rb +1 -1
  27. data/lib/scrivito/configuration.rb +32 -2
  28. data/lib/scrivito/connection_manager.rb +1 -6
  29. data/lib/scrivito/content_conversion.rb +11 -7
  30. data/lib/scrivito/editing_context.rb +12 -0
  31. data/lib/scrivito/gem_info.rb +13 -0
  32. data/lib/scrivito/membership.rb +26 -0
  33. data/lib/scrivito/memberships_collection.rb +78 -0
  34. data/lib/scrivito/migrations/migration.rb +1 -1
  35. data/lib/scrivito/migrations/migration_dsl.rb +37 -0
  36. data/lib/scrivito/obj_class.rb +282 -0
  37. data/lib/scrivito/obj_data.rb +20 -1
  38. data/lib/scrivito/obj_params_parser.rb +2 -0
  39. data/lib/scrivito/obj_search_builder.rb +1 -1
  40. data/lib/scrivito/obj_search_enumerator.rb +11 -6
  41. data/lib/scrivito/objs_collection.rb +130 -0
  42. data/lib/scrivito/restriction_set.rb +54 -0
  43. data/lib/scrivito/user.rb +114 -0
  44. data/lib/scrivito/user_definition.rb +159 -0
  45. data/lib/scrivito/widget_garbage_collection.rb +4 -4
  46. data/lib/scrivito/workspace.rb +13 -78
  47. data/lib/scrivito/workspace_data_from_service.rb +2 -0
  48. metadata +15 -5
@@ -58,7 +58,7 @@ class CmsFieldTag < Struct.new(
58
58
  end
59
59
 
60
60
  if FIELD_TYPES_WITH_ORIGINAL_CONTENT.include?(field_type)
61
- original_value = view_context.display_original_value(current_value)
61
+ original_value = view_context.display_value(current_value)
62
62
  original_content = original_content(field_type, original_value)
63
63
  options['private-field-original-content'] = MultiJson.encode(original_content)
64
64
  end
@@ -27,6 +27,8 @@ module Scrivito
27
27
  nil
28
28
  elsif link_array?(value)
29
29
  convert_links(value)
30
+ elsif value.is_a?(Link)
31
+ convert_link(value)
30
32
  elsif value.is_a?(BasicObj)
31
33
  value.id
32
34
  elsif widget_array?(value)
@@ -88,10 +90,13 @@ module Scrivito
88
90
 
89
91
  def convert_links(links)
90
92
  links.map do |link|
91
- link.to_cms_api_linklist_params
93
+ convert_link(link)
92
94
  end
93
95
  end
94
96
 
97
+ def convert_link(link)
98
+ link.to_cms_api_linklist_params
99
+ end
95
100
  end
96
101
  end
97
102
  end
@@ -5,7 +5,7 @@ module Scrivito
5
5
  def upload_file(file)
6
6
  upload_permission = CmsRestApi.get('blobs/upload_permission')
7
7
 
8
- fields = upload_permission['fields'].to_a + [[:file, file]]
8
+ fields = upload_permission['fields'].merge({file: file})
9
9
 
10
10
  # Net/HTTP does not support multipart forms
11
11
  RestClient.post(upload_permission['url'], fields)
@@ -32,6 +32,8 @@ module Scrivito
32
32
  # Determine if current visitor is permitted to edit content.
33
33
  attr_accessor :editing_auth_callback
34
34
 
35
+ attr_accessor :find_user_proc
36
+
35
37
  # Configure a callback to be invoked when the Scrivito SDK determines,
36
38
  # if current visitor is permitted to edit content.
37
39
  # Default is <code>false</code>.
@@ -50,6 +52,34 @@ module Scrivito
50
52
  end
51
53
  end
52
54
 
55
+ # Configures how to find users for the in-place GUI.
56
+ # @api public
57
+ # @param [Proc] find_user_proc proc for finding a user by the user id
58
+ # @yieldparam [String] user_id id of the user
59
+ # @yieldreturn [Scrivito::User] if the user with the given user id was found
60
+ # @yieldreturn [NilClass] if the user with the given user id was not found
61
+ # @raise [Scrivito::ScrivitoError] if the proc returns neither a {Scrivito::User}, nor +nil+
62
+ # @note This configuration key is optional. If it is not configured the in-place GUI would
63
+ # behave normally, but would not be able to find any users.
64
+ # @example Return a "dummy" {Scrivito::User}
65
+ # Scrivito.configure do |config|
66
+ # config.find_user do |user_id|
67
+ # Scrivito::User.new(user_id)
68
+ # end
69
+ # end
70
+ # @example Find the user with a custom user model and convert it to a {Scrivito::User}
71
+ # Scrivito.configure do |config|
72
+ # config.find_user do |user_id|
73
+ # my_user = MyUserModel.find(user_id)
74
+ # if my_user
75
+ # my_user.to_scrivito_user
76
+ # end
77
+ # end
78
+ # end
79
+ def find_user(&find_user_proc)
80
+ self.find_user_proc = find_user_proc
81
+ end
82
+
53
83
  # TODO: Legacy compatiblity. Remove when DisplayHelper gets removed.
54
84
  def editor_interface_enabled?
55
85
  false
@@ -150,7 +180,7 @@ module Scrivito
150
180
  self.endpoint = 'api.scrivito.com'
151
181
  end
152
182
 
153
- attr_accessor :choose_homepage_callback
183
+ attr_accessor :choose_homepage_callback, :activate_users_and_permissions
154
184
 
155
185
  # Configure a callback to be invoked when the Scrivito SDK delivers the homepage.
156
186
  # The given callback will receive the rack env
@@ -175,7 +205,7 @@ module Scrivito
175
205
 
176
206
  def obj_formats
177
207
  @obj_formats ||= {
178
- '_changes_list' => proc do |obj|
208
+ '_default' => proc do |obj|
179
209
  {
180
210
  id: obj.id,
181
211
  obj_class_name: obj.obj_class_name,
@@ -89,12 +89,7 @@ module Scrivito
89
89
  end
90
90
 
91
91
  def user_agent
92
- @user_agent ||= (
93
- gem_info = Gem.loaded_specs["scrivito_sdk"]
94
- if gem_info
95
- "#{gem_info.name}-#{gem_info.version}"
96
- end
97
- )
92
+ @user_agent ||= "#{GemInfo.name}-#{GemInfo.version}"
98
93
  end
99
94
  end
100
95
  end
@@ -28,15 +28,19 @@ module Scrivito
28
28
 
29
29
  def self.convert_linklist_urls(linklist, request_host, request_port)
30
30
  linklist.map do |link_data|
31
- if link_data.has_key?(:url)
32
- link_data.delete(:obj_id)
33
- url = link_data.delete(:url)
34
- link = Link.parse(url, request_host, request_port)
35
- link_data.merge!(link.to_cms_api_linklist_params)
36
- end
31
+ convert_link(link_data, request_host, request_port)
32
+ end
33
+ end
37
34
 
38
- link_data
35
+ def self.convert_link(link_data, request_host, request_port)
36
+ if link_data && link_data.has_key?(:url)
37
+ link_data.delete(:obj_id)
38
+ url = link_data.delete(:url)
39
+ link = Link.parse(url, request_host, request_port)
40
+ link_data.merge!(link.to_cms_api_linklist_params)
39
41
  end
42
+
43
+ link_data
40
44
  end
41
45
  end
42
46
 
@@ -16,6 +16,18 @@ class EditingContext
16
16
  unless @editor_already_evaluated
17
17
  @editor_already_evaluated = true
18
18
  @editor = @editor_callback.call
19
+
20
+ if @editor && !@editor.is_a?(Scrivito::User)
21
+ if Scrivito::Configuration.activate_users_and_permissions
22
+ raise ScrivitoError.new(
23
+ "The editing auth callback has to return a Scrivito::User or falsy."+
24
+ " To upgrade please return Scrivito::User.new(id) and set the permissions" +
25
+ " of the user. See the documentation for further details."
26
+ )
27
+ else
28
+ @editor = User.anonymous_admin
29
+ end
30
+ end
19
31
  end
20
32
 
21
33
  @editor
@@ -0,0 +1,13 @@
1
+ module Scrivito
2
+ module GemInfo
3
+ class << self
4
+ delegate :name, :version, to: :spec
5
+
6
+ private
7
+
8
+ def spec
9
+ @spec ||= Gem.loaded_specs['scrivito_sdk']
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module Scrivito
2
+
3
+ # @api beta
4
+ # Represents a Membership of a {User} in a {Workspace}
5
+ class Membership
6
+
7
+ # @api beta
8
+ # The {User User's} id
9
+ #
10
+ # @return [String]
11
+ attr_reader :user_id
12
+
13
+ # @api beta
14
+ # The role associated with this membership.
15
+ #
16
+ # @note Currently the only available role is "owner".
17
+ #
18
+ # @return [String] the name of role
19
+ attr_reader :role
20
+
21
+ def initialize(user_id, data)
22
+ @user_id = user_id
23
+ @role = data.fetch("role")
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,78 @@
1
+ module Scrivito
2
+ # @api beta
3
+ # The MembershipsCollection includes all members of a given {Workspace}.
4
+ # You can access it using {Workspace#memberships} method.
5
+ class MembershipsCollection
6
+ extend Forwardable
7
+ include Enumerable
8
+
9
+ attr_reader :workspace
10
+
11
+ # @api beta
12
+ # @!method each
13
+ # Iterate over all {Membership Memberships} of a specfic {Workspace}. Allows
14
+ # you to use all methods defined by ruby's Enumerable module.
15
+ #
16
+ # @yield [Membership]
17
+ #
18
+ # @return [Enumerator] if no block is given an Enumerator is returned
19
+ #
20
+ # @example
21
+ # # Optain all owners of a workspace
22
+ # my_workspace.memberships.select do |membership|
23
+ # membership.role == "owner"
24
+ # end
25
+ #
26
+ # # Get an array of all the members' user_ids
27
+ # my_workspace.memberships.map { |membership| membership.user_id }
28
+ #
29
+ # # Or use it directly to iterate over all items
30
+ # my_workspace.memberships.each do |membership|
31
+ # puts "User #{membership.user_id} has the role #{membership.role}"
32
+ # end
33
+ #
34
+ # @note For a complete list of all provided methods please view the
35
+ # documentation of the Enumerable module
36
+ def_delegator :memberships, :each
37
+
38
+ def initialize(workspace)
39
+ @workspace = workspace
40
+ end
41
+
42
+ # @api beta
43
+ # return a hash where the keys are user_ids and the values are Membership-Instances
44
+ # @return [Hash<String, Membership>]
45
+ def to_h
46
+ memberships.inject(HashWithIndifferentAccess.new) do |hash, membership|
47
+ hash[membership.user_id] = membership
48
+ hash
49
+ end
50
+ end
51
+
52
+ # @api beta
53
+ # Returns the membership for a user or nil
54
+ #
55
+ # @param [User, String] id_or_user
56
+ # @return [Membership, nil]
57
+ def [](id_or_user)
58
+ id = if id_or_user.respond_to?(:id)
59
+ id_or_user.id
60
+ else
61
+ id_or_user
62
+ end
63
+
64
+ to_h[id]
65
+ end
66
+
67
+ private
68
+
69
+ def memberships
70
+ @memberships ||= begin
71
+ workspace.data.memberships.map do |id, data|
72
+ Membership.new(id, data)
73
+ end
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -9,7 +9,7 @@ module Scrivito
9
9
  #
10
10
  # class CreateTestAttribute < Scrivito::Migrations::Migration
11
11
  # def up
12
- # add_attribute_to('homepage', :name => 'test', :type => 'string')
12
+ # ObjClass.find('Homepage').attributes.add(Attribute.new(name: 'test', type: :string))
13
13
  # end
14
14
  # end
15
15
  class Migration
@@ -5,6 +5,8 @@ module Scrivito
5
5
  module MigrationDsl
6
6
  # Adds an attribute to an object class.
7
7
  #
8
+ # @deprecated Please use {AttributeCollection#add} instead.
9
+ #
8
10
  # @example Add "test" attribute to object class "Foo.
9
11
  #
10
12
  # add_attribute_to('Foo', { name: 'test', type: 'string' })
@@ -14,6 +16,11 @@ module Scrivito
14
16
  #
15
17
  # @return nothing
16
18
  def add_attribute_to(obj_class_name, params)
19
+ Deprecation.warn_method(
20
+ 'add_attribute_to',
21
+ 'ObjClass#attributes.add(Attribute.new(params))'
22
+ )
23
+
17
24
  attributes = get_obj_class(obj_class_name)['attributes']
18
25
  attributes << params
19
26
 
@@ -22,6 +29,8 @@ module Scrivito
22
29
 
23
30
  # Deletes an attribute from an object class.
24
31
  #
32
+ # @deprecated Please use {Attribute#destroy} instead.
33
+ #
25
34
  # @example Delete "test" attribute from object class "Foo.
26
35
  #
27
36
  # delete_attribute_from('Foo', 'test')
@@ -32,6 +41,11 @@ module Scrivito
32
41
  #
33
42
  # @return nothing
34
43
  def delete_attribute_from(obj_class_name, attribute_name)
44
+ Deprecation.warn_method(
45
+ 'delete_attribute_from',
46
+ 'ObjClass#attributes[attribute_name].destroy()'
47
+ )
48
+
35
49
  attributes = get_obj_class(obj_class_name)['attributes']
36
50
  attributes = attributes.delete_if do |attribute|
37
51
  attribute['name'] == attribute_name.to_s
@@ -42,6 +56,8 @@ module Scrivito
42
56
 
43
57
  # Updates an attribute for an object class.
44
58
  #
59
+ # @deprecated Please use {Attribute#update} instead.
60
+ #
45
61
  # @example Update "test" attribute for object class "Foo.
46
62
  #
47
63
  # update_attribute_for('Foo', 'test', { title: 'New Title' })
@@ -53,6 +69,11 @@ module Scrivito
53
69
  #
54
70
  # @return nothing
55
71
  def update_attribute_for(obj_class_name, attribute_name, params)
72
+ Deprecation.warn_method(
73
+ 'update_attribute_for',
74
+ 'ObjClass#attributes[attribute_name].update(params)'
75
+ )
76
+
56
77
  attribute_name = attribute_name.to_s
57
78
  attributes = get_obj_class(obj_class_name)['attributes']
58
79
  found = false
@@ -75,6 +96,8 @@ module Scrivito
75
96
 
76
97
  # Creates a CMS object class.
77
98
  #
99
+ # @deprecated Please use {ObjClass.create} instead.
100
+ #
78
101
  # @example Create "Test" Object Class
79
102
  #
80
103
  # create_obj_class(name: 'Test', type: 'publication')
@@ -85,6 +108,8 @@ module Scrivito
85
108
  # @return nothing
86
109
  # @api public
87
110
  def create_obj_class(attributes = {})
111
+ Deprecation.warn_method('create_obj_class', 'ObjClass.create(attributes)')
112
+
88
113
  endpoint = "workspaces/#{Workspace.current.id}/obj_classes"
89
114
 
90
115
  CmsRestApi.post(endpoint, obj_class: attributes)
@@ -92,6 +117,8 @@ module Scrivito
92
117
 
93
118
  # Fetches all object attributes and their values.
94
119
  #
120
+ # @deprecated Please use {BasicObj.find} instead.
121
+ #
95
122
  # @example Get all attributes for the obj with id "abc123"
96
123
  #
97
124
  # get_obj('abc123')
@@ -101,6 +128,8 @@ module Scrivito
101
128
  # @return [Hash] a hash with attributes and their values.
102
129
  # @api public
103
130
  def get_obj(id)
131
+ Deprecation.warn_method('get_obj', 'Obj.find(id)')
132
+
104
133
  endpoint = "workspaces/#{Workspace.current.id}/objs/#{id}"
105
134
 
106
135
  CmsRestApi.get(endpoint)
@@ -108,6 +137,8 @@ module Scrivito
108
137
 
109
138
  # Fetches all object class attributes and their values.
110
139
  #
140
+ # @deprecated Please use {ObjClass.find} instead.
141
+ #
111
142
  # @example Get all attributes for the object class "Test"
112
143
  #
113
144
  # get_obj_class('Test')
@@ -117,6 +148,8 @@ module Scrivito
117
148
  # @return [Hash] a hash with attributes and their values.
118
149
  # @api public
119
150
  def get_obj_class(id)
151
+ Deprecation.warn_method('get_obj_class', 'ObjClass.find(id)')
152
+
120
153
  endpoint = "workspaces/#{Workspace.current.id}/obj_classes/#{id}"
121
154
 
122
155
  CmsRestApi.get(endpoint)
@@ -124,6 +157,8 @@ module Scrivito
124
157
 
125
158
  # Updates a CMS object class.
126
159
  #
160
+ # @deprecated Please use {ObjClass#update} instead.
161
+ #
127
162
  # @example Update the title of the "Test" Object Class
128
163
  #
129
164
  # update_obj_class('Test', title: 'Test Title')
@@ -134,6 +169,8 @@ module Scrivito
134
169
  # @return nothing
135
170
  # @api public
136
171
  def update_obj_class(id, attributes = {})
172
+ Deprecation.warn_method('update_obj_class', 'ObjClass#update(attributes)')
173
+
137
174
  endpoint = "workspaces/#{Workspace.current.id}/obj_classes/#{id}"
138
175
 
139
176
  CmsRestApi.put(endpoint, obj_class: attributes)
@@ -0,0 +1,282 @@
1
+ module Scrivito
2
+ # This class represents a CMS obj class. Obj classes can be created, updated and all properties
3
+ # can be read. The class also provides methods to find obj classes. The attributes of an obj class
4
+ # are defined by {Scrivito::Attribute} instances.
5
+ #
6
+ # @api public
7
+ class ObjClass
8
+ include ModelIdentity
9
+
10
+ class << self
11
+ # Returns all the obj classes.
12
+ #
13
+ # @api public
14
+ #
15
+ # @example Find all obj classes in the current {Scrivito::Workspace}.
16
+ # ObjClass.all
17
+ #
18
+ # @return [Array<Scrivito::ObjClass>]
19
+ def all
20
+ results = CmsRestApi.get("workspaces/#{Workspace.current.id}/obj_classes")['results']
21
+
22
+ results.map do |properties|
23
+ new(properties)
24
+ end
25
+ end
26
+
27
+ # Finds an obj class by its name.
28
+ #
29
+ # @api public
30
+ #
31
+ # @example Find the obj class named "Homepage" in the current {Scrivito::Workspace}.
32
+ # ObjClass.find('Homepage')
33
+ #
34
+ # @param [String] name The name of the obj class.
35
+ # @return [Scrivito::ObjClass]
36
+ # @raise [Scrivito::ResourceNotFound] Raised when no obj class with the given +name+ can be found.
37
+ def find(name)
38
+ response = begin
39
+ CmsRestApi.get("workspaces/#{Workspace.current.id}/obj_classes/#{name}")
40
+ rescue Scrivito::ClientError
41
+ raise ResourceNotFound, "Could not find '#{self}' with name '#{name}'."
42
+ end
43
+
44
+ new(response)
45
+ end
46
+
47
+ # Creates a new obj class and persists it in the CMS.
48
+ #
49
+ # @api public
50
+ #
51
+ # This allows you to set the different properties of an obj class by
52
+ # providing a hash with the property names as keys and the values you want
53
+ # to set as values. Attributes can be either given as {Scrivito::Attribute} instances or as
54
+ # an attribute property hash.
55
+ #
56
+ # @example Create a non-binary obj class.
57
+ # ObjClass.create(name: 'Homepage', is_binary: false)
58
+ #
59
+ # @example Create a binary obj class.
60
+ # ObjClass.create(name: 'Image', is_binary: true)
61
+ #
62
+ # @example Create an obj class with attributes passed in as an Array of attribute property hashes.
63
+ # ObjClass.create(name: 'Blog', attributes: [
64
+ # { name: 'headline', type: :string },
65
+ # { name: 'category', type: :enum, values: %w(tech social) },
66
+ # ])
67
+ #
68
+ # @example Create an obj class with attributes passed in as an Array of {Scrivito::Attribute} instances.
69
+ # ObjClass.create(name: 'Blog', attributes: [
70
+ # Attribute.new(name: 'headline', type: :string),
71
+ # Attribute.new(name: 'category', type: :enum, values: %w(tech social)),
72
+ # ])
73
+ #
74
+ # @param [Hash] properties
75
+ # @option properties [String] :name The name of the obj class.
76
+ # @option properties [Boolean] :is_binary Is this a binary or non-binary obj class?
77
+ # @option properties [Boolean] :is_active Is it possible to create instances of this obj class?
78
+ # @option properties [Array<Scrivito::Attribute>, Array<Hash>] :attributes A list of
79
+ # attributes for this obj class. Can be either a list of attribute instances or attribute
80
+ # property hashes.
81
+ #
82
+ # @return [Scrivito::ObjClass]
83
+ def create(properties)
84
+ properties = properties.with_indifferent_access
85
+
86
+ unless properties.has_key?(:is_binary)
87
+ raise ScrivitoError, 'The "is_binary" property is mandatory. Please provide' \
88
+ ' a hash containing an "is_binary" key with true or false value.'
89
+ end
90
+
91
+ if properties[:attributes]
92
+ properties[:attributes].map! do |attribute|
93
+ attribute.respond_to?(:to_cms_rest_api) ? attribute : Attribute.new(attribute)
94
+ end
95
+ end
96
+
97
+ params = format_properties_for_cms(properties)
98
+ obj_class = new(params)
99
+
100
+ if properties[:attributes]
101
+ properties[:attributes].each do |attribute|
102
+ attribute.obj_class = obj_class
103
+ end
104
+ end
105
+
106
+ payload = { 'obj_class' => params }
107
+ response = CmsRestApi.post("workspaces/#{Workspace.current.id}/obj_classes", payload)
108
+
109
+ obj_class.update_instance_properties(response)
110
+
111
+ obj_class
112
+ end
113
+
114
+ private
115
+
116
+ # Formats obj class properties into a CMS REST API format.
117
+ # @param [Hash] properties
118
+ # @return [Hash] Properties formated for the CMS.
119
+ def format_properties_for_cms(properties)
120
+ params = properties.dup
121
+
122
+ if params.has_key?(:is_binary)
123
+ params[:type] = params.delete(:is_binary) ? :generic : :publication
124
+ end
125
+
126
+ if params.has_key?(:attributes)
127
+ params[:attributes] = params[:attributes].map do |attribute|
128
+ attribute.to_cms_rest_api
129
+ end
130
+ end
131
+
132
+ params
133
+ end
134
+ end
135
+
136
+ # Initializes a new obj class. It expects the CMS backend representation of an obj class.
137
+ #
138
+ # See {ObjClass.create} for a detailed overview of how to set properties.
139
+ #
140
+ # @param [Hash] properties
141
+ # @return [Scrivito::ObjClass]
142
+ # @raise [Scrivito::ScrivitoError]
143
+ def initialize(properties)
144
+ update_instance_properties(properties)
145
+ end
146
+
147
+ # Returns a unique identifier of this obj class. Implements
148
+ # the {Scrivito::ModelIdentity} interface.
149
+ # @return [String]
150
+ def id
151
+ @name
152
+ end
153
+
154
+ # Returns the name of this obj class.
155
+ # @api public
156
+ # @return [String]
157
+ def name
158
+ @name
159
+ end
160
+
161
+ # Returns if new {Scrivito::BasicObj} instances can be created with this obj class.
162
+ # @api public
163
+ # @return [Boolean]
164
+ def is_active
165
+ @is_active
166
+ end
167
+ alias_method :active?, :is_active
168
+
169
+ # Returns if new {Scrivito::BasicObj} instances created with this obj class are
170
+ # binary objects like images or PDF documents.
171
+ # @api public
172
+ # @return [Boolean]
173
+ def is_binary
174
+ @is_binary
175
+ end
176
+ alias_method :binary?, :is_binary
177
+
178
+ # Returns the attributes for this obj class.
179
+ #
180
+ # @api public
181
+ #
182
+ # @example Find an attribute named "locale" for the obj class "Homepage".
183
+ # ObjClass.find('Homepage').attributes['locale']
184
+ #
185
+ # @example Add a new +string+ attribute named "headline" to the "Homepage" obj class by providing an attribute property hash.
186
+ # ObjClass.find('Homepage').attributes.add(name: 'headline', type: :string)
187
+ #
188
+ # @example Add a new +enum+ attribute named "category" to the "Homepage" obj class by providing an attribute instance.
189
+ # attribute = Attribute.new(name: 'category', type: :enum, values: %w(tech social))
190
+ # ObjClass.find('Homepage').attributes.add(attribute)
191
+ #
192
+ # @example Iterate over the list of attributes from the obj class "Homepage" and print their name and type.
193
+ # ObjClass.find('Homepage').attributes.each do |attribute|
194
+ # puts "#{attribute.name}:#{attribute.type}"
195
+ # end
196
+ #
197
+ # @return [Scrivito::AttributeCollection]
198
+ def attributes
199
+ @attributes
200
+ end
201
+
202
+ # Updates this obj class and persists the changes in the CMS. It is not possible to
203
+ # update the +name+ or +is_binary+ property.
204
+ #
205
+ # @api public
206
+ #
207
+ # See {Scrivito::ObjClass.create} for a detailed overview of
208
+ # what properties are allowed and how to set them.
209
+ #
210
+ # @param [Hash] properties
211
+ #
212
+ # @raise [ScrivitoError] Raised when trying to change +name+ or +is_binary+.
213
+ #
214
+ # @return [nil]
215
+ def update(properties)
216
+ params = properties.with_indifferent_access
217
+
218
+ if params.has_key?(:is_binary)
219
+ raise ScrivitoError, "#{self.class} does not support changing 'is_binary'. Please remove" \
220
+ " the key from the properties."
221
+ end
222
+
223
+ if params.has_key?(:name)
224
+ raise ScrivitoError, "#{self.class} does not support changing 'name'. Please remove" \
225
+ " the key from the properties."
226
+ end
227
+
228
+ if params.has_key?(:attributes)
229
+ params[:attributes].map! do |attribute|
230
+ unless attribute.respond_to?(:to_cms_rest_api)
231
+ attribute = Attribute.new(attribute)
232
+ end
233
+
234
+ attribute.obj_class = self
235
+ attribute.to_cms_rest_api
236
+ end
237
+ end
238
+
239
+ payload = { obj_class: params }
240
+ response = CmsRestApi.put("workspaces/#{Workspace.current.id}/obj_classes/#{name}", payload)
241
+
242
+ update_instance_properties(response)
243
+
244
+ nil
245
+ end
246
+
247
+ # Updates the instance properties of this obj class with +properties+
248
+ # given in the CMS REST API format.
249
+ #
250
+ # @param [Hash] properties
251
+ # @return [void]
252
+ def update_instance_properties(properties)
253
+ properties = properties.with_indifferent_access
254
+
255
+ if properties.has_key?(:type)
256
+ properties[:is_binary] = %w(image generic).include?(properties[:type])
257
+ end
258
+
259
+ @name = properties[:name].to_s
260
+ @is_active = properties[:is_active]
261
+ @is_binary = properties[:is_binary]
262
+ @attributes = create_attribute_collection(properties[:attributes] || [])
263
+ end
264
+
265
+ private
266
+
267
+ # Creates an attribute collection from an Array of attributes given in the CMS REST API format
268
+ # and binds all attributes to this obj class.
269
+ #
270
+ # @param [Array] attributes
271
+ # @return [Scrivito::AttributeCollection]
272
+ def create_attribute_collection(attributes)
273
+ attributes = attributes.map do |properties|
274
+ attribute = Attribute.new(properties)
275
+ attribute.obj_class = self
276
+ attribute
277
+ end
278
+
279
+ AttributeCollection.new(self, attributes)
280
+ end
281
+ end
282
+ end