decidim-proposals 0.18.1 → 0.19.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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_proposals_manifest.js +0 -1
  3. data/app/assets/javascripts/decidim/proposals/admin/proposals_form.js.es6 +5 -0
  4. data/app/cells/decidim/proposals/collaborative_draft_m_cell.rb +1 -0
  5. data/app/cells/decidim/proposals/endorsers_list_cell.rb +1 -0
  6. data/app/cells/decidim/proposals/irreversible_action_modal_cell.rb +1 -0
  7. data/app/cells/decidim/proposals/participatory_text_proposal/buttons.erb +8 -8
  8. data/app/cells/decidim/proposals/participatory_text_proposal_cell.rb +13 -0
  9. data/app/cells/decidim/proposals/proposal_link_to_collaborative_draft_cell.rb +4 -8
  10. data/app/cells/decidim/proposals/{proposal_link_to_collaborative_draft → proposal_link_to_rejected_emendation}/show.erb +0 -0
  11. data/app/cells/decidim/proposals/proposal_link_to_rejected_emendation_cell.rb +34 -0
  12. data/app/cells/decidim/proposals/proposal_linked_resources/show.erb +9 -0
  13. data/app/cells/decidim/proposals/proposal_linked_resources_cell.rb +14 -0
  14. data/app/cells/decidim/proposals/proposal_m_cell.rb +3 -0
  15. data/app/commands/decidim/proposals/admin/create_proposal.rb +10 -33
  16. data/app/commands/decidim/proposals/admin/import_participatory_text.rb +2 -0
  17. data/app/commands/decidim/proposals/admin/merge_proposals.rb +1 -0
  18. data/app/commands/decidim/proposals/admin/publish_participatory_text.rb +24 -1
  19. data/app/commands/decidim/proposals/admin/update_participatory_text.rb +11 -7
  20. data/app/commands/decidim/proposals/admin/update_proposal.rb +9 -1
  21. data/app/commands/decidim/proposals/gallery_methods.rb +67 -0
  22. data/app/commands/decidim/proposals/unvote_proposal.rb +1 -0
  23. data/app/commands/decidim/proposals/update_proposal.rb +6 -1
  24. data/app/commands/decidim/proposals/vote_proposal.rb +1 -0
  25. data/app/controllers/concerns/decidim/proposals/collaborative_orderable.rb +1 -15
  26. data/app/controllers/concerns/decidim/proposals/orderable.rb +1 -15
  27. data/app/controllers/decidim/proposals/admin/participatory_texts_controller.rb +5 -0
  28. data/app/controllers/decidim/proposals/application_controller.rb +1 -0
  29. data/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +1 -0
  30. data/app/controllers/decidim/proposals/proposal_endorsements_controller.rb +1 -1
  31. data/app/controllers/decidim/proposals/proposal_votes_controller.rb +1 -1
  32. data/app/controllers/decidim/proposals/proposals_controller.rb +22 -23
  33. data/app/forms/decidim/proposals/admin/proposal_form.rb +3 -0
  34. data/app/forms/decidim/proposals/admin/proposals_fork_form.rb +1 -0
  35. data/app/forms/decidim/proposals/proposal_wizard_create_step_form.rb +1 -0
  36. data/app/helpers/decidim/proposals/admin/proposals_helper.rb +1 -0
  37. data/app/helpers/decidim/proposals/map_helper.rb +1 -1
  38. data/app/helpers/decidim/proposals/proposal_cells_helper.rb +2 -0
  39. data/app/helpers/decidim/proposals/proposal_endorsements_helper.rb +1 -0
  40. data/app/helpers/decidim/proposals/proposal_votes_helper.rb +5 -0
  41. data/app/helpers/decidim/proposals/proposal_wizard_helper.rb +1 -0
  42. data/app/models/decidim/proposals/collaborative_draft.rb +1 -0
  43. data/app/models/decidim/proposals/proposal.rb +4 -8
  44. data/app/models/decidim/proposals/proposal_endorsement.rb +2 -0
  45. data/app/models/decidim/proposals/proposal_vote.rb +2 -0
  46. data/app/permissions/decidim/proposals/admin/permissions.rb +1 -0
  47. data/app/permissions/decidim/proposals/permissions.rb +17 -0
  48. data/app/presenters/decidim/proposals/admin_log/value_types/proposal_state_presenter.rb +1 -0
  49. data/app/presenters/decidim/proposals/collaborative_draft_presenter.rb +1 -1
  50. data/app/presenters/decidim/proposals/proposal_presenter.rb +4 -2
  51. data/app/queries/decidim/proposals/metrics/endorsements_metric_manage.rb +1 -0
  52. data/app/queries/decidim/proposals/metrics/proposal_followers_metric_measure.rb +2 -0
  53. data/app/queries/decidim/proposals/metrics/proposal_participants_metric_measure.rb +3 -0
  54. data/app/queries/decidim/proposals/metrics/proposals_metric_manage.rb +1 -0
  55. data/app/queries/decidim/proposals/metrics/votes_metric_manage.rb +1 -0
  56. data/app/services/decidim/proposals/diff_renderer.rb +43 -0
  57. data/app/services/decidim/proposals/proposal_builder.rb +23 -0
  58. data/app/services/decidim/proposals/proposal_search.rb +5 -3
  59. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +24 -0
  60. data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +3 -3
  61. data/app/views/decidim/proposals/collaborative_drafts/_collaborative_drafts.html.erb +1 -1
  62. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +0 -3
  63. data/app/views/decidim/proposals/proposal_endorsements/_identity.html.erb +1 -1
  64. data/app/views/decidim/proposals/proposals/_filters.html.erb +2 -1
  65. data/app/views/decidim/proposals/proposals/_proposal_preview.html.erb +1 -1
  66. data/app/views/decidim/proposals/proposals/_proposals.html.erb +1 -1
  67. data/app/views/decidim/proposals/proposals/index.html.erb +1 -1
  68. data/app/views/decidim/proposals/proposals/participatory_texts/_index.html.erb +1 -1
  69. data/app/views/decidim/proposals/proposals/show.html.erb +13 -9
  70. data/config/locales/ar.yml +2 -0
  71. data/config/locales/ca.yml +20 -0
  72. data/config/locales/cs.yml +20 -0
  73. data/config/locales/de.yml +2 -0
  74. data/config/locales/en.yml +20 -0
  75. data/config/locales/es-MX.yml +18 -0
  76. data/config/locales/es-PY.yml +18 -0
  77. data/config/locales/es.yml +20 -0
  78. data/config/locales/fi-plain.yml +20 -0
  79. data/config/locales/fi.yml +20 -0
  80. data/config/locales/fr.yml +21 -1
  81. data/config/locales/hu.yml +20 -0
  82. data/config/locales/it.yml +16 -0
  83. data/config/locales/nl.yml +20 -0
  84. data/config/locales/sv.yml +15 -0
  85. data/config/locales/tr-TR.yml +7 -0
  86. data/lib/decidim/content_parsers/proposal_parser.rb +2 -2
  87. data/lib/decidim/content_renderers/proposal_renderer.rb +1 -1
  88. data/lib/decidim/proposals/commentable_proposal.rb +1 -0
  89. data/lib/decidim/proposals/component.rb +8 -3
  90. data/lib/decidim/proposals/engine.rb +0 -1
  91. data/lib/decidim/proposals/markdown_to_proposals.rb +11 -7
  92. data/lib/decidim/proposals/proposal_serializer.rb +20 -2
  93. data/lib/decidim/proposals/version.rb +1 -1
  94. metadata +24 -38
  95. data/app/assets/config/decidim_proposals_manifest.css +0 -3
  96. data/app/assets/javascripts/decidim/proposals/social_share.js +0 -2
  97. data/app/assets/stylesheets/decidim/proposals/social_share.css.scss +0 -22
  98. data/config/initializers/social_share_button.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 306966eaa2bcf8c8ffc812a513e1b388be7f32f436ad0a227259ca84bffc84aa
4
- data.tar.gz: 91791cb5717209c350d5ccd74a2d7bb49e5fe02c7e23d1ffde5ddfcc5eea0ca9
3
+ metadata.gz: 0e4a0b1c5edf206b2bf649405971a154486744d8946368b0454eca7936d51c47
4
+ data.tar.gz: 89554df3c8b7adcc5a3d9f694f5f08fbe59a6bd3a1e646d314ffc3b796425e46
5
5
  SHA512:
6
- metadata.gz: 576553bcf02a966a59848742b93262a0cbbb6a7e25eaa1c168b074d3341545ac9c3165a22b929b006fa906a2b433f9c4396fd51d9814e72506a02f75e623a462
7
- data.tar.gz: 25240f1221131cfea87c90e6bada749cdb5fd52cf25d2ba936977fa7d142f2ae25e23b1e9955086a02e9178987fc7a40d26e7855c096c05e71b2c504f0e4e9e9
6
+ metadata.gz: cea6a62ae70be12318f9d46209add1cace49be33745d7cefedd8eec3de5a8b319a759839c24a950c8bc6c814c21ce6eb8afebcbbac1c41e464c7e78989433d80
7
+ data.tar.gz: d90297aa8f6a80d1314d692b087a3fe5a1f8d1fea071762610eceb03661d346d1654bc62be2cf1f2c9181ba38c49103ef0c862c0210daec0d5b7e92516597175
@@ -1,4 +1,3 @@
1
- //= link decidim/proposals/social_share.js
2
1
  //= link decidim/proposals/add_proposal.js
3
2
  //= link decidim/proposals/admin/proposals_form.js
4
3
  //= link_tree ../images/decidim
@@ -20,4 +20,9 @@ $(() => {
20
20
  toggleDisabledHiddenFields();
21
21
 
22
22
  }
23
+
24
+ $(document).on("closed.zf.callout", (event) => {
25
+ $(event.target).remove();
26
+ });
27
+
23
28
  });
@@ -32,6 +32,7 @@ module Decidim
32
32
 
33
33
  def badge_classes
34
34
  return super unless options[:full_badge]
35
+
35
36
  state_classes.concat(["label", "collaborative-draft-status"]).join(" ")
36
37
  end
37
38
 
@@ -14,6 +14,7 @@ module Decidim
14
14
 
15
15
  def show
16
16
  return unless endorsers.any?
17
+
17
18
  render
18
19
  end
19
20
 
@@ -10,6 +10,7 @@ module Decidim
10
10
  class IrreversibleActionModalCell < Decidim::ViewModel
11
11
  def show
12
12
  return unless action.presence
13
+
13
14
  render :show
14
15
  end
15
16
 
@@ -1,18 +1,18 @@
1
1
  <div class="columns mediumlarge-4 hidden-section p-sm">
2
2
  <div class="medium-8">
3
3
  <%= follow_button_for(model, true) %>
4
- <% if amendments_enabled? %>
5
- <div class="button-group button-group--collapse mb-s row collapse">
4
+ <% if amendmendment_creation_enabled? || visible_emendations.any? %>
5
+ <div class="button-group button-group--collapse mb-s row collapse amend-buttons">
6
6
  <%= link_to resource_amendments_path, class: "column medium-4 button light secondary" do %>
7
- <%= model.emendations.count %>
8
- <% end %>
9
- <%= link_to amend_resource_path, class: "column button hollow secondary button--sc" do %>
10
- <%= t("amend", scope: "decidim.proposals.participatory_text_proposal.buttons") %>
11
- <% end %>
7
+ <%= visible_emendations.count %>
8
+ <% end %>
9
+ <%= link_to amend_resource_path, class: "column button hollow secondary button--sc", disabled: amend_button_disabled? do %>
10
+ <%= t("amend", scope: "decidim.proposals.participatory_text_proposal.buttons") %>
11
+ <% end %>
12
12
  </div>
13
13
  <% end %>
14
14
  <% if component_settings.comments_enabled? %>
15
- <div class="button-group button-group--collapse row collapse">
15
+ <div class="button-group button-group--collapse row collapse comment-buttons">
16
16
  <% if current_settings.comments_blocked? %>
17
17
  <%= content_tag :button, class: "column medium-4 button light secondary", title: t("endorse", scope: "decidim.proposals.participatory_text_proposal.buttons") do %>
18
18
  <%= icon "comment-square", class: "icon--small", aria_label: t("comments", scope: "decidim.proposals.participatory_text_proposal.buttons"), role: "img" %>
@@ -33,6 +33,7 @@ module Decidim
33
33
 
34
34
  def body
35
35
  return unless model.participatory_text_level == "article"
36
+
36
37
  formatted = simple_format(present(model).body)
37
38
  decidim_sanitize(strip_links(formatted))
38
39
  end
@@ -72,6 +73,18 @@ module Decidim
72
73
  def participatory_space_type_name
73
74
  translated_attribute current_participatory_space.model_name.human
74
75
  end
76
+
77
+ def visible_emendations
78
+ @visible_emendations ||= model.visible_emendations_for(current_user)
79
+ end
80
+
81
+ def amendmendment_creation_enabled?
82
+ (current_component.settings.amendments_enabled? && current_settings.amendment_creation_enabled?)
83
+ end
84
+
85
+ def amend_button_disabled?
86
+ !amendmendment_creation_enabled?
87
+ end
75
88
  end
76
89
  end
77
90
  end
@@ -5,19 +5,15 @@ require "cell/partial"
5
5
  module Decidim
6
6
  module Proposals
7
7
  # This cell renders the link to the source collaborative draft of a proposal.
8
- class ProposalLinkToCollaborativeDraftCell < Decidim::ViewModel
9
- def show
10
- render if collaborative_draft
11
- end
12
-
8
+ class ProposalLinkToCollaborativeDraftCell < ProposalLinkedResourcesCell
13
9
  private
14
10
 
15
- def collaborative_draft
16
- @collaborative_draft ||= model.linked_resources(:collaborative_draft, "created_from_collaborative_draft").first
11
+ def linked_resource
12
+ @linked_resource ||= model.linked_resources(:collaborative_draft, "created_from_collaborative_draft").first
17
13
  end
18
14
 
19
15
  def link_to_resource
20
- link_to resource_locator(collaborative_draft).path, class: "link" do
16
+ link_to resource_locator(linked_resource).path, class: "link" do
21
17
  t("link_to_collaborative_draft_text", scope: "decidim.proposals.proposals.show")
22
18
  end
23
19
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cell/partial"
4
+
5
+ module Decidim
6
+ module Proposals
7
+ # This cell renders the link to the rejected emendation promoted to proposal.
8
+ class ProposalLinkToRejectedEmendationCell < ProposalLinkedResourcesCell
9
+ private
10
+
11
+ def linked_resource
12
+ @linked_resource ||= model.linked_promoted_resource
13
+ end
14
+
15
+ def link_to_resource
16
+ link_to resource_locator(linked_resource).path, class: "link" do
17
+ if model.emendation?
18
+ t("link_to_proposal_from_emendation_text", scope: "decidim.proposals.proposals.show")
19
+ else
20
+ t("link_to_promoted_emendation_text", scope: "decidim.proposals.proposals.show")
21
+ end
22
+ end
23
+ end
24
+
25
+ def link_help_text
26
+ if model.emendation?
27
+ t("link_to_proposal_from_emendation_help_text", scope: "decidim.proposals.proposals.show")
28
+ else
29
+ t("link_to_promoted_emendation_help_text", scope: "decidim.proposals.proposals.show")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ <div class="text-center mt-sm">
2
+ <%= link_to_resource %>
3
+
4
+ <div class="text-center">
5
+ <small>
6
+ <%= link_help_text %>
7
+ </small>
8
+ </div>
9
+ </div>
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cell/partial"
4
+
5
+ module Decidim
6
+ module Proposals
7
+ # This cell renders the linked resource of a proposal.
8
+ class ProposalLinkedResourcesCell < Decidim::ViewModel
9
+ def show
10
+ render if linked_resource
11
+ end
12
+ end
13
+ end
14
+ end
@@ -36,6 +36,7 @@ module Decidim
36
36
 
37
37
  def has_footer?
38
38
  return false if model.emendation?
39
+
39
40
  true
40
41
  end
41
42
 
@@ -45,12 +46,14 @@ module Decidim
45
46
 
46
47
  def badge_classes
47
48
  return super unless options[:full_badge]
49
+
48
50
  state_classes.concat(["label", "proposal-status"]).join(" ")
49
51
  end
50
52
 
51
53
  def statuses
52
54
  return [:endorsements_count, :comments_count] if model.draft?
53
55
  return [:creation_date, :endorsements_count, :comments_count] if !has_link_to_resource? || !can_be_followed?
56
+
54
57
  [:creation_date, :follow, :endorsements_count, :comments_count]
55
58
  end
56
59
 
@@ -5,6 +5,8 @@ module Decidim
5
5
  module Admin
6
6
  # A command with all the business logic when a user creates a new proposal.
7
7
  class CreateProposal < Rectify::Command
8
+ include AttachmentMethods
9
+ include GalleryMethods
8
10
  include HashtagsMethods
9
11
 
10
12
  # Public: Initializes the command.
@@ -28,9 +30,15 @@ module Decidim
28
30
  return broadcast(:invalid) if attachment_invalid?
29
31
  end
30
32
 
33
+ if process_gallery?
34
+ build_gallery
35
+ return broadcast(:invalid) if gallery_invalid?
36
+ end
37
+
31
38
  transaction do
32
39
  create_proposal
33
40
  create_attachment if process_attachments?
41
+ create_gallery if process_gallery?
34
42
  send_notification
35
43
  end
36
44
 
@@ -39,7 +47,7 @@ module Decidim
39
47
 
40
48
  private
41
49
 
42
- attr_reader :form, :proposal, :attachment
50
+ attr_reader :form, :proposal, :attachment, :gallery
43
51
 
44
52
  def create_proposal
45
53
  @proposal = Decidim::Proposals::ProposalBuilder.create(
@@ -47,6 +55,7 @@ module Decidim
47
55
  author: form.author,
48
56
  action_user: form.current_user
49
57
  )
58
+ @attached_to = @proposal
50
59
  end
51
60
 
52
61
  def attributes
@@ -64,38 +73,6 @@ module Decidim
64
73
  }
65
74
  end
66
75
 
67
- def build_attachment
68
- @attachment = Attachment.new(
69
- title: form.attachment.title,
70
- file: form.attachment.file,
71
- attached_to: @proposal
72
- )
73
- end
74
-
75
- def attachment_invalid?
76
- if attachment.invalid? && attachment.errors.has_key?(:file)
77
- form.attachment.errors.add :file, attachment.errors[:file]
78
- true
79
- end
80
- end
81
-
82
- def attachment_present?
83
- form.attachment.file.present?
84
- end
85
-
86
- def create_attachment
87
- attachment.attached_to = proposal
88
- attachment.save!
89
- end
90
-
91
- def attachments_allowed?
92
- form.current_component.settings.attachments_allowed?
93
- end
94
-
95
- def process_attachments?
96
- attachments_allowed? && attachment_present?
97
- end
98
-
99
76
  def send_notification
100
77
  Decidim::EventsManager.publish(
101
78
  event: "decidim.events.proposals.proposal_published",
@@ -28,6 +28,8 @@ module Decidim
28
28
  end
29
29
 
30
30
  broadcast(:ok)
31
+ rescue StandardError
32
+ broadcast(:invalid_file)
31
33
  end
32
34
 
33
35
  private
@@ -40,6 +40,7 @@ module Decidim
40
40
 
41
41
  def proposals_to_link
42
42
  return previous_links if form.same_component?
43
+
43
44
  form.proposals
44
45
  end
45
46
 
@@ -39,7 +39,7 @@ module Decidim
39
39
 
40
40
  def publish_drafts
41
41
  Decidim::Proposals::Proposal.where(component: form.current_component).drafts.find_each do |proposal|
42
- add_failure(proposal) unless proposal.update(published_at: Time.current)
42
+ add_failure(proposal) unless publish_proposal(proposal)
43
43
  end
44
44
  raise ActiveRecord::Rollback if @failures.any?
45
45
  end
@@ -47,6 +47,29 @@ module Decidim
47
47
  def add_failure(proposal)
48
48
  @failures[proposal.id] = proposal.errors.full_messages
49
49
  end
50
+
51
+ # This will be the PaperTrail version shown in the version control feature (1 of 1).
52
+ # For an attribute to appear in the new version it has to be reset
53
+ # and reassigned, as PaperTrail only keeps track of object CHANGES.
54
+ def publish_proposal(proposal)
55
+ title, body = reset_proposal_title_and_body(proposal)
56
+
57
+ Decidim.traceability.perform_action!(:create, proposal, form.current_user, visibility: "all") do
58
+ proposal.update(title: title, body: body, published_at: Time.current)
59
+ end
60
+ end
61
+
62
+ # Reset the attributes to an empty string and return the old values.
63
+ def reset_proposal_title_and_body(proposal)
64
+ title = proposal.title
65
+ body = proposal.body
66
+
67
+ PaperTrail.request(enabled: false) do
68
+ proposal.update_columns(title: "", body: "") # rubocop:disable Rails/SkipsModelValidations
69
+ end
70
+
71
+ [title, body]
72
+ end
50
73
  end
51
74
  end
52
75
  end
@@ -35,14 +35,18 @@ module Decidim
35
35
 
36
36
  attr_reader :form
37
37
 
38
+ # Prevents PaperTrail from creating versions while updating participatory text proposals.
39
+ # A first version will be created when publishing the Participatory Text.
38
40
  def update_contents_and_resort_proposals(form)
39
- form.proposals.each do |prop_form|
40
- proposal = Decidim::Proposals::Proposal.where(component: form.current_component).find(prop_form.id)
41
- proposal.set_list_position(prop_form.position) if proposal.position != prop_form.position
42
- proposal.title = prop_form.title
43
- proposal.body = prop_form.body if proposal.participatory_text_level == Decidim::Proposals::ParticipatoryTextSection::LEVELS[:article]
44
-
45
- add_failure(proposal) unless proposal.save
41
+ PaperTrail.request(enabled: false) do
42
+ form.proposals.each do |prop_form|
43
+ proposal = Proposal.where(component: form.current_component).find(prop_form.id)
44
+ proposal.set_list_position(prop_form.position) if proposal.position != prop_form.position
45
+ proposal.title = prop_form.title
46
+ proposal.body = prop_form.body if proposal.participatory_text_level == ParticipatoryTextSection::LEVELS[:article]
47
+
48
+ add_failure(proposal) unless proposal.save
49
+ end
46
50
  end
47
51
  raise ActiveRecord::Rollback if @failures.any?
48
52
  end
@@ -6,6 +6,7 @@ module Decidim
6
6
  # A command with all the business logic when a user updates a proposal.
7
7
  class UpdateProposal < Rectify::Command
8
8
  include AttachmentMethods
9
+ include GalleryMethods
9
10
  include HashtagsMethods
10
11
 
11
12
  # Public: Initializes the command.
@@ -34,10 +35,17 @@ module Decidim
34
35
  return broadcast(:invalid) if attachment_invalid?
35
36
  end
36
37
 
38
+ if process_gallery?
39
+ build_gallery
40
+ return broadcast(:invalid) if gallery_invalid?
41
+ end
42
+
37
43
  transaction do
38
44
  update_proposal
39
45
  update_proposal_author
40
46
  create_attachment if process_attachments?
47
+ create_gallery if process_gallery?
48
+ photo_cleanup!
41
49
  end
42
50
 
43
51
  broadcast(:ok, proposal)
@@ -45,7 +53,7 @@ module Decidim
45
53
 
46
54
  private
47
55
 
48
- attr_reader :form, :proposal, :attachment
56
+ attr_reader :form, :proposal, :attachment, :gallery
49
57
 
50
58
  def update_proposal
51
59
  Decidim.traceability.update!(
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ # A module with all the gallery common methods for proposals
6
+ # and collaborative draft commands.
7
+ # Allows to create several image attachments at once
8
+ module GalleryMethods
9
+ private
10
+
11
+ def build_gallery
12
+ @gallery = []
13
+ @form.add_photos.each do |photo|
14
+ next unless image? photo
15
+
16
+ @gallery << Attachment.new(
17
+ title: photo.original_filename,
18
+ file: photo,
19
+ attached_to: @attached_to
20
+ )
21
+ end
22
+ end
23
+
24
+ def image?(image)
25
+ return unless image.respond_to? :content_type
26
+
27
+ image.content_type.start_with? "image"
28
+ end
29
+
30
+ def gallery_invalid?
31
+ gallery.each do |photo|
32
+ if photo.invalid? && photo.errors.has_key?(:file)
33
+ @form.errors.add(:add_photos, photo.errors[:file])
34
+ return true
35
+ end
36
+ end
37
+ false
38
+ end
39
+
40
+ def create_gallery
41
+ @gallery.map! do |photo|
42
+ photo.attached_to = @attached_to
43
+ photo.save!
44
+ @form.photos << photo.id.to_s
45
+ end
46
+ end
47
+
48
+ def photo_cleanup!
49
+ @attached_to.photos.each do |photo|
50
+ photo.destroy! if @form.photos.exclude? photo.id.to_s
51
+ end
52
+ # manually reset cached photos
53
+ @attached_to.reload
54
+ @attached_to.instance_variable_set(:@photos, nil)
55
+ end
56
+
57
+ # maybe a custom settings options would be nice
58
+ def gallery_allowed?
59
+ @form.current_component.settings.attachments_allowed?
60
+ end
61
+
62
+ def process_gallery?
63
+ gallery_allowed? && @form.add_photos.any?
64
+ end
65
+ end
66
+ end
67
+ end