모듈:Protected edit request/active

require('strict')
local yesno, makeMessageBox -- passed in from Module:Protected edit request
local makeToolbar = require('Module:Toolbar')._main
local getPagetype = require('Module:Pagetype')._main
local effectiveProtectionLevel = require('Module: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', sysop = 'editprotected', interfaceadmin = 'editinterfaceprotected'}
	return levelsprotectionLevel
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('Special:WhatLinksHere/' .. self.prefixedText, display)
	end
	function obj:makeCompareLink(otherTitle, display)
		display = display or 'diff'
		local comparePagesTitle = title.new('Special:ComparePages')
		return comparePagesTitle:makeUrlLink({page1 = self.prefixedText, page2 = otherTitle.prefixedText}, display)
	end
	function obj:makeLogLink(logType, display)
		local logTitle = title.new('Special:Log')
		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(argsnum)
		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 = {'*' = 'unprotected', autoconfirmed = 'semi-protected', extendedconfirmed = 'extended-confirmed-protected', templateeditor = 'template-protected', sysop = 'fully protected', interfaceadmin = 'interface-protected'}
	for level, protectionText in pairs(levels) do
		if level == boxProtectionLevel then
			return mw.ustring.format('%s', protectionText)
		end
	end
	error('알 수 없는 보호 수준: ' .. 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 Module:Toolbar
	tbargs.style = 'font-size: smaller;'
	tbargs.separator = 'dot'
	-- Page links.
	table.insert(tbargs, title:makeEditLink('edit'))
	table.insert(tbargs, title:makeHistoryLink('history'))
	table.insert(tbargs, title:makeLastEditLink('last'))
	table.insert(tbargs, title:makeWhatLinksHereLink('links'))
	-- Sandbox links.
	local sandboxTitle = title:getSubpageTitle('연습장')
	if sandboxTitle and sandboxTitle.exists then
		table.insert(tbargs, sandboxTitle:makeViewLink('sandbox'))
		table.insert(tbargs, sandboxTitle:makeEditLink('edit sandbox'))
		table.insert(tbargs, sandboxTitle:makeHistoryLink('sandbox history'))
		table.insert(tbargs, sandboxTitle:makeLastEditLink('sandbox last edit'))
		table.insert(tbargs, title:makeCompareLink(sandboxTitle, 'sandbox diff'))
	end
	-- Test cases links.
	local testcasesTitle = title:getSubpageTitle('시험장')
	if testcasesTitle and testcasesTitle.exists then
		table.insert(tbargs, testcasesTitle:makeViewLink('test cases'))
	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 = 'en',
				name = title.text,
				namespace = title.namespace,
			},
			fragment = 'bottom'
		}
		tclink = string.format('%s transclusion count', 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', 'protection log'))
	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(titles1)
	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 = 'It is requested that'
	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(titles1)
		else
			pagetype = 'pages'
		end
		return mw.ustring.format("%s edits be made to the following%s %s:", requested, protectionText, pagetype)
	end
	-- Deal with cases where we are passed only one title.
	local title = titles1
	local stringToFormat
	if title.exists then
		stringToFormat = '%s an edit be made to the%s %s at %s.'
	else
		stringToFormat = '%s the%s %s at %s be created.'
	end
	stringToFormat = "" .. stringToFormat .. ""
	return mw.ustring.format(stringToFormat, requested, protectionText, title.pagetype, 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 = "This template must be followed by a complete and specific description of the request, "
	if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
		local editText = 'edit'
		if isPlural then
			editText = editText .. 's'
		end
		local descriptionCompleteText = mw.ustring.format('so that an editor unfamiliar with the subject matter could complete the requested %s immediately.', editText)
		descriptionText = descriptionText .. descriptionCompleteText
	else
		descriptionText = descriptionText .. 'that is, specify what text should be removed and a verbatim copy of the text that should replace it. '
			.. "Please change X" is not acceptable and will be rejected; the request must be of the form "please change X to Y".
	end
	local smallText = 
	if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
		local templateFullText
		if boxProtectionLevel == 'sysop' then
			templateFullText = 'fully protected'
		elseif boxProtectionLevel == 'templateeditor' then
			templateFullText = 'template-protected'
		end
		smallText =	'Edit requests to ' .. templateFullText	.. " pages should only be used for edits that are either uncontroversial or supported by consensus."
			.. " If the proposed edit might be controversial, discuss it on the protected page's talk page before using this template."
	else
		local userText
		local responseTemplate
		if boxProtectionLevel == 'extendedconfirmed' then
			userText = '장기인증된 사용자'
			responseTemplate = blurb.makeTemplateLink('EEp')
		elseif boxProtectionLevel == 'autoconfirmed' then
			userText = '자동 인증된 사용자'
			responseTemplate = blurb.makeTemplateLink('ESp')
		elseif boxProtectionLevel == 'interfaceadmin' then
			userText = '인터페이스 관리자'
			responseTemplate = blurb.makeTemplateLink('EIp')
		else
			userText = 'user'
			responseTemplate = blurb.makeTemplateLink('ESp')
		end
		local answeredPara = blurb.makeParaText('answered', 'no')
		local stringToFormat =	'The edit may be made by any %s. '
			.. Remember to change the %s parameter to "yes" when the request has been accepted, rejected or on hold awaiting user input. 
			.. "This is so that inactive or completed requests don't needlessly fill up the edit requests category. "
			.. 'You may also wish to use the %s template in the response.'
		smallText = mw.ustring.format(stringToFormat, userText, answeredPara, responseTemplate)
	end
	if not isPlural then
		local title = titles1
		if title.namespace == 10 or title.namespace == 828 then
			local sandboxTitle = title:getSubpageTitle('연습장')
			if sandboxTitle and sandboxTitle.exists then
				smallText = smallText .. ' Consider making changes first to the '
					.. sandboxTitle:makeViewLink(title.pagetype .. "'s sandbox")
				local testcasesTitle = title:getSubpageTitle('시험장')
				if testcasesTitle and testcasesTitle.exists then
					smallText = smallText .. ' and ' .. testcasesTitle:makeViewLink('test them thoroughly here')
				end
				smallText = smallText .. ' before submitting an edit request.'
			end
		end
	end
	if hasNonInterfacePage then
		smallText = smallText .. ' To request that a page be protected or unprotected, make a protection request.'
	end
	if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' or boxProtectionLevel == 'interfaceadmin' then
		smallText = smallText .. ' When the request has been completed or denied, please add the ' .. blurb.makeParaText('answered', 'yes') .. ' parameter to deactivate the template.'
	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 Module: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', full = 'sysop', interface = 'interfaceadmin'}
	obj.boxProtectionLevel = boxProtectionLevelsprotectionType
	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.titles1.protectionLevel ~= 'unprotected' then
		obj.boxProtectionLevel = obj.titles1.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.svg'
	elseif boxProtectionLevel == 'interfaceadmin' then
		padlock = 'Interface-protection-shackle.svg '
	elseif boxProtectionLevel == 'templateeditor' then
		padlock = 'Template-protection-shackle.svg'
	elseif boxProtectionLevel == 'autoconfirmed' then
		padlock = 'Semi-protection-shackle.svg'
	elseif boxProtectionLevel == 'extendedconfirmed' then
		padlock = 'Extended-protection-shackle.svg'
	else
		padlock = 'Padlock-bronze-open.svg'
	end
	local stringToFormat = 'link='
	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 = 'Wikipedia semi-protected edit requests',
		extendedconfirmed = 'Wikipedia extended-confirmed-protected edit requests',
		templateeditor = 'Wikipedia template-protected edit requests',
		sysop = 'Wikipedia fully-protected edit requests',
		interfaceadmin = 'Wikipedia interface-protected edit requests'
	}
	addCat(protectionCatsboxProtectionLevel)
	if self.titles:hasOtherProtectionLevel(boxProtectionLevel) then
		addCat('Wikipedia edit requests possibly using incorrect templates')
	end
	return table.concat(cats)
end
function box:export()
	if not self.titles.currentTitle.isTalkPage and not self.demo then
		return '오류: 보호 편집 요청은 토론 문서에서만 할 수 있습니다.'
	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 Module:Protected edit request
----------------------------------------------------------------------
return function(superclass, yn, mb)
	yesno = yn
	makeMessageBox = mb
	return setmetatable(box, superclass)
end