Modul:Protection banner: Unterschied zwischen den Versionen
start converting the getCategoryName function
(expand the Image class) |
(start converting the getCategoryName function) |
||
Zeile 200: | Zeile 200: | ||
function Category:initialize() | function Category:initialize() | ||
end | |||
function Category:setName(name) | |||
self._name = name | |||
end | end | ||
Zeile 219: | Zeile 223: | ||
local ProtectionCategory = Category:subclass('ProtectionCategory') | local ProtectionCategory = Category:subclass('ProtectionCategory') | ||
function ProtectionCategory:setName(name, configObj, protectionStatusObj, namespace) | |||
--[[ | |||
-- Sets the protection category. If a category name is not provided, this | |||
-- method gets a category name from the module config, given a combination | |||
-- of the protection type, the protection level, the namespace number, the | |||
-- reason for protection, and the expiry date. | |||
--]] | |||
local cats = configObj:getConfigTable('categories') | |||
-- Get the namespace category key from the namespace number. | |||
local nskey | |||
do | |||
local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') | |||
if not namespace or type(namespace) ~= 'number' then | |||
nskey = nil | |||
else | |||
nskey = categoryNamespaces[ns] | |||
if not nskey and ns % 2 == 1 then | |||
nskey = 'talk' | |||
end | |||
end | |||
end | |||
--[[ | |||
-- Define the properties table. Each property is a table containing the | |||
-- canonical order that the property is tested in, the position the | |||
-- property has in the category key strings, and the property value itself. | |||
--]] | |||
local properties = { | |||
expiry = {order = 1, keypos = 5, val = expiry}, | |||
namespace = {order = 2, keypos = 3, val = nskey}, | |||
reason = {order = 3, keypos = 4, val = reason}, | |||
level = {order = 4, keypos = 2, val = level}, | |||
action = {order = 5, keypos = 1, val = action} | |||
} | |||
--[[ | |||
-- Load the category order configuration for the reason specified. | |||
-- The configuration is stored in the categoryOrder field of each reason | |||
-- subtable of cfg.reasons. If the value is a table, then the order is the | |||
-- values specified in the table. If the value is a string, then the | |||
-- property corresponding to that string is tested last (i.e. it is the most | |||
-- important, because it keeps its specified value the longest) and the | |||
-- other properties are tested in the canonical order. If the value is of | |||
-- any other type then the canonical order is used. | |||
--]] | |||
local reasonTable = reason and cfg.reasons[reason] | |||
local categoryOrder = reasonTable and reasonTable.categoryOrder | |||
local categoryOrderType = type(categoryOrder) | |||
local configOrder = {} | |||
if categoryOrderType == 'table' then | |||
local dupes = {} | |||
for i = 1, 5 do | |||
local propertiesKey = categoryOrder[i] | |||
if not propertiesKey then | |||
local msg = 'no entry found for key ' | |||
.. i | |||
.. ' in the cfg.reasons.' | |||
.. reason | |||
.. '.categoryOrder table' | |||
error(msg) | |||
end | |||
local property = properties[propertiesKey] | |||
if not property then | |||
local msg = 'invalid value "' | |||
.. propertiesKey | |||
.. '" detected in the cfg.reasons.' | |||
.. reason | |||
.. '.categoryOrder table' | |||
error(msg) | |||
end | |||
if dupes[propertiesKey] then | |||
local msg = 'duplicate values "' | |||
.. propertiesKey | |||
.. '" detected in the cfg.reasons.' | |||
.. reason | |||
.. '.categoryOrder table' | |||
error(msg) | |||
else | |||
dupes[propertiesKey] = true | |||
end | |||
configOrder[i] = property | |||
end | |||
else | |||
for propertiesKey, t in pairs(properties) do | |||
configOrder[t.order] = t | |||
end | |||
if categoryOrderType == 'string' then | |||
local property = properties[categoryOrder] | |||
if not property then | |||
local msg = '"' | |||
.. categoryOrder | |||
.. '" is not a valid value of cfg.reasons.' | |||
.. reason | |||
.. '.categoryOrder' | |||
error(msg) | |||
end | |||
toTableEnd(configOrder, property.order) | |||
end | |||
end | |||
--[[ | |||
-- Define the attempt order. Properties with no value defined are moved | |||
-- to the end, where they will later be given the value "all". This is | |||
-- to cut down on the number of table lookups in the cats table, which | |||
-- grows exponentially with the number of properties with valid values. | |||
-- We keep track of the number of active properties with the noActive | |||
-- parameter. | |||
--]] | |||
local active, inactive = {}, {} | |||
for i, t in ipairs(configOrder) do | |||
if t.val then | |||
active[#active + 1] = t | |||
else | |||
inactive[#inactive + 1] = t | |||
end | |||
end | |||
local noActive = #active | |||
local attemptOrder = active | |||
for i, t in ipairs(inactive) do | |||
attemptOrder[#attemptOrder + 1] = t | |||
end | |||
--[[ | |||
-- Check increasingly generic key combinations until we find a match. | |||
-- If a specific category exists for the combination of properties | |||
-- we are given, that match will be found first. If not, we keep | |||
-- trying different key combinations until we match using the key | |||
-- "all-all-all-all-all". | |||
-- | |||
-- To generate the keys, we index the property subtables using a | |||
-- binary matrix with indexes i and j. j is only calculated up to | |||
-- the number of active properties. For example, if there were three | |||
-- active properties, the matrix would look like this, with 0 | |||
-- corresponding to the string "all", and 1 corresponding to the | |||
-- val field in the property table: | |||
-- | |||
-- j 1 2 3 | |||
-- i | |||
-- 1 1 1 1 | |||
-- 2 0 1 1 | |||
-- 3 1 0 1 | |||
-- 4 0 0 1 | |||
-- 5 1 1 0 | |||
-- 6 0 1 0 | |||
-- 7 1 0 0 | |||
-- 8 0 0 0 | |||
-- | |||
-- Values of j higher than the number of active properties are set | |||
-- to the string "all". | |||
-- | |||
-- A key for the category table is constructed for each value of i. | |||
-- The correct position of the value in the key is determined by the | |||
-- pos field in the property table. | |||
--]] | |||
for i = 1, 2^noActive do | |||
local key = {} | |||
for j, t in ipairs(attemptOrder) do | |||
if j > noActive then | |||
key[t.keypos] = 'all' | |||
else | |||
local quotient = i / 2 ^ (j - 1) | |||
quotient = math.ceil(quotient) | |||
if quotient % 2 == 1 then | |||
key[t.keypos] = t.val | |||
else | |||
key[t.keypos] = 'all' | |||
end | |||
end | |||
end | |||
key = table.concat(key, '-') | |||
local attempt = cats[key] | |||
if attempt then | |||
return attempt | |||
end | |||
end | |||
error( | |||
'No category match found;' | |||
.. ' please define the category for key "all-all-all-all-all"' | |||
) | |||
end | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |