scrivito_sdk 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -450,16 +450,16 @@ html.scrivito_bottombar_on {
450
450
  line-height: 15px;
451
451
  color: #eee;
452
452
  }
453
- .scrivito_menu_box .scrivito_menu_item.disabled span:hover,
454
- .scrivito_menu_box .scrivito_menu_item.disabled a:hover {
453
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled span:hover,
454
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled a:hover {
455
455
  cursor: help;
456
456
  color: #696969!important;
457
457
  background: #274324;
458
458
  }
459
- .scrivito_menu_box .scrivito_menu_item.disabled span,
460
- .scrivito_menu_box .scrivito_menu_item.disabled a,
461
- .scrivito_menu_box .scrivito_menu_item.disabled span .scrivito_icon,
462
- .scrivito_menu_box .scrivito_menu_item.disabled a .scrivito_icon {
459
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled span,
460
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled a,
461
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled span .scrivito_icon,
462
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled a .scrivito_icon {
463
463
  color: #696969!important;
464
464
  cursor: help;
465
465
  }
@@ -653,6 +653,11 @@ body.scrivito_editing_active {
653
653
  -moz-transition: box-shadow linear .5s;
654
654
  -o-transition: box-shadow linear .5s;
655
655
  transition: box-shadow linear .5s;
656
+ -webkit-transform: translate3d(0, 0, 0);
657
+ -moz-transform: translate3d(0, 0, 0);
658
+ -ms-transform: translate3d(0, 0, 0);
659
+ -o-transform: translate3d(0, 0, 0);
660
+ transform: translate3d(0, 0, 0);
656
661
  }
657
662
  .scrivito_topbar .scrivito_first_level .scrivito_button_bar:hover,
658
663
  .scrivito_topbar .scrivito_first_level .scrivito_button_bar:focus,
@@ -697,6 +702,11 @@ body.scrivito_editing_active {
697
702
  -moz-transition: box-shadow linear .5s;
698
703
  -o-transition: box-shadow linear .5s;
699
704
  transition: box-shadow linear .5s;
705
+ -webkit-transform: translate3d(0, 0, 0);
706
+ -moz-transform: translate3d(0, 0, 0);
707
+ -ms-transform: translate3d(0, 0, 0);
708
+ -o-transform: translate3d(0, 0, 0);
709
+ transform: translate3d(0, 0, 0);
700
710
  }
701
711
  .scrivito_topbar .scrivito_second_level .scrivito_separator {
702
712
  display: block;
@@ -788,6 +798,11 @@ body.scrivito_editing_active {
788
798
  -moz-transition: all ease-in-out .4s;
789
799
  -o-transition: all ease-in-out .4s;
790
800
  transition: all ease-in-out .4s;
801
+ -webkit-transform: translate3d(0, 0, 0);
802
+ -moz-transform: translate3d(0, 0, 0);
803
+ -ms-transform: translate3d(0, 0, 0);
804
+ -o-transform: translate3d(0, 0, 0);
805
+ transform: translate3d(0, 0, 0);
791
806
  }
792
807
  .scrivito_viewmodes_wrapper.disable_trasitions .scrivito_viewmodes .scrivito_viewmode_pill {
793
808
  -webkit-transition: none;
@@ -887,8 +902,12 @@ body.scrivito_editing_active {
887
902
  font-size: 7px;
888
903
  color: #ddd;
889
904
  }
890
- .scrivito_menu_box.scrivito_switch_mode_menu {
905
+ .scrivito_viewmodes .scrivito_viewmode_label .scrivito_menu_box {
891
906
  left: 18px;
907
+ top: 10px;
908
+ }
909
+ #scrivito_current_page_menu .scrivito_menu_box {
910
+ top: 20px;
892
911
  }
893
912
  .scrivito_editing_confirmation {
894
913
  display: none;
@@ -945,6 +964,11 @@ body.scrivito_editing_active {
945
964
  -moz-transition: background ease-in-out .6s;
946
965
  -o-transition: background ease-in-out .6s;
947
966
  transition: background ease-in-out .6s;
967
+ -webkit-transform: translate3d(0, 0, 0);
968
+ -moz-transform: translate3d(0, 0, 0);
969
+ -ms-transform: translate3d(0, 0, 0);
970
+ -o-transform: translate3d(0, 0, 0);
971
+ transform: translate3d(0, 0, 0);
948
972
  }
949
973
  .scrivito_editing_marker:hover,
950
974
  .scrivito_editing_marker:active {
@@ -953,6 +977,11 @@ body.scrivito_editing_active {
953
977
  -moz-transition: background ease-in-out .2s;
954
978
  -o-transition: background ease-in-out .2s;
955
979
  transition: background ease-in-out .2s;
980
+ -webkit-transform: translate3d(0, 0, 0);
981
+ -moz-transform: translate3d(0, 0, 0);
982
+ -ms-transform: translate3d(0, 0, 0);
983
+ -o-transform: translate3d(0, 0, 0);
984
+ transform: translate3d(0, 0, 0);
956
985
  }
957
986
  .scrivito_editing_marker .scrivito_icon {
958
987
  padding: 0;
@@ -1004,6 +1033,11 @@ body.scrivito_editing_active {
1004
1033
  -moz-transition: opacity ease-in-out .4s;
1005
1034
  -o-transition: opacity ease-in-out .4s;
1006
1035
  transition: opacity ease-in-out .4s;
1036
+ -webkit-transform: translate3d(0, 0, 0);
1037
+ -moz-transform: translate3d(0, 0, 0);
1038
+ -ms-transform: translate3d(0, 0, 0);
1039
+ -o-transform: translate3d(0, 0, 0);
1040
+ transform: translate3d(0, 0, 0);
1007
1041
  pointer-events: none;
1008
1042
  }
1009
1043
  [data-scrivito-display-mode="editing"] [data-scrivito-private-child-list-path].scrivito_entered:hover > .scrivito_editing_marker .scrivito_editing_marker_title,
@@ -1016,6 +1050,11 @@ body.scrivito_editing_active {
1016
1050
  -moz-transition: opacity ease-in-out .4s;
1017
1051
  -o-transition: opacity ease-in-out .4s;
1018
1052
  transition: opacity ease-in-out .4s;
1053
+ -webkit-transform: translate3d(0, 0, 0);
1054
+ -moz-transform: translate3d(0, 0, 0);
1055
+ -ms-transform: translate3d(0, 0, 0);
1056
+ -o-transform: translate3d(0, 0, 0);
1057
+ transform: translate3d(0, 0, 0);
1019
1058
  }
1020
1059
  .scrivito_structure_marker {
1021
1060
  display: block;
@@ -1044,6 +1083,11 @@ body.scrivito_editing_active {
1044
1083
  -moz-transition: background ease-in-out .6s;
1045
1084
  -o-transition: background ease-in-out .6s;
1046
1085
  transition: background ease-in-out .6s;
1086
+ -webkit-transform: translate3d(0, 0, 0);
1087
+ -moz-transform: translate3d(0, 0, 0);
1088
+ -ms-transform: translate3d(0, 0, 0);
1089
+ -o-transform: translate3d(0, 0, 0);
1090
+ transform: translate3d(0, 0, 0);
1047
1091
  }
1048
1092
  .scrivito_structure_marker:hover,
1049
1093
  .scrivito_structure_marker:active {
@@ -1053,6 +1097,11 @@ body.scrivito_editing_active {
1053
1097
  -moz-transition: background ease-in-out .2s;
1054
1098
  -o-transition: background ease-in-out .2s;
1055
1099
  transition: background ease-in-out .2s;
1100
+ -webkit-transform: translate3d(0, 0, 0);
1101
+ -moz-transform: translate3d(0, 0, 0);
1102
+ -ms-transform: translate3d(0, 0, 0);
1103
+ -o-transform: translate3d(0, 0, 0);
1104
+ transform: translate3d(0, 0, 0);
1056
1105
  }
1057
1106
  .scrivito_structure_marker .scrivito_icon {
1058
1107
  padding: 0;
@@ -1222,16 +1271,26 @@ a.scrivito_button:active {
1222
1271
  -moz-transition: opacity 0.1s linear;
1223
1272
  -o-transition: opacity 0.1s linear;
1224
1273
  transition: opacity 0.1s linear;
1274
+ -webkit-transform: translate3d(0, 0, 0);
1275
+ -moz-transform: translate3d(0, 0, 0);
1276
+ -ms-transform: translate3d(0, 0, 0);
1277
+ -o-transform: translate3d(0, 0, 0);
1278
+ transform: translate3d(0, 0, 0);
1225
1279
  background: rgba(0, 0, 0, 0.8);
1226
1280
  }
1227
1281
  .scrivito_overlay.scrivito_show {
1228
- z-index: 222222;
1282
+ z-index: 333333;
1229
1283
  opacity: 0.85;
1230
1284
  filter: alpha(opacity=85);
1231
1285
  -webkit-transition: opacity 0.6s linear;
1232
1286
  -moz-transition: opacity 0.6s linear;
1233
1287
  -o-transition: opacity 0.6s linear;
1234
1288
  transition: opacity 0.6s linear;
1289
+ -webkit-transform: translate3d(0, 0, 0);
1290
+ -moz-transform: translate3d(0, 0, 0);
1291
+ -ms-transform: translate3d(0, 0, 0);
1292
+ -o-transform: translate3d(0, 0, 0);
1293
+ transform: translate3d(0, 0, 0);
1235
1294
  }
1236
1295
  .scrivito_overlay .scrivito_processing {
1237
1296
  display: block;
@@ -1563,7 +1622,7 @@ a.scrivito_button:active {
1563
1622
  position: fixed;
1564
1623
  left: 50%;
1565
1624
  top: -100%;
1566
- z-index: 1000;
1625
+ z-index: 333333;
1567
1626
  overflow: auto;
1568
1627
  color: #fff;
1569
1628
  width: 500px;
@@ -1580,6 +1639,11 @@ a.scrivito_button:active {
1580
1639
  -moz-transition: all 0.45s ease-in;
1581
1640
  -o-transition: all 0.45s ease-in;
1582
1641
  transition: all 0.45s ease-in;
1642
+ -webkit-transform: translate3d(0, 0, 0);
1643
+ -moz-transform: translate3d(0, 0, 0);
1644
+ -ms-transform: translate3d(0, 0, 0);
1645
+ -o-transform: translate3d(0, 0, 0);
1646
+ transform: translate3d(0, 0, 0);
1583
1647
  }
1584
1648
  .scrivito_modal_prompt.scrivito_show {
1585
1649
  top: 50%;
@@ -1667,6 +1731,11 @@ a.scrivito_button:active {
1667
1731
  -moz-transition: all 0.25s ease-in;
1668
1732
  -o-transition: all 0.25s ease-in;
1669
1733
  transition: all 0.25s ease-in;
1734
+ -webkit-transform: translate3d(0, 0, 0);
1735
+ -moz-transform: translate3d(0, 0, 0);
1736
+ -ms-transform: translate3d(0, 0, 0);
1737
+ -o-transform: translate3d(0, 0, 0);
1738
+ transform: translate3d(0, 0, 0);
1670
1739
  }
1671
1740
  .scrivito_modal_small {
1672
1741
  width: 500px;
@@ -1812,6 +1881,12 @@ a.scrivito_button:active {
1812
1881
  vertical-align: middle;
1813
1882
  line-height: 14px;
1814
1883
  }
1884
+ .scrivito_details_dialog .scrivito_modal_header .scrivito_saving_state_bar {
1885
+ right: 50px;
1886
+ }
1887
+ .scrivito_details_dialog .scrivito_modal_header .scrivito_menu_box {
1888
+ top: 20px;
1889
+ }
1815
1890
  .scrivito_changes_overview.scrivito_modal_large .scrivito_modal_header select {
1816
1891
  font-weight: normal;
1817
1892
  border: 0px;
@@ -2147,6 +2222,11 @@ a.scrivito_button:active {
2147
2222
  -moz-transition: all ease-in-out .3s;
2148
2223
  -o-transition: all ease-in-out .3s;
2149
2224
  transition: all ease-in-out .3s;
2225
+ -webkit-transform: translate3d(0, 0, 0);
2226
+ -moz-transform: translate3d(0, 0, 0);
2227
+ -ms-transform: translate3d(0, 0, 0);
2228
+ -o-transform: translate3d(0, 0, 0);
2229
+ transform: translate3d(0, 0, 0);
2150
2230
  -webkit-border-radius: 5px;
2151
2231
  -moz-border-radius: 5px;
2152
2232
  border-radius: 5px;
@@ -2161,6 +2241,11 @@ a.scrivito_button:active {
2161
2241
  -moz-transition: all ease-in-out .3s;
2162
2242
  -o-transition: all ease-in-out .3s;
2163
2243
  transition: all ease-in-out .3s;
2244
+ -webkit-transform: translate3d(0, 0, 0);
2245
+ -moz-transform: translate3d(0, 0, 0);
2246
+ -ms-transform: translate3d(0, 0, 0);
2247
+ -o-transform: translate3d(0, 0, 0);
2248
+ transform: translate3d(0, 0, 0);
2164
2249
  }
2165
2250
  .scrivito_editing_widget_preview:active,
2166
2251
  .scrivito_editing_widget_preview.selected {
@@ -2173,6 +2258,11 @@ a.scrivito_button:active {
2173
2258
  -moz-transition: all ease-in-out .3s;
2174
2259
  -o-transition: all ease-in-out .3s;
2175
2260
  transition: all ease-in-out .3s;
2261
+ -webkit-transform: translate3d(0, 0, 0);
2262
+ -moz-transform: translate3d(0, 0, 0);
2263
+ -ms-transform: translate3d(0, 0, 0);
2264
+ -o-transform: translate3d(0, 0, 0);
2265
+ transform: translate3d(0, 0, 0);
2176
2266
  }
2177
2267
  .scrivito_editing_widget_preview .scrivito_editing_widget_visualization {
2178
2268
  height: 120px;
@@ -1,10 +1,38 @@
1
1
  class <%= class_name %> < ::Scrivito::Migration
2
2
  def up
3
- # get_obj_class('Test')
4
- # create_obj_class(name: 'Test', type: :publication, attributes: [])
5
- # update_obj_class('Test', title: 'Test Title')
6
- # add_attribute_to('Test', { name: 'test', type: 'string' })
7
- # update_attribute_for('Test', 'test', { title: 'New Title' })
8
- # delete_attribute_from('Test', 'test')
3
+ # This migration file allows to create and modify object class definitions or to change the CMS
4
+ # content programatically. All Scrivito SDK classes and methods are available and arbitrary Ruby
5
+ # code can be executed.
6
+ #
7
+ # Use `bundle exec rake cms:migrate` to run all migrations that are new to the `rtc` workspace.
8
+ # Migrations are identified by an ID and only get executed once. If you migrate the CMS an
9
+ # existing `rtc` workspace is used or a new `rtc` workspace is created. Only one developer at a
10
+ # time can run migrations, which means to quickly try to publish the current migrations.
11
+ #
12
+ # Use `bundle exec rake cms:migrate:publish` to publish your `rtc` workspace that holds the
13
+ # latest unpublished migrations.
14
+ #
15
+ # To get you started, here is a list of the most common SDK methods to alter the CMS content.
16
+ #
17
+ # @example Create a new obj class named "Homepage" of type "publication" that has a "string" attribute named "locale".
18
+ # Scrivito::ObjClass.create(name: 'Homepage', type: :publication, attributes: [
19
+ # {name: 'locale', type: :string}
20
+ # ])
21
+ #
22
+ # @example Find the obj class named "Homepage".
23
+ # Scrivito::ObjClass.find('Homepage')
24
+ #
25
+ # @example Update the "title" of an obj class named "Homepage".
26
+ # Scrivito::ObjClass.find('Homepage').update(title: 'Home')
27
+ #
28
+ # @example Add an "enum" attribute named "category" to the obj class named "Homepage".
29
+ # Scrivito::ObjClass.find('Homepage').attributes.add(name: 'category', type: :enum, values: %w(tech, social))
30
+ #
31
+ # @example Update the "category" attribute and add another value.
32
+ # attribute = Scrivito::ObjClass.find('Homepage').attributes['category']
33
+ # attribute.update(values: attribute.values << 'media')
34
+ #
35
+ # @example Destroy the attribute "category" from the obj class "Homepage".
36
+ # Scrivito::ObjClass.find('Homepage').attributes['category'].destroy
9
37
  end
10
38
  end
@@ -1,14 +1,11 @@
1
1
  class Create<%= class_name %> < ::Scrivito::Migration
2
2
  def up
3
- create_obj_class(
3
+ Scrivito::ObjClass.create(
4
4
  name: '<%= class_name %>',
5
- type: 'publication',
5
+ is_binary: false,
6
6
  title: '<%= class_name.underscore.humanize %>',
7
7
  # attributes: [
8
- # {
9
- # name: 'example',
10
- # type: :string,
11
- # },
8
+ # { name: 'example', type: :string },
12
9
  # ]
13
10
  )
14
11
  end
@@ -0,0 +1,158 @@
1
+ module Scrivito
2
+ # This class represents a CMS attribute. Attributes can be created, updated, deleted and all
3
+ # attribute properties can be read. Attributes are part of an
4
+ # {Scrivito::ObjClass} and therefore each attribute belongs to exactly
5
+ # one {Scrivito::ObjClass}. Most of the operations interact with the currently
6
+ # selected {Scrivito::Workspace}. Operations like +create+, +destroy+
7
+ # and +update+ need to be performed in the "rtc" workspace.
8
+ #
9
+ # @api public
10
+ class Attribute
11
+ include ModelIdentity
12
+
13
+ # Initializes a new attribute.
14
+ #
15
+ # @api public
16
+ #
17
+ # This allows you to set the different properties of an attribute by
18
+ # providing a Hash with the property names as keys and the values you want to set as values.
19
+ #
20
+ # @example Create a new attribute with name "locale" and type "string".
21
+ # Attribute.new(name: 'locale', type: :string)
22
+ #
23
+ # @example Create a new "enum" attribute named "category" and provide values.
24
+ # Attribute.new(name: 'category', type: :enum, values: %w(tech social))
25
+ #
26
+ # @param [Hash] properties
27
+ # @option properties [String] :name The name of the attribute.
28
+ # @option properties [String] :type The type of the attribute, can be +string+, +text+, +html+, +linklist+, +link+, +reference+, +referencelist+, +date+, +binary+, +widget+, +enum+ or +multienum+.
29
+ # @option properties [Array<String>] :values Possible values if the type is either +enum+ or +multienum+.
30
+ #
31
+ # @return [Scrivito::Attribute]
32
+ # @raise [Scrivito::ScrivitoError] Raised when no +properties+ are provided.
33
+ def initialize(properties)
34
+ raise ScrivitoError, 'Please provide a hash of Attribute properties.' unless properties
35
+
36
+ update_instance_properties(properties)
37
+ end
38
+
39
+ # Returns the name of this attribute.
40
+ # @api public
41
+ # @return [String]
42
+ def name
43
+ @name
44
+ end
45
+
46
+ # Returns the type of this attribute. The type is either +string+, +text+, +html+, +linklist+,
47
+ # +link+, +reference+, +referencelist+, +date+, +binary+, +widget+, +enum+ or +multienum+.
48
+ # @api public
49
+ # @return [String]
50
+ def type
51
+ @type
52
+ end
53
+
54
+ # Returns the values of this attribute, if it is of type +enum+ or +multienum+.
55
+ # @api public
56
+ # @return [Array<String>] values
57
+ def values
58
+ @values
59
+ end
60
+
61
+ # Returns the obj class this attribute belongs to.
62
+ # @api public
63
+ # @return [Scrivito::ObjClass]
64
+ attr_reader :obj_class
65
+
66
+ # Returns a unique identifier of this attribute. An attribute is unique by
67
+ # its +name+ and its +obj_class+. Implements the {Scrivito::ModelIdentity} interface.
68
+ # @return [Array]
69
+ def id
70
+ [name, obj_class]
71
+ end
72
+
73
+ # Binds this attribute to an obj class.
74
+ # @return [Scrivito::ObjClass]
75
+ attr_writer :obj_class
76
+
77
+ # Updates this attribute and persists the changes
78
+ # in the CMS on its obj class. The +obj_class+ and +name+ of this attribute can not be updated.
79
+ #
80
+ # @api public
81
+ #
82
+ # See {Attribute#initialize} for a detailed overview of what properties are allowed
83
+ # and how to set them.
84
+ #
85
+ # @example Change the +type+ of the "locale" attribute to "string".
86
+ # attribute = ObjClass.find('Homepage').attributes['locale']
87
+ # attribute.update(type: :string)
88
+ #
89
+ # @example Adding the value "sports" to the +enum+ attribute "category" on the "Homepage" obj class.
90
+ # attribute = ObjClass.find('Homepage').attributes['category']
91
+ # attribute.update(values: attribute.values << 'sports')
92
+ #
93
+ # @param [Hash] properties
94
+ #
95
+ # @return [nil]
96
+ # @raise [Scrivito::ScrivitoError] Raised when trying to change the +name+ or +obj_class+ property.
97
+ def update(properties)
98
+ properties = properties.with_indifferent_access
99
+
100
+ if properties.has_key?(:name)
101
+ raise ScrivitoError, "#{self.class} does not support changing its 'name'. Please remove" \
102
+ " the key from the properties."
103
+ end
104
+
105
+ properties = to_cms_rest_api.merge(properties)
106
+ update_instance_properties(properties)
107
+ obj_class.update(attributes: obj_class.attributes.to_a)
108
+
109
+ nil
110
+ end
111
+
112
+ # Destroys this attribute and persists the change in the CMS.
113
+ #
114
+ # @api public
115
+ #
116
+ # @example Remove the "locale" attribute from the "Homepage" obj class.
117
+ # ObjClass.find('Homepage').attributes['locale'].destroy
118
+ #
119
+ # @return [nil]
120
+ def destroy
121
+ obj_class.attributes.delete(self)
122
+ obj_class.update(attributes: obj_class.attributes.to_a)
123
+
124
+ nil
125
+ end
126
+
127
+ # Returns this attribute in the CMS REST API format.
128
+ #
129
+ # @return [Hash]
130
+ def to_cms_rest_api
131
+ data = {
132
+ name: name,
133
+ type: type,
134
+ }
135
+
136
+ if %w(enum multienum).include?(type)
137
+ data[:values] = values
138
+ end
139
+
140
+ data
141
+ end
142
+
143
+ private
144
+
145
+ # Updates the instance properties of this attribute with +properties+
146
+ # given in the CMS REST API format.
147
+ #
148
+ # @param [Hash] properties
149
+ # @return [void]
150
+ def update_instance_properties(properties)
151
+ properties = properties.with_indifferent_access
152
+
153
+ @name = properties[:name].to_s
154
+ @type = properties[:type].to_s
155
+ @values = (properties[:values] || []).map(&:to_s)
156
+ end
157
+ end
158
+ end