161 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
--[[-------------------------------------------------------------------
 | 
						|
QBCore Framework
 | 
						|
Copyright (C) 2021 Joshua Eger
 | 
						|
 | 
						|
This program is free software: you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation, either version 3 of the License, or
 | 
						|
(at your option) any later version.
 | 
						|
 | 
						|
This program is distributed in the hope that it will be useful,
 | 
						|
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
GNU General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with this program.  If not, see <https://www.gnu.org/licenses/>
 | 
						|
-----------------------------------------------------------------------
 | 
						|
The code below and any function calls related to translation / locale 
 | 
						|
are licensed above with credit to copyright holder(s).
 | 
						|
Source: <https://github.com/qbcore-framework/>
 | 
						|
---------------------------------------------------------------------]]
 | 
						|
 | 
						|
--- @class Locale
 | 
						|
Locale = {}
 | 
						|
Locale.__index = Locale
 | 
						|
 | 
						|
local function translateKey(phrase, subs)
 | 
						|
    if type(phrase) ~= 'string' then
 | 
						|
        error('TypeError: translateKey function expects arg #1 to be a string')
 | 
						|
    end
 | 
						|
 | 
						|
    -- Substituions
 | 
						|
    if not subs then
 | 
						|
        return phrase
 | 
						|
    end
 | 
						|
 | 
						|
    -- We should be escaping gsub just in case of any
 | 
						|
    -- shenanigans with nested template patterns or injection
 | 
						|
 | 
						|
    -- Create and copy our return string
 | 
						|
    local result = phrase
 | 
						|
 | 
						|
    -- Initial Scan over result looking for substituions
 | 
						|
    for k, v in pairs(subs) do
 | 
						|
        local templateToFind = '%%{' .. k .. '}'
 | 
						|
        result = result:gsub(templateToFind, tostring(v)) -- string to allow all types
 | 
						|
    end
 | 
						|
 | 
						|
    return result
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
--- Constructor function for a new Locale class instance
 | 
						|
--- @param opts table<string, any> - Constructor opts param
 | 
						|
--- @return Locale
 | 
						|
function Locale:new(opts)
 | 
						|
    local self = {}
 | 
						|
    setmetatable(self, Locale)
 | 
						|
    self.warnOnMissing = opts.warnOnMissing or true
 | 
						|
 | 
						|
    self.phrases = {}
 | 
						|
    self:extend(opts.phrases or {})
 | 
						|
 | 
						|
    return self
 | 
						|
end
 | 
						|
 | 
						|
--- Method for extending an instances phrases map. This is also, used
 | 
						|
--- internally for initial population of phrases field.
 | 
						|
--- @param phrases table<string, string> - Table of phrase definitions
 | 
						|
--- @param prefix string | nil - Optional prefix used for recursive calls
 | 
						|
--- @return void
 | 
						|
function Locale:extend(phrases, prefix)
 | 
						|
    for key, phrase in pairs(phrases) do
 | 
						|
        local prefixKey = prefix and ('%s.%s'):format(prefix, key) or key
 | 
						|
        -- If this is a nested table, we need to go reeeeeeeeeeeecursive
 | 
						|
        if type(phrase) == 'table' then
 | 
						|
            self:extend(phrase, prefixKey)
 | 
						|
        else
 | 
						|
            self.phrases[prefixKey] = phrase
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
--- Clear locale instance phrases
 | 
						|
--- Might be useful for memory management of large phrase maps.
 | 
						|
--- @return void
 | 
						|
function Locale:clear()
 | 
						|
    self.phrases = {}
 | 
						|
end
 | 
						|
 | 
						|
--- Clears all phrases and replaces it with the passed phrases table
 | 
						|
--- @param phrases table<string, any>
 | 
						|
function Locale:replace(phrases)
 | 
						|
    phrases = phrases or {}
 | 
						|
    self.clear()
 | 
						|
    self.extend(phrases)
 | 
						|
end
 | 
						|
 | 
						|
--- Gets & Sets a locale depending on if an argument is passed
 | 
						|
--- @param newLocale string - Optional new locale to set
 | 
						|
--- @return string
 | 
						|
function Locale:locale(newLocale)
 | 
						|
    if (newLocale) then
 | 
						|
        self.currentLocale = newLocale
 | 
						|
    end
 | 
						|
    return self.currentLocale
 | 
						|
end
 | 
						|
 | 
						|
--- Primary translation method for a phrase of given key
 | 
						|
--- @param key string - The phrase key to target
 | 
						|
--- @param subs table<string, string>
 | 
						|
--- @return string
 | 
						|
function Locale:t(key, subs)
 | 
						|
    local phrase, result
 | 
						|
    subs = subs or {}
 | 
						|
 | 
						|
    -- See if the passed key resolves to a valid phrase string
 | 
						|
    if type(self.phrases[key]) == 'string' then
 | 
						|
        phrase = self.phrases[key]
 | 
						|
        -- At this point we know whether the phrase does not exist for this key
 | 
						|
    else
 | 
						|
        if self.warnOnMissing then
 | 
						|
            print(('^3Warning: Missing phrase for key: "%s"'):format(key))
 | 
						|
        end
 | 
						|
        result = key
 | 
						|
    end
 | 
						|
 | 
						|
    if type(phrase) == 'string' then
 | 
						|
        result = translateKey(phrase, subs)
 | 
						|
    end
 | 
						|
 | 
						|
    return result
 | 
						|
end
 | 
						|
 | 
						|
--- Check if a phrase key has already been defined within the Locale instance phrase maps.
 | 
						|
--- @return boolean
 | 
						|
function Locale:has(key)
 | 
						|
    return self.phrases[key] ~= nil
 | 
						|
end
 | 
						|
 | 
						|
--- Will remove phrase keys from a Locale instance, using recursion/
 | 
						|
--- @param phraseTarget string | table
 | 
						|
--- @param prefix string
 | 
						|
function Locale:delete(phraseTarget, prefix)
 | 
						|
    -- If the target is a string, we know that this is the end
 | 
						|
    -- of nested table tree.
 | 
						|
    if type(phraseTarget) == 'string' then
 | 
						|
        self.phrases[phraseTarget] = nil
 | 
						|
    else
 | 
						|
        for key, phrase in pairs(phraseTarget) do
 | 
						|
            local prefixKey = prefix and prefix .. '.' .. key or key
 | 
						|
 | 
						|
            if type(phrase) == 'table' then
 | 
						|
                self:delete(phrase, prefixKey)
 | 
						|
            else
 | 
						|
                self.phrases[prefixKey] = nil
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 |