locomotivecms_steam 1.1.2 → 1.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +41 -52
  4. data/lib/locomotive/steam/adapters/filesystem/sanitizers/page.rb +30 -35
  5. data/lib/locomotive/steam/adapters/filesystem.rb +8 -0
  6. data/lib/locomotive/steam/adapters/mongodb/command.rb +8 -1
  7. data/lib/locomotive/steam/adapters/mongodb.rb +10 -1
  8. data/lib/locomotive/steam/entities/content_entry.rb +13 -6
  9. data/lib/locomotive/steam/entities/page.rb +4 -0
  10. data/lib/locomotive/steam/entities/site.rb +1 -0
  11. data/lib/locomotive/steam/errors.rb +3 -0
  12. data/lib/locomotive/steam/initializers/dragonfly.rb +3 -5
  13. data/lib/locomotive/steam/initializers/sprockets.rb +10 -0
  14. data/lib/locomotive/steam/liquid/drops/content_entry.rb +8 -0
  15. data/lib/locomotive/steam/liquid/drops/content_entry_collection.rb +1 -1
  16. data/lib/locomotive/steam/liquid/tags/action.rb +59 -0
  17. data/lib/locomotive/steam/middlewares/entry_submission.rb +1 -1
  18. data/lib/locomotive/steam/middlewares/helpers.rb +8 -0
  19. data/lib/locomotive/steam/middlewares/locale.rb +1 -5
  20. data/lib/locomotive/steam/middlewares/locale_redirection.rb +1 -7
  21. data/lib/locomotive/steam/middlewares/renderer.rb +6 -3
  22. data/lib/locomotive/steam/middlewares/site.rb +12 -5
  23. data/lib/locomotive/steam/middlewares/sitemap.rb +6 -2
  24. data/lib/locomotive/steam/middlewares/thread_safe.rb +0 -4
  25. data/lib/locomotive/steam/models/associations/many_to_many.rb +1 -1
  26. data/lib/locomotive/steam/models/entity.rb +5 -0
  27. data/lib/locomotive/steam/models/repository.rb +4 -0
  28. data/lib/locomotive/steam/repositories/content_entry_repository.rb +23 -4
  29. data/lib/locomotive/steam/repositories/content_type_field_repository.rb +4 -0
  30. data/lib/locomotive/steam/services/action_service.rb +92 -0
  31. data/lib/locomotive/steam/services/content_entry_service.rb +114 -0
  32. data/lib/locomotive/steam/services/email_service.rb +102 -0
  33. data/lib/locomotive/steam/services/entry_submission_service.rb +6 -58
  34. data/lib/locomotive/steam/services/liquid_parser_service.rb +6 -0
  35. data/lib/locomotive/steam/services/url_builder_service.rb +5 -2
  36. data/lib/locomotive/steam/services.rb +13 -1
  37. data/lib/locomotive/steam/version.rb +1 -1
  38. data/lib/locomotive/steam.rb +5 -3
  39. data/locomotivecms_steam.gemspec +2 -0
  40. data/spec/fixtures/default/data/messages.yml +0 -0
  41. data/spec/integration/services/content_entry_service_spec.rb +110 -0
  42. data/spec/unit/adapters/filesystem_adapter_spec.rb +10 -0
  43. data/spec/unit/adapters/mongodb_adapter_spec.rb +18 -0
  44. data/spec/unit/entities/content_entry_spec.rb +34 -0
  45. data/spec/unit/entities/editable_element_spec.rb +19 -0
  46. data/spec/unit/entities/page_spec.rb +29 -0
  47. data/spec/unit/liquid/drops/content_entry_collection_spec.rb +4 -0
  48. data/spec/unit/liquid/drops/content_entry_spec.rb +5 -2
  49. data/spec/unit/liquid/tags/action_spec.rb +23 -0
  50. data/spec/unit/liquid/tags/link_to_spec.rb +12 -4
  51. data/spec/unit/liquid/tags/locale_switcher_spec.rb +15 -7
  52. data/spec/unit/liquid/tags/nav_spec.rb +19 -11
  53. data/spec/unit/liquid/tags/path_to_spec.rb +12 -4
  54. data/spec/unit/middlewares/helpers_spec.rb +29 -0
  55. data/spec/unit/middlewares/locale_redirection_spec.rb +11 -29
  56. data/spec/unit/middlewares/site_spec.rb +66 -13
  57. data/spec/unit/middlewares/sitemap_spec.rb +44 -0
  58. data/spec/unit/models/i18n_field_spec.rb +23 -0
  59. data/spec/unit/repositories/content_entry_repository_spec.rb +39 -7
  60. data/spec/unit/repositories/content_type_field_repository_spec.rb +10 -0
  61. data/spec/unit/services/action_service_spec.rb +173 -0
  62. data/spec/unit/services/content_entry_service_spec.rb +63 -0
  63. data/spec/unit/services/email_service_spec.rb +198 -0
  64. data/spec/unit/services/entry_submission_service_spec.rb +28 -112
  65. data/spec/unit/services/url_builder_service_spec.rb +14 -5
  66. metadata +50 -6
  67. data/spec/unit/middlewares/locale_spec.rb +0 -52
@@ -37,6 +37,14 @@ module Locomotive::Steam
37
37
  path
38
38
  end
39
39
 
40
+ # make sure the location passed in parameter doesn't
41
+ # include the "mounted_on" parameter.
42
+ # If so, returns the location without the "mounted_on" string.
43
+ def make_local_path(location)
44
+ return location if mounted_on.blank?
45
+ location.gsub(Regexp.new('^' + mounted_on), '')
46
+ end
47
+
40
48
  def mounted_on
41
49
  request.env['steam.mounted_on']
42
50
  end
@@ -28,7 +28,7 @@ module Locomotive::Steam
28
28
  protected
29
29
 
30
30
  def extract_locale
31
- _locale = locale_from_params || default_locale
31
+ _locale = params[:locale] || default_locale
32
32
  _path = request.path_info
33
33
 
34
34
  if _path =~ /^\/(#{site.locales.join('|')})+(\/|$)/
@@ -44,10 +44,6 @@ module Locomotive::Steam
44
44
  env['steam.locale'] = services.locale = _locale
45
45
  end
46
46
 
47
- def locale_from_params
48
- locales.include?(params[:locale]) ? params[:locale] : nil
49
- end
50
-
51
47
  end
52
48
  end
53
49
  end
@@ -23,7 +23,7 @@ module Locomotive::Steam
23
23
  if site.prefix_default_locale
24
24
  path_with_default_locale if locale_not_mentioned_in_path?
25
25
  else
26
- path_without_default_locale if default_locale? && locale_mentioned_in_path?
26
+ env['steam.path'] if default_locale? && locale_mentioned_in_path?
27
27
  end
28
28
  end
29
29
  end
@@ -50,12 +50,6 @@ module Locomotive::Steam
50
50
  end
51
51
  end
52
52
 
53
- def path_without_default_locale
54
- modify_path do |segments|
55
- segments.delete_at(1)
56
- end
57
- end
58
-
59
53
  end
60
54
  end
61
55
 
@@ -20,7 +20,7 @@ module Locomotive::Steam
20
20
  redirect_to(page.redirect_url, page.redirect_type)
21
21
  else
22
22
  content = parse_and_render_liquid
23
- render_response(content, page.not_found? ? 404 : 200, page.response_type)
23
+ render_response(content, page.not_found? ? 404: 200, page.response_type)
24
24
  end
25
25
  end
26
26
 
@@ -53,7 +53,8 @@ module Locomotive::Steam
53
53
  services: services,
54
54
  repositories: services.repositories,
55
55
  logger: Locomotive::Common::Logger,
56
- live_editing: !!env['steam.live_editing']
56
+ live_editing: !!env['steam.live_editing'],
57
+ session: request.session
57
58
  }
58
59
  end
59
60
 
@@ -71,7 +72,8 @@ module Locomotive::Steam
71
72
  'now' => Time.zone.now,
72
73
  'today' => Date.today,
73
74
  'mode' => Locomotive::Steam.configuration.mode,
74
- 'wagon' => Locomotive::Steam.configuration.mode == :test
75
+ 'wagon' => Locomotive::Steam.configuration.mode == :test,
76
+ 'live_editing' => !!env['steam.live_editing']
75
77
  }
76
78
  end
77
79
 
@@ -102,6 +104,7 @@ module Locomotive::Steam
102
104
  'ip_address' => request.ip,
103
105
  'post?' => request.post?,
104
106
  'base_url' => request.base_url,
107
+ 'user_agent' => request.user_agent,
105
108
  'mounted_on' => mounted_on
106
109
  }
107
110
  end
@@ -16,7 +16,8 @@ module Locomotive::Steam
16
16
  # log anyway
17
17
  log_site(site)
18
18
 
19
- redirect_to_first_domain_if_enabled(site)
19
+ # redirect to the first domain and/or HTTPS if defined by the site
20
+ redirect_if_required(site)
20
21
  end
21
22
 
22
23
  private
@@ -40,9 +41,11 @@ module Locomotive::Steam
40
41
  end
41
42
  end
42
43
 
43
- def redirect_to_first_domain_if_enabled(site)
44
- if redirect_to_first_domain?(site)
45
- klass = request.scheme == 'https' ? URI::HTTPS : URI::HTTP
44
+ def redirect_if_required(site)
45
+ return if env['steam.is_default_host']
46
+
47
+ if redirect_to_first_domain?(site) || redirect_to_https?(site)
48
+ klass = request.scheme == 'https' || redirect_to_https?(site) ? URI::HTTPS : URI::HTTP
46
49
  redirect_to klass.build(
47
50
  host: site.domains.first,
48
51
  port: [80, 443].include?(request.port) ? nil : request.port,
@@ -54,11 +57,15 @@ module Locomotive::Steam
54
57
  def redirect_to_first_domain?(site)
55
58
  # the site parameter can be an instance of Locomotive::Steam::Services::Defer and
56
59
  # so comparing just site may not be reliable.
57
- !env['steam.is_default_host'] &&
58
60
  site.try(:redirect_to_first_domain) &&
59
61
  site.domains.first != request.host
60
62
  end
61
63
 
64
+ def redirect_to_https?(site)
65
+ site.try(:redirect_to_https) &&
66
+ request.scheme != 'https'
67
+ end
68
+
62
69
  def log_site(site)
63
70
  if site.nil?
64
71
  msg = "Unable to find a site, url asked: #{request.url} ".colorize(color: :light_white, background: :red)
@@ -27,8 +27,8 @@ module Locomotive::Steam
27
27
  end
28
28
 
29
29
  def build_pages_to_xml
30
- repositories.page.published.map do |page|
31
- next if page.index? || page.not_found?
30
+ page_repository.published.map do |page|
31
+ next if page.index? || page.not_found? || page.layout?
32
32
 
33
33
  build_page_xml(page)
34
34
  end.flatten.join.strip
@@ -80,6 +80,10 @@ module Locomotive::Steam
80
80
  services.repositories
81
81
  end
82
82
 
83
+ def page_repository
84
+ repositories.page
85
+ end
86
+
83
87
  def url_for(page, locale = nil)
84
88
  services.url_builder.url_for(page, locale)
85
89
  end
@@ -53,10 +53,6 @@ module Locomotive::Steam::Middlewares
53
53
  @liquid_assigns ||= env.fetch('steam.liquid_assigns')
54
54
  end
55
55
 
56
- def locales
57
- site.locales
58
- end
59
-
60
56
  def default_locale
61
57
  site.default_locale
62
58
  end
@@ -6,7 +6,7 @@ module Locomotive::Steam
6
6
  def __load__
7
7
  key = @repository.k(:_id, :in)
8
8
 
9
- @repository.local_conditions[key] = @entity[__target_key__]
9
+ @repository.local_conditions[key] = @entity[__target_key__] || []
10
10
 
11
11
  # use order_by from options as the default one for further queries
12
12
  @repository.local_conditions[:order_by] = @options[:order_by] unless @options[:order_by].blank?
@@ -39,6 +39,11 @@ module Locomotive::Steam
39
39
  attributes[name]
40
40
  end
41
41
 
42
+ def change(new_attributes)
43
+ attributes.merge!((new_attributes || {}).with_indifferent_access)
44
+ self
45
+ end
46
+
42
47
  def serialize
43
48
  attributes.dup
44
49
  end
@@ -32,6 +32,10 @@ module Locomotive::Steam
32
32
  adapter.create(mapper, scope, entity)
33
33
  end
34
34
 
35
+ def update(entity)
36
+ adapter.update(mapper, scope, entity)
37
+ end
38
+
35
39
  def inc(entity, attribute, amount = 1)
36
40
  adapter.inc(mapper, entity, attribute, amount)
37
41
  end
@@ -131,7 +131,7 @@ module Locomotive
131
131
  end
132
132
 
133
133
  def prepare_conditions(*conditions)
134
- _conditions = Conditions.new(conditions.first, self.content_type.fields).prepare
134
+ _conditions = Conditions.new(adapter, conditions.first, self.content_type.fields).prepare
135
135
 
136
136
  super({ _visible: true }, _conditions)
137
137
  end
@@ -185,8 +185,10 @@ module Locomotive
185
185
 
186
186
  class Conditions
187
187
 
188
- def initialize(conditions = {}, fields)
189
- @conditions, @fields, @operators = conditions.try(:with_indifferent_access) || {}, fields, {}
188
+ def initialize(adapter, conditions = {}, fields)
189
+ @adapter = adapter
190
+ @conditions = conditions.try(:with_indifferent_access) || {}
191
+ @fields, @operators = fields, {}
190
192
 
191
193
  @conditions.each do |name, value|
192
194
  _name, operator = name.to_s.split('.')
@@ -200,6 +202,9 @@ module Locomotive
200
202
  field.select_options.by_name(value).try(:_id)
201
203
  end
202
204
 
205
+ # date
206
+ _prepare(@fields.dates_and_date_times) { |field, value| value_to_date(value, field.type) }
207
+
203
208
  # belongs_to
204
209
  _prepare(@fields.belongs_to) { |field, value| value_to_id(value) }
205
210
 
@@ -233,11 +238,25 @@ module Locomotive
233
238
  end
234
239
 
235
240
  def value_to_id(value)
236
- if value.respond_to?(:each) # array
241
+ _value = if value.is_a?(Hash)
242
+ value['_id'] || value[:_id]
243
+ elsif value.respond_to?(:each) # array
237
244
  values_to_ids(value)
238
245
  else
239
246
  value.respond_to?(:_id) ? value._id : value
240
247
  end
248
+
249
+ @adapter.make_id(_value)
250
+ end
251
+
252
+ def value_to_date(value, type)
253
+ _value = if value.is_a?(String)
254
+ Chronic.time_class = Time.zone
255
+ Chronic.parse(value)
256
+ else
257
+ value
258
+ end
259
+ type == :date ? _value.to_date : _value.to_datetime
241
260
  end
242
261
 
243
262
  def values_to_ids(value)
@@ -26,6 +26,10 @@ module Locomotive
26
26
  query { where(type: :file) }.all
27
27
  end
28
28
 
29
+ def dates_and_date_times
30
+ query { where(k(:type, :in) => %i(date date_time)) }.all
31
+ end
32
+
29
33
  def belongs_to
30
34
  query { where(type: :belongs_to) }.all
31
35
  end
@@ -0,0 +1,92 @@
1
+ # Force ExecJS to select the best engine based on the current configuration.
2
+ # It means that if, down the road, we load a different javascript engine,
3
+ # the ExecJS runtime won't be affected.
4
+ require 'duktape'
5
+ require 'execjs'
6
+ ExecJS.runtimes.delete_if { |mod| mod.is_a?(ExecJS::DuktapeRuntime) }
7
+ ExecJS.instance_variable_set(:@runtime, ExecJS::Runtimes.autodetect)
8
+
9
+ module Locomotive
10
+ module Steam
11
+
12
+ class ActionService
13
+
14
+ BUILT_IN_FUNCTIONS = %w(
15
+ getProp
16
+ setProp
17
+ getSessionProp
18
+ setSessionProp
19
+ sendEmail
20
+ allEntries
21
+ findEntry
22
+ createEntry
23
+ updateEntry)
24
+
25
+ attr_accessor_initialize :site, :email, :content_entry_service
26
+
27
+ def run(script, params = {}, liquid_context)
28
+ context = Duktape::Context.new
29
+
30
+ define_built_in_functions(context, liquid_context)
31
+
32
+ script = <<-JS
33
+ function locomotiveAction(site, params) {
34
+ #{script}
35
+ }
36
+ JS
37
+
38
+ # puts script.inspect # DEBUG
39
+
40
+ context.exec_string script
41
+
42
+ context.call_prop('locomotiveAction', site.as_json, params)
43
+ end
44
+
45
+ private
46
+
47
+ def define_built_in_functions(context, liquid_context)
48
+ BUILT_IN_FUNCTIONS.each do |name|
49
+ context.define_function name, &send(:"#{name.underscore}_lambda", liquid_context)
50
+ end
51
+ end
52
+
53
+ def send_email_lambda(liquid_context)
54
+ -> (options) { !!email.send_email(options, liquid_context) }
55
+ end
56
+
57
+ def get_prop_lambda(liquid_context)
58
+ -> (name) { liquid_context[name].as_json }
59
+ end
60
+
61
+ def set_prop_lambda(liquid_context)
62
+ -> (name, value) { liquid_context.scopes.last[name] = value }
63
+ end
64
+
65
+ def get_session_prop_lambda(liquid_context)
66
+ -> (name) { liquid_context.registers[:session][name.to_sym].as_json }
67
+ end
68
+
69
+ def set_session_prop_lambda(liquid_context)
70
+ -> (name, value) { liquid_context.registers[:session][name.to_sym] = value }
71
+ end
72
+
73
+ def all_entries_lambda(liquid_context)
74
+ -> (type, conditions) { content_entry_service.all(type, conditions, true) }
75
+ end
76
+
77
+ def find_entry_lambda(liquid_context)
78
+ -> (type, id_or_slug) { content_entry_service.find(type, id_or_slug, true) }
79
+ end
80
+
81
+ def create_entry_lambda(liquid_context)
82
+ -> (type, attributes) { content_entry_service.create(type, attributes, true) }
83
+ end
84
+
85
+ def update_entry_lambda(liquid_context)
86
+ -> (type, id_or_slug, attributes) { content_entry_service.update(type, id_or_slug, attributes, true) }
87
+ end
88
+
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,114 @@
1
+ require 'sanitize'
2
+
3
+ module Locomotive
4
+ module Steam
5
+
6
+ class ContentEntryService
7
+
8
+ include Locomotive::Steam::Services::Concerns::Decorator
9
+
10
+ attr_accessor_initialize :content_type_repository, :repository, :locale
11
+
12
+ def all(type_slug, conditions = {}, as_json = false)
13
+ with_repository(type_slug) do |_repository|
14
+ _repository.all(conditions).map do |entry|
15
+ _decorate(entry, as_json)
16
+ end
17
+ end
18
+ end
19
+
20
+ def find(type_slug, id_or_slug, as_json = false)
21
+ with_repository(type_slug) do |_repository|
22
+ entry = _repository.by_slug(id_or_slug) || _repository.find(id_or_slug)
23
+ _decorate(entry, as_json)
24
+ end
25
+ end
26
+
27
+ # Warning: do not work with localized and file fields
28
+ def create(type_slug, attributes, as_json = false)
29
+ with_repository(type_slug) do |_repository|
30
+ entry = _repository.build(clean_attributes(attributes))
31
+ decorated_entry = i18n_decorate { entry }
32
+
33
+ if validate(_repository, decorated_entry)
34
+ _repository.create(entry)
35
+ end
36
+
37
+ _json_decorate(decorated_entry, as_json)
38
+ end
39
+ end
40
+
41
+ # Warning: do not work with localized and file fields
42
+ def update(type_slug, id_or_slug, attributes, as_json = false)
43
+ with_repository(type_slug) do |_repository|
44
+ entry = _repository.by_slug(id_or_slug) || _repository.find(id_or_slug)
45
+ decorated_entry = i18n_decorate { entry.change(clean_attributes(attributes)) }
46
+
47
+ if validate(_repository, decorated_entry)
48
+ _repository.update(entry)
49
+ end
50
+
51
+ _json_decorate(decorated_entry, as_json)
52
+ end
53
+ end
54
+
55
+ def delete(type_slug, id_or_slug)
56
+ with_repository(type_slug) do |_repository|
57
+ entry = _repository.by_slug(id_or_slug) || _repository.find(id_or_slug)
58
+ _repository.delete(entry)
59
+ end
60
+ end
61
+
62
+ def get_type(slug)
63
+ return nil if slug.blank?
64
+
65
+ content_type_repository.by_slug(slug)
66
+ end
67
+
68
+ private
69
+
70
+ def with_repository(type_or_slug)
71
+ type = type_or_slug.respond_to?(:fields) ? type_or_slug : get_type(type_or_slug)
72
+
73
+ return if type.nil?
74
+
75
+ yield(repository.with(type))
76
+ end
77
+
78
+ def _decorate(entry, as_json)
79
+ decorated_entry = i18n_decorate { entry }
80
+ _json_decorate(decorated_entry, as_json)
81
+ end
82
+
83
+ def _json_decorate(entry, as_json)
84
+ as_json ? entry.as_json : entry
85
+ end
86
+
87
+ def clean_attributes(attributes)
88
+ attributes.each do |key, value|
89
+ next unless value.is_a?(String)
90
+ attributes[key] = Sanitize.clean(value, Sanitize::Config::BASIC)
91
+ end
92
+ attributes
93
+ end
94
+
95
+ def validate(_repository, entry)
96
+ # simple validations (existence of values) first
97
+ entry.valid?
98
+
99
+ # check if the entry has unique values for its
100
+ # fields marked as unique
101
+ content_type_repository.look_for_unique_fields(entry.content_type).each do |name, _|
102
+ if _repository.exists?(name => entry.send(name))
103
+ entry.errors.add(name, :unique)
104
+ end
105
+ end
106
+
107
+ entry.errors.empty?
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+ end
114
+
@@ -0,0 +1,102 @@
1
+ require 'pony'
2
+
3
+ module Locomotive
4
+ module Steam
5
+
6
+ class EmailService
7
+
8
+ attr_accessor_initialize :page_finder_service, :liquid_parser, :asset_host, :simulation
9
+
10
+ def send_email(options, context)
11
+ prepare_options(options, context)
12
+
13
+ log(options, simulation)
14
+
15
+ !simulation ? send_email!(options) : nil
16
+ end
17
+
18
+ def send_email!(options)
19
+ Pony.mail(options)
20
+ end
21
+
22
+ def logger
23
+ Locomotive::Common::Logger
24
+ end
25
+
26
+ private
27
+
28
+ def prepare_options(options, context)
29
+ build_body(options.symbolize_keys!, context, options.delete(:html))
30
+
31
+ extract_attachment(options)
32
+
33
+ options[:via] ||= :smtp
34
+ options[:via_options] ||= options.delete(:smtp).try(:symbolize_keys)
35
+ end
36
+
37
+ def build_body(options, context, html = true)
38
+ key = html || html.nil? ? :html_body : :body
39
+
40
+ document = (if handle = options.delete(:page_handle)
41
+ parse_page(handle)
42
+ elsif body = options.delete(:body)
43
+ liquid_parser.parse_string(body)
44
+ else
45
+ raise "[EmailService] the body or page_handle options are missing."
46
+ end)
47
+
48
+ options[key] = document.render(context)
49
+ end
50
+
51
+ def parse_page(handle)
52
+ if page = page_finder_service.by_handle(handle, false)
53
+ liquid_parser.parse(page) # the liquid parser decorates the page (i18n)
54
+ else
55
+ raise "[EmailService] No page found with the following handle: #{handle}"
56
+ end
57
+ end
58
+
59
+ def extract_attachment(options)
60
+ (options[:attachments] || {}).each do |filename, value|
61
+ options[:attachments][filename] = read_attachment(value)
62
+ end
63
+ end
64
+
65
+ def read_attachment(value)
66
+ url = case value
67
+ when /^https?:\/\// then value
68
+ when /^\// then asset_host.compute(value, false)
69
+ else
70
+ nil
71
+ end
72
+
73
+ url ? _read_http_attachment(url) : value
74
+ end
75
+
76
+ def _read_http_attachment(url)
77
+ begin
78
+ uri = URI(url)
79
+ Net::HTTP.get(uri)
80
+ rescue Exception => e
81
+ logger.error "[SendEmail] Unable to read the '#{url}' url, error: #{e.message}"
82
+ nil
83
+ end
84
+ end
85
+
86
+ def log(options, simulation)
87
+ message = ["[#{simulation ? 'Test' : 'Live'}] Sent email via #{options[:via]} (#{options[:via_options].inspect}):"]
88
+ message << "From: #{options[:from]}"
89
+ message << "To: #{options[:to]}"
90
+ message << "Subject: #{options[:subject]}"
91
+ message << "Attachments: #{options[:attachments]}"
92
+ message << "-----------"
93
+ message << (options[:body] || options[:html_body]).gsub("\n", "\n\t")
94
+ message << "-----------"
95
+
96
+ logger.info message.join("\n") + "\n\n"
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+ end
@@ -1,76 +1,24 @@
1
- require 'sanitize'
2
-
3
1
  module Locomotive
4
2
  module Steam
5
3
 
6
4
  class EntrySubmissionService
7
5
 
8
- include Locomotive::Steam::Services::Concerns::Decorator
9
-
10
- attr_accessor_initialize :content_type_repository, :repository, :locale
6
+ attr_accessor_initialize :service
11
7
 
12
- def submit(slug, attributes = {})
13
- type = get_type(slug)
8
+ def submit(type_slug, attributes = {})
9
+ type = service.get_type(type_slug)
14
10
 
15
11
  return nil if type.nil? || type.public_submission_enabled == false
16
12
 
17
- clean_attributes(attributes)
18
-
19
- build_entry(type, attributes) do |entry|
20
- if validate(entry)
21
- repository.create(entry)
22
- end
23
- end
13
+ service.create(type, attributes)
24
14
  end
25
15
 
26
16
  def find(type_slug, slug)
27
- type = get_type(type_slug)
28
-
29
- return nil if type.nil?
30
-
31
- i18n_decorate { repository.with(type).by_slug(slug) }
17
+ service.find(type_slug, slug)
32
18
  end
33
19
 
34
20
  def to_json(entry)
35
- return nil if entry.nil?
36
-
37
- entry.to_json
38
- end
39
-
40
- private
41
-
42
- def get_type(slug)
43
- return nil if slug.blank?
44
-
45
- content_type_repository.by_slug(slug)
46
- end
47
-
48
- def build_entry(type, attributes, &block)
49
- i18n_decorate { repository.with(type).build(attributes) }.tap do |entry|
50
- yield(entry)
51
- end
52
- end
53
-
54
- def validate(entry)
55
- # simple validations (existence of values) first
56
- entry.valid?
57
-
58
- # check if the entry has unique values for its
59
- # fields marked as unique
60
- content_type_repository.look_for_unique_fields(entry.content_type).each do |name, _|
61
- if repository.with(entry.content_type).exists?(name => entry.send(name))
62
- entry.errors.add(name, :unique)
63
- end
64
- end
65
-
66
- entry.errors.empty?
67
- end
68
-
69
- def clean_attributes(attributes)
70
- attributes.each do |key, value|
71
- next unless value.is_a?(String)
72
- attributes[key] = Sanitize.clean(value, Sanitize::Config::BASIC)
73
- end
21
+ entry.try(&:to_json)
74
22
  end
75
23
 
76
24
  end
@@ -14,6 +14,12 @@ module Locomotive
14
14
  default_editable_content: {})
15
15
  end
16
16
 
17
+ def parse_string(string)
18
+ Locomotive::Steam::Liquid::Template.parse(string,
19
+ snippet_finder: snippet_finder,
20
+ parser: self)
21
+ end
22
+
17
23
  def _parse(object, options = {})
18
24
  # Note: the template must not be parsed here
19
25
  Locomotive::Steam::Liquid::Template.parse(object.liquid_source, options)