We're currently performing an overhaul of our entire tournament results system so results will be missing from team and player pages for a while, and there may be some errors on tournament pages. Please bear with us as we complete this update.

Module:OrgNavbox

From Call of Duty Esports Wiki
Jump to: navigation, search

To edit the documentation or categories for this module, click here.


local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_map = require("Module:MapUtil")
local util_page = require("Module:PageUtil")
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_title = require('Module:TitleUtil')
local util_vars = require('Module:VarsUtil')
local m_team = require('Module:Team')

local lang = mw.getLanguage('en')
local systems = mw.loadData('Module:Systems')

local TeamMembers = require('Module:QueryTeamMembers').main

local SUFFIX, SYSTEM

-- structure of data:

-- aboveFold = thisteam, [thisteam] = { list of players }
-- belowFold = {
--		active = { team, team, team, }
--		inactive = { list, of, teams },
--		[team] = { list of players }, ........
-- }


local p = {}
local h = {}

function p.main(frame)
	local args = util_args.merge()
	if util_vars.getBool('suppressorgnavbox') then return '' end
	-- get inputs
	h.castArgs(args)
	local vars = h.getVariables(args)
	return p._makeNavbox(vars)
end

function p._makeNavbox(vars)
	if not vars.team then return '' end
	local data = h.getData(vars)
	if not data then return '' end
	SUFFIX = vars.suffix
	SYSTEM = vars.system
	h.processLinks(data)
	return h.makeOutput(data, vars)
end

function h.castArgs(args)
	-- args provided include team and is_player
	-- if we're on a player page, we also will know system already
	-- but if we're on a team page we'll have to query here, which we'll do later
	-- suffix is whether or not we care about the suffix of the page we're on
	args.suffix = util_args.castAsBool(args.suffix)
	args.team = args[1]
end

function h.getVariables(args)
	-- copy args to a separate internal object
	local title = util_title.titleTable()
	local ret = {}
	local titleteam = table.remove(title,1)
	ret.team = args.team
	ret.organization = args.organization
	ret.system = args.system and systems[args.system] or h.getSystemFromTitle(title)
	ret.teamlink = util_title.concatSubpage(ret.team, ret.system)
	ret.suffix = args.suffix and next(title) and table.concat(title,'/')
	ret.state = args.innerstate or 'mw-collapsed'
	return ret
end

function h.getSystemFromTitle(title)
	-- if we're on a team page then the system will be the 2nd part of the title
	-- this only applies to team pages because players aren't system-specific
	if title[1] and systems[title[1]] then
		return systems[table.remove(title,1)]
	end
	return nil
end

function h.getData(vars)
	-- to make a navbox, we must have either an active roster or sister teams
	-- if we have an active roster, we query that and it will go above the fold
	-- if we have sister teams, all of that goes below the fold
	local data = {}
	local active = false
	local thisteam = vars.team
	local thisteamlink = vars.teamlink
	if h.isActive(thisteamlink) then
		active = true
		data.aboveFold = thisteam
		data[thisteam] = h.getPlayers(thisteamlink)
	end
	if vars.team then
		h.addSisterTeamInfoToData(vars, data)
	end
	return (active or data.hasSister) and data
end

function h.isActive(teamlink)
	-- a team is active if both its page exists and also it's not disbanded
	if not mw.title.makeTitle('',teamlink).exists then return false end
	local query = {
		tables = 'Teams',
		fields = 'IsDisbanded [boolean]',
		where = string.format('_pageName="%s"',teamlink),
	}
	return not util_cargo.getOneResult(query)
end

function h.getPlayers(team)
	local result = TeamMembers(team)
	local playerData = {}
	for i, row in ipairs(result) do
		playerData[i] = row.Link
		playerData[row.Link] = {
			link = row.Link,
			ID = row.ID,
			RoleList = row.RoleList,
		}
	end
	return playerData
end

function h.addSisterTeamInfoToData(vars, data)
	-- all data about sister teams goes below the fold except sisterDataLocation & hasSister
	-- sisterDataLocation is to be used for the edit button of the navbox
	-- hasSister will be checked to see if we proceed with making the navbox or not & then ignored
	local row = h.getSisterTeamData(vars.team)
	if not row then return end
	data.belowFold = h.parseSisterTeamData(row)
	h.addSisterTeamPlayersToActiveData(data.belowFold)
	data.sisterDataLocation = row._pageName
	data.hasSister = true
end

function h.getSisterTeamData(team)
	local query = {
		tables = 'SisterTeams',
		fields = {
			"Status=Status",
			"_pageName",
			"ActiveList=ActiveList",
			"InactiveList=InactiveList"
		},
		where = ('Team="%s"'):format(m_team.teamlinkname(team)),
	}
	return util_cargo.getOneRow(query)
end

function h.parseSisterTeamData(row)
	local teamData = {
		active = util_text.splitNonempty(row.ActiveList),
		inactive = util_text.split(row.InactiveList),
	}
	if not teamData.inactive then return end
	for _, team in ipairs(teamData.inactive) do
		teamData.inactive[team] = { link = team, name = team }
	end
	return teamData
end

function h.addSisterTeamPlayersToActiveData(belowFold)
	for _, team in ipairs(belowFold.active) do
		belowFold[team] = h.getPlayers(team)
	end
end

-- process links

-- need to figure out how to deal with different systems & links
-- but i think that will be handled with team links / sister team concepts
function h.processLinks(data)
	-- we want the navbox to link to corresponding subpages always
	-- so make a long list of all links we have, and then determine existence
	-- make a lookup table that we'll refer to when printing to decide if we link to the subpage or not
	local linksToCheck = h.getListOfAllLinks(data)
	util_map.inPlace(linksToCheck, util_title.concatSubpage, SUFFIX)
	local linksHash = util_table.hash(util_page.whichPagesExist(linksToCheck))
	h.processLinksInData(data, linksHash)
end

function h.getListOfAllLinks(data)
	local linksToCheck = {}
	if data.aboveFold then
		linksToCheck[#linksToCheck+1] = data.aboveFold
		linksToCheck[#linksToCheck+1] = util_title.concatSubpageSystem(data.aboveFold, SYSTEM)
		util_table.mergeArrays(linksToCheck, data[data.aboveFold])
	end
	if data.belowFold then
		util_table.mergeArrays(linksToCheck, data.belowFold.inactive)
		for k, v in ipairs(data.belowFold.active) do
			linksToCheck[#linksToCheck+1] = v
			util_table.mergeArrays(linksToCheck, data.belowFold[v])
		end
	end
	return linksToCheck
end

function h.processLinksInData(data, linksHash)
	-- we need 3 pieces of information per link: the link, the display, and whether the proper subpage exists (so we can add the class if needed)
	-- where before we had a table of links, we can add tables of names/exists by adding extra data
	-- where we had a constant, we need to transform to having a table of information
	h.addExtraDataToLinkTables(data[data.aboveFold], linksHash)
	data.aboveFold = h.transformLinkToTable(data.aboveFold, linksHash)
	if data.belowFold then
		for i, team in ipairs(data.belowFold.active) do
			h.addExtraDataToLinkTables(data.belowFold[team], linksHash)
			data.belowFold.active[i] = h.transformLinkToTable(team, linksHash)
		end
		h.addExtraDataToLinkTables(data.belowFold.inactive, linksHash)
	end
	return
end

function h.addExtraDataToLinkTables(list, hash)
	if not list or not next(list) then return end
	for k, v in ipairs(list) do
		local newlink = util_title.concatSubpage(v, SUFFIX)
		local exists = hash[lang:ucfirst(newlink)]
		list[v].exists = exists
		list[v].link = exists and newlink or v
	end
	return
end

function h.transformLinkToTable(link, linksHash)
	if not link then return nil end
	local newlink = util_title.concatSubpage(link, SUFFIX)
	local exists = linksHash[lang:ucfirst(newlink)]
	return {
		name = link,
		exists = exists,
		link = exists and newlink or link
	}
end

-- print output
function h.makeOutput(data, args)
	-- navboxargs will be sent to Template:Navbox
	-- if there's an active roster, then the active roster is printed expanded above the fold
	-- then if there's sister team data we print that below the fold
	local thisteam = data.aboveFold
	local navboxargs = {
		name = data.sisterDataLocation or 'OrgNavbox',
		state = 'mw-collapsible'
	}
	local i = 1
	if thisteam then
		navboxargs.group1 = h.makeOneLink(
			util_title.concatSubpageSystem(thisteam.link, SYSTEM),
			m_team.teammediumname(thisteam.name),
			thisteam.exists
		)
		navboxargs.list1 = h.makePlayersOutput(data[thisteam.name])
		navboxargs.title = h.makeNavboxTitle(thisteam.name, 'Roster')
		i = i + 1
	else
		navboxargs.title = h.makeNavboxTitle(args.team, 'Organization')
	end
	
	if data.belowFold then
		navboxargs['list' .. i] = h.belowFold(data.belowFold, args.innerstate)
	end
	return mw.getCurrentFrame():expandTemplate{ title = 'Navbox', args = navboxargs }
end

function h.makeNavboxTitle(thisteam, defaulttext)
	return ('<span class="%s">%s</span> %s'):format(
		SUFFIX and 'no-subpage' or '',
		m_team.rightlonglinked(thisteam, { system = SYSTEM, size = 45 }),
		SUFFIX and ('- ' .. SUFFIX) or defaulttext
	)
end

function h.belowFold(data, state)
	-- print all of the active teams along with their list of players
	-- then print all of the inactive teams just as a list
	-- we return an already-made template that gets passed to the outer navbox as an arg
	local navboxargs = {
		'child',
		title = 'Other Teams In Organization (Click [Show] to the Right)',
		state = state
	}
	for i, v in ipairs(data.active) do
		navboxargs['group' .. i] = h.makeOneLink(
			util_title.concatSubpageSystem(v.link, SYSTEM),
			v.name,
			v.exists
		)
		navboxargs['list' .. i] = h.makePlayersOutput(data[v.name])
	end
	if data.inactive then
		navboxargs.below = h.makeTeamsOutput(data.inactive)
	end
	return mw.getCurrentFrame():expandTemplate{ title = 'Navbox', args = navboxargs }
end

function h.makePlayersOutput(data)
	local display = {}
	for _, link in ipairs(data) do
		local linkInfo = data[link]
		display[#display+1] = ('%s%s'):format(
			linkInfo.RoleList:images() or '',
			h.makeOneLink(linkInfo.link, linkInfo.ID, linkInfo.exists)
		)
	end
	return util_table.concat(display,' &#8226; ')
end

function h.makeTeamsOutput(data)
	local display = {}
	for _, link in ipairs(data or {}) do
		local linkInfo = data[link]
		display[#display+1] = h.makeOneLink(linkInfo.link, linkInfo.name, linkInfo.exists)
	end
	local output = table.concat(display,' &#8226; ')
	return output
end

function h.makeOneLink(link, name, exists)
	-- concat link and display, adding the span class if it's not linking to the right subpage
	if (not SUFFIX) or exists then
		return util_text.intLink(link, name)
	else
		return ('<span class="no-subpage">[[%s|%s]]</span>'):format(link, name or link)
	end
end	

return p