Module:Item util
This is a meta module.
This module is meant to be used only by other modules. It should not be invoked in wikitext.
This meta module provides utility functions for modules that deal with items.
Usage
This module should be loaded with require()
.
The above documentation is transcluded from Module:Item util/doc.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
-------------------------------------------------------------------------------
--
-- Module:Item util
--
-- This meta module contains utility functions for modules that deal with items
-------------------------------------------------------------------------------
local m_util = require('Module:Util')
local m_cargo -- Lazy load require('Module:Cargo')
-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Item util')
-- The cfg table contains all localisable strings and configuration, to make it
-- easier to port this module to another wiki.
local cfg = use_sandbox and mw.loadData('Module:Item util/config/sandbox') or mw.loadData('Module:Item util/config')
local i18n = cfg.i18n
-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------
local m = {}
function m.get_item_namespaces(args)
-- Returns item namespaces from config as a table or as a comma-separated string
args.format = args.format or 'table'
if args.format == 'list' then
return cfg.item_namespaces_list
end
return cfg.item_namespaces
end
function m.query_item(args)
m_cargo = m_cargo or require('Module:Cargo')
if not m_util.table.has_any_key(args, cfg.search_terms) then
error(i18n.errors.missing_search_term)
end
local tables = {'items'}
local fields = {
'items._pageName=_pageName',
'items.drop_enabled=drop_enabled',
'items.class_id=class_id',
}
if type(args.fields) == 'table' and #args.fields > 0 then
fields = m_util.table.merge(fields, args.fields)
end
local query = {
groupBy = 'items._pageID',
orderBy = 'items.drop_enabled DESC',
}
local search_param
local results
if args.metadata_id then
query.where = string.format(
'items.metadata_id = "%s"',
args.metadata_id
)
search_param = 'metadata_id'
elseif args.page then
-- Join with _pageData in order to check for page redirect
tables[#tables+1] = '_pageData'
query.join = 'items._pageName = _pageData._pageNameOrRedirect'
query.where = string.format(
'_pageData._pageName = "%s"',
m_cargo.addslashes(args.page)
)
search_param = 'page'
else
tables[#tables+1] = 'maps'
tables[#tables+1] = 'map_series'
query.join = 'items._pageID = maps._pageID, maps.series = map_series.name'
query.where = string.format(
'items._pageNamespace IN (%s)',
m.get_item_namespaces{format = 'list'}
)
query.orderBy = 'map_series.ordinal DESC, items.drop_enabled DESC'
if args.item_name_exact then
query.where = query.where .. string.format(
' AND items.name = "%s"',
m_cargo.addslashes(args.item_name_exact)
)
search_param = 'item_name_exact'
else
query.where = query.where .. string.format(
' AND items.name_list HOLDS "%s"',
m_cargo.addslashes(args.item_name)
)
search_param = 'item_name'
end
end
results = m_cargo.query(tables, fields, query)
local err
if #results == 0 then
-- No results found
err = m_util.misc.raise_error_or_return{
raise_required = true,
args = args,
msg = string.format(
i18n.errors.no_results_found,
search_param,
args[search_param]
)
}
elseif #results > 1 then
-- More than one result found
--
-- If results are all maps, use the one from the most recent map
-- series, regardless of whether it's drop enabled. Otherwise,
-- if only one of the results is drop enabled then use that one.
local map_count = 0
local drop_enabled_count = 0
for i, v in ipairs(results) do
if v['class_id'] == 'Map' then
map_count = map_count + 1
end
if m_util.cast.boolean(v['items.drop_enabled']) then
drop_enabled_count = drop_enabled_count + 1
end
end
if (map_count == 0 or map_count ~= #results) and drop_enabled_count ~= 1 then
err = m_util.misc.raise_error_or_return{
raise_required = true,
args = args,
msg = string.format(
i18n.errors.many_results_found,
search_param,
args[search_param]
)
}
end
end
if err ~= nil and not m_util.cast.boolean(args.nocat) then
return {error = err .. m_util.misc.add_category({args.error_category or i18n.categories.failed_query}) }
end
return results[1] -- orderBy ensures that the first result is the one we want
end
return m