Bước tới nội dung

Mô đun:Protected edit request/active

Bách khoa toàn thư mở Wikipedia
require('strict')local yesno, makeMessageBox -- passed in from Mô đun:Protected edit requestlocal makeToolbar = require('Mô đun:Toolbar')._mainlocal getPagetype = require('Mô đun:Pagetype')._mainlocal effectiveProtectionLevel = require('Mô đun:Effective protection level')._main------------------------------------------------------------------------ Helper functions----------------------------------------------------------------------local function makeWikilink(page, display)	if display then		return mw.ustring.format('[[%s|%s]]', page, display)	else		return mw.ustring.format('[[%s]]', page)	endend------------------------------------------------------------------------ Title class------------------------------------------------------------------------ This is basically the mw.title class with some extras thrown in.local title = {}title.__index = titlefunction 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]endfunction 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 <span></span>]', 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 objend------------------------------------------------------------------------ TitleTable class----------------------------------------------------------------------local titleTable = {}titleTable.__index = titleTablefunction 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 < 1 then		local subjectNs = titles.currentTitle.subjectNsText		if subjectNs ~= '' then			subjectNs = subjectNs .. ':'		end		table.insert(titles, title.new(subjectNs .. titles.currentTitle.text))	end	-- Set the metatable.	setmetatable(titles, titleTable)	return titlesendfunction titleTable:memoize(memoField, func, ...)	if self[memoField] ~= nil then		return self[memoField]	else		self[memoField] = func(...)		return self[memoField]	endendfunction titleTable:titleIterator()	local i = 0	local n = #self	return function()		i = i + 1		if i <= n then			return self[i]		end	endendfunction titleTable:hasSameProperty(memoField, getPropertyFunc)	-- If the titles table has more than one title in it, check if they have the same property.	-- The property is found using the getPropertyFunc function, which takes a title object as its single argument.		local function hasSameProperty(getPropertyFunc)		local property		for i, obj in ipairs(self) do			if i == 1 then				property = getPropertyFunc(obj)			elseif getPropertyFunc(obj) ~= property then				return false			end		end		return true	end	return self:memoize(memoField, hasSameProperty, getPropertyFunc)end	function titleTable:hasSameExistenceStatus()	-- Returns true if all the titles exist, or if they all don't exist. Returns false if there is a mixture of existence statuses.	return self:hasSameProperty('sameExistenceStatus', function (title) return title.exists end)endfunction titleTable:hasSameProtectionStatus()	-- Checks if all the titles have the same protection status (either for creation protection or for edit-protection - the two are not mixed).	local sameExistenceStatus = self:hasSameExistenceStatus()	if sameExistenceStatus then		return self:hasSameProperty('sameProtectionStatus', function (title) return title.protectionLevel end)	else		return sameExistenceStatus	endendfunction titleTable:hasSamePagetype()	-- Checks if all the titles have the same pagetype.	return self:hasSameProperty('samePagetype', function (title) return title.pagetype end)endfunction titleTable:propertyExists(memoField, getPropertyFunc)	-- Checks if a title with a certain property exists.	-- The property is found using the getPropertyFunc function, which takes a title object as its single argument	-- and should return a boolean value.	local function propertyExists(getPropertyFunc)		for titleObj in self:titleIterator() do			if getPropertyFunc(titleObj) then				return true			end		end		return false	end	return self:memoize(memoField, propertyExists, getPropertyFunc)endfunction titleTable:hasNonInterfacePage()	return self:propertyExists('nonInterfacePage', function (titleObj) return titleObj.namespace ~= 8 end)endfunction titleTable:hasTemplateOrModule()	return self:propertyExists('templateOrModule', function (titleObj) return titleObj.namespace == 10 or titleObj.namespace == 828 end)endfunction titleTable:hasNonTemplateOrModule()	return self:propertyExists('nontemplateormodule', function (titleobj) return titleobj.namespace ~= 10 and titleobj.namespace ~= 828 end)endfunction titleTable:hasOtherProtectionLevel(level)	for titleObj in self:titleIterator() do		if titleObj.protectionLevel ~= level then			return true		end	end	return falseendfunction titleTable:getProtectionLevels()	local function getProtectionLevels()		local levels = {}		for titleObj in self:titleIterator() do			local level = titleObj.protectionLevel			levels[level] = true		end		return levels	end	return self:memoize('protectionLevels', getProtectionLevels)end------------------------------------------------------------------------ Blurb class definition----------------------------------------------------------------------local blurb = {}blurb.__index = blurbfunction blurb.new(titleTable, boxProtectionLevel)	local obj = {}	obj.titles = titleTable	obj.boxProtectionLevel = boxProtectionLevel	obj.linkCount = 0 -- Counter for the number of total items in the object's link lists. 	setmetatable(obj, blurb)	return objend-- Static methods --function blurb.makeParaText(name, val)	local pipe = mw.text.nowiki('|')	local equals = mw.text.nowiki('=')	val = val and ("''" .. val .. "''") or ''	return mw.ustring.format('<code style="white-space: nowrap;">%s%s%s%s</code>', pipe, name, equals, val)endfunction blurb.makeTemplateLink(s)	return mw.ustring.format('%s[[Bản mẫu:%s|%s]]%s', mw.text.nowiki('{{'), s,	s, mw.text.nowiki('}}'))endfunction 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('[[Wikipedia:Khóa trang|%s]]', protectionText)		end	end	error('Mức khóa không rõ ' .. boxProtectionLevel)endfunction blurb.getPagetypePlural(title)	local pagetype = title.pagetype	if pagetype == 'category' then		return 'categories'	else		return pagetype .. 's'	endend-- 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)endfunction blurb:makeLinkLists()	local titles = self.titles	if #titles == 1 then		return self:makeLinkList(titles[1])	else		local ret = {}		table.insert(ret, '<ul>')		for i, titleObj in ipairs(titles) do			table.insert(ret, mw.ustring.format('<li>%s %s</li>', titleObj:makeViewLink(titleObj.prefixedText), self:makeLinkList(titleObj)))		end		table.insert(ret, '</ul>')		return table.concat(ret)	endendfunction blurb:makeIntro()	local titles = self.titles	local requested = 'Có [[:Thể loại:Yêu cầu sửa đổi trang bị khóa|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))endfunction 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 [[Wikipedia:Quy định khóa|' .. templateFullText	.. "]] để thực hiện các sửa đổi '''không gây tranh cãi''' hoặc đã đạt được [[Wikipedia:Đồng thuận|đồ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 [[Wikipedia:Quyền truy cập của thành viên#Thành viên được xác nhận mở rộng|được xác nhận mở rộng]]'			responseTemplate = blurb.makeTemplateLink('EEp')		elseif boxProtectionLevel == 'autoconfirmed' then			userText = 'Thành viên [[Wikipedia:Quyền truy cập của thành viên#Thành viên tự xác nhận|tự động xác nhận]]'			responseTemplate = blurb.makeTemplateLink('ESp')		elseif boxProtectionLevel == 'interfaceadmin' then			userText = '[[Wikipedia:Quyền truy cập của thành viên#Thành viên được xác nhận mở rộng|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ể [[Wikipedia:Yêu cầu khóa hay mở khóa trang|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<p style="font-size:smaller; line-height:1.3em;">\n%s\n</p>', descriptionText, smallText)endfunction 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 = '<br />'	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 = boxfunction 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 objendfunction 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 = '[[Tập tin:%s|%dpx|alt=|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)endfunction 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('<span class="plainlinks" style="display:none">%s</span>', table.concat(ret))endfunction box:setBlurbText()	self:setArg('text', self.blurb:export() .. self:buildUrnLinks())endfunction 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)endfunction box:exportRequestCategories()	local cats = {}	local boxProtectionLevel = self.boxProtectionLevel	local function addCat(cat)		table.insert(cats, mw.ustring.format('[[Thể loại:%s]]', 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)endfunction box:export()	if not self.titles.currentTitle.isTalkPage and not self.demo then		return '<span class="error">Lỗi: Chỉ có thể yêu cầu sửa đổi trang bị khóa trên trang thảo luận.</span>[[Thể loại:Yêu cầu sửa đổi trang bị khóa không phải 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