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
@@ -30,6 +30,7 @@ module Decidim
30
30
 
31
31
  def author_presenter
32
32
  return unless author
33
+
33
34
  @author_presenter ||= Decidim::UserPresenter.new(author)
34
35
  end
35
36
 
@@ -67,28 +67,16 @@ module Decidim
67
67
  @resource_url ||= resource_locator.url
68
68
  end
69
69
 
70
- # Whether this event should be notified or not. Useful when you want the
71
- # event to decide based on the params.
72
- #
73
- # It returns false when the resource or any element in the chain is a
74
- # `Decidim::Publicable` and it isn't published or participatory_space
75
- # is a `Decidim::Participable` and the user can't participate.
76
- def notifiable?
77
- return false if resource.is_a?(Decidim::Publicable) && !resource.published?
78
- return false if participatory_space.is_a?(Decidim::Publicable) && !participatory_space&.published?
79
- return false if component && !component.published?
80
-
81
- return false if participatory_space.is_a?(Decidim::Participable) && !participatory_space.can_participate?(user)
82
-
83
- true
84
- end
85
-
86
70
  def resource_text; end
87
71
 
88
72
  def resource_title
89
73
  return unless resource
90
74
 
91
- if resource.respond_to?(:title)
75
+ if resource.is_a?(Decidim::Hashtaggable)
76
+ translated_title = translated_attribute(resource.title)
77
+ renderer = Decidim::ContentRenderers::HashtagRenderer.new(translated_title)
78
+ renderer.render(links: false).html_safe
79
+ elsif resource.respond_to?(:title)
92
80
  translated_attribute(resource.title)
93
81
  elsif resource.respond_to?(:name)
94
82
  translated_attribute(resource.name)
@@ -97,17 +85,19 @@ module Decidim
97
85
 
98
86
  private
99
87
 
100
- attr_reader :event_name, :resource, :user, :user_role, :extra
101
-
102
88
  def component
103
- return resource.component if resource.is_a?(Decidim::HasComponent)
104
89
  return resource if resource.is_a?(Decidim::Component)
90
+
91
+ resource.try(:component)
105
92
  end
106
93
 
107
94
  def participatory_space
108
- return resource if resource.is_a?(Decidim::ParticipatorySpaceResourceable)
109
- component&.participatory_space
95
+ return resource if resource.is_a?(Decidim::Participable)
96
+
97
+ resource.try(:participatory_space)
110
98
  end
99
+
100
+ attr_reader :event_name, :resource, :user, :user_role, :extra
111
101
  end
112
102
  end
113
103
  end
@@ -30,6 +30,7 @@ module Decidim
30
30
 
31
31
  def author_presenter
32
32
  return unless author
33
+
33
34
  @author_presenter ||= Decidim::UserPresenter.new(author)
34
35
  end
35
36
 
@@ -54,6 +54,7 @@ module Decidim
54
54
  # then the role is appended to the i18n scope.
55
55
  def i18n_scope
56
56
  return event_name if user_role.blank? || !event_has_roles?
57
+
57
58
  "#{event_name}.#{user_role}"
58
59
  end
59
60
 
@@ -79,12 +80,14 @@ module Decidim
79
80
  # Caches the path for the given resource when it's a Decidim::Component.
80
81
  def resource_path
81
82
  return super unless resource.is_a?(Decidim::Component)
83
+
82
84
  @resource_path ||= main_component_path(resource)
83
85
  end
84
86
 
85
87
  # Caches the URL for the given resource when it's a Decidim::Component.
86
88
  def resource_url
87
89
  return super unless resource.is_a?(Decidim::Component)
90
+
88
91
  @resource_url ||= main_component_url(resource)
89
92
  end
90
93
 
@@ -28,6 +28,7 @@ module Decidim
28
28
 
29
29
  def headers
30
30
  return [] if processed_collection.empty?
31
+
31
32
  processed_collection.first.keys
32
33
  end
33
34
 
@@ -28,6 +28,7 @@ module Decidim
28
28
  @fingerprint_options[:block] = block
29
29
  else
30
30
  raise "You must provide a set of fields to generate the fingerprint." unless fields
31
+
31
32
  @fingerprint_options[:fields] = fields
32
33
  end
33
34
  end
@@ -9,5 +9,13 @@ module Decidim
9
9
  has_many :follows, as: :followable, foreign_key: "decidim_followable_id", foreign_type: "decidim_followable_type", class_name: "Decidim::Follow"
10
10
  has_many :followers, through: :follows, source: :user
11
11
  end
12
+
13
+ def followers
14
+ if respond_to?(:participatory_space) && participatory_space.present? && participatory_space.respond_to?(:followers)
15
+ super.or(participatory_space.followers).distinct
16
+ else
17
+ super
18
+ end
19
+ end
12
20
  end
13
21
  end
@@ -28,6 +28,23 @@ module Decidim
28
28
  end
29
29
  # rubocop:enable Metrics/ParameterLists
30
30
 
31
+ # Public: generates a radio buttons input from a collection and adds help
32
+ # text and errors.
33
+ #
34
+ # attribute - the name of the field
35
+ # collection - the collection from which we will render the check boxes
36
+ # value_attribute - a Symbol or a Proc defining how to find the value attribute
37
+ # text_attribute - a Symbol or a Proc defining how to find the text attribute
38
+ # options - a Hash with options
39
+ # html_options - a Hash with options
40
+ #
41
+ # Renders a collection of radio buttons.
42
+ # rubocop:disable Metrics/ParameterLists
43
+ def collection_radio_buttons(attribute, collection, value_attribute, text_attribute, options = {}, html_options = {})
44
+ super + error_and_help_text(attribute, options)
45
+ end
46
+ # rubocop:enable Metrics/ParameterLists
47
+
31
48
  # Public: Generates an form field for each locale.
32
49
  #
33
50
  # type - The form field's type, like `text_area` or `text_input`
@@ -79,6 +96,7 @@ module Decidim
79
96
 
80
97
  def translated_one_locale(type, name, locale, options = {})
81
98
  return hashtaggable_text_field(type, name, locale, options.merge(value: options[:value])) if options[:hashtaggable]
99
+
82
100
  send(
83
101
  type,
84
102
  "#{name}_#{locale.to_s.gsub("-", "__")}",
@@ -299,7 +317,7 @@ module Decidim
299
317
 
300
318
  # Public: Override so checkboxes are rendered before the label.
301
319
  def check_box(attribute, options = {}, checked_value = "1", unchecked_value = "0")
302
- custom_label(attribute, options[:label], options[:label_options], true, false) do
320
+ custom_label(attribute, options[:label], options[:label_options], true) do
303
321
  options.delete(:label)
304
322
  options.delete(:label_options)
305
323
  @template.check_box(@object_name, attribute, objectify_options(options), checked_value, unchecked_value)
@@ -365,10 +383,10 @@ module Decidim
365
383
  else
366
384
  @template.content_tag :label, I18n.t("default_image", scope: "decidim.forms")
367
385
  end
368
- template += @template.link_to @template.image_tag(file.url), file.url, target: "_blank"
386
+ template += @template.link_to @template.image_tag(file.url), file.url, target: "_blank", rel: "noopener"
369
387
  elsif file_is_present?(file)
370
388
  template += @template.label_tag I18n.t("current_file", scope: "decidim.forms")
371
- template += @template.link_to file.file.filename, file.url, target: "_blank"
389
+ template += @template.link_to file.file.filename, file.url, target: "_blank", rel: "noopener"
372
390
  end
373
391
 
374
392
  if file_is_present?(file)
@@ -524,6 +542,7 @@ module Decidim
524
542
  # Returns a klass object.
525
543
  def find_validator(attribute, klass)
526
544
  return unless object.respond_to?(:_validators)
545
+
527
546
  object._validators[attribute].find { |validator| validator.class == klass }
528
547
  end
529
548
 
@@ -632,12 +651,14 @@ module Decidim
632
651
  def file_is_image?(file)
633
652
  return unless file && file.respond_to?(:url)
634
653
  return file.content_type.start_with? "image" if file.content_type.present?
654
+
635
655
  Mime::Type.lookup_by_extension(File.extname(file.url)[1..-1]).to_s.start_with? "image" if file.url.present?
636
656
  end
637
657
 
638
658
  # Private: Returns whether the file exists or not.
639
659
  def file_is_present?(file)
640
660
  return unless file && file.respond_to?(:url)
661
+
641
662
  file.present?
642
663
  end
643
664
 
@@ -15,6 +15,7 @@ module Decidim
15
15
  # Returns a `BadgeStatus` instance.
16
16
  def self.status_for(user, badge_name)
17
17
  return unless user.is_a?(Decidim::UserBaseEntity)
18
+
18
19
  BadgeStatus.new(user, find_badge(badge_name))
19
20
  end
20
21
 
@@ -28,6 +29,7 @@ module Decidim
28
29
  def self.increment_score(user, badge_name, amount = 1)
29
30
  return unless amount.positive?
30
31
  return unless user.is_a?(Decidim::UserBaseEntity)
32
+
31
33
  BadgeScorer.new(user, find_badge(badge_name)).increment(amount)
32
34
  end
33
35
 
@@ -41,6 +43,7 @@ module Decidim
41
43
  def self.decrement_score(user, badge_name, amount = 1)
42
44
  return unless amount.positive?
43
45
  return unless user.is_a?(Decidim::UserBaseEntity)
46
+
44
47
  BadgeScorer.new(user, find_badge(badge_name)).decrement(amount)
45
48
  end
46
49
 
@@ -53,6 +56,7 @@ module Decidim
53
56
  # Returns nothing.
54
57
  def self.set_score(user, badge_name, score)
55
58
  return unless user.is_a?(Decidim::UserBaseEntity)
59
+
56
60
  BadgeScorer.new(user, find_badge(badge_name)).set(score)
57
61
  end
58
62
 
@@ -29,6 +29,7 @@ module Decidim
29
29
  # Returns an Integer with the remaining score.
30
30
  def next_level_in
31
31
  return nil if level >= @badge.levels.count
32
+
32
33
  @badge.levels[level] - score
33
34
  end
34
35
 
@@ -15,6 +15,7 @@ module Decidim
15
15
 
16
16
  def previous_category
17
17
  return if categorization.versions.count <= 1
18
+
18
19
  Decidim::Category.find_by(id: categorization.versions.last.reify.decidim_category_id)
19
20
  end
20
21
 
@@ -22,6 +23,7 @@ module Decidim
22
23
 
23
24
  def category_belongs_to_organization
24
25
  return unless category
26
+
25
27
  errors.add(:category, :invalid) unless component.categories.where(id: category.id).exists?
26
28
  end
27
29
  end
@@ -11,14 +11,9 @@ module Decidim
11
11
  included do
12
12
  belongs_to :component, foreign_key: "decidim_component_id", class_name: "Decidim::Component", touch: true
13
13
  delegate :organization, to: :component, allow_nil: true
14
- delegate :participatory_space, to: :component, allow_nil: true
14
+ delegate :participatory_space, :can_participate_in_space?, to: :component, allow_nil: true
15
15
 
16
- def can_participate_in_space?(user)
17
- return true unless participatory_space.try(:private_space?)
18
- return false unless user
19
-
20
- participatory_space.users.include?(user)
21
- end
16
+ alias_method :can_participate?, :can_participate_in_space?
22
17
  end
23
18
 
24
19
  class_methods do
@@ -31,8 +31,15 @@ module Decidim
31
31
  end
32
32
  end
33
33
 
34
+ def can_participate?(user)
35
+ return true unless private_space?
36
+ return false unless user
37
+
38
+ users.include?(user)
39
+ end
40
+
34
41
  def self.public_spaces
35
- where(private_space: false)
42
+ where(private_space: false).published
36
43
  end
37
44
 
38
45
  def self.private_spaces
@@ -11,11 +11,11 @@ module Decidim
11
11
  end
12
12
 
13
13
  def settings
14
- settings_schema(:global).new(self[:settings]["global"])
14
+ new_settings_schema(:global, self[:settings]["global"])
15
15
  end
16
16
 
17
17
  def settings=(data)
18
- self[:settings]["global"] = settings_schema(:global).new(data)
18
+ self[:settings]["global"] = new_settings_schema(:global, data)
19
19
  end
20
20
 
21
21
  def current_settings
@@ -27,24 +27,24 @@ module Decidim
27
27
  end
28
28
 
29
29
  def default_step_settings
30
- settings_schema(:step).new(self[:settings]["default_step"])
30
+ new_settings_schema(:step, self[:settings]["default_step"])
31
31
  end
32
32
 
33
33
  def default_step_settings=(data)
34
- self[:settings]["default_step"] = settings_schema(:step).new(data)
34
+ self[:settings]["default_step"] = new_settings_schema(:step, data)
35
35
  end
36
36
 
37
37
  def step_settings
38
38
  return {} unless participatory_space.allows_steps?
39
39
 
40
40
  participatory_space.steps.each_with_object({}) do |step, result|
41
- result[step.id.to_s] = settings_schema(:step).new(self[:settings].dig("steps", step.id.to_s))
41
+ result[step.id.to_s] = new_settings_schema(:step, self[:settings].dig("steps", step.id.to_s))
42
42
  end
43
43
  end
44
44
 
45
45
  def step_settings=(data)
46
46
  self[:settings]["steps"] = data.each_with_object({}) do |(key, value), result|
47
- result[key.to_s] = settings_schema(:step).new(value)
47
+ result[key.to_s] = new_settings_schema(:step, value)
48
48
  end
49
49
  end
50
50
 
@@ -59,8 +59,12 @@ module Decidim
59
59
  step_settings.fetch(active_step.id.to_s)
60
60
  end
61
61
 
62
- def settings_schema(name)
63
- manifest.settings(name.to_sym).schema
62
+ # Returns a Class with the attributes sanitized, coerced and filtered
63
+ # to the right type. See Decidim::SettingsManifest#schema.
64
+ def new_settings_schema(name, data)
65
+ return {} unless manifest && participatory_space
66
+
67
+ manifest.settings(name).schema.new(data, participatory_space.organization.default_locale)
64
68
  end
65
69
 
66
70
  def default_values
@@ -11,10 +11,14 @@ module Decidim
11
11
  renderer.render(links: false).html_safe
12
12
  end
13
13
 
14
+ alias_method :formatted_title, :search_title
15
+
14
16
  def search_body
15
17
  renderer = Decidim::ContentRenderers::HashtagRenderer.new(body)
16
18
  renderer.render(links: false).html_safe
17
19
  end
20
+
21
+ alias_method :formatted_body, :search_body
18
22
  end
19
23
  end
20
24
  end
@@ -14,6 +14,7 @@ module Decidim
14
14
  def calculate(day, resource)
15
15
  operation = manager_class.constantize.new(day, resource)
16
16
  return unless operation.valid?
17
+
17
18
  operation.calculate
18
19
  end
19
20
  end
@@ -35,6 +35,7 @@ module Decidim
35
35
  #
36
36
  def nicknamize(name, scope = {})
37
37
  return unless name
38
+
38
39
  disambiguate(
39
40
  name.parameterize(separator: "_")[nickname_length_range],
40
41
  scope
@@ -82,6 +82,7 @@ module Decidim
82
82
 
83
83
  def cta_button_text_key
84
84
  return :more_info if empty_published_component?
85
+
85
86
  :take_part
86
87
  end
87
88
  end
@@ -51,6 +51,7 @@ module Decidim
51
51
  def participatory_space_sibling_scope(participatory_space_name)
52
52
  manifest = Decidim.find_participatory_space_manifest(participatory_space_name)
53
53
  return self.class.none unless manifest
54
+
54
55
  scope = manifest.participatory_spaces.call(organization)
55
56
 
56
57
  scope
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ # A concern with the components needed when you want a model to have a component.
7
+ module Randomable
8
+ extend ActiveSupport::Concern
9
+
10
+ class_methods do
11
+ # Public: Randomly orders a collection given a seed.
12
+ def order_randomly(seed)
13
+ transaction do
14
+ connection.execute("SELECT setseed(#{connection.quote(seed)})")
15
+ order(Arel.sql("RANDOM()")).load
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -98,6 +98,7 @@ module Decidim
98
98
  if value_field.is_a?(Array)
99
99
  value_field.collect do |vfield_name|
100
100
  raise ArgumentError, "nested fields not supported for translations" if vfield_name.is_a?(Hash)
101
+
101
102
  resource.send(vfield_name.to_sym)
102
103
  end
103
104
  else
@@ -122,6 +123,7 @@ module Decidim
122
123
  def read_i18n_field(resource, locale, field_name)
123
124
  content = read_field(resource, @declared_fields, field_name)
124
125
  return if content.nil?
126
+
125
127
  content = Array.wrap(content).collect do |item|
126
128
  item.is_a?(Hash) ? item[locale] : item
127
129
  end
@@ -50,6 +50,7 @@ module Decidim
50
50
  #
51
51
  def try_add_to_index_as_search_resource
52
52
  return unless self.class.search_resource_fields_mapper.index_on_create?(self)
53
+
53
54
  add_to_index_as_search_resource
54
55
  end
55
56
 
@@ -105,6 +106,7 @@ module Decidim
105
106
  class_methods do
106
107
  def search_resource_fields_mapper
107
108
  raise "`searchable_fields` should be declared when including Searchable" unless defined?(@search_resource_indexable_fields)
109
+
108
110
  @search_resource_indexable_fields
109
111
  end
110
112