# -*- encoding : utf-8 -*- require 'phrase/delegate' class Phrase::Backend::PhraseService attr_accessor :api_client, :blacklisted_keys def initialize(args = {}) self end def translate(*args) key = lookup_normalized_key(*args) if Phrase.disabled? or key_is_blacklisted?(key[:key]) I18n.translate_without_phrase(*args) else phrase_delegate_for(key[:key], *args) end end protected def key_is_blacklisted?(key) blacklisted_keys.each do |blacklisted_key| if key.to_s[/\A#{blacklisted_key.gsub("*", ".*")}\Z/].present? return true end end false end def blacklisted_keys @blacklisted_keys ||= api_client.fetch_blacklisted_keys end def api_client @api_client ||= Phrase::Api::Client.new(Phrase.auth_token) end def phrase_delegate_for(key=nil, *args) return nil unless key.present? options = args[1].nil? ? {} : args[1] Phrase::Delegate.new(key, options) end def lookup_normalized_key(*args) caller = identify_caller duped_args = args.map { |item| item.is_a?(Symbol) ? item : item.dup } if caller && duped_args.first =~ /^\./ duped_args = transform_args_for_caller(caller, *duped_args) end new_args = split_args(*duped_args) normalized_key = I18n::Backend::Flatten.normalize_flat_keys(*new_args) normalized_key.gsub!("..", ".") {:key => normalized_key} end def identify_caller caller = nil send(:caller)[0..6].each do |string| caller = match_caller(string) unless caller end if caller && caller.present? find_lookup_scope(caller) else nil end end def match_caller(string) string.match(/(views)(\/.+)(?>:[0-9]+:in)/) end def split_args(*args) options = args.last.is_a?(Hash) ? args.pop : {} key ||= args.shift locale = options.delete(:locale) || I18n.locale return [locale, key, options[:scope], nil] end def transform_args_for_caller(caller, *args) _scope = caller options = args.last.is_a?(Hash) ? args.pop : {} if !options[:scope].presence && _scope.presence options[:scope] = _scope end args.push(options) parts = args.first.to_s.split(".").select { |e| !e.blank? } args[0] = parts[0] if parts.size == 1 return args end def find_lookup_scope(caller) split_path = caller[2][1..-1].split(".")[0].split("/") template_or_partial = remove_underscore_form_partial(split_path[-1]) split_path[-1] = template_or_partial split_path.map!(&:to_sym) end def remove_underscore_form_partial(template_or_partial) if template_or_partial.to_s[0,1] == "_" template_or_partial.to_s[1..-1] else template_or_partial.to_s end end end