-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathloader.rb
115 lines (100 loc) · 3.77 KB
/
loader.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# frozen_string_literal: true
module Decidim
module TermCustomizer
# The loader class is a middleman that converts the Translation model
# objects to a flat translation hash that can be directly used in the i18n
# backend. The main purpose of this class is to add caching possibility for
# the translation hashes.
class Loader
def initialize(resolver)
@resolver = resolver
end
# Converts the translation objects to a flat hash where the keys are
# the translatable keys used in the i18n backend containing the locales.
# The values of the hash are the translations for the keys.
#
# The final hash looks similar like this:
# {
# en: {
# decidim: {
# translation: "Term EN"
# }
# },
# fi: {
# decidim: {
# translation: "Term FI"
# }
# }
# }
#
# This will also cache the results and fetch the result directly from
# cache on consequent calls until the cache is expired.
def translations_hash
# In order to avoid endless loops with cache logging calling the I18n
# calling the translation loader, calling cache logging calling I18n
# (etc.), temporarily mute the cache logging during this call. If the
# cache logging level is set to `Logger::DEBUG`, it could happen as
# explained at:
# https://github.com/mainio/decidim-module-term_customizer/issues/38
@translations_hash ||= Rails.cache.mute do
Rails.cache.fetch(cache_key, expires_in: 24.hours) do
final_hash = {}
resolver.translations.each do |tr|
keyparts = [tr.locale] + tr.key.split(".")
lastkey = keyparts.pop.to_sym
current = final_hash
keyparts.each do |key|
current[key.to_sym] ||= {}
current = current[key.to_sym]
end
current[lastkey] = tr.value
end
final_hash
end
end
end
# Clears the translations cache only for the current context defined by
# the resolver.
def clear_cache
Rails.cache.delete_matched("#{cache_key_base}/*")
rescue NotImplementedError, NoMethodError
# Some cache store, such as `ActiveSupport::Cache::MemCacheStore` or
# `ActiveSupport::Cache::DalliStore` do not support `delete_matched`.
# Therefore, clear all the possibly existing
# cache keys manually for each space and component.
# Clear all the "organization" translation keys.
Rails.cache.delete(cache_key_base)
# Iterate over the participatory spaces and their components to manually
# clear the cached records for all of them.
Decidim.participatory_space_registry.manifests.each do |manifest|
manifest.model_class_name.constantize.all.each do |space|
Rails.cache.delete("#{cache_key_base}/space_#{space.id}")
next unless space.respond_to?(:components)
space.components.each do |component|
Rails.cache.delete(
"#{cache_key_base}/space_#{space.id}/component_#{component.id}"
)
end
end
end
end
private
attr_reader :resolver
def cache_key
parts = [cache_key_base]
parts << "space_#{resolver.space.id}" if resolver.space
parts << "component_#{resolver.component.id}" if resolver.component
parts.join("/")
end
def cache_key_base
main_key =
if resolver.organization
"organization_#{resolver.organization.id}"
else
"system"
end
"decidim_term_customizer/#{main_key}"
end
end
end
end