Prijeđi na sadržaj

Modul:Submit an edit request

Ovaj modul je pod trajnom zaštitom
Izvor: Wikipedija

-- This module implements {{Submit an edit request}}.

local CONFIG_MODULE = 'Module:Submit an edit request/config'

-- Load necessary modules
local mRedirect = require('Module:Redirect')
local cfg = mw.loadData(CONFIG_MODULE)
local effectiveProtectionLevel = require('Module:Effective protection level')._main
local escape = require('Module:String')._escapePattern
local lang = mw.language.getContentLanguage()

local p = {}

local validLevels = {
	semi = 'semi',
	extended = 'extended',
	template = 'template',
	full = 'full',
	interface = 'interface',
	manual = 'manual',
}

-- Localisation for Serbo-Croatian
local typeAliases = {
	['djelomična'] = 'semi',
	['djelomična zaštita'] = 'semi',

	['statusna'] = 'extended',
	['statusna zaštita'] = 'extended',

	['šablonska'] = 'template',
	['šablonska zaštita'] = 'template',

	['puna'] = 'full',
	['puna zaštita'] = 'full',
	['potpuna'] = 'full',
	['potpuna zaštita'] = 'full',

	['sučelje'] = 'interface',
	['sučeljska'] = 'interface',
	['zaštita sučelja'] = 'interface',
	['sučeljska zaštita'] = 'interface',

	['ručno'] = 'manual',
}

local protectionLevelAliases = {
	autoconfirmed = 'semi',
	extendedconfirmed = 'extended',
	templateeditor = 'template',
	sysop = 'full',
	interfaceadmin = 'interface',
	['interface-admin'] = 'interface',
}

local parameterAliases = {
	tip = 'type',
	vrsta = 'type',
	razina = 'type',
	prikaz = 'display',
	tekst = 'display',
	natpis = 'display',
	odgovoreno = 'answered',
	odg = 'answered',
}

local function normalizeLevel(level)
	if type(level) == 'string' then
		local value = mw.ustring.lower(mw.text.trim(level))
		return typeAliases[value] or value
	end

	return level
end

local function yesno(value, default)
	if value == nil then
		return default
	end

	if type(value) == 'boolean' then
		return value
	end

	value = mw.ustring.lower(mw.text.trim(tostring(value)))

	if value == 'yes' or value == 'y' or value == 'true' or value == '1'
		or value == 'da' or value == 'd' then
		return true
	elseif value == 'no' or value == 'n' or value == 'false' or value == '0'
		or value == 'ne' or value == 'nema' then
		return false
	end

	return default
end

local function normalizeArgs(args)
	local ret = {}

	for k, v in pairs(args or {}) do
		ret[k] = v
	end

	for alias, canonical in pairs(parameterAliases) do
		if ret[canonical] == nil and ret[alias] ~= nil then
			ret[canonical] = ret[alias]
		end
	end

	ret.type = normalizeLevel(ret.type)

	return ret
end

local function message(key, ...)
	local params = {...}
	local msg = cfg[key]

	if #params < 1 then
		return msg
	else
		return mw.message.newRawMessage(msg):params(params):plain()
	end
end

local function validateLevel(level)
	level = normalizeLevel(level)
	return level and validLevels[level]
end

local function getEffectiveRequestLevel(titleObj)
	if not titleObj then
		return nil
	end

	local level = effectiveProtectionLevel('edit', titleObj)
	return protectionLevelAliases[level]
end

local function getRequestLevel(level, titleObj)
	return validateLevel(level)
		or getEffectiveRequestLevel(titleObj)
		or 'full'
end

local function getEditintroLevel(level, titleObj)
	return validateLevel(level)
		or getEffectiveRequestLevel(titleObj)
end

local function getLevelInfo(level, field)
	local levelCfg = cfg.protectionLevels[level] or cfg.protectionLevels.full
	return levelCfg and levelCfg[field]
end

local function resolveRedirect(page)
	return mRedirect.luaMain(page)
end

local function isProtected(page)
	local titleObj = mw.title.new(page)
	if not titleObj then
		return false
	end

	local action = titleObj.exists and 'edit' or 'create'
	return effectiveProtectionLevel(action, titleObj) ~= '*'
end

local function getSubjectTitle(titleObj)
	if titleObj and titleObj.isTalkPage and titleObj.subjectPageTitle then
		return titleObj.subjectPageTitle
	end

	return titleObj
end

local function isTemplateOrModule(titleObj)
	return titleObj and (
		titleObj.namespace == 10
		or titleObj.namespace == 828
	)
end

local function makeSubpageLink(titleObj, subpageKey, displayKey, createDisplayKey)
	local subpage = message(subpageKey)
	local display = message(displayKey)
	local createDisplay = message(createDisplayKey)

	local subpageTitle = mw.title.new(titleObj.prefixedText .. '/' .. subpage)
	if not subpageTitle then
		return display
	end

	if subpageTitle.exists then
		return string.format(
			'[[%s|%s]]',
			subpageTitle.prefixedText,
			display
		)
	end

	return string.format(
		'<span class="plainlinks">[%s %s]</span>',
		tostring(mw.uri.fullUrl(subpageTitle.prefixedText, {
			action = 'edit',
		})),
		createDisplay
	)
end

local function getEditintroImage(level)
	local images = cfg['editintro-images'] or {}
	return images[level] or images.default or 'Semi-protection-shackle-no-text.svg'
end

local function makeEditintroText(titleObj)
	local ret = {}

	ret[#ret + 1] = string.format(
		'<div style="text-align: center; font-size: 140%%;">\'\'\'%s\'\'\'</div>',
		message('editintro-heading')
	)

	ret[#ret + 1] = '* ' .. message('editintro-main-page-request')
	ret[#ret + 1] = '* ' .. message('editintro-first-request')

	if isTemplateOrModule(titleObj) then
		local sandboxLink = makeSubpageLink(
			titleObj,
			'editintro-sandbox-subpage',
			'editintro-sandbox-display',
			'editintro-create-sandbox-display'
		)
		local testLink = makeSubpageLink(
			titleObj,
			'editintro-test-subpage',
			'editintro-test-display',
			'editintro-create-test-display'
		)

		ret[#ret + 1] = '* ' .. message(
			'editintro-specific-template',
			sandboxLink,
			testLink
		)
	else
		ret[#ret + 1] = '* ' .. message('editintro-specific-page')
	end

	ret[#ret + 1] = '* ' .. message('editintro-reasons')

	return table.concat(ret, '\n')
end

local function getRequestPageText(args)
	local pages = {}
	local i = 1

	while args[i] do
		local page = mw.text.trim(args[i])
		if page ~= '' then
			table.insert(pages, page)
		end
		i = i + 1
	end

	if #pages == 0 then
		return ''
	end

	local links = {}
	for _, page in ipairs(pages) do
		table.insert(links, '[[:' .. page .. ']]')
	end

	return message('request-page-text', table.concat(links, ', '))
end

local function getRequestCategory(level)
	local categories = cfg['request-categories'] or {}
	return categories[level] or categories.full
end

local function makeRequestText(level, pageText)
	local levelText = getLevelInfo(level, 'requestLevelText')
		or getLevelInfo(level, 'levelText')
		or getLevelInfo('full', 'requestLevelText')
		or getLevelInfo('full', 'levelText')

	return message('request-active-text', levelText, pageText)
end

local function makeAnsweredRequestText(pageText)
	return message('request-answered-text', pageText)
end

function p.makeRequestUrl(level, titleObj)
	titleObj = titleObj or mw.title.getCurrentTitle()

	local mainPageContent = cfg['main-page-content'] or {}
	local basePage = titleObj.basePageTitle.fullText
	if mainPageContent[basePage] then
		return tostring(mw.uri.fullUrl(message('main-page-request-page')))
	end

	local talkPageName = titleObj.talkPageTitle
	if talkPageName == nil then
		return tostring(mw.uri.fullUrl(message('protected-talk-page-request-page')))
	end

	talkPageName = resolveRedirect(talkPageName.prefixedText)
	if isProtected(talkPageName) then
		return tostring(mw.uri.fullUrl(message('protected-talk-page-request-page')))
	end

	level = getRequestLevel(level, titleObj)
	if level == 'manual' then
		return tostring(mw.uri.fullUrl(talkPageName, {
			action = 'edit',
			section = 'new',
		}))
	end

	local sectionname = message(
		'preload-title-text',
		getLevelInfo(level, 'levelText'),
		lang:formatDate(message('preload-title-date-format'))
	)

	local content = mw.title.new(talkPageName):getContent()
	if content and content:find('== *' .. escape(sectionname) .. ' *==') then
		local dedup = 2
		while true do
			local newname = message('preload-title-dedup-suffix', sectionname, dedup)
			if not content:find('== *' .. escape(newname) .. ' *==') then
				sectionname = newname
				break
			end
			dedup = dedup + 1
		end
	end

	local url = mw.uri.fullUrl(talkPageName, {
		action = 'edit',
		editintro = getLevelInfo(level, 'editintro'),
		preload = message('preload-template'),
		preloadtitle = sectionname,
		section = 'new',
	})
	url = tostring(url)

	-- Add the preload parameters. @TODO: merge this into the mw.uri.fullUrl
	-- query table once [[phab:T93059]] is fixed.
	local function encodeParam(key, val)
		return string.format('&%s=%s', mw.uri.encode(key), mw.uri.encode(val))
	end

	url = url .. encodeParam('preloadparams[]', getLevelInfo(level, 'requestTemplate'))
	url = url .. encodeParam('preloadparams[]', titleObj.prefixedText)
	url = url .. encodeParam('preloadparams[]', level)

	return url
end

function p._link(args)
	args = normalizeArgs(args)

	return string.format(
		'<span class="plainlinks">[%s %s]</span>',
		p.makeRequestUrl(args.type),
		args.display or message('default-display-value')
	)
end

function p._button(args)
	args = normalizeArgs(args)

	return require('Module:Clickable button').main{
		[1] = args.display or message('default-display-value'),
		url = p.makeRequestUrl(args.type),
		class = 'mw-ui-progressive',
	}
end

function p._editintro(args, titleObj)
	args = normalizeArgs(args)
	titleObj = getSubjectTitle(titleObj or mw.title.getCurrentTitle())

	local level = getEditintroLevel(args.type, titleObj)
	local image = getEditintroImage(level)

	local box = require('Module:Message box').main('tmbox', {
		type = 'notice',
		style = message('editintro-style'),
		image = string.format('[[File:%s|45px|link=|alt=]]', image),
		text = makeEditintroText(titleObj),
	})

	return tostring(
		mw.html.create('div')
			:addClass('mw-parser-output')
			:wikitext(box)
	)
end

function p._request(args)
	args = normalizeArgs(args)

	local level = getRequestLevel(args.type, mw.title.new(args[1] or ''))
	local answered = yesno(args.answered or args.ans, false)
	local demo = yesno(args.demo, false)
	local skiptalk = yesno(args.skiptalk, false)
	local titleObj = mw.title.getCurrentTitle()

	if not titleObj.isTalkPage and not demo and not skiptalk then
		local ret = message('request-not-on-talk-page-error')

		if titleObj.namespace ~= 10 then
			ret = ret .. '[[Kategorija:' .. message('request-not-on-talk-page-category') .. ']]'
		end

		return ret
	end

	local pageText = getRequestPageText(args)

	local boxArgs = {
		class = 'editrequest',
	}

	if answered then
		boxArgs.type = 'notice'
		boxArgs.small = 'yes'
		boxArgs.smalltext = makeAnsweredRequestText(pageText)
	else
		boxArgs.type = 'content'
		boxArgs.image = message('request-active-image')
		boxArgs.text = makeRequestText(level, pageText)
	end

	local ret = require('Module:Message box').main('tmbox', boxArgs)

	if not answered and not demo then
		local category = getRequestCategory(level)
		if category then
			ret = ret .. '[[Kategorija:' .. category .. ']]'
		end
	end

	return ret
end

local function makeInvokeFunc(func, wrapper)
	return function (frame)
		local options = {}
		if wrapper then
			options.wrappers = {wrapper}
		end

		local args = require('Module:Arguments').getArgs(frame, options)
		return func(args)
	end
end

p.link = makeInvokeFunc(p._link, message('link-wrapper-template'))
p.button = makeInvokeFunc(p._button, message('button-wrapper-template'))
p.request = makeInvokeFunc(p._request)

function p.editintro(frame)
	local args = require('Module:Arguments').getArgs(frame)
	return p._editintro(args)
end

return p