locale.rb 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class Locale < ApplicationModel
  3. has_many :knowledge_base_locales, inverse_of: :system_locale, dependent: :restrict_with_error,
  4. class_name: 'KnowledgeBase::Locale', foreign_key: :system_locale_id
  5. =begin
  6. returns the records of all locales that are to be synchronized
  7. =end
  8. def self.to_sync
  9. # read used locales based on env, e. g. export Z_LOCALES='en-us:de-de'
  10. return Locale.where(active: true, locale: ENV['Z_LOCALES'].split(':')) if ENV['Z_LOCALES']
  11. return Locale.where(active: true, locale: %w[en-us de-de]) if Rails.env.test?
  12. Locale.where(active: true)
  13. end
  14. =begin
  15. sync locales from config/locales.yml
  16. =end
  17. def self.sync
  18. file = Rails.root.join('config/locales.yml')
  19. return false if !File.exist?(file)
  20. data = YAML.load_file(file)
  21. to_database(data)
  22. true
  23. end
  24. # Default system locale
  25. #
  26. # @example
  27. # Locale.default
  28. def self.default
  29. Setting.get('locale_default') || 'en-us'
  30. end
  31. private_class_method def self.to_database(data)
  32. ActiveRecord::Base.transaction do
  33. data.each do |locale|
  34. exists = Locale.find_by(locale: locale['locale'])
  35. if exists
  36. exists.update!(locale.symbolize_keys!)
  37. else
  38. Locale.create!(locale.symbolize_keys!)
  39. end
  40. end
  41. end
  42. end
  43. # Returns ICU language code for usage with TwitterCldr gem
  44. # Not all locales are supported, so nil can be returned as well!
  45. #
  46. # One-liner to filter which locales are not supported by said gem:
  47. #
  48. # Locale.all.select { |locale| !TwitterCldr.supported_locale? locale.language_code }
  49. def cldr_language_code
  50. case locale
  51. when 'es-ca' # Catalin, looks like it should be ca-es instead?
  52. 'ca'
  53. when 'sr-cyrl-rs'
  54. 'sr-Cyrl-ME'
  55. when 'sr-latn-rs'
  56. 'sr-Latn-ME'
  57. else
  58. split = locale.split('-')
  59. split.second&.upcase!
  60. joined = split.join('-')
  61. if TwitterCldr.supported_locale? joined
  62. joined
  63. elsif TwitterCldr.supported_locale? split.first
  64. split.first
  65. end
  66. end
  67. end
  68. # Returns Postgres database collation names
  69. #
  70. # One-liner to verify that locales exist on a given Postgres server:
  71. #
  72. # Locale.all.select { |locale| ApplicationModel.connection.execute("SELECT * FROM pg_collation WHERE collname = '#{locale.postgres_collation_name}';").none? }
  73. def postgres_collation_name
  74. case locale
  75. when 'es-ca' # Catalan, looks like it should be ca-es instead?
  76. 'ca-x-icu'
  77. when 'no-no' # Norwegian, nn vs no?
  78. 'nn-NO-x-icu'
  79. when 'zh-cn' # China uses simplified
  80. 'zh-Hans-x-icu'
  81. when 'zh-tw' # Taiwan uses traditional
  82. 'zh-Hant-x-icu'
  83. when 'sr-cyrl-rs'
  84. 'sr-Cyrl-ME-x-icu'
  85. when 'sr-latn-rs'
  86. 'sr-Latn-ME-x-icu'
  87. else
  88. split = locale.split('-')
  89. split.second&.upcase!
  90. "#{split.join('-')}-x-icu"
  91. end
  92. end
  93. end