Edit the documentation or categories for this module. This module has an i18n file.
local lang = mw.getLanguage('en')
local m_team = require('Module:Team')
local TeamHistory = require('Module:Infobox/TeamHist').teamHist
local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_game = require('Module:GameUtil')
local util_html = require('Module:HtmlUtil')
local util_infobox = require('Module:InfoboxUtil')
local util_map = require('Module:MapUtil')
local util_sentence = require("Module:SentenceUtil")
local util_table = require('Module:TableUtil')
local util_text = require("Module:TextUtil")
local util_title = require("Module:TitleUtil")
local util_toggle = require("Module:ToggleUtil")
local util_vars = require('Module:VarsUtil')
local i18n = require('Module:i18nUtil')
local RoleList = require('Module:RoleList')
local Country = require('Module:Country')
local CountryList = require('Module:CountryList')
local Region = require('Module:Region')
local RegionList = require('Module:RegionList')
local ChampionList = require('Module:ChampionList')
local PlayerCurrentTeam = require('Module:PlayerCurrentTeam').main
local IntroSentence = require('Module:IntroSentence/Player').main
local NOIMAGE = 'Unknown Infobox Image - Player.png'
local Infobox = require('Module:Infobox'):extends()
Infobox.type = 'Player'
Infobox.LAYOUT = {
tabs = 'PlayerTabsHeader',
sections = { 'Background Information', 'Competitive', 'Social Media & Links', 'Team History' },
contents = {
{ 'Name', 'Country', 'Nationality', 'Birthday', 'Died', 'Residency', 'ResidencyPrev' },
{ 'Team', 'Contract', 'Role', 'PreviousRole', 'Champions', 'CompIDs', 'SoloIDs' },
{ 'social', social = 'wide' },
{ 'teamhist', teamhist = 'wide' },
},
classes = { Residency = "infobox-region" },
}
local h = {} -- helper functions
local p = {}
function p.main(frame)
local args = util_args.merge()
return Infobox(args):run()
end
function Infobox:getSettings(args, processed)
local ret = self:super('getSettings', args, processed)
ret.nocat = false
return ret
end
function Infobox:castArgs(args)
self:super('castArgs', args)
args._display = args.id
args.role = RoleList(args.role, { sub = util_args.castAsBool(args.checkboxIsSub) })
args.favchamps = ChampionList(util_args.numberedArgsToTable(args, 'favchamp'))
args.residency = Region(args.residency)
args.res_prev1 = Region(args['residency-prev1'])
args.res_prev2 = Region(args['residency-prev2'])
args.res_prev = RegionList(util_args.numberedArgsToTable(args, 'residency-prev'))
args.country = Country(args.country)
args.nationality = CountryList(args.nationality)
args.hasAutoTeams = util_args.castAsBool(args.checkboxAutoTeams)
-- we only want to display a nationality if it's different from the country
if args.country:name() == args.nationality:names() then
args.nationality = CountryList()
end
args.isretiredplayer = util_args.castAsBool(args.isretiredplayer)
args.isretired = util_args.castAsBool(args.isretired)
args.towildrift = util_args.castAsBool(args.towildrift)
args.isLowContentHasBio = util_args.castAsBool(args.has_bio)
end
function Infobox:getProcessed(args)
if args.hasAutoTeams then
args.team = nil
args.team2 = nil
end
local processed = {
pagename = mw.title.getCurrentTitle().text,
bday = h.getBirthdayAndAgeIfAppropriate(args),
died = h.getDeathDateIfNeeded(args),
lc = args.id and lang:lcfirst(args.id) == args.id,
image = h.getImage(args),
}
processed.entity = processed.lc and util_text.lcfirst(processed.pagename) or processed.pagename
local teamhist, last = TeamHistory(args)
processed.teams = h.getTeamsTable(args, processed, last)
processed.teamhist = not args.hasAutoTeams and teamhist
processed.roleLast = h.getCargoLastRole(args, processed)
processed.resPrevList = h.getResPrevList(args, processed.teams, args.hasAutoTeams)
processed.contract = h.getContract(processed.teams)
return processed
end
function h.getImage(args)
if not util_args.castAsBool(args.checkboxAutoImage) then
return util_infobox.getFile(args.image, NOIMAGE)
end
return util_infobox.getFileNoExistenceCheck(h.queryForImage(args), NOIMAGE)
end
function h.getBirthdayAndAgeIfAppropriate(args)
local bday = util_infobox.makeBday(args.birth_date_year, args.birth_date_month, args.birth_date_day)
if args.died then
bday.age = nil
bday.displayandage = bday.display
end
return bday
end
function h.getDeathDateIfNeeded(args)
if not args.died then return {} end
return util_infobox.makeBday(args.birth_date_year, args.birth_date_month, args.birth_date_day, args.died)
end
function h.getTeamsTable(args, processed, last)
if args.hasAutoTeams then
return PlayerCurrentTeam(mw.title.getCurrentTitle().text)
end
local teams = h.getLegacyTeams(args, processed)
teams.last = last or {}
return teams
end
function h.getLegacyTeams(args, processed)
local ret = util_map.inPlace(
util_args.numberedArgsToTable(args, 'team') or {},
h.getOneLegacyTeam, args, processed
)
return ret
end
function h.getOneLegacyTeam(team, args, processed)
local ret = {
team = m_team.teamlinkname(team),
role = args.role,
sub = util_args.castAsBool(args.checkboxIsSub),
}
return ret
end
function h.getCargoLastRole(args, processed)
if not args.hasAutoTeams then return args.role end
-- role could be nil if player has 0 team entries
if not processed.teams.last.role then return args.role end
return processed.teams.last.role:_or(args.role)
end
function h.getResPrevList(args, teams, hasAutoTeams)
if not hasAutoTeams then
return args.res_prev
end
if not teams.resPrevList then return RegionList() end
if teams.resPrevList and #teams.resPrevList == 0 then return RegionList() end
local resPrevList = teams.resPrevList
return RegionList(util_table.concat(util_table.reverse(util_table.uniqueArray(resPrevList))))
end
function Infobox:getDisplay(args, processed)
local display = self:super('getDisplay', args, processed)
local tbl = {
title = args.id or processed.pagename,
image = not args.isLowContent and processed.image,
notice = h.getNotice(args),
-- background info
Name = args.name and (args.name .. (args.nativename and (' (%s)'):format(args.nativename) or '')),
Country = args.country:flair(),
Nationality = args.nationality:flairs{sep='<br>'},
Birthday = processed.bday.displayandage,
Died = processed.died.displayandage,
Residency = h.getResidencyAndNotes(args),
ResidencyPrev = processed.resPrevList:flairs{sep='<br>'},
-- competitive
Team = h.getCurrentTeam(processed.teams),
Contract = processed.contract,
Role = args.role:flairs{len='role'},
Champions = args.favchamps:images(),
CompIDs = util_table.concatFromArgs(args, 'compID',', '),
SoloIDs = args.ids,
-- social
teamhist = processed.teamhist,
class = h.getClass(args, processed)
}
return Infobox.mergeDisplay(display, tbl)
end
function h.queryForImage(args)
local query = {
tables = {
'PlayerRedirects=PR',
'PlayerImages=PI',
'Tournaments=T',
},
join = {
'PR.AllName=PI.Link',
'PI.Tournament=T.OverviewPage',
},
where = h.getImageWhere(args),
fields = { 'PI.FileName' },
orderBy = 'COALESCE(PI.SortDate, T.DateStartFuzzy, T.Date) DESC',
}
return util_cargo.getOneResult(query)
end
function h.getImageWhere(args)
local where = {
('PR._pageName="%s"'):format(mw.title.getCurrentTitle().text),
('PI._pageName IS NOT NULL'),
('PI.IsProfileImage="1"'),
}
return where
end
function h.getResidencyAndNotes(args)
if not args.residency_notes then return args.residency:flair() end
local residencyFlair = args.residency:flair()
local span = mw.html.create("span")
:wikitext(residencyFlair)
local popup = util_toggle.popupButton(span, "residency-note")
popup.inner:wikitext(args.residency_notes)
return tostring(span)
end
function h.getNotice(args)
-- args.died is not a boolean
if args.died then
return i18n.print('notice_deceased')
end
if args.isretiredplayer then
return i18n.print('notice_retiredPlayer')
end
if args.isretired then
return i18n.print('notice_retiredCompetition')
end
if args.towildrift then
return i18n.print('notice_towildrift')
end
return nil
end
function h.getCurrentTeam(teams)
if #teams == 0 then return nil end
return util_table.concat(
util_map.extractField(teams, 'team', m_team.rightmediumlinked),
'<br>'
)
end
function h.getContract(teams)
if #teams == 0 then return nil end
if not teams.contractDates then return nil end
if #teams == 1 then
return h.getContractDateFromFirstTeam(teams)
end
-- if they are on two teams but it's one org, we just show the date, nothing else
-- but if they're on more than one org then we need to show a team icon next to the contract date
local allSisterTeams = h.getListOfSisterTeamPages(teams)
if #allSisterTeams == 1 then
return h.getContractDateFromFirstTeam(teams)
end
return h.getAllContracts(teams)
end
function h.getContractDateFromFirstTeam(teams)
util_vars.log(teams.contractDates)
return teams.contractDates[teams[1].SisterTeamPage]
end
function h.getAllContracts(teams)
local contracts = {}
for _, team in ipairs(teams) do
local contract = teams.contractDates[team.SisterTeamPage]
if contract then
contracts[#contracts+1] = ('%s%s'):format(
m_team.onlyimagelinked(team.team),
contract
)
end
end
if #contracts == 0 then return nil end
return util_table.concat(contracts, '<br>')
end
function h.getListOfSisterTeamPages(teams)
local sisterTeamsUsed = {}
local allSisterTeams = {}
for _, team in ipairs(teams) do
if not sisterTeamsUsed[team.SisterTeamPage] then
allSisterTeams[#allSisterTeams+1] = team.SisterTeamPage
sisterTeamsUsed[team.SisterTeamPage] = true
end
end
return allSisterTeams
end
function h.getClass(args, processed)
local listOfClasses = {
args.hasAutoTeams and 'infobox-player-narrow',
args.isLowContent and 'infobox-low-content',
args.isLowContentHasBio and 'infobox-has-bio',
}
return util_table.concat(listOfClasses, ' ')
end
function Infobox:getCargo(args, processed)
local cargo = self:super('getCargo', args, processed)
cargo[#cargo+1] = h.getPlayersCargo(args, processed)
util_table.mergeArrays(
cargo,
h.getPlayerLeagueHistory(args)
)
return cargo
end
function h.getPlayersCargo(args, processed)
local ret = {
_table = 'Players',
OverviewPage = mw.title.getCurrentTitle().text,
Image = h.getImageCargo(args, processed),
Name = args.name,
Player = processed.entity,
NativeName = args.nativename,
NameAlphabet = args.namealphabet,
NameFull = args.name and (args.name .. (args.nativename and (' (%s)'):format(args.nativename) or '')),
Country = args.country,
Nationality = args.nationality,
NationalityPrimary = args.nationality:first(),
Age = processed.bday.age or '',
Birthdate = processed.bday.store or '',
Deathdate = processed.died.store or '',
ResidencyFormer = args['residency-prev1'] or processed.resPrevList:first(),
Team = processed.teams[1] and processed.teams[1].team,
Team2 = processed.teams[2] and processed.teams[2].team,
TeamSystem = 'PC',
Team2System = 'PC',
Residency = args.residency,
Role = args.role,
Contract = processed.contract,
FavChamps = util_table.concatFromArgs(args, 'favchamp', ','),
TeamLast = processed.teams.last and processed.teams.last.team,
RoleLast = processed.roleLast,
IsSubstitute = args.checkboxIsSub,
IsLowercase = processed.lc,
IsAutoTeam = args.checkboxAutoTeams,
SoloqueueIds = args.ids,
IsPersonality = args.page_type == 'Personality',
IsLowContent = args.isLowContent,
ID = args.id,
IsRetired = args.isretired or args.towildrift,
ToWildrift = args.towildrift,
-- social fields
Askfm = args.askfm,
Discord = args.discord,
Facebook = args.facebook,
Instagram = args.instagram,
Lolpros = args.lolpros,
Reddit = args.reddit,
Stream = args.stream,
Twitter = args.twitter,
Vk = args.vk,
Website = args.website,
Weibo = args.weibo,
Youtube = args.youtube,
}
return ret
end
function h.getImageCargo(args, processed)
if util_args.castAsBool(args.checkboxAutoImage) then
return nil
end
if processed.image == NOIMAGE then return nil end
if not processed.image then return nil end
return processed.image:gsub('_', ' ')
end
function h.getPlayerLeagueHistory(args)
if util_args.castAsBool(args.noplh) then return {} end
if not util_game.store_player_league_history then return {} end
local plhTable = require('Module:PlayerLeagueHistory')._main(mw.title.getCurrentTitle().text)
return plhTable
end
function Infobox:getDisambigSentence(args, processed)
-- we can't store "now known as" here but we can store everything else
-- the "now known as" text is going to have to change, but that's ok maybe
local replacements = {
RESIDENCY = args.residency:image(),
LINK = util_text.intLinkOrText(mw.title.getCurrentTitle().text),
-- TODO: should this, actually be country...?
NATIONALITY = args.country:exists() and args.country:get('adjective'),
FORMER = not processed.teams[1] and i18n.default('former') or '',
ROLE = processed.roleLast:sentence(),
TEAM = processed.teams[1] and m_team.rightmediumlinked(processed.teams[1].team),
-- NOW_KNOWN_AS = row.CurrentName and i18n.default('nowKnownAs', row.CurrentName) or '',
}
return util_sentence.makeReplacements(i18n.default('disambigSentence'), replacements)
end
function Infobox:getVariables(args, processed)
local variables = self:super('getVariables', args, processed)
local tbl = {
suppressorgnavbox = args.checkboxSuppressOrgNavbox,
introSentence = h.getIntroSentence(args, processed, 'Display'),
description = h.getIntroSentence(args, processed, 'Description'),
checkboxAutoTeams = args.checkboxAutoTeams,
residency = args.residency:get(),
isretired = args.isretired or args.isretiredplayer or args.towildrift or args.died,
towildrift = args.towildrift,
current_id = processed.entity,
isdeceased = args.died and true or false,
}
local i = 2
repeat
thisteam = 'team' .. i
tbl[thisteam] = args[thisteam] and m_team.teamlinkname(args[thisteam])
i = i + 1
until(not args[thisteam])
return util_table.merge(variables, tbl)
end
function h.getIntroSentence(args, processed, sentenceType)
local data = mw.clone(args)
local name = mw.text.split(args.name or '', ' ')
data.firstname = table.remove(name, 1)
data.lastname = table.concat(name, ' ')
data.lastteam = processed.teams.last.team
data.role = args.role:_or(processed.roleLast)
data.teamStr = args.team and m_team.teamlinkname(args.team)
data.isasub = util_args.castAsBool(args.checkboxIsSub)
data.ispersonality = args.page_type == 'Personality'
data.page_type = args.page_type
data.isretired = args.isretired
data.lastteampresent = h.getLastTeamPresent(args, processed)
data.currentTeamList = processed.teams
data.hasAutoTeams = args.hasAutoTeams
return IntroSentence(data, sentenceType)
end
function h.getLastTeamPresent(args, processed)
if processed.teams and #processed.teams > 0 then return true end
return processed.teams.last.date and processed.teams.last.date:find('Present')
end
function Infobox:getCategories(args, processed)
local inheritedCategories = self:super('getCategories', args)
local ns = mw.title.getCurrentTitle().nsText
if ns == 'Self' then
return { 'SelfPlayers', }
end
if ns ~= '' then return {} end
-- now assume ns is main
local tbl = {
'Players',
args.residency:exists() and args.residency:get('adjective') .. ' Residents',
not args.role:exists() and 'Players Without Role',
h.getSuspendedCategory(args, processed),
h.isAFreeAgent(args, processed) and 'Free Agents',
args.isretired and 'Retired Players',
args.birth_date_year and 'Players Born In ' .. args.birth_date_year,
args.role:has(nil, 'Coach') and 'Coaches',
not args.hasAutoTeams and 'Players without auto teams',
}
if args.country:exists() then
if args.page_type == 'Personality' then
tbl[#tbl+1] = ('%s Personalities'):format(args.country:get('adjective'))
else
tbl[#tbl+1] = 'Players Born in ' .. args.country:name{the=true}
end
end
for _, region in ipairs(processed.resPrevList) do
tbl[#tbl+1] = ('Former %s Residents'):format(region:get('adjective'))
end
if not util_args.castAsBool(args.checkboxAutoImage) then
tbl[#tbl+1] = 'Manual Image'
end
return util_table.mergeArrays(tbl, inheritedCategories)
end
function h.isAFreeAgent(args, processed)
if not args.hasAutoTeams then
if args.team then return false end
if args.isretired then return false end
return true
end
return not h.getCurrentTeam(processed.teams)
end
function h.getSuspendedCategory(args, processed)
if processed.teams.last.team ~= 'Suspended' then return false end
if not processed.teams.last.date then return false end
if not processed.teams.last.date:find('Present') then return false end
return 'Suspended Players'
end
return p