decidim-core 0.18.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim-core might be problematic. Click here for more details.

Files changed (275) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_core_manifest.js +3 -0
  3. data/app/assets/javascripts/decidim/social_share.js +2 -0
  4. data/app/assets/stylesheets/decidim/extras/_social_share.css.scss +36 -0
  5. data/app/assets/stylesheets/decidim/modules/_input-gallery.scss +24 -0
  6. data/app/assets/stylesheets/decidim/modules/_navbar.scss +1 -1
  7. data/app/cells/decidim/activities_cell.rb +13 -8
  8. data/app/cells/decidim/activity_cell.rb +19 -5
  9. data/app/cells/decidim/address/details.erb +2 -2
  10. data/app/cells/decidim/amendable/amenders_list/show.erb +1 -1
  11. data/app/cells/decidim/amendable/amenders_list_cell.rb +5 -1
  12. data/app/cells/decidim/amendable/announcement_cell.rb +22 -9
  13. data/app/cells/decidim/amendable/wizard_step_form_cell.rb +121 -0
  14. data/app/cells/decidim/announcement_cell.rb +1 -0
  15. data/app/cells/decidim/author_cell.rb +7 -0
  16. data/app/cells/decidim/card_m_cell.rb +3 -1
  17. data/app/cells/decidim/coauthorships_cell.rb +3 -1
  18. data/app/cells/decidim/collapsible_authors_cell.rb +1 -0
  19. data/app/cells/decidim/collapsible_list_cell.rb +1 -0
  20. data/app/cells/decidim/content_blocks/highlighted_content_banner_cell.rb +1 -0
  21. data/app/cells/decidim/content_blocks/last_activity_cell.rb +3 -2
  22. data/app/cells/decidim/content_blocks/metrics_cell.rb +1 -0
  23. data/app/cells/decidim/content_blocks/stats_cell.rb +1 -0
  24. data/app/cells/decidim/content_blocks/sub_hero_cell.rb +1 -0
  25. data/app/cells/decidim/diff_cell.rb +1 -1
  26. data/app/cells/decidim/fingerprint/show.erb +1 -1
  27. data/app/cells/decidim/follow_button_cell.rb +3 -0
  28. data/app/cells/decidim/members_cell.rb +1 -0
  29. data/app/cells/decidim/notifications/show.erb +1 -1
  30. data/app/cells/decidim/profile_cell.rb +1 -0
  31. data/app/cells/decidim/profile_sidebar_cell.rb +4 -0
  32. data/app/cells/decidim/search_results_cell.rb +1 -0
  33. data/app/cells/decidim/search_results_section/show.erb +1 -1
  34. data/app/cells/decidim/tos_page_cell.rb +1 -0
  35. data/app/cells/decidim/user_group_pending_invitations_list_cell.rb +1 -0
  36. data/app/cells/decidim/user_group_pending_requests_list_cell.rb +1 -0
  37. data/app/cells/decidim/wizard_step_form/wizard_aside.erb +14 -0
  38. data/app/cells/decidim/wizard_step_form/wizard_header.erb +18 -0
  39. data/app/cells/decidim/wizard_step_form_cell.rb +112 -0
  40. data/app/commands/decidim/amendable/accept.rb +1 -1
  41. data/app/commands/decidim/amendable/create_draft.rb +70 -0
  42. data/app/commands/decidim/amendable/destroy_draft.rb +40 -0
  43. data/app/commands/decidim/amendable/promote.rb +13 -11
  44. data/app/commands/decidim/amendable/publish_draft.rb +76 -0
  45. data/app/commands/decidim/amendable/update_draft.rb +54 -0
  46. data/app/commands/decidim/amendable/withdraw.rb +31 -15
  47. data/app/commands/decidim/create_follow.rb +1 -0
  48. data/app/commands/decidim/create_omniauth_registration.rb +22 -4
  49. data/app/commands/decidim/create_registration.rb +5 -0
  50. data/app/commands/decidim/delete_follow.rb +1 -0
  51. data/app/commands/decidim/search.rb +1 -0
  52. data/app/controllers/concerns/decidim/action_authorization.rb +2 -0
  53. data/app/controllers/concerns/decidim/amendments_controller.rb +148 -28
  54. data/app/controllers/concerns/decidim/devise_controllers.rb +3 -2
  55. data/app/controllers/concerns/decidim/force_authentication.rb +38 -0
  56. data/app/controllers/concerns/decidim/impersonate_users.rb +1 -0
  57. data/app/controllers/concerns/decidim/locale_switcher.rb +44 -17
  58. data/app/controllers/concerns/decidim/needs_tos_accepted.rb +8 -0
  59. data/app/controllers/concerns/decidim/orderable.rb +36 -0
  60. data/app/controllers/concerns/decidim/participatory_space_context.rb +2 -0
  61. data/app/controllers/concerns/decidim/safe_redirect.rb +24 -0
  62. data/app/controllers/decidim/application_controller.rb +19 -2
  63. data/app/controllers/decidim/devise/confirmations_controller.rb +6 -0
  64. data/app/controllers/decidim/devise/invitations_controller.rb +8 -4
  65. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +4 -1
  66. data/app/controllers/decidim/errors_controller.rb +3 -0
  67. data/app/controllers/decidim/follows_controller.rb +2 -2
  68. data/app/controllers/decidim/messaging/conversations_controller.rb +2 -2
  69. data/app/controllers/decidim/profiles_controller.rb +4 -1
  70. data/app/controllers/decidim/scopes_controller.rb +16 -4
  71. data/app/events/decidim/amendable/amendment_base_event.rb +4 -0
  72. data/app/forms/decidim/account_form.rb +1 -1
  73. data/app/forms/decidim/amendable/create_form.rb +3 -19
  74. data/app/forms/decidim/amendable/edit_form.rb +22 -0
  75. data/app/forms/decidim/amendable/form.rb +42 -20
  76. data/app/forms/decidim/amendable/promote_form.rb +4 -7
  77. data/app/forms/decidim/amendable/publish_form.rb +21 -0
  78. data/app/forms/decidim/amendable/reject_form.rb +1 -1
  79. data/app/forms/decidim/amendable/review_form.rb +9 -4
  80. data/app/forms/decidim/invite_user_form.rb +1 -0
  81. data/app/forms/decidim/notifications_settings_form.rb +1 -0
  82. data/app/forms/decidim/registration_form.rb +4 -3
  83. data/app/forms/decidim/user_group_form.rb +1 -0
  84. data/app/forms/decidim/user_interests_form.rb +1 -0
  85. data/app/helpers/decidim/amendments_helper.rb +33 -19
  86. data/app/helpers/decidim/cells_helper.rb +2 -0
  87. data/app/helpers/decidim/layout_helper.rb +1 -0
  88. data/app/helpers/decidim/map_helper.rb +1 -1
  89. data/app/helpers/decidim/meta_tags_helper.rb +1 -0
  90. data/app/helpers/decidim/resource_reference_helper.rb +1 -0
  91. data/app/jobs/decidim/event_publisher_job.rb +60 -0
  92. data/app/jobs/decidim/metric_job.rb +1 -0
  93. data/app/models/decidim/action_log.rb +12 -0
  94. data/app/models/decidim/amendment.rb +31 -2
  95. data/app/models/decidim/attachment.rb +2 -0
  96. data/app/models/decidim/authorization.rb +1 -0
  97. data/app/models/decidim/category.rb +1 -0
  98. data/app/models/decidim/component.rb +7 -0
  99. data/app/models/decidim/content_block.rb +1 -0
  100. data/app/models/decidim/follow.rb +3 -0
  101. data/app/models/decidim/identity.rb +1 -0
  102. data/app/models/decidim/impersonation_log.rb +2 -0
  103. data/app/models/decidim/newsletter.rb +1 -0
  104. data/app/models/decidim/participatory_process_user_role.rb +1 -0
  105. data/app/models/decidim/participatory_space_private_user.rb +1 -0
  106. data/app/models/decidim/permission_action.rb +2 -0
  107. data/app/models/decidim/report.rb +1 -0
  108. data/app/models/decidim/scope.rb +1 -0
  109. data/app/models/decidim/searchable_resource.rb +1 -1
  110. data/app/models/decidim/static_page.rb +1 -0
  111. data/app/models/decidim/user.rb +2 -0
  112. data/app/permissions/decidim/permissions.rb +18 -14
  113. data/app/permissions/decidim/user_manager_permissions.rb +9 -2
  114. data/app/presenters/decidim/admin_log/organization_presenter.rb +1 -0
  115. data/app/presenters/decidim/admin_log/participatory_space_private_user_presenter.rb +1 -1
  116. data/app/presenters/decidim/admin_log/user_presenter.rb +1 -1
  117. data/app/presenters/decidim/hashtag_presenter.rb +1 -1
  118. data/app/presenters/decidim/log/base_presenter.rb +1 -0
  119. data/app/presenters/decidim/log/diff_presenter.rb +1 -1
  120. data/app/presenters/decidim/log/value_types/area_presenter.rb +1 -0
  121. data/app/presenters/decidim/log/value_types/area_type_presenter.rb +1 -0
  122. data/app/presenters/decidim/log/value_types/currency_presenter.rb +1 -0
  123. data/app/presenters/decidim/log/value_types/date_presenter.rb +1 -0
  124. data/app/presenters/decidim/log/value_types/locale_presenter.rb +1 -0
  125. data/app/presenters/decidim/log/value_types/percentage_presenter.rb +1 -0
  126. data/app/presenters/decidim/log/value_types/scope_presenter.rb +1 -0
  127. data/app/presenters/decidim/log/value_types/scope_type_presenter.rb +1 -0
  128. data/app/presenters/decidim/metric_charts_presenter.rb +1 -0
  129. data/app/presenters/decidim/metric_object_presenter.rb +4 -0
  130. data/app/queries/decidim/metric_manage.rb +3 -0
  131. data/app/queries/decidim/metric_measure.rb +1 -0
  132. data/app/queries/decidim/metrics/followers_metric_manage.rb +3 -0
  133. data/app/queries/decidim/metrics/participants_metric_manage.rb +4 -0
  134. data/app/queries/decidim/similar_emendations.rb +56 -0
  135. data/app/resolvers/decidim/core/metric_resolver.rb +1 -0
  136. data/app/services/decidim/action_authorizer.rb +1 -0
  137. data/app/services/decidim/action_logger.rb +1 -0
  138. data/app/services/decidim/activity_search.rb +1 -0
  139. data/app/services/decidim/email_notification_generator.rb +4 -0
  140. data/app/services/decidim/notification_generator.rb +2 -0
  141. data/app/services/decidim/notification_generator_for_recipient.rb +0 -1
  142. data/app/services/decidim/resource_search.rb +1 -1
  143. data/app/services/decidim/traceability.rb +1 -0
  144. data/app/uploaders/decidim/application_uploader.rb +1 -0
  145. data/app/uploaders/decidim/attachment_uploader.rb +16 -0
  146. data/app/uploaders/decidim/avatar_uploader.rb +0 -2
  147. data/app/uploaders/decidim/data_portability_uploader.rb +1 -0
  148. data/app/uploaders/decidim/homepage_image_uploader.rb +0 -2
  149. data/app/uploaders/decidim/image_uploader.rb +15 -1
  150. data/app/uploaders/decidim/oauth_application_logo_uploader.rb +0 -1
  151. data/app/uploaders/decidim/official_image_footer_uploader.rb +0 -1
  152. data/app/uploaders/decidim/official_image_header_uploader.rb +0 -1
  153. data/app/uploaders/decidim/open_data_uploader.rb +1 -0
  154. data/app/validators/etiquette_validator.rb +5 -0
  155. data/app/views/decidim/account/delete.html.erb +2 -2
  156. data/app/views/decidim/account/show.html.erb +1 -1
  157. data/app/views/decidim/amendments/_edit_form_fields.html.erb +16 -13
  158. data/app/views/decidim/amendments/_similar_emendation.html.erb +24 -0
  159. data/app/views/decidim/amendments/compare_draft.html.erb +21 -0
  160. data/app/views/decidim/amendments/edit_draft.html.erb +31 -0
  161. data/app/views/decidim/amendments/new.html.erb +5 -17
  162. data/app/views/decidim/amendments/preview_draft.html.erb +32 -0
  163. data/app/views/decidim/amendments/review.html.erb +5 -3
  164. data/app/views/decidim/application/_document.html.erb +1 -1
  165. data/app/views/decidim/application/_photos.html.erb +1 -1
  166. data/app/views/decidim/data_portability/show.html.erb +1 -1
  167. data/app/views/decidim/devise/invitations/edit.html.erb +2 -2
  168. data/app/views/decidim/devise/sessions/new.html.erb +1 -1
  169. data/app/views/decidim/doorkeeper/authorizations/new.html.erb +3 -3
  170. data/app/views/decidim/export_mailer/data_portability_export.html.erb +1 -1
  171. data/app/views/decidim/searches/index.js.erb +6 -0
  172. data/app/views/decidim/shared/_address_details.html.erb +2 -2
  173. data/app/views/decidim/shared/_embed_modal.html.erb +1 -1
  174. data/app/views/decidim/shared/_share_modal.html.erb +7 -4
  175. data/app/views/layouts/decidim/_application.html.erb +0 -1
  176. data/app/views/layouts/decidim/_head.html.erb +13 -12
  177. data/app/views/layouts/decidim/_logo.html.erb +1 -1
  178. data/app/views/layouts/decidim/_social_media_links.html.erb +5 -5
  179. data/app/views/layouts/decidim/_user_menu.html.erb +1 -1
  180. data/app/views/layouts/decidim/_wrapper.html.erb +2 -2
  181. data/app/views/layouts/decidim/mailer.html.erb +2 -2
  182. data/config/locales/ar.yml +27 -17
  183. data/config/locales/ca.yml +79 -15
  184. data/config/locales/cs.yml +73 -14
  185. data/config/locales/de.yml +62 -12
  186. data/config/locales/en.yml +80 -16
  187. data/config/locales/eo-UY.yml +16 -0
  188. data/config/locales/es-MX.yml +73 -11
  189. data/config/locales/es-PY.yml +73 -11
  190. data/config/locales/es.yml +79 -15
  191. data/config/locales/eu.yml +6 -13
  192. data/config/locales/fi-plain.yml +75 -11
  193. data/config/locales/fi.yml +80 -16
  194. data/config/locales/fr.yml +70 -16
  195. data/config/locales/gl.yml +6 -13
  196. data/config/locales/hu.yml +80 -17
  197. data/config/locales/id-ID.yml +6 -12
  198. data/config/locales/it.yml +56 -14
  199. data/config/locales/nl.yml +76 -12
  200. data/config/locales/no.yml +11 -2
  201. data/config/locales/pl.yml +6 -15
  202. data/config/locales/pt-BR.yml +6 -13
  203. data/config/locales/pt.yml +6 -13
  204. data/config/locales/ru.yml +7 -2
  205. data/config/locales/sv.yml +34 -18
  206. data/config/locales/tr-TR.yml +15 -12
  207. data/config/locales/uk.yml +7 -2
  208. data/config/routes.rb +7 -0
  209. data/db/migrate/20180226140756_add_version_to_action_logs.rb +1 -0
  210. data/db/migrate/20180305132906_rename_features_to_components.rb +1 -0
  211. data/db/migrate/20190412131728_fix_user_names.rb +1 -1
  212. data/db/migrate/20190610093742_add_force_users_to_authenticate_before_access_organization.rb +10 -0
  213. data/db/migrate/20190618075906_add_confidential_to_doorkeeper_application.rb +13 -0
  214. data/db/migrate/{20190925091507_add_uniq_index_to_decidim_metrics.rb → 20190829092826_add_uniq_index_to_decidim_metrics.rb} +0 -0
  215. data/lib/decidim/amendable.rb +87 -13
  216. data/lib/decidim/attributes/localized_date.rb +5 -0
  217. data/lib/decidim/attributes/time_with_zone.rb +5 -0
  218. data/lib/decidim/authorable.rb +3 -0
  219. data/lib/decidim/authorization_form_builder.rb +2 -2
  220. data/lib/decidim/component_manifest.rb +2 -0
  221. data/lib/decidim/content_parsers.rb +2 -0
  222. data/lib/decidim/content_parsers/hashtag_parser.rb +1 -1
  223. data/lib/decidim/content_parsers/link_parser.rb +10 -0
  224. data/lib/decidim/content_parsers/newline_parser.rb +20 -0
  225. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  226. data/lib/decidim/content_processor.rb +2 -0
  227. data/lib/decidim/content_renderers.rb +1 -0
  228. data/lib/decidim/content_renderers/hashtag_renderer.rb +1 -1
  229. data/lib/decidim/content_renderers/link_renderer.rb +24 -0
  230. data/lib/decidim/content_renderers/user_renderer.rb +2 -2
  231. data/lib/decidim/core.rb +11 -0
  232. data/lib/decidim/core/engine.rb +2 -28
  233. data/lib/decidim/core/test.rb +4 -1
  234. data/lib/decidim/core/test/factories.rb +35 -8
  235. data/lib/decidim/core/test/shared_examples/amendable/create_amendment_draft_examples.rb +50 -0
  236. data/lib/decidim/core/test/shared_examples/amendable/destroy_amendment_draft_examples.rb +39 -0
  237. data/lib/decidim/core/test/shared_examples/amendable/promote_amendment_examples.rb +27 -3
  238. data/lib/decidim/core/test/shared_examples/amendable/{create_amendment_examples.rb → publish_amendment_draft_examples.rb} +26 -17
  239. data/lib/decidim/core/test/shared_examples/amendable/update_amendment_draft_examples.rb +42 -0
  240. data/lib/decidim/core/test/shared_examples/amendable/withdraw_amendment_examples.rb +19 -11
  241. data/lib/decidim/core/test/shared_examples/has_attachment_collections.rb +1 -1
  242. data/lib/decidim/core/test/shared_examples/has_attachments.rb +1 -1
  243. data/lib/decidim/core/test/shared_examples/simple_event.rb +4 -0
  244. data/lib/decidim/core/version.rb +1 -1
  245. data/lib/decidim/data_portability_file_zipper.rb +3 -0
  246. data/lib/decidim/events/author_event.rb +1 -0
  247. data/lib/decidim/events/base_event.rb +12 -22
  248. data/lib/decidim/events/coauthor_event.rb +1 -0
  249. data/lib/decidim/events/simple_event.rb +3 -0
  250. data/lib/decidim/exporters/csv.rb +1 -0
  251. data/lib/decidim/fingerprintable.rb +1 -0
  252. data/lib/decidim/followable.rb +8 -0
  253. data/lib/decidim/form_builder.rb +24 -3
  254. data/lib/decidim/gamification.rb +4 -0
  255. data/lib/decidim/gamification/badge_status.rb +1 -0
  256. data/lib/decidim/has_category.rb +2 -0
  257. data/lib/decidim/has_component.rb +2 -7
  258. data/lib/decidim/has_private_users.rb +8 -1
  259. data/lib/decidim/has_settings.rb +12 -8
  260. data/lib/decidim/hashtaggable.rb +4 -0
  261. data/lib/decidim/metric_operation_manifest.rb +1 -0
  262. data/lib/decidim/nicknamizable.rb +1 -0
  263. data/lib/decidim/participable.rb +1 -0
  264. data/lib/decidim/participatory_space_resourceable.rb +1 -0
  265. data/lib/decidim/randomable.rb +20 -0
  266. data/lib/decidim/search_resource_fields_mapper.rb +2 -0
  267. data/lib/decidim/searchable.rb +2 -0
  268. data/lib/decidim/settings_manifest.rb +10 -1
  269. data/lib/decidim/stats_registry.rb +1 -0
  270. data/lib/decidim/view_model.rb +1 -1
  271. data/lib/tasks/decidim_data_portability_tasks.rake +1 -0
  272. data/lib/tasks/decidim_metrics_tasks.rake +2 -0
  273. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.no.js +12 -12
  274. metadata +140 -82
  275. data/app/commands/decidim/amendable/create.rb +0 -80
@@ -12,14 +12,14 @@ module Decidim
12
12
  foreign_type: "decidim_amendable_type",
13
13
  class_name: "Decidim::Amendment"
14
14
 
15
- # resource.emendations : resources that have amend the resource
15
+ # resource.emendations : resources that have amended the original resource
16
16
  has_many :emendations,
17
17
  through: :amendments,
18
18
  source: :emendation,
19
19
  source_type: name,
20
20
  inverse_of: :emendations
21
21
 
22
- # resource.amenders : users that have emendations for the resource
22
+ # resource.amenders : users that have created emendations for the original resource
23
23
  has_many :amenders,
24
24
  through: :amendments,
25
25
  source: :amender
@@ -35,6 +35,34 @@ module Decidim
35
35
 
36
36
  scope :only_amendables, -> { where.not(id: joins(:amendable)) }
37
37
  scope :only_emendations, -> { where(id: joins(:amendable)) }
38
+ # retrieves resources that are emendations and visible to the user
39
+ # based on the component's amendments settings.
40
+ scope :only_visible_emendations_for, lambda { |user, component|
41
+ return only_emendations unless component.settings.amendments_enabled
42
+
43
+ case component.current_settings.amendments_visibility
44
+ when "participants"
45
+ return none unless user
46
+
47
+ where(id: joins(:amendable).where("decidim_amendments.decidim_user_id = ?", user.id))
48
+ else # Assume 'all'
49
+ only_emendations
50
+ end
51
+ }
52
+ # retrieves both resources that are amendables and emendations filtering out the emendations
53
+ # that are not visible to the user based on the component's amendments settings.
54
+ scope :amendables_and_visible_emendations_for, lambda { |user, component|
55
+ return all unless component.settings.amendments_enabled
56
+
57
+ case component.current_settings.amendments_visibility
58
+ when "participants"
59
+ return only_amendables unless user
60
+
61
+ where.not(id: joins(:amendable).where.not("decidim_amendments.decidim_user_id = ?", user.id))
62
+ else # Assume 'all'
63
+ all
64
+ end
65
+ }
38
66
  end
39
67
 
40
68
  class_methods do
@@ -53,46 +81,92 @@ module Decidim
53
81
  end
54
82
  end
55
83
 
84
+ # Returns the fields that can be amended.
56
85
  def amendable_fields
57
86
  self.class.amendable_options[:fields]
58
87
  end
59
88
 
89
+ # Returns the form used for the validation and creation of the emendation.
60
90
  def amendable_form
61
91
  self.class.amendable_options[:form].constantize
62
92
  end
63
93
 
64
- def amendable_type
65
- resource_manifest.model_class_name
66
- end
67
-
94
+ # Returns the polymorphic association.
68
95
  def amendment
69
96
  associated_resource = emendation? ? :emendation : :amendable
70
97
 
71
98
  Decidim::Amendment.find_by(associated_resource => id)
72
99
  end
73
100
 
101
+ # Checks if the resource HAS amended another resource.
102
+ # Returns true or false.
74
103
  def emendation?
75
104
  amendable.present?
76
105
  end
77
106
 
107
+ # Checks if the resource CAN be amended by other resources.
108
+ # Returns true or false.
78
109
  def amendable?
79
110
  amendable.blank?
80
111
  end
81
112
 
82
- def resource_state
113
+ # Returns the state of the amendment or the state of the resource.
114
+ def state
115
+ return amendment.state if emendation?
116
+
83
117
  attributes["state"]
84
118
  end
85
119
 
86
- def emendation_state
87
- return resource_state if resource_state == "withdrawn"
120
+ # Returns the linked resource to or from this model
121
+ # for the given resource name and link name.
122
+ # See Decidim::Resourceable#link_resources
123
+ def linked_promoted_resource
124
+ linked_resources(self.class, "created_from_rejected_emendation").first
125
+ end
126
+
127
+ # Returns the emendations of an amendable that are visible to the user
128
+ # based on the component's amendments settings and filtering out the "drafts".
129
+ def visible_emendations_for(user)
130
+ pubslished_emendations = emendations.published
131
+ return pubslished_emendations unless component.settings.amendments_enabled
132
+
133
+ case component.current_settings.amendments_visibility
134
+ when "participants"
135
+ return self.class.none unless user
88
136
 
89
- amendment.state
137
+ pubslished_emendations.where("decidim_amendments.decidim_user_id = ?", user.id)
138
+ else # Assume 'all'
139
+ pubslished_emendations
140
+ end
90
141
  end
91
142
 
92
- def state
93
- return emendation_state if emendation?
143
+ # Returns the amendments (polymorphic association) of the emendations that
144
+ # are visible to the user based on the component's amendments settings.
145
+ def visible_amendments_for(user)
146
+ amendments.where(emendation: visible_emendations_for(user))
147
+ end
94
148
 
95
- resource_state
149
+ # Handles the logic to assign an author to the resource, be it Authorable or Coauthorable.
150
+ def add_author(author, user_group = nil)
151
+ if is_a?(Decidim::Authorable)
152
+ if persisted?
153
+ update(author: user_group || author)
154
+ else
155
+ self.author = user_group || author
156
+ end
157
+ else # Assume is_a?(Decidim::Coauthorable)
158
+ coauthorships.clear
159
+ add_coauthor(author, user_group: user_group)
160
+ end
161
+ end
162
+
163
+ # Returns an Array of Decidim::User.
164
+ def notifiable_identities
165
+ if is_a?(Decidim::Authorable)
166
+ [author]
167
+ else # Assume is_a?(Decidim::Coauthorable)
168
+ super
169
+ end
96
170
  end
97
171
  end
98
172
  end
@@ -7,10 +7,15 @@ module Decidim
7
7
  class LocalizedDate < Virtus::Attribute
8
8
  def coerce(value)
9
9
  return value unless value.is_a?(String)
10
+
10
11
  Date.strptime(value, I18n.t("date.formats.decidim_short"))
11
12
  rescue ArgumentError
12
13
  nil
13
14
  end
15
+
16
+ def type
17
+ Axiom::Types::Date
18
+ end
14
19
  end
15
20
  end
16
21
  end
@@ -7,10 +7,15 @@ module Decidim
7
7
  class TimeWithZone < Virtus::Attribute
8
8
  def coerce(value)
9
9
  return value unless value.is_a?(String)
10
+
10
11
  Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
11
12
  rescue ArgumentError
12
13
  nil
13
14
  end
15
+
16
+ def type
17
+ Axiom::Types::Time
18
+ end
14
19
  end
15
20
  end
16
21
  end
@@ -36,16 +36,19 @@ module Decidim
36
36
 
37
37
  def verified_user_group
38
38
  return unless user_group
39
+
39
40
  errors.add :user_group, :invalid unless user_group.verified?
40
41
  end
41
42
 
42
43
  def user_group_membership
43
44
  return unless user_group
45
+
44
46
  errors.add :user_group, :invalid unless user_group.users.include? author
45
47
  end
46
48
 
47
49
  def author_belongs_to_organization
48
50
  return if !author || !organization
51
+
49
52
  errors.add(:author, :invalid) unless author == organization || author.respond_to?(:organization) && author.organization == organization
50
53
  end
51
54
  end
@@ -39,7 +39,7 @@ module Decidim
39
39
  return hidden_field(name) if name.to_s == "handler_name"
40
40
 
41
41
  case type.name
42
- when "Date", "Decidim::Attributes::LocalizedDate"
42
+ when "Date", "Time"
43
43
  date_field name
44
44
  else
45
45
  text_field name
@@ -58,7 +58,7 @@ module Decidim
58
58
 
59
59
  def public_attributes
60
60
  form_attributes.inject({}) do |all, attribute|
61
- all.update(attribute.name => attribute.class)
61
+ all.update(attribute.name => attribute.type.primitive)
62
62
  end
63
63
  end
64
64
 
@@ -83,6 +83,7 @@ module Decidim
83
83
  # Returns nothing.
84
84
  def run_hooks(event_name, context = nil)
85
85
  return unless hooks[event_name]
86
+
86
87
  hooks[event_name.to_sym].each do |hook|
87
88
  hook.call(context)
88
89
  end
@@ -146,6 +147,7 @@ module Decidim
146
147
  # Returns nothing.
147
148
  def exports(name, &block)
148
149
  return unless name
150
+
149
151
  @exports ||= []
150
152
  @exports << [name, block]
151
153
  @export_manifests = nil
@@ -5,5 +5,7 @@ module Decidim
5
5
  autoload :BaseParser, "decidim/content_parsers/base_parser"
6
6
  autoload :UserParser, "decidim/content_parsers/user_parser"
7
7
  autoload :HashtagParser, "decidim/content_parsers/hashtag_parser"
8
+ autoload :NewlineParser, "decidim/content_parsers/newline_parser"
9
+ autoload :LinkParser, "decidim/content_parsers/link_parser"
8
10
  end
9
11
  end
@@ -18,7 +18,7 @@ module Decidim
18
18
 
19
19
  # Matches a hashtag if it starts with a letter or number
20
20
  # and only contains letters, numbers or underscores.
21
- HASHTAG_REGEX = /\B#([[:alnum:]](?:[[:alnum:]]|_)*)\b/i
21
+ HASHTAG_REGEX = /\B#([[:alnum:]](?:[[:alnum:]]|_)*)\b/i.freeze
22
22
 
23
23
  # Replaces hashtags name with new or existing hashtags models global ids.
24
24
  #
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ContentParsers
5
+ # As recommended here: decidim-core/lib/decidim/content_processor.rb
6
+ # We are declaring the class and leaving it empty as we only want the renderer.
7
+ class LinkParser < BaseParser
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ContentParsers
5
+ # A parser that searches newline escape sequences in content.
6
+ #
7
+ # The escape sequences `\r\n` and `\r` will be replaced by `\n`.
8
+ #
9
+ # @see BaseParser Examples of how to use a content parser
10
+ class NewlineParser < BaseParser
11
+ ESCAPE_SEQUENCES = ["\r\n", "\r"].freeze
12
+ REGEX = Regexp.union(ESCAPE_SEQUENCES)
13
+
14
+ # @return [String] the content with the escape sequences replaced.
15
+ def rewrite
16
+ content.gsub(REGEX, "\n")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -18,7 +18,7 @@ module Decidim
18
18
 
19
19
  # Matches a nickname if it starts with a letter or number
20
20
  # and only contains letters, numbers or underscores.
21
- MENTION_REGEX = /\B@([a-zA-Z0-9]\w*)\b/
21
+ MENTION_REGEX = /\B@([a-zA-Z0-9]\w*)\b/.freeze
22
22
 
23
23
  # Replaces found mentions matching a nickname of an existing
24
24
  # user in the current organization with a global id. Other
@@ -64,6 +64,7 @@ module Decidim
64
64
  parsed = if content.is_a?(Hash)
65
65
  Decidim.content_processors.each_with_object(rewrite: content, metadata: {}) do |type, result|
66
66
  next unless type == :hashtag
67
+
67
68
  result[:rewrite].each do |key, value|
68
69
  parser = parser_klass(type).constantize.new(value, context)
69
70
  result[:rewrite][key] = parser.rewrite
@@ -73,6 +74,7 @@ module Decidim
73
74
  else
74
75
  Decidim.content_processors.each_with_object(rewrite: content, metadata: {}) do |type, result|
75
76
  next unless type == :hashtag
77
+
76
78
  parser = parser_klass(type).constantize.new(result[:rewrite], context)
77
79
  result[:rewrite] = parser.rewrite
78
80
  result[:metadata][type] = parser.metadata
@@ -5,5 +5,6 @@ module Decidim
5
5
  autoload :BaseRenderer, "decidim/content_renderers/base_renderer"
6
6
  autoload :UserRenderer, "decidim/content_renderers/user_renderer"
7
7
  autoload :HashtagRenderer, "decidim/content_renderers/hashtag_renderer"
8
+ autoload :LinkRenderer, "decidim/content_renderers/link_renderer"
8
9
  end
9
10
  end
@@ -10,7 +10,7 @@ module Decidim
10
10
  # @see BaseRenderer Examples of how to use a content renderer
11
11
  class HashtagRenderer < BaseRenderer
12
12
  # Matches a global id representing a Decidim::Hashtag
13
- GLOBAL_ID_REGEX = %r{gid:\/\/[\w-]*\/Decidim::Hashtag\/(\d+)\/?(_?)([[:alnum:]](?:[[:alnum:]]|_)*)?\b}
13
+ GLOBAL_ID_REGEX = %r{gid:\/\/[\w-]*\/Decidim::Hashtag\/(\d+)\/?(_?)([[:alnum:]](?:[[:alnum:]]|_)*)?\b}.freeze
14
14
 
15
15
  # Replaces found Global IDs matching an existing hashtag with
16
16
  # a link to their detail page. The Global IDs representing an
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ContentRenderers
5
+ # A renderer that converts URLs to links and strips attributes in anchors.
6
+ #
7
+ # Examples:
8
+ # `<a href="http://urls.net" onmouseover="alert('hello')">URLs</a>`
9
+ # Gets rendered as:
10
+ # `<a href="https://decidim.org" target="_blank" rel="noopener">https://decidim.org</a>`
11
+ # And:
12
+ # `<a href="javascript:document.cookies">click me</a>`
13
+ # Gets rendered as:
14
+ # `click me`
15
+ #
16
+ # @see BaseRenderer Examples of how to use a content renderer
17
+ class LinkRenderer < BaseRenderer
18
+ # @return [String] the content ready to display (contains HTML)
19
+ def render(options = { target: "_blank", rel: "noopener" })
20
+ Anchored::Linker.auto_link(content, options)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -10,7 +10,7 @@ module Decidim
10
10
  # @see BaseRenderer Examples of how to use a content renderer
11
11
  class UserRenderer < BaseRenderer
12
12
  # Matches a global id representing a Decidim::User
13
- GLOBAL_ID_REGEX = %r{gid://\S+/Decidim::User/\d+}
13
+ GLOBAL_ID_REGEX = %r{gid://\S+/Decidim::User/\d+}.freeze
14
14
 
15
15
  # Replaces found Global IDs matching an existing user with
16
16
  # a link to their profile. The Global IDs representing an
@@ -21,7 +21,7 @@ module Decidim
21
21
  content.gsub(GLOBAL_ID_REGEX) do |user_gid|
22
22
  user = GlobalID::Locator.locate(user_gid)
23
23
  Decidim::UserPresenter.new(user).display_mention
24
- rescue ActiveRecord::RecordNotFound => _ex
24
+ rescue ActiveRecord::RecordNotFound => _e
25
25
  ""
26
26
  end
27
27
  end
@@ -79,6 +79,7 @@ module Decidim
79
79
  autoload :IoEncoder, "decidim/io_encoder"
80
80
  autoload :HasResourcePermission, "decidim/has_resource_permission"
81
81
  autoload :PermissionsRegistry, "decidim/permissions_registry"
82
+ autoload :Randomable, "decidim/randomable"
82
83
 
83
84
  include ActiveSupport::Configurable
84
85
  # Loads seeds from all engines.
@@ -275,6 +276,16 @@ module Decidim
275
276
  %w(admin user_manager)
276
277
  end
277
278
 
279
+ # Exposes a configuration option: An Array of Strings that serve both as
280
+ # locale keys and values to construct the input collection in
281
+ # Decidim::Amendment::VisibilityStepSetting::options.
282
+ # This collection is used in Decidim::Admin::SettingsHelper to generate a
283
+ # radio buttons collection input field form for a Decidim::Component
284
+ # step setting :amendments_visibility.
285
+ config_accessor :amendments_visibility_options do
286
+ %w(all participants)
287
+ end
288
+
278
289
  # Public: Registers a global engine. This method is intended to be used
279
290
  # by component engines that also offer unscoped functionality
280
291
  #
@@ -185,35 +185,16 @@ module Decidim
185
185
 
186
186
  initializer "decidim.notifications" do
187
187
  Decidim::EventsManager.subscribe(/^decidim\.events\./) do |event_name, data|
188
- EmailNotificationGeneratorJob.perform_later(
189
- event_name,
190
- data[:event_class],
191
- data[:resource],
192
- data[:followers],
193
- data[:affected_users],
194
- data[:extra]
195
- )
196
- NotificationGeneratorJob.perform_later(
197
- event_name,
198
- data[:event_class],
199
- data[:resource],
200
- data[:followers],
201
- data[:affected_users],
202
- data[:extra]
203
- )
188
+ EventPublisherJob.perform_later(event_name, data)
204
189
  end
205
190
  end
206
191
 
207
192
  initializer "decidim.content_processors" do |_app|
208
193
  Decidim.configure do |config|
209
- config.content_processors += [:user, :hashtag]
194
+ config.content_processors += [:user, :hashtag, :link]
210
195
  end
211
196
  end
212
197
 
213
- initializer "paper_trail" do
214
- PaperTrail.config.track_associations = false
215
- end
216
-
217
198
  initializer "add_cells_view_paths" do
218
199
  Cell::ViewModel.view_paths << File.expand_path("#{Decidim::Core::Engine.root}/app/cells")
219
200
  Cell::ViewModel.view_paths << File.expand_path("#{Decidim::Core::Engine.root}/app/cells/amendable")
@@ -246,13 +227,6 @@ module Decidim
246
227
  default_scopes :public
247
228
  optional_scopes []
248
229
 
249
- # Change the native redirect uri for client apps
250
- # When clients register with the following redirect uri, they won't be redirected to any server and the authorization code will be displayed within the provider
251
- # The value can be any string. Use nil to disable this feature. When disabled, clients must provide a valid URL
252
- # (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi)
253
- #
254
- native_redirect_uri "urn:ietf:wg:oauth:2.0:oob"
255
-
256
230
  # Forces the usage of the HTTPS protocol in non-native redirect uris (enabled
257
231
  # by default in non-development environments). OAuth2 delegates security in
258
232
  # communication to the HTTPS protocol so it is wise to keep this enabled.