decidim-core 0.29.2 → 0.29.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +5 -3
  3. data/app/cells/decidim/profile_actions/show.erb +1 -1
  4. data/app/cells/decidim/report_button/already_reported_modal.erb +2 -2
  5. data/app/cells/decidim/report_button/flag_modal.erb +13 -27
  6. data/app/cells/decidim/report_button_cell.rb +2 -8
  7. data/app/cells/decidim/report_user_button/already_reported_modal.erb +11 -0
  8. data/app/cells/decidim/report_user_button/flag_modal.erb +46 -0
  9. data/app/cells/decidim/report_user_button/show.erb +2 -0
  10. data/app/cells/decidim/report_user_button_cell.rb +59 -0
  11. data/app/cells/decidim/resource_types_filter/show.erb +1 -1
  12. data/app/cells/decidim/resource_types_filter_cell.rb +6 -6
  13. data/app/cells/decidim/user_activity/show.erb +1 -1
  14. data/app/commands/decidim/create_omniauth_registration.rb +14 -8
  15. data/app/commands/decidim/create_report.rb +1 -6
  16. data/app/commands/decidim/search.rb +14 -0
  17. data/app/controllers/decidim/profiles_controller.rb +2 -2
  18. data/app/controllers/decidim/reports_controller.rb +1 -1
  19. data/app/controllers/decidim/user_activities_controller.rb +1 -1
  20. data/app/forms/decidim/account_form.rb +5 -2
  21. data/app/helpers/decidim/orders_helper.rb +2 -1
  22. data/app/helpers/decidim/participatory_space_helpers.rb +1 -1
  23. data/app/jobs/decidim/hide_child_resources_job.rb +24 -0
  24. data/app/mailers/decidim/reported_mailer.rb +1 -0
  25. data/app/models/decidim/action_log.rb +1 -9
  26. data/app/models/decidim/report.rb +1 -1
  27. data/app/models/decidim/user.rb +0 -4
  28. data/app/models/decidim/user_base_entity.rb +4 -0
  29. data/app/packs/src/decidim/datepicker/datepicker_functions.js +3 -3
  30. data/app/packs/src/decidim/index.js +4 -2
  31. data/app/packs/src/decidim/map/provider/here.js +1 -1
  32. data/app/packs/stylesheets/decidim/_content_blocks.scss +4 -0
  33. data/app/packs/stylesheets/decidim/_hashtags.scss +5 -0
  34. data/app/packs/stylesheets/decidim/_header.scss +11 -5
  35. data/app/packs/stylesheets/decidim/application.scss +1 -0
  36. data/app/presenters/decidim/log/user_presenter.rb +1 -0
  37. data/app/presenters/decidim/user_presenter.rb +1 -1
  38. data/app/services/decidim/base_diff_renderer.rb +2 -0
  39. data/app/services/decidim/static_map_generator.rb +1 -1
  40. data/app/views/decidim/last_activities/index.html.erb +1 -1
  41. data/app/views/decidim/reported_mailer/hide.html.erb +17 -1
  42. data/app/views/decidim/reported_mailer/report.html.erb +1 -1
  43. data/app/views/decidim/searches/_count.html.erb +1 -1
  44. data/app/views/decidim/searches/_filters.html.erb +40 -38
  45. data/app/views/decidim/shared/_orders.html.erb +2 -2
  46. data/app/views/layouts/decidim/footer/_main_legal.html.erb +1 -1
  47. data/config/locales/ar.yml +41 -28
  48. data/config/locales/bg.yml +10 -24
  49. data/config/locales/bs-BA.yml +2 -0
  50. data/config/locales/ca-IT.yml +2111 -0
  51. data/config/locales/ca.yml +57 -29
  52. data/config/locales/cs.yml +55 -32
  53. data/config/locales/de.yml +48 -24
  54. data/config/locales/el.yml +10 -15
  55. data/config/locales/en.yml +44 -16
  56. data/config/locales/eo.yml +2 -0
  57. data/config/locales/es-MX.yml +56 -28
  58. data/config/locales/es-PY.yml +61 -33
  59. data/config/locales/es.yml +60 -32
  60. data/config/locales/eu.yml +112 -87
  61. data/config/locales/fi-plain.yml +44 -28
  62. data/config/locales/fi.yml +46 -30
  63. data/config/locales/fr-CA.yml +58 -25
  64. data/config/locales/fr.yml +57 -24
  65. data/config/locales/ga-IE.yml +4 -4
  66. data/config/locales/gl.yml +25 -15
  67. data/config/locales/hu.yml +9 -23
  68. data/config/locales/id-ID.yml +24 -16
  69. data/config/locales/is-IS.yml +10 -1
  70. data/config/locales/it.yml +35 -27
  71. data/config/locales/ja.yml +55 -25
  72. data/config/locales/lb.yml +24 -22
  73. data/config/locales/lt.yml +5 -17
  74. data/config/locales/lv.yml +18 -15
  75. data/config/locales/nl.yml +23 -18
  76. data/config/locales/no.yml +18 -16
  77. data/config/locales/pl.yml +7 -21
  78. data/config/locales/pt-BR.yml +11 -24
  79. data/config/locales/pt.yml +18 -16
  80. data/config/locales/ro-RO.yml +243 -86
  81. data/config/locales/ru.yml +23 -8
  82. data/config/locales/sk.yml +29 -18
  83. data/config/locales/sl.yml +4 -0
  84. data/config/locales/sr-CS.yml +2 -0
  85. data/config/locales/sv.yml +22 -26
  86. data/config/locales/tr-TR.yml +24 -23
  87. data/config/locales/uk.yml +12 -2
  88. data/config/locales/zh-CN.yml +18 -15
  89. data/config/locales/zh-TW.yml +8 -16
  90. data/lib/decidim/asset_router/storage.rb +7 -2
  91. data/lib/decidim/attributes/time_with_zone.rb +5 -1
  92. data/lib/decidim/content_parsers/blob_parser.rb +10 -8
  93. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  94. data/lib/decidim/core/test/shared_examples/reports_examples.rb +48 -6
  95. data/lib/decidim/core/test/shared_examples/social_share_examples.rb +32 -0
  96. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +26 -0
  97. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +26 -0
  98. data/lib/decidim/core/version.rb +1 -1
  99. data/lib/decidim/map/provider/dynamic_map/here.rb +1 -40
  100. data/lib/decidim/map/provider/static_map/here.rb +34 -0
  101. data/lib/decidim/moderation_tools.rb +16 -2
  102. data/lib/decidim/nicknamizable.rb +1 -1
  103. data/lib/decidim/reportable.rb +6 -2
  104. data/lib/decidim/translatable_attributes.rb +5 -1
  105. data/lib/tasks/upgrade/clean_hidden_resources.rake +33 -0
  106. data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +23 -20
  107. metadata +15 -14
  108. data/app/cells/decidim/author/flag.erb +0 -6
  109. data/app/cells/decidim/author/flag_user.erb +0 -14
  110. data/app/cells/decidim/flag_modal/flag_user.erb +0 -34
  111. data/app/cells/decidim/flag_modal/show.erb +0 -52
  112. data/app/cells/decidim/flag_modal_cell.rb +0 -56
  113. data/app/cells/decidim/profile_sidebar/show.erb +0 -167
  114. data/app/cells/decidim/profile_sidebar_cell.rb +0 -68
  115. data/app/packs/src/decidim/vendor/leaflet-tilelayer-here.js +0 -212
@@ -52,8 +52,13 @@ module Decidim
52
52
  when ActiveStorage::Blob
53
53
  blob_url(**)
54
54
  else # ActiveStorage::VariantWithRecord, ActiveStorage::Variant
55
- ensure_current_host(nil, **)
56
- representation_url(**)
55
+ if blob && blob.attachments.any?
56
+ ensure_current_host(blob.attachments.first&.record, **)
57
+ representation_url(**)
58
+ else
59
+ ensure_current_host(nil, **)
60
+ representation_url(**, only_path: true)
61
+ end
57
62
  end
58
63
  end
59
64
 
@@ -23,7 +23,11 @@ module Decidim
23
23
  def cast_value(value)
24
24
  return value unless value.is_a?(String)
25
25
 
26
- Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
26
+ if Date._iso8601(value).present?
27
+ Time.zone.iso8601(value)
28
+ else
29
+ Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
30
+ end
27
31
  rescue ArgumentError
28
32
  fallback = super
29
33
  return fallback unless fallback.is_a?(Time)
@@ -20,19 +20,19 @@ module Decidim
20
20
  # https://github.com/rails/rails/blob/a7e379896552ce43b822385c03c37f2bd47739d3/activestorage/config/routes.rb#L5-L14
21
21
  BLOB_REGEX = %r{
22
22
  # Group 1: Host part
23
- (
23
+ (?<host_part>
24
24
  # Group 2: Domain and subpath part
25
- https?://((?!/rails).)+
25
+ #{URI::DEFAULT_PARSER.make_regexp(%w(https http))}
26
26
  )?
27
27
  /rails/active_storage
28
28
  # Group 3: Blob path, representation path or disk service path
29
- /(blobs/redirect|blobs/proxy|blobs|representations/redirect|representations/proxy|representations|disk)
29
+ /(?<type_part>blobs/redirect|blobs/proxy|blobs|representations/redirect|representations/proxy|representations|disk)
30
30
  # Group 4: Signed ID for blobs or encoded key for disk service
31
- /([^/]+)
31
+ /(?<key_part>[^/]+)
32
32
  # Group 5: Variation part (only for representations)
33
33
  (
34
34
  # Group 6: Variation key for representations
35
- /([\w.=-]+)
35
+ /(?<variation_part>[\w.=-]+)
36
36
  )?
37
37
  # Group 7: Filename
38
38
  /([\w.=-]+)
@@ -46,8 +46,10 @@ module Decidim
46
46
 
47
47
  def replace_blobs(text)
48
48
  text.gsub(BLOB_REGEX) do |match|
49
- type_part = Regexp.last_match(3)
50
- key_part = Regexp.last_match(4)
49
+ named_captures = Regexp.last_match.named_captures
50
+
51
+ type_part = named_captures["type_part"]
52
+ key_part = named_captures["key_part"]
51
53
 
52
54
  variation_key = nil
53
55
  blob =
@@ -59,7 +61,7 @@ module Decidim
59
61
  # Representation or blob
60
62
  if type_part.start_with?("representations")
61
63
  # Representation
62
- variation_part = Regexp.last_match(6)
64
+ variation_part = named_captures["variation_part"]
63
65
  variation_key = generate_variation_key(variation_part)
64
66
  end
65
67
 
@@ -49,7 +49,7 @@ module Decidim
49
49
 
50
50
  def existing_mentionables
51
51
  @existing_mentionables ||= mentionable_class.where(
52
- "decidim_organization_id = ? AND LOWER(nickname) IN (?)",
52
+ "decidim_organization_id = ? AND nickname IN (?)",
53
53
  current_organization.id,
54
54
  content_nicknames
55
55
  )
@@ -33,17 +33,46 @@ shared_examples "higher user role hides" do
33
33
  before do
34
34
  login_as user, scope: :user
35
35
  end
36
- around do |example|
37
- previous = Capybara.raise_server_errors
38
36
 
39
- Capybara.raise_server_errors = false
40
- example.run
41
- Capybara.raise_server_errors = previous
37
+ it "reports the resource" do
38
+ visit reportable_path
39
+
40
+ expect(page).to have_css(%(button[data-dialog-open="flagModal"]))
41
+ find(%(button[data-dialog-open="flagModal"])).click
42
+ expect(page).to have_css(".flag-modal", visible: :visible)
43
+
44
+ within ".flag-modal" do
45
+ find(:css, "input[name='report[hide]']").set(true)
46
+ click_on "Hide"
47
+ end
48
+
49
+ sleep(1)
50
+
51
+ expect(page).to have_current_path(reportable_index_path, ignore_query: true)
52
+
53
+ expect(reportable.reload).to be_hidden
42
54
  end
55
+ end
56
+ end
57
+
58
+ shared_examples "higher user role hides resource with comments" do
59
+ context "and the admin hides a resource with comments" do
60
+ let!(:comments) { create_list(:comment, 2, body: "Dummy comment", commentable: reportable, author: user) }
61
+
62
+ before do
63
+ login_as user, scope: :user
64
+ end
65
+
66
+ it "hides the resource" do
67
+ visit decidim.search_path
68
+ expect(page).to have_content(translated(comments.first.body))
69
+ expect(page).to have_content(translated(comments.second.body))
43
70
 
44
- it "reports the resource" do
45
71
  visit reportable_path
46
72
 
73
+ expect(page).to have_content(translated(comments.first.body))
74
+ expect(page).to have_content(translated(comments.second.body))
75
+
47
76
  expect(page).to have_css(%(button[data-dialog-open="flagModal"]))
48
77
  find(%(button[data-dialog-open="flagModal"])).click
49
78
  expect(page).to have_css(".flag-modal", visible: :visible)
@@ -53,7 +82,19 @@ shared_examples "higher user role hides" do
53
82
  click_on "Hide"
54
83
  end
55
84
 
85
+ sleep(1)
86
+
87
+ expect(page).to have_current_path(reportable_index_path, ignore_query: true)
88
+
89
+ perform_enqueued_jobs
90
+
56
91
  expect(reportable.reload).to be_hidden
92
+ expect(comments.first.reload).to be_hidden
93
+ expect(comments.second.reload).to be_hidden
94
+
95
+ visit decidim.search_path
96
+ expect(page).to have_no_content(translated(comments.first.body))
97
+ expect(page).to have_no_content(translated(comments.second.body))
57
98
  end
58
99
  end
59
100
  end
@@ -120,6 +161,7 @@ shared_examples "reports by user type" do
120
161
  let!(:user) { create(:user, :admin, :confirmed, organization:) }
121
162
  include_examples "higher user role reports"
122
163
  include_examples "higher user role hides"
164
+ include_examples "higher user role hides resource with comments"
123
165
  end
124
166
  context "When reporting user is process admin" do
125
167
  let!(:user) { create :process_admin, :confirmed, participatory_process: }
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ def visit_resource
6
+ return visit resource if resource.is_a?(String)
7
+
8
+ return visit decidim.root_path if resource.is_a?(Decidim::Organization)
9
+
10
+ visit resource_locator(resource).path
11
+ end
12
+
13
+ shared_examples "a social share widget" do
14
+ it "has the social share button" do
15
+ visit_resource
16
+
17
+ expect(page).to have_css('button[data-dialog-open="socialShare"]')
18
+ end
19
+
20
+ it "lists all the expected social share providers" do
21
+ visit_resource
22
+ click_on "Share"
23
+
24
+ within "#socialShare" do
25
+ expect(page).to have_css('a[title="Share to X"]')
26
+ expect(page).to have_css('a[title="Share to Facebook"]')
27
+ expect(page).to have_css('a[title="Share to WhatsApp"]')
28
+ expect(page).to have_css('a[title="Share to Telegram"]')
29
+ expect(page).to have_css(".share-modal__input")
30
+ end
31
+ end
32
+ end
@@ -8,6 +8,7 @@ shared_examples "an uncommentable component" do
8
8
  manifest:,
9
9
  participatory_space:)
10
10
  end
11
+ let!(:comment) { create(:comment, commentable: resources.first) }
11
12
 
12
13
  it "does not displays comments count" do
13
14
  component.update!(settings: { comments_enabled: false })
@@ -18,4 +19,29 @@ shared_examples "an uncommentable component" do
18
19
  expect(page).to have_no_link(resource_locator(resource).path)
19
20
  end
20
21
  end
22
+
23
+ describe "when search a comment in the global search" do
24
+ it "does displays the comments" do
25
+ visit decidim.root_path
26
+
27
+ within ".main-bar__search" do
28
+ fill_in "term", with: comment.body["en"]
29
+ find("input#input-search").native.send_keys :enter
30
+ end
31
+
32
+ expect(page).to have_content("1 Results for the search")
33
+ end
34
+
35
+ it "does not displays the comment when comments are disable" do
36
+ component.update!(settings: { comments_enabled: false })
37
+ visit decidim.root_path
38
+
39
+ within ".main-bar__search" do
40
+ fill_in "term", with: comment.body["en"]
41
+ find("input#input-search").native.send_keys :enter
42
+ end
43
+
44
+ expect(page).to have_content("0 Results for the search")
45
+ end
46
+ end
21
47
  end
@@ -2,6 +2,32 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
+ shared_examples "a version of a hidden object" do
6
+ before do
7
+ visit resource_path
8
+ click_on "see other versions"
9
+ click_on("Version 1 of #{hidden_object.reload.versions.size}")
10
+ end
11
+
12
+ around do |example|
13
+ previous = Capybara.raise_server_errors
14
+
15
+ Capybara.raise_server_errors = false
16
+ example.run
17
+ Capybara.raise_server_errors = previous
18
+ end
19
+
20
+ it "shows an error page" do
21
+ expect(page).to have_content("Changes at")
22
+
23
+ create(:moderation, reportable: hidden_object, hidden_at: 1.day.ago)
24
+
25
+ visit current_path
26
+
27
+ expect(page).to have_content(ActiveRecord::RecordNotFound)
28
+ end
29
+ end
30
+
5
31
  shared_examples "versions controller" do
6
32
  let(:base_params) do
7
33
  if resource.is_a?(Decidim::Participable)
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-core version.
5
5
  module Core
6
6
  def self.version
7
- "0.29.2"
7
+ "0.29.3"
8
8
  end
9
9
  end
10
10
  end
@@ -49,46 +49,7 @@ module Decidim
49
49
  private
50
50
 
51
51
  def language_code
52
- primary = I18n.locale.to_s
53
- secondary = primary.split("-")[0]
54
- available_language_codes[primary] || available_language_codes[secondary] || ""
55
- end
56
-
57
- def available_language_codes
58
- @available_language_codes ||= {
59
- "ar" => "ara", # Arabic
60
- "eu" => "baq", # Basque
61
- "ca" => "cat", # Catalan
62
- "zh" => "chi", # Chinese (simplified)
63
- # "" => "cht", # Chinese (traditional)
64
- "cs" => "cze", # Czech
65
- "da" => "dan", # Danish
66
- "nl" => "dut", # Dutch
67
- "en" => "eng", # English
68
- "fi" => "fin", # Finnish
69
- "fr" => "fre", # French
70
- "de" => "ger", # German
71
- "ga" => "gle", # Gaelic
72
- "el" => "gre", # Greek
73
- "he" => "heb", # Hebrew
74
- "hi" => "hin", # Hindi
75
- "id" => "ind", # Indonesian
76
- "it" => "ita", # Italian
77
- "no" => "nor", # Norwegian
78
- "fa" => "per", # Persian
79
- "pl" => "pol", # Polish
80
- "pt" => "por", # Portuguese
81
- "ru" => "rus", # Russian
82
- "si" => "sin", # Sinhalese
83
- "es" => "spa", # Spanish
84
- "sv" => "swe", # Swedish
85
- "th" => "tha", # Thai
86
- "tr" => "tur", # Turkish
87
- "uk" => "ukr", # Ukrainian
88
- "ur" => "urd", # Urdu
89
- "vi" => "vie", # Vietnamese
90
- "cy" => "wel" # Welsh
91
- }
52
+ I18n.locale.to_s
92
53
  end
93
54
  end
94
55
  end
@@ -6,8 +6,42 @@ module Decidim
6
6
  module StaticMap
7
7
  # The static map utility class for the HERE maps service
8
8
  class Here < ::Decidim::Map::StaticMap
9
+ def url(latitude:, longitude:, options: {})
10
+ map_url = configuration.fetch(:url, nil)
11
+ return super unless map_url
12
+
13
+ return super unless map_url.include?("mia/v3")
14
+
15
+ w = options[:width] || Decidim::Map::StaticMap::DEFAULT_SIZE
16
+ h = options[:height] || Decidim::Map::StaticMap::DEFAULT_SIZE
17
+
18
+ params = {
19
+ apiKey: configuration[:api_key],
20
+ overlay: "point:#{latitude},#{longitude};icon=cp;size=large|#{latitude},#{longitude};style=circle;width=50m;color=%231B9D2C60"
21
+ }
22
+
23
+ URI.parse("#{map_url}:radius=90/#{w}x#{h}/png8").tap do |uri|
24
+ uri.query = URI.encode_www_form(params)
25
+ end.to_s
26
+ end
27
+
9
28
  # @See Decidim::Map::StaticMap#url_params
10
29
  def url_params(latitude:, longitude:, options: {})
30
+ ActiveSupport::Deprecation.warn(
31
+ <<~DEPRECATION.strip
32
+ Please use a V3 version HERE maps.
33
+ For further information, see:
34
+ https://www.here.com/docs/bundle/map-image-migration-guide-v3/page/README.html
35
+ Also make sure your Decidim.maps configurations are using the
36
+ up to date format.
37
+ You need to change:
38
+ static_url = "https://image.maps.ls.hereapi.com/mia/1.6/mapview" if static_provider == "here" && static_url.blank?
39
+ to:
40
+ static_url = "https://image.maps.hereapi.com/mia/v3/base/mc/overlay" if static_provider == "here"
41
+ in your config/initializers/decidim.rb file.
42
+ DEPRECATION
43
+ )
44
+
11
45
  params = {
12
46
  c: "#{latitude}, #{longitude}",
13
47
  z: options[:zoom] || Decidim::Map::StaticMap::DEFAULT_ZOOM,
@@ -59,9 +59,11 @@ module Decidim
59
59
  event_class: Decidim::ResourceHiddenEvent,
60
60
  resource: @reportable,
61
61
  extra: {
62
- report_reasons:
62
+ report_reasons:,
63
+ force_email: true
63
64
  },
64
- affected_users: @reportable.try(:authors) || [@reportable.try(:normalized_author)]
65
+ affected_users:,
66
+ force_send: true
65
67
  }
66
68
 
67
69
  Decidim::EventsManager.publish(**data)
@@ -80,10 +82,22 @@ module Decidim
80
82
  @reportable.moderation.update!(hidden_at: Time.current)
81
83
  @reportable.try(:touch)
82
84
  end
85
+
86
+ if @reportable.is_a?(Decidim::Comments::Commentable)
87
+ @reportable.comment_threads.each do |comment|
88
+ Decidim::HideChildResourcesJob.perform_later(comment, @current_user.id)
89
+ end
90
+ end
91
+
92
+ send_notification_to_author
83
93
  end
84
94
 
85
95
  private
86
96
 
97
+ def affected_users
98
+ @affected_users ||= (@reportable.try(:authors) || [@reportable.try(:author)]).select { |author| author.is_a?(Decidim::User) }
99
+ end
100
+
87
101
  def report_reasons
88
102
  @reportable.moderation.reports.pluck(:reason).uniq
89
103
  end
@@ -52,7 +52,7 @@ module Decidim
52
52
  candidate = name
53
53
 
54
54
  2.step do |n|
55
- return candidate if Decidim::UserBaseEntity.where("nickname ILIKE ?", candidate.downcase).where(scope).empty?
55
+ return candidate if Decidim::UserBaseEntity.where(nickname: candidate.downcase).where(scope).empty?
56
56
 
57
57
  candidate = numbered_variation_of(name, n)
58
58
  end
@@ -53,8 +53,12 @@ module Decidim
53
53
  # Public: The reported content url
54
54
  #
55
55
  # Returns String
56
- def reported_content_url
57
- raise NotImplementedError
56
+ def reported_content_url(options = {})
57
+ if hidden?
58
+ ResourceLocatorPresenter.new(self).index(options)
59
+ else
60
+ ResourceLocatorPresenter.new(self).url(options)
61
+ end
58
62
  end
59
63
 
60
64
  # Public: The collection of attribute names that are considered
@@ -62,7 +62,7 @@ module Decidim
62
62
  final = super(value)
63
63
  return unless final # Do not set the `nil` values for the parent hash
64
64
 
65
- final = value_type.serialize(final) if value_type
65
+ final = value_type.serialize(final) if value_type && !attachment?(final)
66
66
 
67
67
  public_send("#{name}=", field.merge(locale => final))
68
68
  end
@@ -127,5 +127,9 @@ module Decidim
127
127
  locale.to_s == try(:default_locale).to_s ||
128
128
  locale.to_s == try(:current_organization).try(:default_locale).to_s
129
129
  end
130
+
131
+ def attachment?(value)
132
+ value.is_a?(String) && value.include?(ActiveStorage.routes_prefix)
133
+ end
130
134
  end
131
135
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :decidim do
4
+ namespace :upgrade do
5
+ namespace :clean do
6
+ desc "Removes all related resources from hidden resource"
7
+ task hidden_resources: :environment do
8
+ logger.info("Removing child resources for hidden parents...")
9
+ Decidim::Moderation.hidden.find_each do |moderation_for_hidden_resource|
10
+ reportable = moderation_for_hidden_resource.reportable
11
+
12
+ current_user = if Decidim.module_installed?(:ai)
13
+ reportable.organization.users.find_by!(email: Decidim::Ai::SpamDetection.reporting_user_email)
14
+ else
15
+ reportable.organization.admins.first
16
+ end
17
+
18
+ tool = Decidim::ModerationTools.new(reportable, current_user)
19
+ tool.hide!
20
+ rescue NameError => e
21
+ log_error "Could not hide child resources for reportable id #{moderation_for_hidden_resource.id} because: #{e.message}"
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def log_error(msg)
28
+ puts msg
29
+ Rails.logger.error(msg)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -2,37 +2,40 @@
2
2
 
3
3
  namespace :decidim do
4
4
  namespace :upgrade do
5
- desc "Modifies nicknames with random numbers when exists similar ones case-insensitively"
6
- task fix_nickname_uniqueness: :environment do
7
- logger = Logger.new($stdout)
8
- logger.info("Updating conflicting user nicknames...")
5
+ desc "Modifies nickname of the user to lower case"
6
+ task :fix_nickname_casing => :environment do
7
+ logger.info("Fixing user nicknames case...")
9
8
 
10
- # list of users already changed in the process
11
9
  has_changed = []
10
+ Decidim::UserBaseEntity.not_deleted.find_each do |user|
11
+ user.nickname.downcase!
12
12
 
13
- Decidim::User.not_deleted.find_each do |user|
14
- next if has_changed.include? user.id
15
-
16
- Decidim::User.where(organization: user.organization)
17
- .where("nickname ILIKE ?", user.nickname.downcase)
18
- .where.not(id: has_changed + [user.id])
19
- .not_deleted
20
- .order(:created_at)
21
- .each do |similar_user|
22
- # change her nickname to the lowercased one with numbers if needed
23
- begin
24
- update_user_nickname(similar_user, Decidim::UserBaseEntity.nicknamize(similar_user.nickname, organization: similar_user.organization))
25
- rescue ActiveRecord::RecordInvalid => e
26
- logger.warn("User ID (#{similar_user.id}) : #{e}")
13
+ begin
14
+ if user.nickname_changed?
15
+ user.save!
16
+ has_changed << user.id
27
17
  end
28
- has_changed.append(similar_user.id)
18
+ rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
19
+ update_user_nickname(user, Decidim::UserBaseEntity.nicknamize(user.nickname, organization: user.organization))
20
+ has_changed << user.id
21
+ rescue ActiveRecord::RecordInvalid # rubocop:disable Lint/DuplicateRescueException
22
+ logger.warn("User ID (#{user.id}) : #{e}")
29
23
  end
30
24
  end
31
25
  logger.info("Process terminated, #{has_changed.count} users nickname have been updated.")
32
26
  end
33
27
 
28
+ desc "Modifies nicknames with random numbers when exists similar ones case-insensitively"
29
+ task :fix_nickname_uniqueness => :environment do
30
+ Rake::Task["decidim:upgrade:fix_nickname_casing"].execute
31
+ end
32
+
34
33
  private
35
34
 
35
+ def logger
36
+ @logger ||= Logger.new($stdout)
37
+ end
38
+
36
39
  def send_notification_to(user)
37
40
  Decidim::EventsManager.publish(
38
41
  event: "decidim.events.nickname_event",