alchemy_cms 3.3.3 → 3.4.0.rc1

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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +42 -4
  4. data/README.md +7 -3
  5. data/alchemy_cms.gemspec +1 -0
  6. data/app/assets/javascripts/alchemy/{alchemy.js → admin.js} +1 -2
  7. data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +28 -25
  8. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +1 -0
  9. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +7 -1
  10. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +1 -1
  11. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +26 -0
  12. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +56 -1
  13. data/app/assets/stylesheets/alchemy/_variables.scss +1 -0
  14. data/app/assets/stylesheets/alchemy/admin.scss +2 -1
  15. data/app/assets/stylesheets/alchemy/archive.scss +7 -0
  16. data/app/assets/stylesheets/alchemy/base.scss +0 -42
  17. data/app/assets/stylesheets/alchemy/buttons.scss +2 -1
  18. data/app/assets/stylesheets/alchemy/form_fields.scss +9 -0
  19. data/app/assets/stylesheets/alchemy/forms.scss +36 -10
  20. data/app/assets/stylesheets/alchemy/frame.scss +12 -1
  21. data/app/assets/stylesheets/alchemy/icons.scss +1 -1
  22. data/app/assets/stylesheets/alchemy/jquery-ui.scss +0 -260
  23. data/app/assets/stylesheets/alchemy/jquery.datetimepicker.scss +507 -0
  24. data/app/assets/stylesheets/alchemy/lists.scss +62 -0
  25. data/app/assets/stylesheets/alchemy/selects.scss +9 -2
  26. data/app/assets/stylesheets/alchemy/sitemap.scss +28 -51
  27. data/app/assets/stylesheets/alchemy/toolbar.scss +0 -2
  28. data/app/controllers/alchemy/admin/attachments_controller.rb +4 -6
  29. data/app/controllers/alchemy/admin/base_controller.rb +2 -2
  30. data/app/controllers/alchemy/admin/dashboard_controller.rb +2 -2
  31. data/app/controllers/alchemy/admin/languages_controller.rb +5 -0
  32. data/app/controllers/alchemy/admin/pages_controller.rb +14 -5
  33. data/app/controllers/alchemy/admin/resources_controller.rb +17 -1
  34. data/app/controllers/alchemy/base_controller.rb +1 -0
  35. data/app/controllers/alchemy/messages_controller.rb +1 -1
  36. data/app/controllers/alchemy/pages_controller.rb +16 -26
  37. data/app/controllers/alchemy/pictures_controller.rb +23 -10
  38. data/app/controllers/concerns/alchemy/page_redirects.rb +7 -7
  39. data/app/helpers/alchemy/admin/base_helper.rb +22 -19
  40. data/app/helpers/alchemy/admin/essences_helper.rb +26 -11
  41. data/app/helpers/alchemy/admin/pages_helper.rb +2 -1
  42. data/app/helpers/alchemy/essences_helper.rb +0 -35
  43. data/app/helpers/alchemy/url_helper.rb +1 -1
  44. data/app/mailers/alchemy/base_mailer.rb +18 -0
  45. data/app/mailers/alchemy/{messages.rb → messages_mailer.rb} +1 -1
  46. data/app/models/alchemy/attachment.rb +9 -0
  47. data/app/models/alchemy/cell.rb +1 -1
  48. data/app/models/alchemy/essence_picture.rb +4 -1
  49. data/app/models/alchemy/essence_picture_view.rb +68 -0
  50. data/app/models/alchemy/language.rb +8 -10
  51. data/app/models/alchemy/language/code.rb +4 -1
  52. data/app/models/alchemy/page.rb +69 -26
  53. data/app/models/alchemy/page/page_natures.rb +22 -0
  54. data/app/models/alchemy/page/page_scopes.rb +20 -6
  55. data/app/models/alchemy/picture.rb +37 -4
  56. data/app/models/alchemy/site.rb +8 -0
  57. data/app/serializers/alchemy/page_tree_serializer.rb +1 -1
  58. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +9 -6
  59. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +11 -9
  60. data/app/views/alchemy/admin/attachments/_filter_bar.html.erb +32 -0
  61. data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +14 -2
  62. data/app/views/alchemy/admin/attachments/index.html.erb +10 -9
  63. data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +20 -9
  64. data/app/views/alchemy/admin/dashboard/_recent_pages.html.erb +11 -1
  65. data/app/views/alchemy/admin/languages/_form.html.erb +1 -0
  66. data/app/views/alchemy/admin/languages/index.html.erb +7 -8
  67. data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +1 -1
  68. data/app/views/alchemy/admin/layoutpages/index.html.erb +2 -2
  69. data/app/views/alchemy/admin/pages/_current_page.html.erb +4 -0
  70. data/app/views/alchemy/admin/pages/_form.html.erb +16 -1
  71. data/app/views/alchemy/admin/pages/_locked_page.html.erb +2 -12
  72. data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
  73. data/app/views/alchemy/admin/pages/_page_for_links.html.erb +2 -2
  74. data/app/views/alchemy/admin/pages/_page_status.html.erb +23 -11
  75. data/app/views/alchemy/admin/pages/edit.html.erb +2 -1
  76. data/app/views/alchemy/admin/pages/index.html.erb +2 -2
  77. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +3 -0
  78. data/app/views/alchemy/admin/partials/_site_select.html.erb +9 -0
  79. data/app/views/alchemy/admin/pictures/_picture.html.erb +6 -1
  80. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +2 -1
  81. data/app/views/alchemy/admin/pictures/show.html.erb +1 -1
  82. data/app/views/alchemy/admin/resources/_filter_bar.html.erb +31 -0
  83. data/app/views/alchemy/admin/resources/_form.html.erb +6 -0
  84. data/app/views/alchemy/admin/resources/_tag_list.html.erb +16 -0
  85. data/app/views/alchemy/admin/resources/index.html.erb +13 -1
  86. data/app/views/alchemy/essences/_essence_file_view.html.erb +2 -5
  87. data/app/views/alchemy/essences/_essence_picture_view.html.erb +5 -3
  88. data/app/views/alchemy/{messages → messages_mailer}/contact_form_mail.de.text.erb +0 -0
  89. data/app/views/alchemy/{messages → messages_mailer}/contact_form_mail.en.text.erb +0 -0
  90. data/app/views/alchemy/{messages → messages_mailer}/contact_form_mail.es.text.erb +0 -0
  91. data/app/views/alchemy/{messages → messages_mailer}/new.html.erb +0 -0
  92. data/app/views/layouts/alchemy/admin.html.erb +3 -8
  93. data/config/alchemy/config.yml +4 -3
  94. data/config/initializers/assets.rb +2 -2
  95. data/config/initializers/dragonfly.rb +3 -0
  96. data/config/initializers/mime_types.rb +1 -0
  97. data/config/locales/alchemy.de.yml +10 -2
  98. data/config/locales/alchemy.en.yml +6 -2
  99. data/config/locales/alchemy.es.yml +6 -3
  100. data/config/locales/alchemy.fr.yml +6 -2
  101. data/config/locales/alchemy.it.yml +937 -0
  102. data/config/locales/alchemy.nl.yml +6 -2
  103. data/config/locales/alchemy.ru.yml +3 -2
  104. data/config/locales/simple_form.it.yml +25 -0
  105. data/db/migrate/20160108174834_add_timebased_publishing_columns_to_pages.rb +32 -0
  106. data/db/migrate/20160422195310_add_image_file_format_to_alchemy_pictures.rb +21 -0
  107. data/db/migrate/20160617224938_change_alchemy_pages_locked_to_locked_at.rb +22 -0
  108. data/lib/alchemy/ability_helper.rb +23 -0
  109. data/lib/alchemy/configuration_methods.rb +2 -2
  110. data/lib/alchemy/controller_actions.rb +4 -33
  111. data/lib/alchemy/engine.rb +1 -0
  112. data/lib/alchemy/resource.rb +30 -13
  113. data/lib/alchemy/resources_helper.rb +17 -0
  114. data/lib/alchemy/test_support/factories/page_factory.rb +7 -2
  115. data/lib/alchemy/upgrader.rb +1 -0
  116. data/lib/alchemy/upgrader/tasks/install_asset_manifests.rb +15 -0
  117. data/lib/alchemy/upgrader/three_point_four.rb +16 -0
  118. data/lib/alchemy/version.rb +1 -1
  119. data/lib/rails/generators/alchemy/elements/elements_generator.rb +8 -7
  120. data/lib/rails/generators/alchemy/essence/essence_generator.rb +2 -6
  121. data/lib/rails/generators/alchemy/install/files/all.css +11 -0
  122. data/lib/rails/generators/alchemy/install/files/all.js +11 -0
  123. data/lib/rails/generators/alchemy/install/files/{alchemy.elements.css.scss → article.scss} +0 -0
  124. data/lib/rails/generators/alchemy/install/install_generator.rb +20 -19
  125. data/lib/rails/generators/alchemy/module/module_generator.rb +3 -5
  126. data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +7 -6
  127. data/lib/rails/generators/alchemy/site_layouts/site_layouts_generator.rb +7 -6
  128. data/vendor/assets/javascripts/date-formatter.js +161 -0
  129. data/vendor/assets/javascripts/jquery_plugins/jquery.datetimepicker.full.min.js +2 -0
  130. data/vendor/assets/javascripts/tinymce/langs/it.js +219 -0
  131. metadata +48 -13
  132. data/app/assets/javascripts/alchemy/alchemy.custom.js +0 -1
  133. data/app/assets/stylesheets/alchemy/custom.scss +0 -1
@@ -0,0 +1,68 @@
1
+ module Alchemy
2
+ # Renders an essence picture view
3
+ class EssencePictureView
4
+ include ActionView::Helpers::AssetTagHelper
5
+ include ActionView::Helpers::UrlHelper
6
+ include Rails.application.routes.url_helpers
7
+
8
+ attr_reader :content, :essence, :html_options, :options, :picture
9
+
10
+ DEFAULT_OPTIONS = {
11
+ show_caption: true,
12
+ disable_link: false
13
+ }
14
+
15
+ def initialize(content, options = {}, html_options = {})
16
+ @content = content
17
+ @options = DEFAULT_OPTIONS.update(content.settings).update(options)
18
+ @html_options = html_options
19
+ @essence = content.essence
20
+ @picture = essence.picture
21
+ end
22
+
23
+ def render
24
+ return if picture.blank?
25
+
26
+ output = caption ? img_tag + caption : img_tag
27
+
28
+ if is_linked?
29
+ output = link_to(output, url_for(essence.link), {
30
+ title: essence.link_title.presence,
31
+ target: essence.link_target == "blank" ? "_blank" : nil,
32
+ data: {link_target: essence.link_target.presence}
33
+ })
34
+ end
35
+
36
+ if caption
37
+ content_tag(:figure, output, {class: essence.css_class.presence}.merge(html_options))
38
+ else
39
+ output
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def caption
46
+ return unless show_caption?
47
+ @_caption ||= content_tag(:figcaption, essence.caption)
48
+ end
49
+
50
+ def img_tag
51
+ @_img_tag ||= image_tag(
52
+ essence.picture_url(options), {
53
+ alt: essence.alt_tag.presence,
54
+ title: essence.title.presence,
55
+ class: caption ? nil : essence.css_class.presence
56
+ }.merge(caption ? {} : html_options)
57
+ )
58
+ end
59
+
60
+ def show_caption?
61
+ options[:show_caption] && essence.caption.present?
62
+ end
63
+
64
+ def is_linked?
65
+ !options[:disable_link] && essence.link.present?
66
+ end
67
+ end
68
+ end
@@ -19,7 +19,7 @@
19
19
 
20
20
  module Alchemy
21
21
  class Language < ActiveRecord::Base
22
- belongs_to :site
22
+ belongs_to :site, required: true
23
23
  has_many :pages
24
24
 
25
25
  before_validation :set_locale, if: -> { locale.blank? }
@@ -52,11 +52,10 @@ module Alchemy
52
52
  before_destroy :check_for_default
53
53
  after_destroy :delete_language_root_page
54
54
 
55
- default_scope { on_site(Site.current) }
56
-
57
- scope :published, -> { where(public: true) }
58
- scope :with_root_page, -> { joins(:pages).where(Page.table_name => {language_root: true}) }
59
- scope :on_site, ->(s) { s.present? ? where(site_id: s.id) : all }
55
+ scope :published, -> { where(public: true) }
56
+ scope :with_root_page, -> { joins(:pages).where(Page.table_name => {language_root: true}) }
57
+ scope :on_site, ->(s) { s ? where(site_id: s.id) : all }
58
+ scope :on_current_site, -> { on_site(Site.current) }
60
59
 
61
60
  class << self
62
61
  # Store the current language in the current thread.
@@ -74,11 +73,10 @@ module Alchemy
74
73
  current.pages.language_roots.first
75
74
  end
76
75
 
77
- # Default language
76
+ # Default language for current site
78
77
  def default
79
- find_by(default: true)
78
+ on_current_site.find_by(default: true)
80
79
  end
81
- alias_method :get_default, :default
82
80
  end
83
81
 
84
82
  def label(attrib)
@@ -165,7 +163,7 @@ module Alchemy
165
163
  end
166
164
 
167
165
  def unpublish_pages
168
- pages.update_all(public: false)
166
+ pages.update_all(public_on: nil, public_until: nil)
169
167
  end
170
168
  end
171
169
  end
@@ -13,7 +13,10 @@ module Alchemy::Language::Code
13
13
  def find_by_code(code)
14
14
  codes = code.split('-')
15
15
  codes << '' if codes.length == 1
16
- find_by_language_code_and_country_code(*codes)
16
+ on_current_site.find_by(
17
+ language_code: codes[0],
18
+ country_code: codes[1]
19
+ )
17
20
  end
18
21
  end
19
22
  end
@@ -3,12 +3,12 @@
3
3
  # Table name: alchemy_pages
4
4
  #
5
5
  # id :integer not null, primary key
6
- # name :string(255)
7
- # urlname :string(255)
8
- # title :string(255)
9
- # language_code :string(255)
6
+ # name :string
7
+ # urlname :string
8
+ # title :string
9
+ # language_code :string
10
10
  # language_root :boolean
11
- # page_layout :string(255)
11
+ # page_layout :string
12
12
  # meta_keywords :text
13
13
  # meta_description :text
14
14
  # lft :integer
@@ -17,7 +17,7 @@
17
17
  # depth :integer
18
18
  # visible :boolean default(FALSE)
19
19
  # public :boolean default(FALSE)
20
- # locked :boolean default(FALSE)
20
+ # locked_at :datetime
21
21
  # locked_by :integer
22
22
  # restricted :boolean default(FALSE)
23
23
  # robot_index :boolean default(TRUE)
@@ -31,6 +31,8 @@
31
31
  # language_id :integer
32
32
  # cached_tag_list :text
33
33
  # published_at :datetime
34
+ # public_on :datetime
35
+ # public_until :datetime
34
36
  #
35
37
 
36
38
  module Alchemy
@@ -43,17 +45,32 @@ module Alchemy
43
45
  do_not_autogenerate: true,
44
46
  do_not_sweep: true,
45
47
  visible: false,
46
- public: false,
47
- locked: false,
48
+ public_on: nil,
49
+ public_until: nil,
50
+ locked_at: nil,
48
51
  locked_by: nil
49
52
  }
50
- SKIPPED_ATTRIBUTES_ON_COPY = %w(id updated_at created_at creator_id updater_id lft rgt depth urlname cached_tag_list)
53
+
54
+ SKIPPED_ATTRIBUTES_ON_COPY = %w(
55
+ id
56
+ updated_at
57
+ created_at
58
+ creator_id
59
+ updater_id
60
+ lft
61
+ rgt
62
+ depth
63
+ urlname
64
+ cached_tag_list
65
+ )
66
+
51
67
  PERMITTED_ATTRIBUTES = [
52
68
  :meta_description,
53
69
  :meta_keywords,
54
70
  :name,
55
71
  :page_layout,
56
- :public,
72
+ :public_on,
73
+ :public_until,
57
74
  :restricted,
58
75
  :robot_index,
59
76
  :robot_follow,
@@ -73,6 +90,7 @@ module Alchemy
73
90
  belongs_to :language
74
91
 
75
92
  has_one :site, through: :language
93
+ has_many :site_languages, through: :site, source: :languages
76
94
  has_many :folded_pages
77
95
  has_many :legacy_urls, class_name: 'Alchemy::LegacyPageUrl'
78
96
 
@@ -84,12 +102,29 @@ module Alchemy
84
102
  attr_accessor :do_not_sweep
85
103
  attr_accessor :do_not_validate_language
86
104
 
87
- before_save :set_language_code, if: -> { language.present? }, unless: :systempage?
88
- before_save :set_restrictions_to_child_pages, if: :restricted_changed?, unless: :systempage?
89
- before_save :inherit_restricted_status, if: -> { parent && parent.restricted? }, unless: :systempage?
90
- before_save :update_published_at, if: -> { public && read_attribute(:published_at).nil? }, unless: :systempage?
91
- before_create :set_language_from_parent_or_default, if: -> { language_id.blank? }, unless: :systempage?
92
- after_update :create_legacy_url, if: :urlname_changed?, unless: :redirects_to_external?
105
+ before_save :set_language_code,
106
+ if: -> { language.present? },
107
+ unless: :systempage?
108
+
109
+ before_save :set_restrictions_to_child_pages,
110
+ if: :restricted_changed?,
111
+ unless: :systempage?
112
+
113
+ before_save :inherit_restricted_status,
114
+ if: -> { parent && parent.restricted? },
115
+ unless: :systempage?
116
+
117
+ before_save :set_published_at,
118
+ if: -> { public? && published_at.nil? },
119
+ unless: :systempage?
120
+
121
+ before_create :set_language_from_parent_or_default,
122
+ if: -> { language_id.blank? },
123
+ unless: :systempage?
124
+
125
+ after_update :create_legacy_url,
126
+ if: :urlname_changed?,
127
+ unless: :redirects_to_external?
93
128
 
94
129
  # Concerns
95
130
  include Alchemy::Page::PageScopes
@@ -99,6 +134,9 @@ module Alchemy
99
134
  include Alchemy::Page::PageCells
100
135
  include Alchemy::Page::PageElements
101
136
 
137
+ # site_name accessor
138
+ delegate :name, to: :site, prefix: true, allow_nil: true
139
+
102
140
  # Class methods
103
141
  #
104
142
  class << self
@@ -281,16 +319,16 @@ module Alchemy
281
319
  end
282
320
  alias_method :next_page, :next
283
321
 
284
- # Locks the page to given user without updating the timestamps
322
+ # Locks the page to given user
285
323
  #
286
324
  def lock_to!(user)
287
- update_columns(locked: true, locked_by: user.id)
325
+ update_columns(locked_at: Time.current, locked_by: user.id)
288
326
  end
289
327
 
290
328
  # Unlocks the page without updating the timestamps
291
329
  #
292
330
  def unlock!
293
- if update_columns(locked: false, locked_by: nil)
331
+ if update_columns(locked_at: nil, locked_by: nil)
294
332
  Page.current_preview = nil
295
333
  end
296
334
  end
@@ -335,12 +373,18 @@ module Alchemy
335
373
 
336
374
  # Publishes the page.
337
375
  #
338
- # Sets +public+ to true and the +published_at+ value to current time.
376
+ # Sets +public_on+ and the +published_at+ value to current time
377
+ # and resets +public_until+ to nil
339
378
  #
340
379
  # The +published_at+ attribute is used as +cache_key+.
341
380
  #
342
381
  def publish!
343
- update_columns(published_at: Time.current, public: true)
382
+ current_time = Time.current
383
+ update_columns(
384
+ published_at: current_time,
385
+ public_on: current_time,
386
+ public_until: nil
387
+ )
344
388
  end
345
389
 
346
390
  # Updates an Alchemy::Page based on a new ordering to be applied to it
@@ -380,10 +424,9 @@ module Alchemy
380
424
  public: true
381
425
  }.update(options)
382
426
 
383
- self_and_siblings
384
- .where(["#{self.class.table_name}.lft #{dir} ?", lft])
385
- .where(public: options[:public])
386
- .where(restricted: options[:restricted])
427
+ pages = self_and_siblings.where(["#{Page.table_name}.lft #{dir} ?", lft])
428
+ pages = options[:public] ? pages.published : pages.not_public
429
+ pages.where(restricted: options[:restricted])
387
430
  .reorder(dir == '>' ? 'lft' : 'lft DESC')
388
431
  .limit(1).first
389
432
  end
@@ -402,7 +445,7 @@ module Alchemy
402
445
  legacy_urls.find_or_create_by(urlname: urlname_was)
403
446
  end
404
447
 
405
- def update_published_at
448
+ def set_published_at
406
449
  self.published_at = Time.current
407
450
  end
408
451
  end
@@ -2,6 +2,15 @@ module Alchemy
2
2
  module Page::PageNatures
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ def public?
6
+ current_time = Time.current
7
+ already_public_for?(current_time) && still_public_for?(current_time)
8
+ end
9
+
10
+ def expiration_time
11
+ public_until? ? public_until - Time.current : nil
12
+ end
13
+
5
14
  def taggable?
6
15
  definition['taggable'] == true
7
16
  end
@@ -33,6 +42,11 @@ module Alchemy
33
42
  !PageLayout.get(page_layout).nil? && !PageLayout.get(page_layout)["controller"].blank?
34
43
  end
35
44
 
45
+ # True if page locked_at timestamp and locked_by id are set
46
+ def locked?
47
+ locked_by? && locked_at?
48
+ end
49
+
36
50
  def controller_and_action
37
51
  if has_controller?
38
52
  {
@@ -144,5 +158,13 @@ module Alchemy
144
158
  Alchemy::Config.get(:cache_pages) &&
145
159
  Rails.application.config.action_controller.perform_caching
146
160
  end
161
+
162
+ def already_public_for?(time)
163
+ !public_on.nil? && public_on <= time
164
+ end
165
+
166
+ def still_public_for?(time)
167
+ public_until.nil? || public_until >= time
168
+ end
147
169
  end
148
170
  end
@@ -15,7 +15,7 @@ module Alchemy
15
15
 
16
16
  # All locked pages
17
17
  #
18
- scope :locked, -> { where(locked: true) }
18
+ scope :locked, -> { where.not(locked_at: nil, locked_by: nil) }
19
19
 
20
20
  # All pages locked by given user
21
21
  #
@@ -27,16 +27,12 @@ module Alchemy
27
27
 
28
28
  # All not locked pages
29
29
  #
30
- scope :not_locked, -> { where(locked: false) }
30
+ scope :not_locked, -> { where(locked_at: nil, locked_by: nil) }
31
31
 
32
32
  # All visible pages
33
33
  #
34
34
  scope :visible, -> { where(visible: true) }
35
35
 
36
- # All public pages
37
- #
38
- scope :published, -> { where(public: true) }
39
-
40
36
  # All not restricted pages
41
37
  #
42
38
  scope :not_restricted, -> { where(restricted: false) }
@@ -99,5 +95,23 @@ module Alchemy
99
95
  #
100
96
  scope :sitemap, -> { from_current_site.published.contentpages.where(sitemap: true) }
101
97
  end
98
+
99
+ module ClassMethods
100
+ # All public pages
101
+ #
102
+ def published
103
+ where("#{table_name}.public_on <= :time AND " \
104
+ "(#{table_name}.public_until IS NULL " \
105
+ "OR #{table_name}.public_until >= :time)", time: Time.current)
106
+ end
107
+
108
+ # All not public pages
109
+ #
110
+ def not_public
111
+ where("#{table_name}.public_on IS NULL OR " \
112
+ "#{table_name}.public_on >= :time OR " \
113
+ "#{table_name}.public_until <= :time", time: Time.current)
114
+ end
115
+ end
102
116
  end
103
117
  end
@@ -3,22 +3,25 @@
3
3
  # Table name: alchemy_pictures
4
4
  #
5
5
  # id :integer not null, primary key
6
- # name :string(255)
7
- # image_file_name :string(255)
6
+ # name :string
7
+ # image_file_name :string
8
8
  # image_file_width :integer
9
9
  # image_file_height :integer
10
10
  # created_at :datetime not null
11
11
  # updated_at :datetime not null
12
12
  # creator_id :integer
13
13
  # updater_id :integer
14
- # upload_hash :string(255)
14
+ # upload_hash :string
15
15
  # cached_tag_list :text
16
- # image_file_uid :string(255)
16
+ # image_file_uid :string
17
17
  # image_file_size :integer
18
+ # image_file_format :string
18
19
  #
19
20
 
20
21
  module Alchemy
21
22
  class Picture < ActiveRecord::Base
23
+ CONVERTIBLE_FILE_FORMATS = %w(gif jpg jpeg png).freeze
24
+
22
25
  include Alchemy::NameConversions
23
26
  include Alchemy::Touching
24
27
  include Alchemy::Picture::Sweeping
@@ -183,6 +186,36 @@ module Alchemy
183
186
  convert_to_humanized_name(image_file_name, suffix)
184
187
  end
185
188
 
189
+ # Returns the format the image should be rendered with
190
+ #
191
+ # Only returns a format differing from original if an +image_output_format+
192
+ # is set in config and the image has a convertible file format.
193
+ #
194
+ def default_render_format
195
+ if convertible?
196
+ Config.get(:image_output_format)
197
+ else
198
+ image_file_format
199
+ end
200
+ end
201
+
202
+ # Returns true if the image can be converted
203
+ #
204
+ # If the +image_output_format+ is set to +nil+ or +original+ or the
205
+ # image has not a convertible file format (i.e. SVG) this returns +false+
206
+ #
207
+ def convertible?
208
+ Config.get(:image_output_format) &&
209
+ Config.get(:image_output_format) != 'original' &&
210
+ has_convertible_format?
211
+ end
212
+
213
+ # Returns true if the image can be converted into other formats
214
+ #
215
+ def has_convertible_format?
216
+ image_file_format.in?(CONVERTIBLE_FILE_FORMATS)
217
+ end
218
+
186
219
  # Checks if the picture is restricted.
187
220
  #
188
221
  # A picture is only restricted if it's assigned on restricted pages only.