มอดูล:Protected edit request/active

require('Module:No globals')
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'}
	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 = 'ป', oldid = 'ก'}, 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 = {'*' = 'ที่ไม่มีการป้องกัน', autoconfirmed = 'ที่กึ่งป้องกันไว้', extendedconfirmed = 'extended-confirmed-protected', templateeditor = 'แม่แบบถูกป้องกัน', sysop = 'ที่ป้องกันสมบูรณ์ไว้'}
	for level, protectionText in pairs(levels) do
		if level == boxProtectionLevel then
			return mw.ustring.format('%s', protectionText)
		end
	end
	error('Unknown protection level ' .. 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('แก้'))
	table.insert(tbargs, title:makeHistoryLink('ประวัติ'))
	table.insert(tbargs, title:makeLastEditLink('ล่าสุด'))
	table.insert(tbargs, title:makeWhatLinksHereLink('ลิงก์'))
	-- Sandbox links.
	local sandboxTitle = title:getSubpageTitle('sandbox')
	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('testcases')
	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', 'ปูมการป้องกัน'))
	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 = 'มีคำขอให้'
	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 = 'หน้า'
		end
		return mw.ustring.format("%sแก้ไขต่อหน้าต่อไปนี้ %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แก้ไขต่อ%s%sที่ %s'
	else
		stringToFormat = '%sให้สร้าง%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 = "แม่แบบนี้ต้องตามด้วยคำอธิบายที่สมบูรณ์และจำเพาะเจาะจงของคำขอ"
	if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
		local editText = 'edit'
		if isPlural then
			editText = editText .. 's'
		end
		local descriptionCompleteText = mw.ustring.format('เพื่อให้ผู้เขียนที่ไม่สันทัดกรณีในประเด็นเรื่องสามารถแก้ไขตามคำขอได้ทันที', editText)
		descriptionText = descriptionText .. descriptionCompleteText
	else
		descriptionText = descriptionText .. 'นั่นคือ เจาะจงว่าควรนำข้อความใดออกและสำเนาจดคำต่อคำของข้อความที่ควรใช้ทดแทน'
			.. "กรุณาเปลี่ยน X" ยอมรับไม่ได้ และจะถูกปฏิเสธ คำขอต้องอยู่ในรูป "กรุณาเปลี่ยน X เป็น Y"
	end
	local smallText = 
	if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
		local templateFullText
		if boxProtectionLevel == 'sysop' then
			templateFullText = 'หน้าป้องกันสมบูรณ์'
		elseif boxProtectionLevel == 'templateeditor' then
			templateFullText = 'แม่แบบที่ถูกป้องกัน'
		end
		smallText =	'คำขอแก้ไขต่อ' .. templateFullText .. "ควรใช้หน้าเฉพาะสำหรับการแก้ไขที่ไม่เป็นที่ถกเถียงหรือมีความเห็นพ้องสนับสนุน"
			.. " หากการแก้ไขที่เสนออาจเป็นที่ถกเถียง ให้อภิปรายก่อนในหน้าคุยของหน้าที่ถูกป้องกันก่อนใช้แม่แบบนี้"
	else
		local userText
		if boxProtectionLevel == 'extendedconfirmed' then
			userText = 'extended confirmed user'
		elseif boxProtectionLevel == 'autoconfirmed' then
			userText = 'ผู้ใช้ยืนยันอัตโนมัติ'
		else
			userText = 'ผู้ใช้'
		end
		local answeredPara = blurb.makeParaText('answered', 'no')
		local stringToFormat =	'%sทุกคนสามารถแก้ไขได้'
			.. พึงระลึกว่าเปลี่ยนตัวแปรเสริม%sเป็น "yes" เมื่อยอมรับ ปฏิเสธหรือพักคำขอเพื่อรอการอภิปรายของผู้ใช้แล้ว
			.. "เพื่อให้คำขอที่ไม่มีความเคลื่อนไหวหรือสำเร็จแล้วไม่เติมหมวดหมู่คำขอแก้ไขอย่างไม่จำเป็น"
			.. 'คุณยังอาจต้องการใช้แม่แบบ%sในการตอบ'
		smallText = mw.ustring.format(stringToFormat, userText, answeredPara, blurb.makeTemplateLink('ESp'))
	end
	if not isPlural then
		local title = titles1
		if title.namespace == 10 or title.namespace == 828 then
			local sandboxTitle = title:getSubpageTitle('sandbox')
			if sandboxTitle and sandboxTitle.exists then
				smallText = smallText .. ' พิจารณาเปลี่ยนแปลงในหน้า '
					.. sandboxTitle:makeViewLink("กระบะทรายของ" .. title.pagetype)
				local testcasesTitle = title:getSubpageTitle('หน้าทดลอง')
				if testcasesTitle and testcasesTitle.exists then
					smallText = smallText .. ' and ' .. testcasesTitle:makeViewLink('ทดสอบอย่างถี่ถ้วนที่นี่')
				end
				smallText = smallText .. ' ก่อนเสนอคำขอแก้ไข'
			end
		end
	end
	if hasNonInterfacePage then
		smallText = smallText .. ' คำขอให้ป้องกันหรือเลิกป้องกันหน้า ให้แจ้งผู้ดูแลระบบ'
	end
	if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
		smallText = smallText .. ' เมื่อแก้ไขตามคำขอแล้วหรือปฏิเสธคำขอ กรุณาเพิ่มตัวแปรเสริม ' .. blurb.makeParaText('answered', 'yes') .. ' เพื่อปิดใช้งานแม่แบบ'
	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'}
	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-block.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('หมวดหมู่:%s', cat))
	end
	local protectionCats = {
		autoconfirmed = 'คำขอแก้ไขหน้าที่ถูกกึ่งป้องกันวิกิพีเดีย',
		extendedconfirmed = 'Wikipedia extended-confirmed-protected edit requests', --ไม่มีการป้องกันประเภทนี้ใน thwiki
		templateeditor = 'Wikipedia template-protected edit requests', --ไม่มีการป้องกันประเภทนี้ใน thwiki
		sysop = 'คำขอแก้ไขหน้าที่ถูกป้องกันสมบูรณ์วิกิพีเดีย'
	}
	addCat(protectionCatsboxProtectionLevel)
	if self.titles:hasOtherProtectionLevel(boxProtectionLevel) then
		addCat('คำขอแก้ไขวิกิพีเดียที่อาจใช้แม่แบบไม่ถูกต้อง')
	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