cortex-plugins-core 0.3.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 (39) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +201 -0
  3. data/README.md +24 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/javascripts/cortex-field_types-core/application.js +1 -0
  6. data/app/cells/plugins/core/asset/input.haml +3 -0
  7. data/app/cells/plugins/core/asset_cell.rb +29 -0
  8. data/app/cells/plugins/core/boolean/checkbox.haml +6 -0
  9. data/app/cells/plugins/core/boolean/switch.haml +3 -0
  10. data/app/cells/plugins/core/boolean_cell.rb +39 -0
  11. data/app/cells/plugins/core/cell.rb +7 -0
  12. data/app/cells/plugins/core/checkbox/checkbox.haml +7 -0
  13. data/app/cells/plugins/core/checkbox_cell.rb +31 -0
  14. data/app/cells/plugins/core/date_time/datepicker.haml +4 -0
  15. data/app/cells/plugins/core/date_time_cell.rb +23 -0
  16. data/app/cells/plugins/core/tag/tag_picker.haml +5 -0
  17. data/app/cells/plugins/core/tag_cell.rb +19 -0
  18. data/app/cells/plugins/core/text/input.haml +4 -0
  19. data/app/cells/plugins/core/text/multiline_input.haml +3 -0
  20. data/app/cells/plugins/core/text/wysiwyg.haml +3 -0
  21. data/app/cells/plugins/core/text_cell.rb +53 -0
  22. data/app/cells/plugins/core/tree/checkboxes.haml +6 -0
  23. data/app/cells/plugins/core/tree/dropdown.haml +7 -0
  24. data/app/cells/plugins/core/tree_cell.rb +29 -0
  25. data/app/cells/plugins/core/user/dropdown.haml +4 -0
  26. data/app/cells/plugins/core/user_cell.rb +23 -0
  27. data/app/models/asset_field_type.rb +114 -0
  28. data/app/models/boolean_field_type.rb +36 -0
  29. data/app/models/date_time_field_type.rb +77 -0
  30. data/app/models/tag_field_type.rb +63 -0
  31. data/app/models/text_field_type.rb +86 -0
  32. data/app/models/tree_field_type.rb +111 -0
  33. data/app/models/user_field_type.rb +72 -0
  34. data/lib/cortex/plugins/core/engine.rb +10 -0
  35. data/lib/cortex/plugins/core/version.rb +7 -0
  36. data/lib/cortex/plugins/core.rb +8 -0
  37. data/lib/tasks/cortex/core/db.rake +30 -0
  38. data/lib/tasks/cortex/core/media.rake +165 -0
  39. metadata +165 -0
@@ -0,0 +1,114 @@
1
+ class AssetFieldType < FieldType
2
+ VALIDATION_TYPES = {
3
+ presence: :valid_presence_validation?,
4
+ size: :valid_size_validation?,
5
+ content_type: :valid_content_type_validation?
6
+ }.freeze
7
+
8
+ attr_accessor :asset_file_name,
9
+ :asset_content_type,
10
+ :asset_file_size,
11
+ :asset_updated_at,
12
+ :field_name
13
+
14
+ attr_reader :data, :validations, :dimensions
15
+
16
+ has_attached_file :asset
17
+ do_not_validate_attachment_file_type :asset
18
+ before_save :extract_dimensions
19
+
20
+ validates :asset, attachment_presence: true, if: :validate_presence?
21
+
22
+ def validations=(validations_hash)
23
+ @validations = validations_hash.deep_symbolize_keys
24
+ end
25
+
26
+ def data=(data_hash)
27
+ self.asset = data_hash.deep_symbolize_keys[:asset]
28
+ end
29
+
30
+ def data
31
+ {
32
+ 'asset': {
33
+ 'file_name': asset_file_name,
34
+ 'url': asset.url,
35
+ 'dimensions': dimensions,
36
+ 'content_type': asset_content_type,
37
+ 'file_size': asset_file_size,
38
+ 'updated_at': asset_updated_at
39
+ }
40
+ }
41
+ end
42
+
43
+ def acceptable_validations?
44
+ valid_types? && valid_options?
45
+ end
46
+
47
+ def field_item_as_indexed_json_for_field_type(field_item, options = {})
48
+ json = {}
49
+ json[mapping_field_name] = asset_file_name
50
+ json
51
+ end
52
+
53
+ def mapping
54
+ {name: mapping_field_name, type: :string, analyzer: :keyword}
55
+ end
56
+
57
+ private
58
+
59
+ def image?
60
+ asset_content_type =~ %r{^(image|(x-)?application)/(bmp|gif|jpeg|jpg|pjpeg|png|x-png)$}
61
+ end
62
+
63
+ def extract_dimensions
64
+ return unless image?
65
+ tempfile = asset.queued_for_write[:original]
66
+ unless tempfile.nil?
67
+ geometry = Paperclip::Geometry.from_file(tempfile)
68
+ @dimensions = {
69
+ width: geometry.width.to_i,
70
+ height: geometry.height.to_i
71
+ }
72
+ end
73
+ end
74
+
75
+ def mapping_field_name
76
+ "#{field_name.parameterize('_')}_asset_file_name"
77
+ end
78
+
79
+ def valid_types?
80
+ validations.all? do |type, options|
81
+ VALIDATION_TYPES.include?(type.to_sym)
82
+ end
83
+ end
84
+
85
+ def valid_options?
86
+ validations.all? do |type, options|
87
+ self.send(VALIDATION_TYPES[type])
88
+ end
89
+ end
90
+
91
+ def validate_presence?
92
+ @validations.key? :presence
93
+ end
94
+
95
+ alias_method :valid_presence_validation?, :validate_presence?
96
+
97
+ def valid_size_validation?
98
+ begin
99
+ AttachmentSizeValidator.new(validations[:size].merge(attributes: :asset))
100
+ true
101
+ rescue ArgumentError, NoMethodError
102
+ false
103
+ end
104
+ end
105
+
106
+ def valid_content_type_validation?
107
+ begin
108
+ AttachmentContentTypeValidator.new(validations[:content_type].merge(attributes: :asset))
109
+ true
110
+ rescue ArgumentError, NoMethodError
111
+ false
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,36 @@
1
+ class BooleanFieldType < FieldType
2
+ attr_accessor :data, :value, :field_name
3
+ attr_reader :validations, :metadata
4
+
5
+ def validations=(validations_hash)
6
+ @validations = {}
7
+ end
8
+
9
+ def data=(data_hash)
10
+ @value = data_hash.deep_symbolize_keys[:value]
11
+ end
12
+
13
+ def metadata=(metadata_hash)
14
+ @metadata = metadata_hash.deep_symbolize_keys
15
+ end
16
+
17
+ def field_item_as_indexed_json_for_field_type(field_item, options = {})
18
+ json = {}
19
+ json[mapping_field_name] = field_item.data['boolean']
20
+ json
21
+ end
22
+
23
+ def mapping
24
+ { name: mapping_field_name, type: :string, analyzer: :snowball }
25
+ end
26
+
27
+ def acceptable_validations?
28
+ true
29
+ end
30
+
31
+ private
32
+
33
+ def mapping_field_name
34
+ "#{field_name.parameterize('_')}_boolean"
35
+ end
36
+ end
@@ -0,0 +1,77 @@
1
+ class DateTimeFieldType < FieldType
2
+ VALIDATION_TYPES = {
3
+ presence: :valid_presence_validation?
4
+ }.freeze
5
+
6
+ attr_accessor :data, :timestamp, :field_name
7
+ attr_reader :validations, :metadata
8
+
9
+ validates :timestamp, presence: true, if: :validate_presence?
10
+ validate :timestamp_is_valid?
11
+
12
+ def validations=(validations_hash)
13
+ @validations = validations_hash.deep_symbolize_keys
14
+ end
15
+
16
+ def data=(data_hash)
17
+ @timestamp = data_hash.deep_symbolize_keys[:timestamp]
18
+ end
19
+
20
+ def metadata=(metadata_hash)
21
+ @metadata = metadata_hash.deep_symbolize_keys
22
+ end
23
+
24
+ def acceptable_validations?
25
+ valid_types? && valid_options?
26
+ end
27
+
28
+ def field_item_as_indexed_json_for_field_type(field_item, options = {})
29
+ json = {}
30
+ json[mapping_field_name] = field_item.data['date_time']
31
+ json
32
+ end
33
+
34
+ def mapping
35
+ {name: mapping_field_name, type: :string, analyzer: :snowball}
36
+ end
37
+
38
+ private
39
+
40
+ def mapping_field_name
41
+ "#{field_name.parameterize('_')}_date_time"
42
+ end
43
+
44
+ def timestamp_is_valid?
45
+ if @timestamp.nil?
46
+ true
47
+ else
48
+ begin
49
+ DateTime.parse(@timestamp)
50
+ true
51
+ rescue ArgumentError
52
+ errors.add(:timestamp, 'must be a valid date')
53
+ false
54
+ end
55
+ end
56
+ end
57
+
58
+ def valid_types?
59
+ validations.all? do |type, options|
60
+ VALIDATION_TYPES.include?(type)
61
+ end
62
+ end
63
+
64
+ def valid_options?
65
+ validations.all? do |type, options|
66
+ self.send(VALIDATION_TYPES[type])
67
+ end
68
+ end
69
+
70
+ def valid_presence_validation?
71
+ @validations.key? :presence
72
+ end
73
+
74
+ def validate_presence?
75
+ @validations.key? :presence
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ class TagFieldType < FieldType
2
+ VALIDATION_TYPES = {
3
+ presence: :valid_presence_validation?
4
+ }.freeze
5
+
6
+ attr_accessor :data, :tag_list, :field_name
7
+ attr_reader :validations, :metadata
8
+
9
+ validates :tag_list, presence: true, if: :validate_presence?
10
+
11
+ def validations=(validations_hash)
12
+ @validations = validations_hash.deep_symbolize_keys
13
+ end
14
+
15
+ def data=(data_hash)
16
+ @tag_list = data_hash.deep_symbolize_keys[:tag_list]
17
+ @tag_list.nil? ? nil : (@tag_list = @tag_list.split(","))
18
+ end
19
+
20
+ def metadata=(metadata_hash)
21
+ @metadata = metadata_hash.deep_symbolize_keys
22
+ end
23
+
24
+ def acceptable_validations?
25
+ valid_types? && valid_options?
26
+ end
27
+
28
+ def field_item_as_indexed_json_for_field_type(field_item, options = {})
29
+ json = {}
30
+ json[mapping_field_name] = field_item.data['tag']
31
+ json
32
+ end
33
+
34
+ def mapping
35
+ {name: mapping_field_name, type: :string, analyzer: :snowball}
36
+ end
37
+
38
+ private
39
+
40
+ def mapping_field_name
41
+ "#{field_name.parameterize('_')}_tag"
42
+ end
43
+
44
+ def valid_types?
45
+ validations.all? do |type, options|
46
+ VALIDATION_TYPES.include?(type)
47
+ end
48
+ end
49
+
50
+ def valid_options?
51
+ validations.all? do |type, options|
52
+ self.send(VALIDATION_TYPES[type])
53
+ end
54
+ end
55
+
56
+ def valid_presence_validation?
57
+ @validations.key? :presence
58
+ end
59
+
60
+ def validate_presence?
61
+ @validations.key? :presence
62
+ end
63
+ end
@@ -0,0 +1,86 @@
1
+ class TextFieldType < FieldType
2
+ VALIDATION_TYPES = {
3
+ length: :valid_length_validation?,
4
+ presence: :valid_presence_validation?
5
+ }.freeze
6
+
7
+ attr_accessor :data, :text, :field_name
8
+ attr_reader :validations, :metadata
9
+
10
+ validates :text, presence: true, if: :validate_presence?
11
+ validate :text_length, if: :validate_length?
12
+
13
+ def validations=(validations_hash)
14
+ @validations = validations_hash.deep_symbolize_keys
15
+ end
16
+
17
+ def data=(data_hash)
18
+ @text = data_hash.deep_symbolize_keys[:text]
19
+ end
20
+
21
+ def metadata=(metadata_hash)
22
+ @metadata = metadata_hash.deep_symbolize_keys
23
+ end
24
+
25
+ def acceptable_validations?
26
+ valid_types? && valid_options?
27
+ end
28
+
29
+ def field_item_as_indexed_json_for_field_type(field_item, options = {})
30
+ json = {}
31
+ json[mapping_field_name] = field_item.data['text']
32
+ json
33
+ end
34
+
35
+ def mapping
36
+ {name: mapping_field_name, type: :string, analyzer: :snowball}
37
+ end
38
+
39
+ private
40
+
41
+ def mapping_field_name
42
+ "#{field_name.parameterize('_')}_text"
43
+ end
44
+
45
+ def valid_types?
46
+ validations.all? do |type, options|
47
+ VALIDATION_TYPES.include?(type)
48
+ end
49
+ end
50
+
51
+ def valid_options?
52
+ validations.all? do |type, options|
53
+ self.send(VALIDATION_TYPES[type])
54
+ end
55
+ end
56
+
57
+ def valid_length_validation?
58
+ begin
59
+ LengthValidator.new(validations[:length].merge(attributes: [:text]))
60
+ true
61
+ rescue ArgumentError, NoMethodError
62
+ false
63
+ end
64
+ end
65
+
66
+ def valid_presence_validation?
67
+ @validations.key? :presence
68
+ end
69
+
70
+ def text_present
71
+ errors.add(:text, "must be present") if @text.empty?
72
+ end
73
+
74
+ def text_length
75
+ validator = LengthValidator.new(validations[:length].merge(attributes: [:text]))
76
+ validator.validate_each(self, :text, text)
77
+ end
78
+
79
+ def validate_presence?
80
+ @validations.key? :presence
81
+ end
82
+
83
+ def validate_length?
84
+ @validations.key? :length
85
+ end
86
+ end
@@ -0,0 +1,111 @@
1
+ class TreeFieldType < FieldType
2
+ VALIDATION_TYPES = {
3
+ presence: :valid_presence_validation?,
4
+ maximum: :valid_maximum_validation?,
5
+ minimum: :valid_minimum_validation?
6
+ }.freeze
7
+
8
+ attr_accessor :data, :values, :field_name
9
+ attr_reader :validations, :metadata
10
+
11
+ validates :values, presence: true, if: :validate_presence?
12
+ validate :minimum, if: :validate_minimum?
13
+ validate :maximum, if: :validate_maximum?
14
+
15
+ def validations=(validations_hash)
16
+ @validations = validations_hash.deep_symbolize_keys
17
+ end
18
+
19
+ def data=(data_hash)
20
+ values = data_hash.deep_symbolize_keys[:values]
21
+
22
+ if values.is_a?(Hash)
23
+ @values = values.keys
24
+ else
25
+ @values = [values]
26
+ end
27
+ end
28
+
29
+ def metadata=(metadata_hash)
30
+ @metadata = metadata_hash.deep_symbolize_keys.extend(Hashie::Extensions::DeepLocate)
31
+ end
32
+
33
+ def acceptable_validations?
34
+ valid_types? && valid_options?
35
+ end
36
+
37
+ def field_item_as_indexed_json_for_field_type(field_item, options = {})
38
+ json = {}
39
+ json[mapping_field_name] = field_item.data['tree']
40
+ json
41
+ end
42
+
43
+ def mapping
44
+ { name: mapping_field_name, type: :string, analyzer: :snowball }
45
+ end
46
+
47
+ private
48
+
49
+ def mapping_field_name
50
+ "#{field_name.parameterize('_')}_tree"
51
+ end
52
+
53
+ def minimum
54
+ unless @values.nil?
55
+ if @values.length >= @validations[:minimum]
56
+ true
57
+ else
58
+ errors.add(:minimum, "You have selected too few values.")
59
+ false
60
+ end
61
+ end
62
+ end
63
+
64
+ def maximum
65
+ unless @values.nil?
66
+ if @values.length <= @validations[:maximum]
67
+ true
68
+ else
69
+ errors.add(:maximum, "You have selected too many values.")
70
+ false
71
+ end
72
+ end
73
+ end
74
+
75
+ def valid_types?
76
+ validations.all? do |type, options|
77
+ VALIDATION_TYPES.include?(type)
78
+ end
79
+ end
80
+
81
+ def valid_options?
82
+ validations.all? do |type, options|
83
+ self.send(VALIDATION_TYPES[type])
84
+ end
85
+ end
86
+
87
+ def valid_presence_validation?
88
+ @validations.key? :presence
89
+ end
90
+
91
+ def valid_maximum_validation?
92
+ @validations.key? :maximum
93
+ end
94
+
95
+ def valid_minimum_validation?
96
+ @validations.key? :minimum
97
+ end
98
+
99
+ def validate_presence?
100
+ @validations.key? :presence
101
+ end
102
+
103
+ def validate_minimum?
104
+ @validations.key? :minimum
105
+ end
106
+
107
+ def validate_maximum?
108
+ @validations.key? :maximum
109
+ end
110
+
111
+ end
@@ -0,0 +1,72 @@
1
+ class UserFieldType < FieldType
2
+ VALIDATION_TYPES = {
3
+ presence: :valid_presence_validation?
4
+ }.freeze
5
+
6
+ attr_accessor :data, :user_id, :field_name
7
+ attr_reader :validations, :metadata
8
+
9
+ validates :user_id, presence: true, if: :validate_presence?
10
+ validate :valid_user_id?
11
+
12
+ def validations=(validations_hash)
13
+ @validations = validations_hash.deep_symbolize_keys
14
+ end
15
+
16
+ def data=(data_hash)
17
+ @user_id = data_hash.deep_symbolize_keys[:user_id]
18
+ end
19
+
20
+ def metadata=(metadata_hash)
21
+ @metadata = metadata_hash.deep_symbolize_keys
22
+ end
23
+
24
+ def acceptable_validations?
25
+ valid_types? && valid_options?
26
+ end
27
+
28
+ def field_item_as_indexed_json_for_field_type(field_item, options = {})
29
+ json = {}
30
+ json[mapping_field_name] = field_item.data['user']
31
+ json
32
+ end
33
+
34
+ def mapping
35
+ {name: mapping_field_name, type: :string, analyzer: :snowball}
36
+ end
37
+
38
+ private
39
+
40
+ def mapping_field_name
41
+ "#{field_name.parameterize('_')}_user"
42
+ end
43
+
44
+ def valid_user_id?
45
+ return true if id.nil?
46
+
47
+ unless User.exists?(id)
48
+ errors.add(:user_id, "Must be for a Valid User")
49
+ false
50
+ end
51
+ end
52
+
53
+ def valid_types?
54
+ validations.all? do |type, options|
55
+ VALIDATION_TYPES.include?(type)
56
+ end
57
+ end
58
+
59
+ def valid_options?
60
+ validations.all? do |type, options|
61
+ self.send(VALIDATION_TYPES[type])
62
+ end
63
+ end
64
+
65
+ def valid_presence_validation?
66
+ @validations.key? :presence
67
+ end
68
+
69
+ def validate_presence?
70
+ @validations.key? :presence
71
+ end
72
+ end
@@ -0,0 +1,10 @@
1
+ require 'ckeditor'
2
+
3
+ module Cortex
4
+ module Plugins
5
+ module Core
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ module Cortex
2
+ module Plugins
3
+ module Core
4
+ VERSION = '0.3.0'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ require "cortex/plugins/core/engine"
2
+
3
+ module Cortex
4
+ module Plugins
5
+ module Core
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ Bundler.require(:default, Rails.env)
2
+
3
+ namespace :cortex do
4
+ namespace :core do
5
+ namespace :db do
6
+ desc 'Re-Seeds (will wipe existing ContentTypes!) Cortex with Core Custom Content Seed Data'
7
+ task reseed: :environment do
8
+ Rake::Task['cortex:core:db:clear'].execute
9
+ Rake::Task['cortex:core:media:seed'].execute
10
+ Rake::Task['employer:blog:seed'].execute # TODO: Extract
11
+ end
12
+
13
+ desc 'Clear Existing Custom Content Data From DB'
14
+ task clear: :environment do
15
+ puts "Clearing ContentTypes..."
16
+ ContentType.destroy_all
17
+ puts "Clearing Fields..."
18
+ Field.destroy_all
19
+ puts "Clearing ContentItems..."
20
+ ContentItem.destroy_all
21
+ puts "Clearing FieldItems..."
22
+ FieldItem.destroy_all
23
+ puts "Clearing ContentableDecorators..."
24
+ ContentableDecorator.destroy_all
25
+ puts "Clearing Decorators..."
26
+ Decorator.destroy_all
27
+ end
28
+ end
29
+ end
30
+ end