-- The position of the value in the key is determined by the keypos field in
-- each subtable.
---
local cats = cfg.protectionCategories
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 makeCategoryLink(attempt, title.text)
end
end
return ''
end  
function Protection:isIncorrect
local expiry = self.expiry
return not self:shouldHaveProtectionCategory
or type(expiry) == 'number' and expiry < os.time
end  
function Protection:isTemplateProtectedNonTemplate
local action, namespace = self.action, self.title.namespace
return self.level == 'templateeditor'
and (
(action ~= 'edit' and action ~= 'move')
or (namespace ~= 10 and namespace ~= 828)
end  
function Protection:makeCategoryLinks
local msg = self._cfg.msg
local ret = {self:makeProtectionCategory}
if self:isIncorrect then
ret[#ret + 1] = makeCategoryLink(
msg['tracking-category-incorrect'],
self.title.text
end
if self:isTemplateProtectedNonTemplate then
ret[#ret + 1] = makeCategoryLink(
msg['tracking-category-template'],
self.title.text
end
return table.concat(ret)
end  
---
-- Blurb class
---  
local Blurb = {}
Blurb.__index = Blurb  
Blurb.bannerTextFields = {
text = true,
explanation = true,
tooltip = true,
alt = true,
link = true
}  
function Blurb.new(protectionObj, args, cfg)
return setmetatable({
_cfg = cfg,
_protectionObj = protectionObj,
_args = args
}, Blurb)
end  
-- Private methods --  
function Blurb:_formatDate(num)
-- Formats a Unix timestamp into dd Month, YYYY format.
lang = lang or mw.language.getContentLanguage
local success, date = pcall(
lang.formatDate,
lang,
self._cfg.msg['expiry-date-format'] or 'j F Y',
'@' .. tostring(num)
if success then
return date
end
end  
function Blurb:_getExpandedMessage(msgKey)
return self:_substituteParameters(self._cfg.msg[msgKey])
end  
function Blurb:_substituteParameters(msg)
if not self._params then
local parameterFuncs = {}  
parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter
parameterFuncs.EDITREQUEST = self._makeEditRequestParameter
parameterFuncs.EXPIRY = self._makeExpiryParameter
parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter
parameterFuncs.IMAGELINK = self._makeImageLinkParameter
parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter
parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter
parameterFuncs.PAGETYPE = self._makePagetypeParameter
parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter
parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter
parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter
parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter
parameterFuncs.TALKPAGE = self._makeTalkPageParameter
parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter
parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter
parameterFuncs.VANDAL = self._makeVandalTemplateParameter  
self._params = setmetatable({}, {
__index = function (t, k)
local param
if parameterFuncs[k] then
param = parameterFuncs[k](self)
end
param = param or ''
t[k] = param
return param
end
})
end  
msg = msg:gsub('${(%u+)}', self._params)
return msg
end  
function Blurb:_makeCurrentVersionParameter
-- A link to the page history or the move log, depending on the kind of
-- protection.
local pagename = self._protectionObj.title.prefixedText
if self._protectionObj.action == 'move' then
-- We need the move log link.
return makeFullUrl(
'Special:Log',
{type = 'move', page = pagename},
self:_getExpandedMessage('current-version-move-display')
else
-- We need the history link.
return makeFullUrl(
pagename,
{action = 'history'},
self:_getExpandedMessage('current-version-edit-display')
end
end  
function Blurb:_makeEditRequestParameter
local mEditRequest = require('Module:Submit an edit request')
local action = self._protectionObj.action
local level = self._protectionObj.level  
-- Get the edit request type.
local requestType
if action == 'edit' then
if level == 'autoconfirmed' then
requestType = 'semi'
elseif level == 'extendedconfirmed' then
requestType = 'extended'
elseif level == 'templateeditor' then
requestType = 'template'
end
end
requestType = requestType or 'full'  
-- Get the display value.
local display = self:_getExpandedMessage('edit-request-display')  
return mEditRequest._link{type = requestType, display = display}
end  
function Blurb:_makeExpiryParameter
local expiry = self._protectionObj.expiry
if type(expiry) == 'number' then
return self:_formatDate(expiry)
else
return expiry
end
end  
function Blurb:_makeExplanationBlurbParameter
-- Cover special cases first.
if self._protectionObj.title.namespace == 8 then
-- MediaWiki namespace
return self:_getExpandedMessage('explanation-blurb-nounprotect')
end  
-- Get explanation blurb table keys
local action = self._protectionObj.action
local level = self._protectionObj.level
local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject'  
-- Find the message in the explanation blurb table and substitute any
-- parameters.
local explanations = self._cfg.explanationBlurbs
local msg
if explanations[action][level] and explanations[action][level][talkKey] then
msg = explanations[action][level][talkKey]
elseif explanations[action][level] and explanations[action][level].default then
msg = explanations[action][level].default
elseif explanations[action].default and explanations[action].default[talkKey] then
msg = explanations[action].default[talkKey]
elseif explanations[action].default and explanations[action].default.default then
msg = explanations[action].default.default
else
error(string.format(
'could not find explanation blurb for action "%s", level "%s" and talk key "%s"',
action,
level,
talkKey
), 8)
end
return self:_substituteParameters(msg)
end  
function Blurb:_makeImageLinkParameter
local imageLinks = self._cfg.imageLinks
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if imageLinks[action][level] then
msg = imageLinks[action][level]
elseif imageLinks[action].default then
msg = imageLinks[action].default
else
msg = imageLinks.edit.default
end
return self:_substituteParameters(msg)
end  
function Blurb:_makeIntroBlurbParameter
if self._protectionObj:isTemporary then
return self:_getExpandedMessage('intro-blurb-expiry')
else
return self:_getExpandedMessage('intro-blurb-noexpiry')
end
end  
function Blurb:_makeIntroFragmentParameter
if self._protectionObj:isTemporary then
return self:_getExpandedMessage('intro-fragment-expiry')
else
return self:_getExpandedMessage('intro-fragment-noexpiry')
end
end  
function Blurb:_makePagetypeParameter
local pagetypes = self._cfg.pagetypes
return pagetypes[self._protectionObj.title.namespace]
or pagetypes.default
or error('no default pagetype defined', 8)
end  
function Blurb:_makeProtectionBlurbParameter
local protectionBlurbs = self._cfg.protectionBlurbs
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if protectionBlurbs[action][level] then
msg = protectionBlurbs[action][level]
elseif protectionBlurbs[action].default then
msg = protectionBlurbs[action].default
elseif protectionBlurbs.edit.default then
msg = protectionBlurbs.edit.default
else
error('no protection blurb defined for protectionBlurbs.edit.default', 8)
end
return self:_substituteParameters(msg)
end  
function Blurb:_makeProtectionDateParameter
local protectionDate = self._protectionObj.protectionDate
if type(protectionDate) == 'number' then
return self:_formatDate(protectionDate)
else
return protectionDate
end
end  
function Blurb:_makeProtectionLevelParameter
local protectionLevels = self._cfg.protectionLevels
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg