Mô đun:Protected edit request/active

require('strict')

local yesno, makeMessageBox -- passed in from Mô đun:Protected edit request
local makeToolbar = require('Mô đun:Toolbar')._main
local getPagetype = require('Mô đun:Pagetype')._main
local effectiveProtectionLevel = require('Mô đun:Effective protection level')._main

----------------------------------------------------------------------
-- Helper functions
----------------------------------------------------------------------

local function makeWikilink(page, display)
if display then
return mw.ustring.format('%s', page, display)
else
return mw.ustring.format('%s', page)
end
end

----------------------------------------------------------------------
-- Title class
----------------------------------------------------------------------

-- This is basically the mw.title class with some extras thrown in.

local title = {}
title.__index = title

function title.getProtectionLevelText(protectionLevel)
-- Gets the text to use in anchors and urn links.
local levels = {unprotected = 'editunprotected', autoconfirmed = 'editsemiprotected', extendedconfirmed = 'editextendedprotected', templateeditor = 'edittemplateprotected', autopatrolled = 'editautopatrolprotected', sysop = 'editprotected', interfaceadmin = 'editinterfaceprotected'}
return levels[protectionLevel]
end

function title.new(...)
local success, obj = pcall(mw.title.new, ...)
if not (success and obj) then return end

-- Add a protectionLevel property.
obj.protectionLevel = effectiveProtectionLevel(obj.exists and 'edit' or 'create', obj)
if obj.protectionLevel == '' then
-- Make unprotected pages return "unprotected".
obj.protectionLevel = 'unprotected'
elseif obj.protectionLevel == 'user' then
-- If we just need to be registered, pretend we need to be autoconfirmed, since it's the closest thing we have.
obj.protectionLevel = 'autoconfirmed'
end

-- Add a pagetype property.
obj.pagetype = getPagetype{page = obj.prefixedText, defaultns = 'all'}

-- Add link-making methods.
function obj:makeUrlLink(query, display)
return mw.ustring.format('[%s %s]', self:fullUrl(query), display)
end

function obj:makeViewLink(display)
return self:makeUrlLink({redirect = 'no'}, display)
end

function obj:makeEditLink(display)
return self:makeUrlLink({action = 'edit'}, display)
end

function obj:makeHistoryLink(display)
return self:makeUrlLink({action = 'history'}, display)
end

function obj:makeLastEditLink(display)
return self:makeUrlLink({diff = 'cur', oldid = 'prev'}, display)
end

function obj:makeWhatLinksHereLink(display)
return makeWikilink('Đặc biệt:Liên kết đến đây/' .. self.prefixedText, display)
end

function obj:makeCompareLink(otherTitle, display)
display = display or 'diff'
local comparePagesTitle = title.new('Đặc biệt:So sánh trang')
return comparePagesTitle:makeUrlLink({page1 = self.prefixedText, page2 = otherTitle.prefixedText}, display)
end

function obj:makeLogLink(logType, display)
local logTitle = title.new('Đặc biệt:Nhật trình')
return logTitle:makeUrlLink({type = logType, page = self.prefixedText}, display)
end

function obj:urlEncode()
return mw.uri.encode(self.prefixedText, 'WIKI')
end

function obj:makeUrnLink(boxProtectionLevel)
-- Outputs a urn link. The protection level is taken from the template, rather than detected from page itself,
-- as the detection may be inaccurate for cascade-protected and title-blacklisted pages as of Nov 2013.
local protectionLinkText = title.getProtectionLevelText(boxProtectionLevel)
return mw.ustring.format('[urn:x-wp-%s:%s ]', protectionLinkText, self:urlEncode())
end

-- Get a subpage title object, but go through pcall rather than use the unprotected mw.title:subPageTitle.
function obj:getSubpageTitle(subpage)
return title.new(self.prefixedText .. '/' .. subpage)
end

return obj
end

----------------------------------------------------------------------
-- TitleTable class
----------------------------------------------------------------------

local titleTable = {}
titleTable.__index = titleTable

function titleTable.new(args)
-- Get numerical arguments and make title objects for each of them.
local nums = {}
for k, v in pairs(args) do
if type(k) == 'number' then
table.insert(nums, k)
end
end
table.sort(nums)
local titles = {}
for _, num in ipairs(nums) do
local title = title.new(args[num])
table.insert(titles, title)
end
-- Get the current title, and get the subject title if no titles were specified.
titles.currentTitle = mw.title.getCurrentTitle()
if titles %s%s%s%s', pipe, name, equals, val)
end

function blurb.makeTemplateLink(s)
return mw.ustring.format('%s%s%s', mw.text.nowiki())
end

function blurb:makeProtectionText()
local boxProtectionLevel = self.boxProtectionLevel
local levels = {[''] = 'không bị khóa', autoconfirmed = 'bán khóa', extendedconfirmed = 'khóa xác nhận mở rộng', templateeditor = 'khóa bản mẫu', sysop = 'khóa hoàn toàn', interfaceadmin = 'khóa giao diện'}
for level, protectionText in pairs(levels) do
if level == boxProtectionLevel then
return mw.ustring.format('%s', protectionText)
end
end
error('Mức khóa không rõ ' .. boxProtectionLevel)
end

function blurb.getPagetypePlural(title)
local pagetype = title.pagetype
if pagetype == 'category' then
return 'categories'
else
return pagetype .. 's'
end
end

-- Normal methods --

function blurb:makeLinkList(title)
local tbargs = {} -- The argument list to pass to Mô đun:Toolbar
tbargs.style = 'font-size: smaller;'
tbargs.separator = 'dot'
-- Page links.
table.insert(tbargs, title:makeEditLink('sửa'))
table.insert(tbargs, title:makeHistoryLink('lịch sử'))
table.insert(tbargs, title:makeLastEditLink('cuối'))
table.insert(tbargs, title:makeWhatLinksHereLink('liên kết'))
-- Sandbox links.
local sandboxTitle = title:getSubpageTitle('sandbox')
if sandboxTitle and sandboxTitle.exists then
table.insert(tbargs, sandboxTitle:makeViewLink('chỗ thử'))
table.insert(tbargs, sandboxTitle:makeEditLink('sửa chỗ thử'))
table.insert(tbargs, sandboxTitle:makeHistoryLink('lịch sử chỗ thử'))
table.insert(tbargs, sandboxTitle:makeLastEditLink('thay đổi chỗ thử cuối cùng'))
table.insert(tbargs, title:makeCompareLink(sandboxTitle, 'khác biệt chỗ thử'))
end
-- Test cases links.
local testcasesTitle = title:getSubpageTitle('testcases')
if testcasesTitle and testcasesTitle.exists then
table.insert(tbargs, testcasesTitle:makeViewLink('các ca kiểm thử'))
end
-- Transclusion count link.
if title.namespace 10 or title.namespace 828 then -- Only add the transclusion count link for templates and modules.
local tclink = mw.uri.new{
host = 'tools.wmflabs.org',
path = '/templatecount/index.php',
query = {
lang = 'vi',
name = title.text,
namespace = title.namespace,
},
fragment = 'bottom'
}
tclink = string.format('[%s số lần nhúng]', tostring(tclink))
table.insert(tbargs, tclink)
end
-- Protection log link.
if title.namespace ~= 8 then -- MediaWiki pages don't have protection log entries.
table.insert(tbargs, title:makeLogLink('protect', 'nhật trình khóa'))
end
self.linkCount = self.linkCount + tbargs -- Keep track of the number of total links created by the object.
return makeToolbar(tbargs)
end

function blurb:makeLinkLists()
local titles = self.titles
if titles == 1 then
return self:makeLinkList(titles[1])
else
local ret = {}
table.insert(ret, )
for i, titleObj in ipairs(titles) do
table.insert(ret, mw.ustring.format('%s %s', titleObj:makeViewLink(titleObj.prefixedText), self:makeLinkList(titleObj)))
end
table.insert(ret, )
return table.concat(ret)
end
end

function blurb:makeIntro()
local titles = self.titles
local requested = 'Có yêu cầu'
local protectionText
if titles:hasNonInterfacePage() then
protectionText = ' ' .. self:makeProtectionText()
else
protectionText = -- Interface pages cannot be unprotected, so we don't need to explicitly say they are protected.
end
-- Deal with cases where we are passed multiple titles.
if titles > 1 then
local pagetype
if titles:hasSamePagetype() then
pagetype = blurb.getPagetypePlural(titles[1])
else
pagetype = 'trang'
end
return mw.ustring.format("%s muốn sửa các %s%s:", requested, pagetype, protectionText)
end
-- Deal with cases where we are passed only one title.
local title = titles[1]
local stringToFormat
if title.exists then
stringToFormat = '%s muốn sửa %s%s %s.'
else
stringToFormat = '%s tạo %s%s %s.'
end
stringToFormat = "" .. stringToFormat .. ""
return mw.ustring.format(stringToFormat, requested, title.pagetype, protectionText, title:makeViewLink(title.prefixedText))
end

function blurb:makeBody()
local titles = self.titles
local protectionLevels = titles:getProtectionLevels()
local boxProtectionLevel = self.boxProtectionLevel
local hasNonInterfacePage = titles:hasNonInterfacePage()
local isPlural = false
if titles > 1 then
isPlural = true
end

local descriptionText = "Vui lòng trình bày thật rõ ràng, cụ thể và dễ hiểu "
if boxProtectionLevel 'sysop' or boxProtectionLevel 'templateeditor' then
local editText = 'sửa đổi'
if isPlural then
editText = 'các' .. editText
end
local descriptionCompleteText = mw.ustring.format('để cả những người chưa quen vấn đề cũng có thể thực hiện %s được yêu cầu.', editText)
descriptionText = descriptionText .. descriptionCompleteText
else
descriptionText = descriptionText .. 'tức phải ghi rõ nội dung cũ và nội dung mới. '
.. "Phải theo hình thức "nhờ sửa X thành Y". Hay nói cách khác, nếu chỉ ghi chung chung "nhờ sửa x" sẽ không được chấp nhận".
end

local smallText =
if boxProtectionLevel 'sysop' or boxProtectionLevel 'templateeditor' then
local templateFullText
if boxProtectionLevel == 'sysop' then
templateFullText = 'hẳn'
elseif boxProtectionLevel == 'templateeditor' then
templateFullText = 'bản mẫu'
end
smallText = 'Chỉ dùng bản mẫu này để yêu cầu tại trang ' .. templateFullText .. " để thực hiện các sửa đổi không gây tranh cãi hoặc đã đạt được đồng thuận."
.. " Nếu sửa đổi đó có thể gây tranh cãi, hãy thảo luận trước tại trang thảo luận của trang bị khóa rồi mới sử dụng bản mẫu này."
else
local userText
local responseTemplate
if boxProtectionLevel == 'extendedconfirmed' then
userText = 'Thành viên được xác nhận mở rộng'
responseTemplate = blurb.makeTemplateLink('EEp')
elseif boxProtectionLevel == 'autoconfirmed' then
userText = 'Thành viên tự động xác nhận'
responseTemplate = blurb.makeTemplateLink('ESp')
elseif boxProtectionLevel == 'interfaceadmin' then
userText = 'Bảo quản viên giao diện'
responseTemplate = blurb.makeTemplateLink('EIp')
else
userText = 'thành viên'
responseTemplate = blurb.makeTemplateLink('ESp')
end
local answeredPara = blurb.makeParaText('xong', 'chưa')
local stringToFormat = 'Bất kỳ %s nào có thể thực hiện sửa đổi. '
.. Hãy nhớ đổi tham số %s thành “xong” nếu chấp nhận hay chờ người yêu cầu cho thêm chi tiết, hoặc đổi thành “từ chối” nếu từ chối yêu cầu.
.. "Tham số này giúp chúng ta dọn dẹp thể loại yêu cầu sửa trang. "
.. 'Bạn cũng có thể sử dụng bản mẫu %s trong các phản ứng.'
smallText = mw.ustring.format(stringToFormat, userText, answeredPara, blurb.makeTemplateLink('ESp'))
end
if hasNonInterfacePage then
smallText = smallText .. ' Bạn cũng có thể yêu cầu khóa hay mở khóa.'
end
if boxProtectionLevel 'sysop' or boxProtectionLevel 'templateeditor' then
smallText = smallText .. ' Sau khi thực hiện hoặc từ chối, hãy thêm tham số ' .. blurb.makeParaText('xong', 'xong') .. ' để tắt bản mẫu.'
end
return mw.ustring.format('%s\n\n%s\n', descriptionText, smallText)
end

function blurb:export()
local intro = self:makeIntro()
local linkLists = self:makeLinkLists()
local body = self:makeBody()
-- Start long links lists on a new line.
local linkListSep = ' '
if self.linkCount > 5 then
linkListSep =
end
return mw.ustring.format('%s%s%s\n\n%s', intro, linkListSep, linkLists, body)
end

----------------------------------------------------------------------
-- Subclass of Mô đun:Protected edit request's box class for active boxes
----------------------------------------------------------------------

local box = {}
box.__index = box

function box.new(protectionType, args)
-- In the inheritance system used here, an object's metatable is its class, and a class's metatable is its superclass
local obj = getmetatable(box).new(protectionType, args)
setmetatable(obj, box)
local boxProtectionLevels = {semi = 'autoconfirmed', extended = 'extendedconfirmed', template = 'templateeditor', interface = 'interfaceadmin', full = 'sysop'}
obj.boxProtectionLevel = boxProtectionLevels[protectionType]
obj.demo = yesno(args.demo)
-- Set dependent objects.
obj.titles = titleTable.new(args)
if not yesno(args.force) and obj.titles:hasSameProperty('sameProtectionStatus', function (title) return title.protectionLevel end) and obj.titles[1].protectionLevel ~= 'unprotected' then
obj.boxProtectionLevel = obj.titles[1].protectionLevel
end
obj.blurb = blurb.new(obj.titles, obj.boxProtectionLevel)
return obj
end

function box:setImage()
local titles = self.titles
local boxProtectionLevel = self.boxProtectionLevel
local padlock
if boxProtectionLevel == 'sysop' then
padlock = 'Full-protection-shackle-block.svg'
elseif boxProtectionLevel == 'interfaceadmin' then
padlock = 'Interface-protection-shackle-keyhole.svg '
elseif boxProtectionLevel == 'templateeditor' then
padlock = 'Template-protection-shackle-brace-FF0066.svg'
elseif boxProtectionLevel == 'autoconfirmed' then
padlock = 'Semi-protection-shackle.svg'
elseif boxProtectionLevel == 'extendedconfirmed' then
padlock = 'Extended-protection-shackle-check-mark.svg'
else
padlock = 'Padlock-bronze-open.svg'
end
local stringToFormat =
local smallPadlock = mw.ustring.format(stringToFormat, padlock, 25)
local largePadlock = mw.ustring.format(stringToFormat, padlock, 60)
self:setArg('smallimage', smallPadlock)
self:setArg('image', largePadlock)
end

function box:buildUrnLinks()
local ret = {}
local boxProtectionLevel = self.boxProtectionLevel
for titleObj in self.titles:titleIterator() do
table.insert(ret, titleObj:makeUrnLink(boxProtectionLevel))
end
return mw.ustring.format('%s', table.concat(ret))
end

function box:setBlurbText()
self:setArg('text', self.blurb:export() .. self:buildUrnLinks())
end

function box:exportRequestTmbox()
self:setImage()
self:setBlurbText()
self:setArg('class', 'editrequest')
self:setArg('id', title.getProtectionLevelText(self.boxProtectionLevel)) -- for anchor. yes, this leads to multiple elements with the same ID. we should probably fix this at some point
return makeMessageBox('tmbox', self.tmboxArgs)
end

function box:exportRequestCategories()
local cats = {}
local boxProtectionLevel = self.boxProtectionLevel
local function addCat(cat)
table.insert(cats, mw.ustring.format(, cat))
end
local protectionCats = {
autoconfirmed = 'Yêu cầu sửa đổi trang bị bán khóa',
extendedconfirmed = 'Yêu cầu sửa đổi trang bị khóa mở rộng',
templateeditor = 'Yêu cầu sửa đổi trang bị khóa bản mẫu',
sysop = 'Yêu cầu sửa đổi trang bị khóa hẳn',
interfaceadmin = 'Yêu cầu sửa đổi trang bị khóa giao diện'
}
addCat(protectionCats[boxProtectionLevel])
if self.titles:hasOtherProtectionLevel(boxProtectionLevel) then
addCat('Yêu cầu sửa đổi trang có thể dùng bản mẫu sai')
end
return table.concat(cats)
end

function box:export()
if not self.titles.currentTitle.isTalkPage and not self.demo then
return 'Lỗi: Chỉ có thể yêu cầu sửa đổi trang bị khóa trên trang thảo luận.'
end
local ret = {}
table.insert(ret, self:exportRequestTmbox())
if not self.demo then
table.insert(ret, self:exportRequestCategories())
end
return table.concat(ret)
end

----------------------------------------------------------------------
-- Function exported to Mô đun:Protected edit request
----------------------------------------------------------------------

return function(superclass, yn, mb)
yesno = yn
makeMessageBox = mb
return setmetatable(box, superclass)
end