Jump to content

Module:Itemgroup

Ón Vicipéid, an chiclipéid shaor.

Documentation for this module may be created at Module:Itemgroup/doc

local p = {}

-- Argument is 'set' when it exists (not nil) or when it is not an empty string.
local function isSet(var)
	return not (var == nil or (type(var) == 'string' and mw.text.trim(var) == ''))
end

local function getEntityId(frame)
	local id = frame.args.item
	if not isSet(id) then
		id = frame:getParent().args.item
	end
	if not isSet(id) then
		id = mw.wikibase.getEntityIdForCurrentPage()
	end
	return id
end

-- get safely a serialized snak
local function getSnak(statement, snaks)
	local ret = statement
	for i, v in ipairs(snaks) do
		if not ret then return end
		ret = ret[v]
	end
	return ret
end

local function getPropIds(qid, pid)
	local statements = mw.wikibase.getAllStatements(qid, pid)
	if #statements == 0 then
		statements = mw.wikibase.getAllStatements(qid, "P31")
	end
	local ret = {}
	for _, statement in ipairs(statements) do
		if statement.rank ~= "deprecated" then
			local value_id = getSnak(statement, {"mainsnak", "datavalue", "value", "id"})
			if value_id then
				table.insert(ret, value_id)
			end
		end
	end
	return ret
end

local function tableQidKey(data_in) -- fill a table qid = key
	local data_out = {}
	for k, t in pairs(data_in) do
		for i, v in ipairs(t) do
			data_out[v] = k
		end
	end
	return data_out
end

-- removes duplicate values from an array
local function removeDuplicates(t)
	local ret, exists = {}, {}
	for _, v in ipairs(t) do
		if not exists[v] then
			ret[#ret + 1] = v
			exists[v] = true
		end
	end
	return ret
end

function p.parent(frame)
	local qid = getEntityId(frame)
	local prop = frame.args.p
	local data_def = require("Module:Itemgroup/parent")[frame.args[1]]
	if not (qid and prop and data_def) then return end
	local data = tableQidKey(data_def)
	
	local items = {qid}
	for iter = 1, 5 do -- arbitrary max iter set heuristically
		local next_items = {}
		for _, item in ipairs(items) do
			local ids = getPropIds(item, prop)
			for _, id in ipairs(ids) do
				if data[id] then
					return data[id] -- first value id found, that's all
				else
					table.insert(next_items, id) -- save for next iteration
				end
			end
		end
		items = removeDuplicates(next_items)
	end
	
	return data['default']
end

function p.group(frame)
	local qid = getEntityId(frame)
	local data_def = require("Module:Itemgroup/groups")[frame.args[1]]
	if not (qid and data_def) then return end
	local data = tableQidKey(data_def)
	
	return data[qid]
end

function p.list(frame)
	local data_def = require("Module:Itemgroup/list")[frame.args[1]]
	if data_def and data_def[frame.args[2]] then
		return table.concat(data_def[frame.args[2]], ',')
	end
	return
end

return p