decidim-core 0.22.0 → 0.23.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 (306) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_core_manifest.js +5 -0
  3. data/app/assets/javascripts/decidim.js.es6 +2 -0
  4. data/app/assets/javascripts/decidim/ajax_modals.js.es6 +3 -3
  5. data/app/assets/javascripts/decidim/confirm.js.es6 +3 -2
  6. data/app/assets/javascripts/decidim/core/bundle.js +1 -1
  7. data/app/assets/javascripts/decidim/core/bundle.js.map +1 -1
  8. data/app/assets/javascripts/decidim/diff_mode_dropdown.js.es6 +18 -4
  9. data/app/assets/javascripts/decidim/editor.js.es6 +3 -3
  10. data/app/assets/javascripts/decidim/geocoding.js.es6 +60 -0
  11. data/app/assets/javascripts/decidim/geocoding/attach_input.js.es6 +106 -0
  12. data/app/assets/javascripts/decidim/geocoding/format_address.js.es6 +29 -0
  13. data/app/assets/javascripts/decidim/geocoding/provider/here.js.es6 +107 -0
  14. data/app/assets/javascripts/decidim/geocoding/provider/photon.js.es6 +77 -0
  15. data/app/assets/javascripts/decidim/map.js.es6 +34 -124
  16. data/app/assets/javascripts/decidim/map/controller.js.es6 +92 -0
  17. data/app/assets/javascripts/decidim/map/controller/markers.js.es6 +65 -0
  18. data/app/assets/javascripts/decidim/map/controller/static.es6 +48 -0
  19. data/app/assets/javascripts/decidim/map/factory.js.es6 +51 -0
  20. data/app/assets/javascripts/decidim/map/icon.js.es6 +31 -0
  21. data/app/assets/javascripts/decidim/map/legacy.js.es6 +87 -0
  22. data/app/assets/javascripts/decidim/map/provider/default.js.es6 +22 -0
  23. data/app/assets/javascripts/decidim/map/provider/here.js.es6 +22 -0
  24. data/app/assets/javascripts/decidim/security/selfxss_warning.js.es6 +19 -0
  25. data/app/assets/stylesheets/decidim/_decidim.scss +2 -0
  26. data/app/assets/stylesheets/decidim/modules/_cards.scss +15 -0
  27. data/app/assets/stylesheets/decidim/modules/_forms.scss +14 -0
  28. data/app/assets/stylesheets/decidim/modules/_layout.scss +11 -3
  29. data/app/assets/stylesheets/decidim/modules/_map.scss +35 -0
  30. data/app/assets/stylesheets/decidim/modules/_progress-bar.scss +4 -0
  31. data/app/assets/stylesheets/decidim/modules/_reveal.scss +5 -0
  32. data/app/assets/stylesheets/decidim/modules/_status-labels.scss +2 -1
  33. data/app/cells/decidim/author/flag.erb +1 -1
  34. data/app/cells/decidim/author/profile_inline.erb +2 -2
  35. data/app/cells/decidim/author_cell.rb +5 -2
  36. data/app/cells/decidim/card_cell.rb +21 -7
  37. data/app/cells/decidim/card_m/show.erb +1 -1
  38. data/app/cells/decidim/card_m_cell.rb +6 -4
  39. data/app/cells/decidim/collapsible_authors_cell.rb +1 -1
  40. data/app/cells/decidim/diff/diff_mode_html.erb +5 -5
  41. data/app/cells/decidim/follow_button/show.erb +6 -6
  42. data/app/cells/decidim/follow_button_cell.rb +8 -0
  43. data/app/cells/decidim/progress_bar/show.erb +11 -4
  44. data/app/cells/decidim/progress_bar_cell.rb +20 -1
  45. data/app/cells/decidim/translation_bar/show.erb +6 -0
  46. data/app/cells/decidim/translation_bar_cell.rb +52 -0
  47. data/app/cells/decidim/version_cell.rb +1 -1
  48. data/app/cells/decidim/versions_list_cell.rb +1 -1
  49. data/app/commands/decidim/amendable/accept.rb +9 -3
  50. data/app/commands/decidim/amendable/create_draft.rb +2 -0
  51. data/app/commands/decidim/amendable/update_draft.rb +2 -0
  52. data/app/commands/decidim/attachment_methods.rb +12 -5
  53. data/app/commands/decidim/destroy_account.rb +1 -0
  54. data/app/commands/decidim/gallery_methods.rb +16 -9
  55. data/app/commands/decidim/messaging/reply_to_conversation.rb +1 -1
  56. data/app/commands/decidim/multiple_attachments_methods.rb +56 -0
  57. data/app/controllers/concerns/decidim/devise_controllers.rb +1 -0
  58. data/app/controllers/concerns/decidim/filter_resource.rb +24 -6
  59. data/app/controllers/concerns/decidim/flaggable.rb +20 -0
  60. data/app/controllers/concerns/decidim/force_authentication.rb +1 -0
  61. data/app/controllers/concerns/decidim/impersonate_users.rb +1 -1
  62. data/app/controllers/concerns/decidim/needs_snippets.rb +20 -0
  63. data/app/controllers/concerns/decidim/paginable.rb +5 -1
  64. data/app/controllers/concerns/decidim/withdrawable.rb +20 -0
  65. data/app/controllers/decidim/application_controller.rb +16 -0
  66. data/app/controllers/decidim/components/base_controller.rb +6 -1
  67. data/app/controllers/decidim/cookie_policy_controller.rb +6 -3
  68. data/app/controllers/decidim/messaging/conversations_controller.rb +5 -2
  69. data/app/forms/decidim/account_form.rb +5 -1
  70. data/app/forms/decidim/amendable/create_form.rb +1 -1
  71. data/app/forms/decidim/amendable/form.rb +44 -3
  72. data/app/forms/decidim/attachment_form.rb +5 -1
  73. data/app/forms/decidim/user_group_form.rb +5 -1
  74. data/app/helpers/decidim/cells_helper.rb +3 -15
  75. data/app/helpers/decidim/check_boxes_tree_helper.rb +21 -12
  76. data/app/helpers/decidim/cookies_helper.rb +1 -1
  77. data/app/helpers/decidim/decidim_form_helper.rb +1 -1
  78. data/app/helpers/decidim/filter_params_helper.rb +30 -0
  79. data/app/helpers/decidim/map_helper.rb +86 -23
  80. data/app/helpers/decidim/orders_helper.rb +6 -1
  81. data/app/helpers/decidim/paginate_helper.rb +3 -1
  82. data/app/helpers/decidim/scopes_helper.rb +4 -4
  83. data/app/helpers/decidim/translations_helper.rb +7 -1
  84. data/app/jobs/decidim/machine_translation_fields_job.rb +30 -0
  85. data/app/jobs/decidim/machine_translation_resource_job.rb +113 -0
  86. data/app/jobs/decidim/machine_translation_save_job.rb +33 -0
  87. data/app/mailers/decidim/reported_mailer.rb +8 -1
  88. data/app/models/decidim/action_log.rb +1 -1
  89. data/app/models/decidim/area.rb +3 -0
  90. data/app/models/decidim/area_type.rb +4 -0
  91. data/app/models/decidim/attachment.rb +30 -2
  92. data/app/models/decidim/attachment_collection.rb +3 -0
  93. data/app/models/decidim/authorization.rb +3 -0
  94. data/app/models/decidim/category.rb +4 -0
  95. data/app/models/decidim/component.rb +7 -0
  96. data/app/models/decidim/content_block.rb +11 -1
  97. data/app/models/decidim/contextual_help_section.rb +4 -0
  98. data/app/models/decidim/follow.rb +3 -1
  99. data/app/models/decidim/messaging/message.rb +1 -1
  100. data/app/models/decidim/moderation.rb +1 -1
  101. data/app/models/decidim/newsletter.rb +3 -0
  102. data/app/models/decidim/oauth_application.rb +2 -0
  103. data/app/models/decidim/organization.rb +53 -9
  104. data/app/models/decidim/scope.rb +4 -1
  105. data/app/models/decidim/scope_type.rb +3 -0
  106. data/app/models/decidim/share_token.rb +49 -0
  107. data/app/models/decidim/static_page.rb +4 -1
  108. data/app/models/decidim/static_page_topic.rb +3 -0
  109. data/app/models/decidim/user_base_entity.rb +6 -2
  110. data/app/permissions/decidim/permissions.rb +9 -0
  111. data/app/presenters/decidim/log/base_presenter.rb +1 -1
  112. data/app/presenters/decidim/log/value_types/default_presenter.rb +1 -1
  113. data/app/presenters/decidim/official_author_presenter.rb +36 -0
  114. data/app/presenters/decidim/resource_locator_presenter.rb +63 -12
  115. data/app/queries/decidim/similar_emendations.rb +4 -4
  116. data/app/scrubbers/decidim/user_input_scrubber.rb +1 -1
  117. data/app/serializers/decidim/importers/participatory_space_components_importer.rb +1 -1
  118. data/app/services/decidim/base_diff_renderer.rb +17 -0
  119. data/app/services/decidim/open_data_exporter.rb +2 -0
  120. data/app/services/decidim/resource_search.rb +95 -6
  121. data/app/services/decidim/static_map_generator.rb +10 -26
  122. data/app/uploaders/decidim/application_uploader.rb +15 -1
  123. data/app/uploaders/decidim/attachment_uploader.rb +23 -17
  124. data/app/uploaders/decidim/banner_image_uploader.rb +1 -1
  125. data/app/uploaders/decidim/hero_image_uploader.rb +1 -1
  126. data/app/uploaders/decidim/homepage_image_uploader.rb +1 -1
  127. data/app/uploaders/decidim/image_uploader.rb +6 -2
  128. data/app/uploaders/decidim/oauth_application_logo_uploader.rb +1 -1
  129. data/app/uploaders/decidim/official_image_footer_uploader.rb +1 -1
  130. data/app/uploaders/decidim/official_image_header_uploader.rb +1 -1
  131. data/app/uploaders/decidim/organization_logo_uploader.rb +1 -1
  132. data/app/uploaders/decidim/record_image_uploader.rb +15 -0
  133. data/app/validators/etiquette_validator.rb +0 -7
  134. data/app/validators/geocoding_validator.rb +9 -4
  135. data/app/validators/passthru_validator.rb +111 -0
  136. data/app/validators/scope_belongs_to_component_validator.rb +16 -0
  137. data/app/validators/uploader_content_type_validator.rb +44 -0
  138. data/app/views/decidim/authorization_modals/_content.html.erb +2 -2
  139. data/app/views/decidim/devise/registrations/new.html.erb +3 -1
  140. data/app/views/decidim/devise/sessions/new.html.erb +3 -1
  141. data/app/views/decidim/messaging/conversations/_error_modal.html.erb +21 -0
  142. data/app/views/decidim/messaging/conversations/error.js.erb +10 -0
  143. data/app/views/decidim/notification_mailer/event_received.html.erb +2 -2
  144. data/app/views/decidim/reported_mailer/report.html.erb +49 -3
  145. data/app/views/decidim/scopes/_scopes_picker_input.html.erb +15 -14
  146. data/app/views/decidim/searches/_filters.html.erb +1 -0
  147. data/app/views/decidim/shared/_login_modal.html.erb +14 -3
  148. data/app/views/decidim/shared/_static_map.html.erb +1 -1
  149. data/app/views/layouts/decidim/_head.html.erb +2 -0
  150. data/app/views/layouts/decidim/_js_configuration.html.erb +7 -1
  151. data/config/locales/am-ET.yml +1 -0
  152. data/config/locales/ar.yml +3 -4
  153. data/config/locales/bg.yml +1508 -0
  154. data/config/locales/ca.yml +35 -8
  155. data/config/locales/cs.yml +34 -7
  156. data/config/locales/da.yml +1 -0
  157. data/config/locales/de.yml +23 -4
  158. data/config/locales/el.yml +0 -4
  159. data/config/locales/en.yml +30 -3
  160. data/config/locales/eo.yml +92 -0
  161. data/config/locales/es-MX.yml +28 -1
  162. data/config/locales/es-PY.yml +28 -1
  163. data/config/locales/es.yml +44 -17
  164. data/config/locales/et.yml +1 -0
  165. data/config/locales/eu.yml +3 -4
  166. data/config/locales/fi-plain.yml +28 -1
  167. data/config/locales/fi.yml +29 -2
  168. data/config/locales/fr-CA.yml +32 -4
  169. data/config/locales/fr.yml +61 -33
  170. data/config/locales/ga-IE.yml +0 -8
  171. data/config/locales/gl.yml +3 -4
  172. data/config/locales/hr.yml +1 -0
  173. data/config/locales/hu.yml +7 -4
  174. data/config/locales/id-ID.yml +3 -4
  175. data/config/locales/is-IS.yml +3 -9
  176. data/config/locales/is.yml +463 -0
  177. data/config/locales/it.yml +36 -8
  178. data/config/locales/ja-JP.yml +25 -16
  179. data/config/locales/ja.yml +1605 -0
  180. data/config/locales/ko-KR.yml +1 -0
  181. data/config/locales/ko.yml +1 -0
  182. data/config/locales/lt.yml +1 -0
  183. data/config/locales/{lv-LV.yml → lv.yml} +0 -4
  184. data/config/locales/mt.yml +1 -0
  185. data/config/locales/nl.yml +25 -3
  186. data/config/locales/no.yml +133 -6
  187. data/config/locales/om-ET.yml +1 -0
  188. data/config/locales/pl.yml +88 -71
  189. data/config/locales/pt-BR.yml +3 -4
  190. data/config/locales/pt.yml +10 -4
  191. data/config/locales/ro-RO.yml +10 -4
  192. data/config/locales/ru.yml +3 -10
  193. data/config/locales/sk.yml +3 -4
  194. data/config/locales/sl.yml +8 -7
  195. data/config/locales/so-SO.yml +1 -0
  196. data/config/locales/sr-CS.yml +0 -7
  197. data/config/locales/sv.yml +17 -6
  198. data/config/locales/ti-ER.yml +1 -0
  199. data/config/locales/tr-TR.yml +3 -4
  200. data/config/locales/uk.yml +3 -11
  201. data/config/locales/vi-VN.yml +1 -0
  202. data/config/locales/vi.yml +1 -0
  203. data/config/locales/zh-CN.yml +1584 -0
  204. data/config/locales/zh-TW.yml +1 -0
  205. data/db/migrate/20200525184143_add_enable_machine_translation_to_decidim_organizations.rb +7 -0
  206. data/db/migrate/20200702073419_create_decidim_share_tokens.rb +16 -0
  207. data/db/migrate/20200707132401_add_comments_max_length_to_decidim_organization.rb +7 -0
  208. data/db/migrate/20200730142511_add_file_upload_settings_to_decidim_organizations.rb +36 -0
  209. data/db/migrate/20200806092109_add_machine_translation_display_priority_to_organizations.rb +17 -0
  210. data/db/migrate/20201004160335_remove_notifications_with_continuity_badge.rb +9 -0
  211. data/db/seeds.rb +5 -4
  212. data/lib/decidim/authorable.rb +22 -1
  213. data/lib/decidim/authorization_form_builder.rb +7 -0
  214. data/lib/decidim/coauthorable.rb +22 -0
  215. data/lib/decidim/component_manifest.rb +1 -1
  216. data/lib/decidim/content_processor.rb +52 -29
  217. data/lib/decidim/content_renderers/base_renderer.rb +1 -1
  218. data/lib/decidim/content_renderers/hashtag_renderer.rb +2 -0
  219. data/lib/decidim/content_renderers/link_renderer.rb +4 -1
  220. data/lib/decidim/content_renderers/user_group_renderer.rb +3 -1
  221. data/lib/decidim/content_renderers/user_renderer.rb +3 -1
  222. data/lib/decidim/core.rb +67 -12
  223. data/lib/decidim/core/engine.rb +60 -21
  224. data/lib/decidim/core/test.rb +6 -0
  225. data/lib/decidim/core/test/factories.rb +34 -8
  226. data/lib/decidim/core/test/shared_examples/amendable/accept_amendment_examples.rb +4 -4
  227. data/lib/decidim/core/test/shared_examples/amendable_proposals_interface_examples.rb +8 -8
  228. data/lib/decidim/core/test/shared_examples/comments_examples.rb +52 -1
  229. data/lib/decidim/core/test/shared_examples/embed_resource_examples.rb +49 -0
  230. data/lib/decidim/core/test/shared_examples/follows_examples.rb +3 -3
  231. data/lib/decidim/core/test/shared_examples/manage_component_share_tokens.rb +83 -0
  232. data/lib/decidim/core/test/shared_examples/map_examples.rb +186 -0
  233. data/lib/decidim/core/test/shared_examples/preview_component_with_share_token_examples.rb +55 -0
  234. data/lib/decidim/core/test/shared_examples/resource_search_examples.rb +200 -0
  235. data/lib/decidim/core/test/shared_examples/scopable_resource_examples.rb +43 -0
  236. data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +12 -1
  237. data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +2 -2
  238. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +15 -2
  239. data/lib/decidim/core/test/shared_examples/simple_event.rb +7 -0
  240. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +1 -0
  241. data/lib/decidim/core/test/shared_examples/traceable_interface_examples.rb +1 -1
  242. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +1 -1
  243. data/lib/decidim/core/version.rb +1 -1
  244. data/lib/decidim/diffy_extension.rb +21 -0
  245. data/lib/decidim/events/base_event.rb +11 -9
  246. data/lib/decidim/exporters.rb +7 -0
  247. data/lib/decidim/exporters/csv.rb +15 -1
  248. data/lib/decidim/exporters/excel.rb +1 -1
  249. data/lib/decidim/exporters/export_manifest.rb +29 -0
  250. data/lib/decidim/exporters/pdf.rb +56 -0
  251. data/lib/decidim/file_validator_humanizer.rb +98 -0
  252. data/lib/decidim/form_builder.rb +65 -54
  253. data/lib/decidim/geocodable.rb +79 -0
  254. data/lib/decidim/has_attachments.rb +10 -0
  255. data/lib/decidim/has_upload_validations.rb +36 -0
  256. data/lib/decidim/map.rb +214 -0
  257. data/lib/decidim/map/autocomplete.rb +67 -0
  258. data/lib/decidim/map/dynamic_map.rb +89 -0
  259. data/lib/decidim/map/frontend.rb +97 -0
  260. data/lib/decidim/map/geocoding.rb +115 -0
  261. data/lib/decidim/map/provider.rb +12 -0
  262. data/lib/decidim/map/provider/autocomplete/here.rb +20 -0
  263. data/lib/decidim/map/provider/autocomplete/osm.rb +20 -0
  264. data/lib/decidim/map/provider/dynamic_map/here.rb +51 -0
  265. data/lib/decidim/map/provider/dynamic_map/osm.rb +13 -0
  266. data/lib/decidim/map/provider/geocoding/here.rb +58 -0
  267. data/lib/decidim/map/provider/geocoding/osm.rb +30 -0
  268. data/lib/decidim/map/provider/here.rb +21 -0
  269. data/lib/decidim/map/provider/osm.rb +22 -0
  270. data/lib/decidim/map/provider/static_map/here.rb +35 -0
  271. data/lib/decidim/map/provider/static_map/osm.rb +29 -0
  272. data/lib/decidim/map/static_map.rb +133 -0
  273. data/lib/decidim/map/utility.rb +38 -0
  274. data/lib/decidim/organization_settings.rb +267 -0
  275. data/lib/decidim/resource_manifest.rb +1 -1
  276. data/lib/decidim/scopable.rb +9 -6
  277. data/lib/decidim/scopable_component.rb +29 -1
  278. data/lib/decidim/scopable_participatory_space.rb +19 -0
  279. data/lib/decidim/scopable_resource.rb +21 -0
  280. data/lib/decidim/search_resource_fields_mapper.rb +15 -2
  281. data/lib/decidim/searchable.rb +4 -0
  282. data/lib/decidim/settings_manifest.rb +2 -1
  283. data/lib/decidim/shareable_with_token.rb +27 -0
  284. data/lib/decidim/snippets.rb +30 -0
  285. data/lib/decidim/translatable_attributes.rb +42 -4
  286. data/lib/decidim/translatable_resource.rb +78 -0
  287. data/lib/decidim/view_model.rb +1 -0
  288. data/lib/tasks/decidim_locales_tasks.rake +35 -0
  289. data/lib/tasks/decidim_tasks.rake +1 -0
  290. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.bg.js +14 -0
  291. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.da.js +14 -0
  292. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.eo.js +17 -0
  293. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.et.js +18 -0
  294. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.fr-CA.js +16 -0
  295. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.ga.js +15 -0
  296. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.hr.js +13 -0
  297. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.is.js +14 -0
  298. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.ja.js +16 -0
  299. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.lt.js +16 -0
  300. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.lv.js +17 -0
  301. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.mt.js +15 -0
  302. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.sl.js +14 -0
  303. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.sr.js +16 -0
  304. metadata +138 -26
  305. data/app/helpers/decidim/multi_translation_helper.rb +0 -0
  306. data/lib/decidim/hashtaggable.rb +0 -24
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # This job is used by machine translation services to store the result of
5
+ # a field translation. This way services don't need to care about how to
6
+ # save it and also enables storing translations asynchronously when the
7
+ # translation service returns the translated text in a webhook.
8
+ class MachineTranslationSaveJob < ApplicationJob
9
+ queue_as :default
10
+
11
+ # Performs the job. It won't perform anything if the
12
+ # `Decidim.machine_translation_service` config is not set.
13
+ #
14
+ # resource - Any kind of `Decidim::TranslatableResource` model instance
15
+ # field_name - A Symbol representing the name of the field being translated
16
+ # target_locale - A Symbol representing the target locale for the translation
17
+ # translated_text - A String with the value of the field_name, translated
18
+ # into the target_locale
19
+ def perform(resource, field_name, target_locale, translated_text)
20
+ resource.with_lock do
21
+ if resource[field_name]["machine_translations"].present?
22
+ resource[field_name]["machine_translations"] = resource[field_name]["machine_translations"].merge(target_locale => translated_text)
23
+ else
24
+ resource[field_name] = resource[field_name].merge("machine_translations" => { target_locale => translated_text })
25
+ end
26
+
27
+ # rubocop:disable Rails/SkipsModelValidations
28
+ resource.update_column field_name.to_sym, resource[field_name]
29
+ # rubocop:enable Rails/SkipsModelValidations
30
+ end
31
+ end
32
+ end
33
+ end
@@ -4,8 +4,9 @@ module Decidim
4
4
  # A custom mailer for sending notifications to an admin when a report is created..
5
5
  class ReportedMailer < Decidim::ApplicationMailer
6
6
  helper Decidim::ResourceHelper
7
+ helper Decidim::TranslationsHelper
7
8
 
8
- helper_method :reported_content_url, :manage_moderations_url
9
+ helper_method :reported_content_url, :manage_moderations_url, :author_profile_url
9
10
 
10
11
  def report(user, report)
11
12
  with_user(user) do
@@ -13,6 +14,8 @@ module Decidim
13
14
  @participatory_space = @report.moderation.participatory_space
14
15
  @organization = user.organization
15
16
  @user = user
17
+ @author = @report.moderation.reportable.try(:creator_identity) || @report.moderation.reportable.try(:author)
18
+ @content = { title: @report.moderation.reportable.try(:title), body: @report.moderation.reportable.try(:body) }.compact
16
19
  subject = I18n.t("report.subject", scope: "decidim.reported_mailer")
17
20
  mail(to: user.email, subject: subject)
18
21
  end
@@ -38,5 +41,9 @@ module Decidim
38
41
  def manage_moderations_url
39
42
  @manage_moderations_url ||= EngineRouter.admin_proxy(@participatory_space).moderations_url(host: @organization.host)
40
43
  end
44
+
45
+ def author_profile_url
46
+ @author_profile_url ||= @author.is_a?(Decidim::UserBaseEntity) ? decidim.profile_url(@author.nickname, host: @organization.host) : nil
47
+ end
41
48
  end
42
49
  end
@@ -5,7 +5,7 @@ module Decidim
5
5
  # for transparency reasons, to log all actions so all other users can
6
6
  # see the actions being performed.
7
7
  class ActionLog < ApplicationRecord
8
- include Decidim::Scopable
8
+ include Decidim::ScopableParticipatorySpace
9
9
 
10
10
  belongs_to :organization,
11
11
  foreign_key: :decidim_organization_id,
@@ -6,6 +6,9 @@ module Decidim
6
6
  class Area < ApplicationRecord
7
7
  include Traceable
8
8
  include Loggable
9
+ include Decidim::TranslatableResource
10
+
11
+ translatable_fields :name
9
12
 
10
13
  belongs_to :organization,
11
14
  foreign_key: "decidim_organization_id",
@@ -4,6 +4,10 @@ module Decidim
4
4
  # Area types allows to use different types of areas in participatory space
5
5
  # (terriotrial, sectorial, etc.)
6
6
  class AreaType < ApplicationRecord
7
+ include Decidim::TranslatableResource
8
+
9
+ translatable_fields :name, :plural
10
+
7
11
  belongs_to :organization,
8
12
  foreign_key: "decidim_organization_id",
9
13
  class_name: "Decidim::Organization",
@@ -4,14 +4,42 @@ module Decidim
4
4
  # Attachment can be any type of document or images related to a partcipatory
5
5
  # process.
6
6
  class Attachment < ApplicationRecord
7
+ include Decidim::HasUploadValidations
8
+ include Decidim::TranslatableResource
9
+
10
+ translatable_fields :title, :description
7
11
  belongs_to :attachment_collection, class_name: "Decidim::AttachmentCollection", optional: true
8
12
  belongs_to :attached_to, polymorphic: true
9
13
 
10
14
  validates :file, :content_type, presence: true
11
- validates :file, file_size: { less_than_or_equal_to: ->(_attachment) { Decidim.maximum_attachment_size } }
15
+ validates_upload :file
12
16
  mount_uploader :file, Decidim::AttachmentUploader
13
17
 
14
- default_scope { order(arel_table[:weight].asc) }
18
+ default_scope { order(arel_table[:weight].asc, arel_table[:id].asc) }
19
+
20
+ # Returns the organization related to this attachment in case the
21
+ # attached_to model belongs to an organization. Otherwise will return nil.
22
+ #
23
+ # Returns Decidim::Organization or nil.
24
+ def organization
25
+ return unless attached_to
26
+ return attached_to if attached_to.is_a?(Decidim::Organization)
27
+ return unless attached_to.respond_to?(:organization)
28
+
29
+ attached_to.organization
30
+ end
31
+
32
+ # The context of the attachments defines which file upload settings
33
+ # constraints should be used when the file is uploaded. The different
34
+ # contexts can limit for instance which file types the user is allowed to
35
+ # upload.
36
+ #
37
+ # Returns Symbol.
38
+ def context
39
+ return attached_to.attachment_context if attached_to.respond_to?(:attachment_context)
40
+
41
+ :participant
42
+ end
15
43
 
16
44
  # Whether this attachment is a photo or not.
17
45
  #
@@ -4,6 +4,9 @@ module Decidim
4
4
  # Categories serve as a taxonomy for attachments to use for while in the
5
5
  # context of a participatory space.
6
6
  class AttachmentCollection < ApplicationRecord
7
+ include Decidim::TranslatableResource
8
+
9
+ translatable_fields :name, :description
7
10
  belongs_to :collection_for, polymorphic: true
8
11
  has_many :attachments, foreign_key: "attachment_collection_id", class_name: "Decidim::Attachment", dependent: :nullify
9
12
 
@@ -12,6 +12,9 @@ module Decidim
12
12
  # not.
13
13
  class Authorization < ApplicationRecord
14
14
  include Decidim::Traceable
15
+ include Decidim::HasUploadValidations
16
+
17
+ validates_upload :verification_attachment
15
18
  mount_uploader :verification_attachment, Decidim::Verifications::AttachmentUploader
16
19
 
17
20
  belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
@@ -4,6 +4,10 @@ module Decidim
4
4
  # Categories serve as a taxonomy for components to use for while in the
5
5
  # context of a participatory process.
6
6
  class Category < ApplicationRecord
7
+ include Decidim::TranslatableResource
8
+
9
+ translatable_fields :name, :description
10
+
7
11
  belongs_to :participatory_space, foreign_key: "decidim_participatory_space_id", foreign_type: "decidim_participatory_space_type", polymorphic: true
8
12
  has_many :subcategories, foreign_key: "parent_id", class_name: "Decidim::Category", dependent: :destroy, inverse_of: :parent
9
13
  belongs_to :parent, class_name: "Decidim::Category", foreign_key: "parent_id", inverse_of: :subcategories, optional: true
@@ -9,6 +9,8 @@ module Decidim
9
9
  include Publicable
10
10
  include Traceable
11
11
  include Loggable
12
+ include Decidim::ShareableWithToken
13
+ include ScopableComponent
12
14
 
13
15
  belongs_to :participatory_space, polymorphic: true
14
16
 
@@ -87,6 +89,11 @@ module Decidim
87
89
  participatory_space.can_participate?(user)
88
90
  end
89
91
 
92
+ # Public: Public URL for component with given share token as query parameter
93
+ def shareable_url(share_token)
94
+ EngineRouter.main_proxy(self).root_path(self, share_token: share_token.token)
95
+ end
96
+
90
97
  delegate :serializes_specific_data?, to: :manifest
91
98
 
92
99
  private
@@ -15,6 +15,8 @@ module Decidim
15
15
  before_save :save_images
16
16
  after_save :reload_images
17
17
 
18
+ validate :images_container_valid
19
+
18
20
  # Public: finds the published content blocks for the given scope and
19
21
  # organization. Returns them ordered by ascending weight (lowest first).
20
22
  def self.for_scope(scope, organization:)
@@ -79,7 +81,7 @@ module Decidim
79
81
  attr_reader :content_block
80
82
 
81
83
  # Needed to calculate uploads URLs
82
- delegate :id, to: :content_block
84
+ delegate :id, :organization, to: :content_block
83
85
 
84
86
  # Needed to customize the upload URL
85
87
  def self.name
@@ -132,6 +134,14 @@ module Decidim
132
134
 
133
135
  private
134
136
 
137
+ def images_container_valid
138
+ # Note that we cannot call .valid? because it's not an ActiveRecord
139
+ # object. It's ActiveModel and in that case, CarrierWave will not work
140
+ # "normally" with the validators. It adds the errors directly after the
141
+ # uploader was tried to set.
142
+ errors.add(:images_container, :invalid) if images_container.errors.any?
143
+ end
144
+
135
145
  # Internal: Since we're using the `images_container` hack to hold the
136
146
  # uploaders, we need to manually trigger it to save the attached images.
137
147
  def save_images
@@ -2,6 +2,10 @@
2
2
 
3
3
  module Decidim
4
4
  class ContextualHelpSection < ApplicationRecord
5
+ include Decidim::TranslatableResource
6
+
7
+ translatable_fields :content
8
+
5
9
  belongs_to :organization, class_name: "Decidim::Organization"
6
10
  validates :organization, presence: true
7
11
  validates :content, presence: true
@@ -24,7 +24,9 @@ module Decidim
24
24
  end
25
25
 
26
26
  def self.user_follower_ids_for_participatory_spaces(spaces)
27
- joins(:user).where(followable: spaces).pluck(:decidim_user_id).uniq
27
+ # IF the space has questions it's a Consultations
28
+ followables = spaces.flat_map { |space| space.try(:questions) || space }
29
+ joins(:user).where(followable: followables).pluck(:decidim_user_id).uniq
28
30
  end
29
31
 
30
32
  private
@@ -25,7 +25,7 @@ module Decidim
25
25
  inverse_of: :message
26
26
 
27
27
  validates :sender, :body, presence: true
28
- validates :body, length: { maximum: 1_000 }
28
+ validates :body, length: { maximum: ->(_message) { Decidim.config.maximum_conversation_message_length } }
29
29
 
30
30
  default_scope { order(created_at: :asc) }
31
31
 
@@ -6,7 +6,7 @@ module Decidim
6
6
  include Traceable
7
7
  include Loggable
8
8
 
9
- belongs_to :reportable, foreign_key: "decidim_reportable_id", foreign_type: "decidim_reportable_type", polymorphic: true
9
+ belongs_to :reportable, foreign_key: "decidim_reportable_id", foreign_type: "decidim_reportable_type", polymorphic: true, touch: true
10
10
  belongs_to :participatory_space, foreign_key: "decidim_participatory_space_id", foreign_type: "decidim_participatory_space_type", polymorphic: true
11
11
  has_many :reports, foreign_key: "decidim_moderation_id", class_name: "Decidim::Report", dependent: :destroy
12
12
 
@@ -5,6 +5,9 @@ module Decidim
5
5
  class Newsletter < ApplicationRecord
6
6
  include Decidim::Traceable
7
7
  include Decidim::Loggable
8
+ include Decidim::TranslatableResource
9
+
10
+ translatable_fields :subject
8
11
 
9
12
  belongs_to :author, class_name: "User"
10
13
  belongs_to :organization
@@ -4,9 +4,11 @@ module Decidim
4
4
  class OAuthApplication < ::Doorkeeper::Application
5
5
  include Decidim::Traceable
6
6
  include Decidim::Loggable
7
+ include Decidim::HasUploadValidations
7
8
 
8
9
  belongs_to :organization, foreign_key: "decidim_organization_id", class_name: "Decidim::Organization", inverse_of: :oauth_applications
9
10
 
11
+ validates_upload :organization_logo
10
12
  mount_uploader :organization_logo, OAuthApplicationLogoUploader
11
13
 
12
14
  def owner
@@ -8,8 +8,17 @@ module Decidim
8
8
  include TranslationsHelper
9
9
  include Decidim::Traceable
10
10
  include Decidim::Loggable
11
+ include Decidim::HasUploadValidations
12
+ include Decidim::TranslatableResource
13
+ include Decidim::ActsAsAuthor
11
14
 
12
15
  SOCIAL_HANDLERS = [:twitter, :facebook, :instagram, :youtube, :github].freeze
16
+ AVAILABLE_MACHINE_TRANSLATION_DISPLAY_PRIORITIES = %w(original translation).freeze
17
+
18
+ translatable_fields :description, :cta_button_text, :omnipresent_banner_title, :omnipresent_banner_short_description,
19
+ :highlighted_content_banner_title, :highlighted_content_banner_short_description, :highlighted_content_banner_action_title,
20
+ :highlighted_content_banner_action_subtitle, :welcome_notification_subject, :welcome_notification_body, :id_documents_explanation_text,
21
+ :admin_terms_of_use_body
13
22
 
14
23
  has_many :static_pages, foreign_key: "decidim_organization_id", class_name: "Decidim::StaticPage", inverse_of: :organization, dependent: :destroy
15
24
  has_many :static_page_topics, foreign_key: "organization_id", class_name: "Decidim::StaticPageTopic", inverse_of: :organization, dependent: :destroy
@@ -23,6 +32,8 @@ module Decidim
23
32
  has_many :oauth_applications, foreign_key: "decidim_organization_id", class_name: "Decidim::OAuthApplication", inverse_of: :organization, dependent: :destroy
24
33
  has_many :hashtags, foreign_key: "decidim_organization_id", class_name: "Decidim::Hashtag", dependent: :destroy
25
34
 
35
+ has_many :templates, foreign_key: "decidim_organization_id", class_name: "Decidim::Templates::Template", dependent: :destroy if defined? Decidim::Templates
36
+
26
37
  # Users registration mode. Whether users can register or access the system. Doesn't affect users that access through Omniauth integrations.
27
38
  # enabled: Users registration and sign in are enabled (default value).
28
39
  # existing: Users can't be registered in the system. Only existing users can sign in.
@@ -34,16 +45,34 @@ module Decidim
34
45
  validates :time_zone, presence: true, time_zone: true
35
46
  validates :default_locale, inclusion: { in: :available_locales }
36
47
 
48
+ validates_upload :official_img_header
37
49
  mount_uploader :official_img_header, Decidim::OfficialImageHeaderUploader
50
+
51
+ validates_upload :official_img_footer
38
52
  mount_uploader :official_img_footer, Decidim::OfficialImageFooterUploader
53
+
54
+ validates_upload :logo
39
55
  mount_uploader :logo, Decidim::OrganizationLogoUploader
56
+
57
+ validates_upload :favicon
40
58
  mount_uploader :favicon, Decidim::OrganizationFaviconUploader
59
+
60
+ validates_upload :highlighted_content_banner_image
41
61
  mount_uploader :highlighted_content_banner_image, ImageUploader
42
62
 
43
63
  def self.log_presenter_class_for(_log)
44
64
  Decidim::AdminLog::OrganizationPresenter
45
65
  end
46
66
 
67
+ def settings
68
+ Decidim::OrganizationSettings.for(self)
69
+ end
70
+
71
+ # This is needed for the upload validations
72
+ def maximum_upload_size
73
+ settings.upload_maximum_file_size
74
+ end
75
+
47
76
  def available_authorization_handlers
48
77
  available_authorizations & Decidim.authorization_handlers.map(&:name)
49
78
  end
@@ -110,6 +139,20 @@ module Decidim
110
139
  default_except_disabled.merge(tenant_enabled_providers)
111
140
  end
112
141
 
142
+ def machine_translation_prioritizes_original?
143
+ machine_translation_display_priority == "original"
144
+ end
145
+
146
+ def machine_translation_prioritizes_translation?
147
+ machine_translation_display_priority == "translation"
148
+ end
149
+
150
+ # Returns the presenter for this author, to be used in the views.
151
+ # Required by ActsAsAuthor.
152
+ def presenter
153
+ Decidim::Debates::OfficialAuthorPresenter.new
154
+ end
155
+
113
156
  private
114
157
 
115
158
  def tenant_disabled_providers_keys
@@ -133,18 +176,19 @@ module Decidim
133
176
  end
134
177
 
135
178
  def omniauth_provider_settings(provider)
136
- provider_settings = {}
179
+ @omniauth_provider_settings ||= Hash.new do |hash, provider_key|
180
+ hash[provider_key] = begin
181
+ omniauth_settings.each_with_object({}) do |(key, value), provider_settings|
182
+ next unless key.to_s.include?(provider_key.to_s)
137
183
 
138
- omniauth_settings.each do |key, value|
139
- next unless key.to_s.include?(provider.to_s)
184
+ value = Decidim::AttributeEncryptor.decrypt(value) if Decidim::OmniauthProvider.value_defined?(value)
185
+ setting_key = Decidim::OmniauthProvider.extract_setting_key(key, provider_key)
140
186
 
141
- value = Decidim::AttributeEncryptor.decrypt(value) if Decidim::OmniauthProvider.value_defined?(value)
142
- setting_key = Decidim::OmniauthProvider.extract_setting_key(key, provider)
143
-
144
- provider_settings[setting_key] = value
187
+ provider_settings[setting_key] = value
188
+ end
189
+ end
145
190
  end
146
-
147
- provider_settings
191
+ @omniauth_provider_settings[provider]
148
192
  end
149
193
  end
150
194
  end
@@ -7,6 +7,9 @@ module Decidim
7
7
  class Scope < ApplicationRecord
8
8
  include Decidim::Traceable
9
9
  include Decidim::Loggable
10
+ include Decidim::TranslatableResource
11
+
12
+ translatable_fields :name
10
13
 
11
14
  belongs_to :organization,
12
15
  foreign_key: "decidim_organization_id",
@@ -53,7 +56,7 @@ module Decidim
53
56
  end
54
57
 
55
58
  def descendants
56
- organization.scopes.where("? = ANY(decidim_scopes.part_of)", id)
59
+ @descendants ||= organization.scopes.where("? = ANY(decidim_scopes.part_of)", id)
57
60
  end
58
61
 
59
62
  def ancestor_of?(scope)
@@ -4,6 +4,9 @@ module Decidim
4
4
  # Scope types allows to use different types of scopes in participatory process
5
5
  # (municipalities, provinces, states, countries, etc.)
6
6
  class ScopeType < ApplicationRecord
7
+ include Decidim::TranslatableResource
8
+
9
+ translatable_fields :name, :plural
7
10
  belongs_to :organization,
8
11
  foreign_key: "decidim_organization_id",
9
12
  class_name: "Decidim::Organization",
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ class ShareToken < ApplicationRecord
5
+ validates :organization, presence: true
6
+ validates :user, presence: true
7
+ validates :token, presence: true, uniqueness: { scope: [:decidim_organization_id, :token_for_type, :token_for_id] }
8
+
9
+ belongs_to :organization, foreign_key: "decidim_organization_id", class_name: "Decidim::Organization"
10
+ belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
11
+ belongs_to :token_for, foreign_key: "token_for_id", foreign_type: "token_for_type", polymorphic: true
12
+
13
+ after_initialize :generate, :set_default_expiration
14
+
15
+ def self.use!(token_for:, token:)
16
+ record = find_by!(token_for: token_for, token: token)
17
+ record.use!
18
+ end
19
+
20
+ def use!
21
+ return raise StandardError, "Share token '#{token}' for '#{token_for_type}' with id = #{token_for_id} has expired." if expired?
22
+
23
+ update!(times_used: times_used + 1, last_used_at: Time.zone.now)
24
+ end
25
+
26
+ def expired?
27
+ expires_at.past?
28
+ end
29
+
30
+ def url
31
+ token_for.shareable_url(self)
32
+ end
33
+
34
+ private
35
+
36
+ def generate
37
+ return if token.present?
38
+
39
+ loop do
40
+ self.token = SecureRandom.hex(32)
41
+ break if ShareToken.find_by(token: token).blank?
42
+ end
43
+ end
44
+
45
+ def set_default_expiration
46
+ self.expires_at ||= 1.day.from_now
47
+ end
48
+ end
49
+ end